Potion of Hiding & Potion of Sneaking do nothing?

Discussion in 'General Modification' started by Rudy, Mar 15, 2015.

Remove all ads!
  1. Rudy

    Rudy Established Member

    Joined:
    Jan 30, 2005
    Messages:
    345
    Likes Received:
    2
    It does work, and it is very clever.

    Unfortunately, potions that you craft do not have the icon :(. So, I'm not sure what to do here. The significant majority of these new potions that you will see in use will be ones crafted by the player, not found unidentified.
     
  2. Gaear

    Gaear Bastard Maestro Administrator

    Joined:
    Apr 27, 2004
    Messages:
    11,029
    Likes Received:
    42
    I think you can already just use 'give x' and 'create x' in the console if you're using Co8. (Create is unidentified IIRC.)

    Don't forget about transparencies in the icons. The black background has to be transparent so that when you drag the image around in inventory, only the icon shows. If you don't draw over any of the existing transparency in Photoshop, you may retain the transparency in your new image, but if you do stuff like copy/paste into .psd files for example, it'll go away and you'll have to remake the transparency yourself.
     
  3. Rudy

    Rudy Established Member

    Joined:
    Jan 30, 2005
    Messages:
    345
    Likes Received:
    2
    Don't worry, I did the transparencies. :)

    marc: I'm fairly certain the icons won't show up for potions bought in the shops, either, since those are just set to identified, rather than having an identify spell cast on them. For now, I'm just going to leave the icons for all of them. But, if you have any other ideas, I'm very glad to hear them.
     
  4. Rudy

    Rudy Established Member

    Joined:
    Jan 30, 2005
    Messages:
    345
    Likes Received:
    2
    Oh, and Gaear is right about "create x" giving an unidentified item (on the ground).
     
  5. marc1967

    marc1967 Established Member

    Joined:
    Jan 19, 2014
    Messages:
    578
    Likes Received:
    60
    I can't think of any elegant solutions to this, so if you go with those icons you'll just have to keep them in the proto and have them appear on the unidentified potions also. It' s not a big deal, but from a purist point of view, it kind of bothers me.

    The best I can think of, and this is extremely wasteful and I'm not recommending it, is to have a separate proto for an unidentified version, and then when it gets identified just destroy the potion and create the one with the icon. There should be a simpler solution, maybe someone else can think of one.
     
  6. Rudy

    Rudy Established Member

    Joined:
    Jan 30, 2005
    Messages:
    345
    Likes Received:
    2
    Well, there is only one of these that actually exists in the game in an unidentified state, and that is the Protection From Fire one. And while I wouldn't mind creating one extra proto, I don't think messing around with both read magic and identify is worth it to handle one potion.
     
  7. Rudy

    Rudy Established Member

    Joined:
    Jan 30, 2005
    Messages:
    345
    Likes Received:
    2
    Would you think it preferable to just have two different Potions of Protection from Fire? One would not have the icon, and would be the one that exists unidentified in the game. The other would have the icon, and be the one that you craft and find in shops.

    The downside, of course, would be the ones that you find in the temple and identify would not stack with the others, and would be the only ones without an icon, even after they were identified.
     
  8. marc1967

    marc1967 Established Member

    Joined:
    Jan 19, 2014
    Messages:
    578
    Likes Received:
    60
    You're right, it's not worth it for just the one unidentified potion. Just put the label on the unidentifed potion too. My mindset right now is thinking that any potion can potentially turn up anywhere in a treasure hoard, but since it's just that one prot/fire potion, it should all be ok.
     
  9. marc1967

    marc1967 Established Member

    Joined:
    Jan 19, 2014
    Messages:
    578
    Likes Received:
    60
    Rudy, In regards to changing the original Spell711 - Potion of protection from fire.py from the potion condition to the protection from elements condition, you made this change:

    From:
    Code:
    target.obj.condition_add_with_args( 'sp-Potion of protection from energy', spell.id, spell.duration, D20DT_FIRE, protection_pts )
    
    To:
    Code:
    target_item.obj.condition_add_with_args( 'sp-Protection From Elements', spell.id, spell.duration, element_type )
    It seems to be working well, but I noticed something unusual which maybe you can answer:


    The code in Spell369 - Protection From Elements.py makes the call like this:

    Code:
    target_item.obj.condition_add_with_args( 'sp-Protection From Elements', spell.id, [COLOR="Green"]element_type[/COLOR], [COLOR="Red"]spell.duration[/COLOR] )
    
    While the call you make in Spell711 - Potion of protection from fire.py makes the call like this:

    Code:
    target_item.obj.condition_add_with_args( 'sp-Protection From Elements', spell.id, [COLOR="Red"]spell.duration[/COLOR], [COLOR="Green"]element_type[/COLOR] )

    Notice the 3rd and 4th arguments are swapped, but they both seem to be working just fine which is confusing.

    Any thoughts?
     
  10. Rudy

    Rudy Established Member

    Joined:
    Jan 30, 2005
    Messages:
    345
    Likes Received:
    2
    Yeah, I did notice that too. It's very odd; all the rest of the spells that I saw have the same format:

    1st parameter is the condition
    2nd parameter is the spell.id
    3rd parameter is the spell.duration

    Protection from Elements, for whatever bizarre reason, switches the 3rd and 4th parameters. You can switch them, and it works fine.

    My only theory is that internally it can accept the parameters in either order, based on the parameter type. I'm not sure if that's something inherent to Pyton, or something special written into the function.
     
  11. marc1967

    marc1967 Established Member

    Joined:
    Jan 19, 2014
    Messages:
    578
    Likes Received:
    60
    That's the only thing that makes sense, since both calls work properly. It's nothing specific to python that I know of, but it could certainly be programmed into the function.
     
  12. Sitra Achara

    Sitra Achara Senior Member

    Joined:
    Sep 1, 2003
    Messages:
    3,613
    Likes Received:
    537
    LOL, I just looked at the code that applies this condition. Check this out.

    Code:
    .text:100CEF23         mov     eax, [esp+0AECh+var_SpellPktBody.nBaseCasterLevel]
    .text:100CEF27         lea     eax, [eax+eax*2]
    .text:100CEF2A         shl     eax, 2
    .text:100CEF2D         cmp     eax, 78h ; 'x'
    .text:100CEF30         jle     short loc_100CEF37
    .text:100CEF30
    .text:100CEF32         mov     eax, 78h ; 'x'
    .text:100CEF32
    .text:100CEF37
    .text:100CEF37 loc_100CEF37:                           ; CODE XREF: sub_100CEEF0+40j
    .text:100CEF37         mov     edx, [esi+SubDispLstNode.pRootCondNode]
    .text:100CEF3A         push    eax                     ; argIn
    .text:100CEF3B         push    3                       ; nCondArgIdx
    .text:100CEF3D         push    edx                     ; pCondNode
    .text:100CEF3E         call    Condition_Node__Set_Arg
    .text:100CEF43         mov     eax, [esi+SubDispLstNode.pRootCondNode]
    .text:100CEF46         push    1                       ; n
    .text:100CEF48         push    eax                     ; pConditionNode
    .text:100CEF49         call    Condition_Node__Get_arg_n
    .text:100CEF49
    .text:100CEF4E         add     esp, 14h
    .text:100CEF51         dec     eax
    .text:100CEF52         cmp     eax, 0Fh                ; switch 16 cases
    .text:100CEF55         ja      return_0                ; jumptable 100CEF62 default case
    ...
    
    .text:100CEFE9         mov     eax, [esi+SubDispLstNode.pRootCondNode]
    .text:100CEFEC         add     esp, 10h
    .text:100CEFEF         push    edi
    .text:100CEFF0         push    2                       ; n
    .text:100CEFF2         push    eax                     ; pConditionNode
    .text:100CEFF3         call    Condition_Node__Get_arg_n
    .text:100CEFF3
    .text:100CEFF8         mov     ecx, [esi+SubDispLstNode.pRootCondNode]
    .text:100CEFFB         push    1                       ; n
    .text:100CEFFD         push    ecx                     ; pConditionNode
    .text:100CEFFE         mov     edi, eax
    .text:100CF000         call    Condition_Node__Get_arg_n
    .text:100CF000
    .text:100CF005         mov     edx, [esi+SubDispLstNode.pRootCondNode]
    .text:100CF008         push    eax                     ; argIn
    .text:100CF009         push    2                       ; nCondArgIdx
    .text:100CF00B         push    edx                     ; pCondNode
    .text:100CF00C         call    Condition_Node__Set_Arg
    .text:100CF00C
    .text:100CF011         mov     eax, [esi+SubDispLstNode.pRootCondNode]
    .text:100CF014         push    edi                     ; argIn
    .text:100CF015         push    1                       ; nCondArgIdx
    .text:100CF017         push    eax                     ; pCondNode
    .text:100CF018         call    Condition_Node__Set_Arg
    
    TLDR:
    It actually switches the 2nd and 3rd argument!
    You may ask then why both work. That is because if the 2nd arg is > 15 (which it most likely is for duration) then it skips the switch! In other words, it's as if you did the switch by hand :p

    It seems though that the 2nd arg should be element_type, since there's a switch case statement that goes on that arg. It also plays a sound depending on the selection - do you hear a sound in the case where the duration is there first?

    P.S. for reference my notation here is
    condition_add('cond name', 1st arg, 2nd arg, 3rd arg)

    Also, there's code in there that prevents potions of the same element type from stacking - it checks for the 2nd arg, which should thus be element_type.
     
    Last edited: Mar 23, 2015
  13. marc1967

    marc1967 Established Member

    Joined:
    Jan 19, 2014
    Messages:
    578
    Likes Received:
    60
    Wow, that is really weird and enlightening, I knew you couldn't resist digging into this. ;) I'm going by your English translation because I seriously can't read code like that, heh. As someone who delves into code like this a lot, do you see things like that ever? And what was the reason do you think? Did the boss say to one of the lead programmers "hey look, our scripters aren't the brightest, so make the code that if they screw up the arguments it'll still work."

    Also, one of the element types is SONIC, which is 16, and everything still works in either order, so I wonder if that 15 you saw was a 16. I can't see it in the code anywhere.

    BUGS: So both of the methods do work, but each one has a unique 'bug' I found. There are probably others.:

    If duration is the 2nd argument, it plays no sound when cast, as you predicted.

    If element type is the 2nd argument, everything seems ok, but if you accidentally activate another call (drink another potion) while another is active the halo particle effect is permanent after the spell wears off. "Help me Jaroo!!" This lingering halo does not happen if duration is the 2nd argument.

    Not sure which 'bug' is the worst offender.
     
    Last edited: Mar 23, 2015
  14. Rudy

    Rudy Established Member

    Joined:
    Jan 30, 2005
    Messages:
    345
    Likes Received:
    2
    So, so, bizarre...

    marc: What do you mean by "if you accidentally activate a call"?
     
  15. marc1967

    marc1967 Established Member

    Joined:
    Jan 19, 2014
    Messages:
    578
    Likes Received:
    60


    I meant drink another potion while one is already active, but was speaking technically because the call could potentially come from somewhere else, although nothing actually does right now. =P

    Hey a found a CTD bug in the Potion of Protection From Cold (CL 9), and Potion of Protection From Sonic (CL 9) in protos.tab. The spell that is cast when the potion is consumed missing the "Potion of" before it. So they are trying to cast a spell that has no entry in spell_enum.mes.

    It was a simple fix in protos.tab (via World Builder):

    8044, Potion of Protection From Cold (CL 9):
    change: 'Protection from Cold' domain_special 5
    to: 'Potion of Protection from Cold' domain_special 5

    8045, Potion of Protection From Sonic (CL 9):
    change: 'Protection from Sonic' domain_special 5
    to: 'Potion of Protection from Sonic' domain_special 5

    I spent much of the day incorporating all this into my files, and it's working great. Other than the minor stuff above, everything looks solid and I highly recommend to those in charge that these changes get put in. So many lingering things fixed that have been there since the beginning. Oddly one of my favorite fixes was fixing the duration of Resist Energy to 10 mins/level as it is supposed to be.

    Oh one more thing. The potion names are really long, and when you are crafting they wrap around each other in the crafting window and can get hard to read. I wonder if shortening the names is a possibility?
     
Our Host!