desire help with monster that can drop and retrieve object

Ask about ACS, DECORATE, ZScript, or any other scripting questions here!

Moderator: GZDoom Developers

Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.

Please bear in mind that the people helping you do not automatically know how much you know. You may be asked to upload your project file to look at. Don't be afraid to ask questions about what things mean, but also please be patient with the people trying to help you. (And helpers, please be patient with the person you're trying to help!)

desire help with monster that can drop and retrieve object

Postby bimshwel » Tue Jun 14, 2022 12:59 pm

I have had success using ints before to control this sort of thing, and think I could make this work by incorporating those and custom pain frames, but it seems like inventory commands would make more sense, yet I evidently do not understand how they work. It is not CRUCIAL that this work, but I got it into my mind that it COULD work after observing the various documented child/sibling/master and inventory A_s, and so assembled this mess
Code: Select allExpand view
actor fyop2 : fyip 10007
{
health 70
translation "fyip3"
     Speed 7
          xScale 0.078
             yScale 0.072
      states
      {
          Spawn:
               fepd i 1 A_RadiusGive("hat2", 16, RGF_GIVESELF,  1) //A_GiveInventory ("hat2") didn't seem to work
         idle:
          fepd im 10 A_Look
        loop
     See:
          fepd abcdefgh 3 A_Chase     
          Loop

        nohatsee:
         fepf abcdefgh 3
         {
   A_wander;
    A_JumpIfInventory("hat2", 1, "gethat");
    }
          fepf abcdefgh 3
         {
   A_chase;
    A_JumpIfInventory("hat2", 1, "gethat");
    }
        loop
             Missile:
            fefp a 0 A_JumpIfInventory("hat2", 0, "nohatmissile")
     fepd i 10 A_FaceTarget
          fepd j 3 a_startsound ("fyip/zupe")
           fepd k 1 bright a_SpawnProjectile ("zipzupezip", 26, 0, 0)
           fepd k 1 bright a_SpawnProjectile ("zipzupezip", 26, 0, 0)
          fepd k 1 bright a_SpawnProjectile ("zipzupezip", 26, 0, 0)
           fepd l 3 a_SpawnProjectile ("casingthing", 24, 12, -192)
           fepd m 8 A_FaceTarget
            fepd j 3 a_startsound ("fyip/zupe")
           fepd k 1 bright a_SpawnProjectile ("zipzupezip", 26, 0, 0)
          fepd k 1 bright a_SpawnProjectile ("zipzupezip", 26, 0, 0)
          fepd k 1 bright a_SpawnProjectile ("zipzupezip", 26, 0, 0)
           fepd l 3 a_SpawnProjectile("casingthing", 24, 12, -192)
           fepd mjn 3
          GoTo See
        nohatmissile:
             fepf i 10
           {
           A_FaceTarget;
            A_JumpIfInventory("hat2", 1, "gethat");
         }
          fepf j 3 a_startsound ("fyip/zupe")
           fepf k 1 bright a_SpawnProjectile ("zipzupezip", 26, 0, 0)
           fepf k 1 bright a_SpawnProjectile ("zipzupezip", 26, 0, 0)
          fepf k 1 bright a_SpawnProjectile ("zipzupezip", 26, 0, 0)
           fepf l 3 a_SpawnProjectile ("casingthing", 24, 12, -192)
           fepf mjn 3
         goto nohatsee
        pain.slap:
        fefp a 0
        fefp a 0 A_JumpIfInventory("hat2", 0, "nohatpain")
        fedp a 2 A_spawnitemex ("hatthing2", random (0, -1), random (-2, 2), random (32, 48), random (0, -4), random (-2, 2), random (1, 4),  0, SXF_TRANSFERTRANSLATION)   
        fefp a 2 {
        A_TakeInventory("hat2", 1);
        a_setuservar ("user_fyop2hatloss", 1);
        }
         fefp b 2
          fefp b 2 A_Pain
        fefp aabb 2
        goto nohatsee
        nohatpain:
        fefp a 0 a_changevelocity (0,0,2, CVF_RELATIVE)
        fefp a 0 A_Jump (128, "nohatpain2")
          fefp aab 2
          fefp b 2 A_Pain
        fefp aabb 2
          GoTo nohatSee
        nohatPain2:
        fefp ccd 2
          fefp d 2 A_Pain
        fefp ccdd 2
          GoTo nohatSee
                  Pain:
               fedp a 0 A_JumpIfInventory("hat2", 0, "nohatpain")
       fedp a 0 A_Jump (128, "pain2")
          fedp aab 2
          fedp b 2 A_Pain
          GoTo See
        Pain2:
        fedp ccd 2
          fedp d 2 A_Pain
          GoTo See
        gethat:
        fedg a 4 a_removechildren
        fedg bcdef 4
        goto see
//an a_facechild or equivalent code would be nice but for the time being I have only drawn it picking up a hat from the front anyway.
        death:

   fynv a 0 A_JumpIfInventory("hat2", 0, "nohatflop")
FYNV ab 4
FYnv c 4 A_Scream
fynv d 0 A_TakeInventory("hat2", 1)
dropgun:
        FYnv d 0 A_spawnitemex ("gunthing2", random (1, 3), random (-1, -3), random (16, 32), random (.5, 2), random (.5, 1), random (3, 6), 0, SXF_TRANSFERTRANSLATION)
        FYnv c 0 A_spawnitemex ("hatthing2", random (0, -1), random (-2, 2), random (32, 48), random (0, -4), random (-2, 2), random (1, 4),  0, SXF_TRANSFERTRANSLATION)   
        fynv e 0 a_changevelocity (0,0,random (.5, 2),0,0)
          fypf b 0 ThrustThing(angle * 256 / 360 + 128, random (0.5, 2), 0, 0)      
       
          FYnv e 4        
          FYnv f 0 A_Fall
          Fynv ghi 4
     FYnv j -1
          Stop
        nohatflop:
        FYNV kl 4
FYnv m 4 A_Scream
goto dropgun
}
}
this fool consistently fails to respond as if its inventory has changed. it drops a hat when slapped, but ignores the "jumpifinventory" commands and so reverts to the hat-wearing sprites and can be made to drop additional hats. Which is funny but not beneficial.

Code: Select allExpand view
actor hatthing2 : hatthing
{
     States
     {
     Spawn:
          fyoy ab 5
          fyoy c -1
          stop
           death:
          fyoy d 1
        fyoy d 3 A_Fall
          fyoy efg 4
         hatgive:
         fyoy h 10 A_RadiusGive("hat2", 16, RGF_NOMASTER, RGF_EXFILTER, 1)
         //this hopefully will attempt to and potentially succeed returning itself to its "master"
   goto hatgive
        }}

ACTOR hat2 : CustomInventory
{
 States
  {
  Spawn:
    fyoy h -1
    Stop
  //Pickup:
//goto gethat
  }
}

bits for the hat, which may not be directly relevant. I was not sure if it was wise to have the visible dropped object (which the player can grab) be the same as the imaginary inventory object that the monster is [meant to be] given
User avatar
bimshwel
only as old as I feel, and I feel like dirt
 
Joined: 15 Jul 2003
Location: misplaced
Discord: bimshwel #7516

Re: desire help with monster that can drop and retrieve obje

Postby Player701 » Wed Jun 15, 2022 1:37 pm

bimshwel wrote:and so assembled this mess

Sorry to say this, but it is indeed a mess: it's very hard to read your code due to inconsistent indentation. Next time you post code here, please make sure it is indented properly (see examples for DECORATE in the ZDoom Wiki, e.g. here), then it will be much easier to comprehend.

What I can say right now:

Code: Select allExpand view
Spawn:
    fepd i 1 A_RadiusGive("hat2", 16, RGF_GIVESELF,  1) //A_GiveInventory ("hat2") didn't seem to work

Neither A_RadiusGive nor A_GiveInventory will do anything here unless you add the NoDelay flag.


bimshwel wrote:
Code: Select allExpand view
A_JumpIfInventory("hat2", 0, "nohatmissile")

Note that A_JumpIfInventory reserves a special meaning for the value 0 of its second argument:
ZDoom Wiki wrote:Note that if amount is 0, the jump is only performed if the actor is carrying the maximum number of that item. This is useful for checking whether the player has the maximum amount of ammo for a particular weapon, regardless of whether or not he's found a backpack.

Since you haven't defined a MaxAmount for your item class, it defaults to 1, so A_JumpIfInventory("hat2", 0, ...) is equivalent to A_JumpIfInventory("hat2", 1, ...). Therefore, your code probably doesn't work the same way you expect it to.


If you could address the above issues, you will likely be able to fix the problem yourself. If you still can't, please post the new version of your code here, and I'll investigate further when I have the time.
User avatar
Player701
 
 
 
Joined: 13 May 2009
Location: Russia
Discord: Player701#8214
Operating System: Windows 10/8.1/8/201x 64-bit
OS Test Version: No (Using Stable Public Version)
Graphics Processor: nVidia with Vulkan support

Re: desire help with monster that can drop and retrieve obje

Postby bimshwel » Wed Jun 15, 2022 1:44 pm

thank you for the input! Organizational consistency often eludes me but I will attempt to do as you have suggested. I wonder if doing more editing outside of slade and notepad might help me get the alignment more under control.
User avatar
bimshwel
only as old as I feel, and I feel like dirt
 
Joined: 15 Jul 2003
Location: misplaced
Discord: bimshwel #7516

Re: desire help with monster that can drop and retrieve obje

Postby bimshwel » Thu Jun 16, 2022 3:54 pm

ah ha the game will not actually track whether the item is had or not without it having a "use" state, even though the creature cannot use an item apart from merely by having the thing. now i fear that my use of jumpifinventory inside of an anonymous function is causing failure, so i attempted to finally figure out how that is supposed to be done. I have been intimidated by it in the past and merely aimed to avoid needing it.

Code: Select allExpand view
   See:
         fepf a 1
               fepf a 1 nodelay A_JumpIfInventory("hat2", 1, "hatsee")
               //this would be easier if I could have it check for 0 hats but evidently that makes it check for MAXIMUM hats
         
         nohatsee:
               fepf abcdefgh 3
                  {
                     if (Checkinventory("hat2", 1))
                        { A_wander;
                        }
                     else
                        { return state ("gethat");
                        }
                     }
               fepf abcdefgh 3
                  {
                     if (Checkinventory("hat2", 1))
                        { A_chase;
                        }
                     else
                        { return state ("gethat");
                        }
                     }
               loop

I tried to make sense of the description of what to do instead of jumping states, which led to me trying return, which generates a RED error message stating "Return type mismatch." looking up that phrase indicates I have gotten into something that is for the moment beyond my limited range of understanding. I am also not certain that the checkinventory syntax is correct since using it seems to result in a demand for more parameters than https://zdoom.org/wiki/CheckInventory 's example makes use of.
User avatar
bimshwel
only as old as I feel, and I feel like dirt
 
Joined: 15 Jul 2003
Location: misplaced
Discord: bimshwel #7516

Re: desire help with monster that can drop and retrieve obje

Postby Gez » Thu Jun 16, 2022 4:19 pm

Yes, the fact that A_JumpIfWhatever functions stop A_Jumping and merely behave as a sort of If instruction when placed in anonymous functions is a big gotcha.

The return type mismatch is also due to this being an anonymous function.

Basically, and to try to make things as simple as I can explain:
Code: Select allExpand view
{
    if (something)
    {
        return state("mystate")
    }
}

This function has actually two paths. One of them (if "something" evaluates to true) will return a state. The other path is if "somehing" evaluates to false. Then it doesn't return a state, instead it does nothing -- and returns nothing. That means the function can has two different types of a return, either a state or nothing. And that's a mismatch. It should either always return a state, or always return nothing.

The way to fix that is to get your function to return the null state where you don't want it to perform a jump. That would look like this:
Code: Select allExpand view
{
    if (something)
    {
        return state("mystate");
    }
    return state(0);
}


or like this, this works too:
Code: Select allExpand view
{
    if (something)
    {
        return state("mystate");
    }
    return state("");
}

Whichever way you prefer to represent the null state, it provides a safe way to prevent the anonymous function from ending with a jump when other conditions in the function would cause a jump.

In other words, if you do this:
Code: Select allExpand view
             nohatsee:
                   fepf abcdefgh 3
                      {
                         if (Checkinventory("hat2", 1))
                            { A_wander;
                              return state(0);
                            }
                         else
                            { return state ("gethat");
                            }
                         }
                   fepf abcdefgh 3
                      {
                         if (Checkinventory("hat2", 1))
                            { A_chase;
                              return state(0);
                            }
                         else
                            { return state ("gethat");
                            }
                         }
                   loop

That should work, I think.
Gez
 
 
 
Joined: 06 Jul 2007

Re: desire help with monster that can drop and retrieve obje

Postby bimshwel » Thu Jun 16, 2022 5:29 pm

Thank you! That works, but as soon as I realized it worked I saw that what I had presented is the opposite of what I intend; i want it to alternate wandering and chasing if it does NOT have a hat, UNTIL it finds a hat. Or is found by a hat, as the case may need to be.
Code: Select allExpand view
    nohatsee:
                   fepf abcdefgh 3
                      {
                         if (Checkinventory("hat2", 1))
                            { return state ("gethat");
                              return state(0);
                            }
                         else
                            { A_wander;
                            }
                         }
                   fepf abcdefgh 3
                      {
                         if (Checkinventory("hat2", 1))
                            { return state ("gethat");
                              return state(0);
                            }
                         else
                            { A_chase;
                            }
                         }
                   loop

I tried turning it around and am back to the mismatch error I started with, since I still seem unable to check for zero of an inventory item or totally grasp the explanation of why it matches or does not match. and "if hat2 = 1 = false" seems absurd.

Code: Select allExpand view
actor hatthing2 : hatthing
{
     States
     {
     Spawn:
         fyoy ab 5
         fyoy c -1
         stop
   death:
         fyoy d 1
         fyoy d 3 A_Fall
         fyoy efg 4
   hatgive:
         fyoy h 4 A_RadiusGive("hat2", 32, RGF_MONSTERS, 1, fyop2 )
         //this hopefully will attempt to and potentially succeed returning itself to its "master"
   goto hatgive
   use:
         fyoy h 1
        }}

additionally I expect to have trouble with this hat transferer eventually since I am uncertain if it permits me to single out the master as a recipient. I can EXCLUDE the master and it looks like I can invert the settings, which I tried to have it do before, but at that time no transfer occurred. In a worst-case situation I can prevent putting more than one fyop2 in any single zone, since there are a few fyip and fyop variants.

an alternate method might be to have fyop GAIN a fake inventory item when losing its hat, but then would the child hat be able to revoke the fake inventory anti-hat and provoke a state jump in its master? Once again it only appears possible to have this go in the opposite direction.
User avatar
bimshwel
only as old as I feel, and I feel like dirt
 
Joined: 15 Jul 2003
Location: misplaced
Discord: bimshwel #7516

Re: desire help with monster that can drop and retrieve obje

Postby Player701 » Thu Jun 16, 2022 11:23 pm

bimshwel wrote:I still seem unable to check for zero of an inventory item

Since you can jump if you have 1 or more of an item with A_JumpIfInventory(..., 1, ...), the states following the call (which execute when you don't jump) represent the condition when you don't have the item.

Code: Select allExpand view
SomeState:
    TNT1 A 0 A_JumpIfInventory("MyItem", 1, "HaveItem")
DontHaveItem: // This label is for convenience's sake only, it doesn't affect the actual behavior
    // These states will execute if the actor does not have any of MyItem
    ...
    Goto SomeState // Repeat the check
HaveItem:
    // These states will execute if the actor has at least 1 of MyItem
    ...
    Goto SomeState // Repeat the check
User avatar
Player701
 
 
 
Joined: 13 May 2009
Location: Russia
Discord: Player701#8214
Operating System: Windows 10/8.1/8/201x 64-bit
OS Test Version: No (Using Stable Public Version)
Graphics Processor: nVidia with Vulkan support

Re: desire help with monster that can drop and retrieve obje

Postby bimshwel » Thu Jun 16, 2022 11:49 pm

Yes, I moved some stuff around after you pointed out the bit about not being able to check for zero, but when trying to do the same thing inside the anonymous function that Gez described based on my information that I had backwards, possibly on account of already having switched stuff around earlier, I no longer remember, I could not figure out the syntax.
User avatar
bimshwel
only as old as I feel, and I feel like dirt
 
Joined: 15 Jul 2003
Location: misplaced
Discord: bimshwel #7516

Re: desire help with monster that can drop and retrieve obje

Postby Player701 » Thu Jun 16, 2022 11:54 pm

IMO, using anonymous functions for simple inventory checking and jumping is overkill, since A_JumpIfInventory already exists to do exactly that.
User avatar
Player701
 
 
 
Joined: 13 May 2009
Location: Russia
Discord: Player701#8214
Operating System: Windows 10/8.1/8/201x 64-bit
OS Test Version: No (Using Stable Public Version)
Graphics Processor: nVidia with Vulkan support

Re: desire help with monster that can drop and retrieve obje

Postby bimshwel » Fri Jun 17, 2022 12:01 am

It isn't NECESSARY, but doing it the other way, my code looks even uglier
Code: Select allExpand view
fepf a 0 A_JumpIfInventory("hat2", 1, "hatget")
fepf a 3 a_wander
fepf b 0 A_JumpIfInventory("hat2", 1, "hatget")
fepf b 3 a_wander
fepf c 0 A_JumpIfInventory("hat2", 1, "hatget")
fepf c 3 a_wander
fepf d 0 A_JumpIfInventory("hat2", 1, "hatget")
fepf d 3 a_wander
fepf e 0 A_JumpIfInventory("hat2", 1, "hatget")
fepf e 3 a_wander
fepf f 0 A_JumpIfInventory("hat2", 1, "hatget")
fepf f 3 a_wander
fepf g 0 A_JumpIfInventory("hat2", 1, "hatget")
fepf g 3 a_wander
fepf h 0 A_JumpIfInventory("hat2", 1, "hatget")
fepf h 3 a_wander

I end up having to do tedious, ugly, difficult to amend stuff when I can't figure out the proper way rather often, so as long as I am asking questions it seemed worth checking on a better way out of it this one time, that I might be able to apply to others as I encounter or re-encounter them.
Last edited by bimshwel on Fri Jun 17, 2022 12:13 am, edited 1 time in total.
User avatar
bimshwel
only as old as I feel, and I feel like dirt
 
Joined: 15 Jul 2003
Location: misplaced
Discord: bimshwel #7516

Re: desire help with monster that can drop and retrieve obje

Postby Player701 » Fri Jun 17, 2022 12:12 am

Sorry, didn't see you wanted to do the check during every single state instead of just in the beginning of the state sequence. Then it is indeed better to simplify the code by using anonymous function blocks. Looking at your previous example, I can see you have some extraneous return statements there. Here's how the block should look like:

Code: Select allExpand view
{
    if (Checkinventory("hat2", 1))
    {
        return state("gethat");
    }
   
    A_Wander; // or A_Chase
}

It should be functionally identical to yours - the only question is whether it does what you actually want it to do.
User avatar
Player701
 
 
 
Joined: 13 May 2009
Location: Russia
Discord: Player701#8214
Operating System: Windows 10/8.1/8/201x 64-bit
OS Test Version: No (Using Stable Public Version)
Graphics Processor: nVidia with Vulkan support

Re: desire help with monster that can drop and retrieve obje

Postby bimshwel » Fri Jun 17, 2022 12:21 am

thank you for looking at it again! so now it is laid out like
Code: Select allExpand view
    nohatsee:
                   fepf abcdefgh 3
                  {
                  if (Checkinventory("hat2", 1))
                     {
                     return state("gethat");
                     }
                  A_Wander;
                  }
                   fepf abcdefgh 3
                  {
                     if (Checkinventory("hat2", 1))
                     {
                     return state("gethat");
                     }   
                  A_Chase;
                  }
                   loop
      

but is still generating mismatch errors, specifically on the closing fancy brackets after wander and chase.
User avatar
bimshwel
only as old as I feel, and I feel like dirt
 
Joined: 15 Jul 2003
Location: misplaced
Discord: bimshwel #7516

Re: desire help with monster that can drop and retrieve obje

Postby Gez » Fri Jun 17, 2022 12:27 am

Player701 wrote:Looking at your previous example, I can see you have some extraneous return statements there.

What did I just say? They're not extraneous.

Code: Select allExpand view
{
    if (Checkinventory("hat2", 1))
    {
        return state("gethat");
    }
    A_Wander; // or A_Chase
    return state(0);
}
Gez
 
 
 
Joined: 06 Jul 2007

Re: desire help with monster that can drop and retrieve obje

Postby Player701 » Fri Jun 17, 2022 12:30 am

There were two returns following each other in the same block, so the second one was definitely unnecessary. That's what I was talking about. And yeah, looks like it needs one in the end as well. Sure been a while since I coded in DECORATE... :?
User avatar
Player701
 
 
 
Joined: 13 May 2009
Location: Russia
Discord: Player701#8214
Operating System: Windows 10/8.1/8/201x 64-bit
OS Test Version: No (Using Stable Public Version)
Graphics Processor: nVidia with Vulkan support

Re: desire help with monster that can drop and retrieve obje

Postby bimshwel » Fri Jun 17, 2022 1:09 am

ehhhhh one step at a time! I don't mind porting it all to zscript eventually; I constructed a great many more messes than this over my years trying. But yes it all, or at least everything immediately relevant, functions now, thank you! This setup should no doubt help in future matters and if I see the code pieces enough eventually I will comprehend them better.

And it is greatly amusing to me to finally see the hat grasp in action. The beasts are so disorderly when bunched together i couldn't tell if the wrong one was trying to receive a hat it couldn't remove anyway so this should not attempt to become anyone else's problem again for a while.
ehhhhdit:
Code: Select allExpand view
   fyoy h 4 A_RadiusGive("hat2", 32, RGF_MONSTERS|RGF_NOMASTER|rgf_inclusive, 1, fyop2)

this seems to be behaving so the matter may indeed be concluded.
User avatar
bimshwel
only as old as I feel, and I feel like dirt
 
Joined: 15 Jul 2003
Location: misplaced
Discord: bimshwel #7516


Return to Scripting

Who is online

Users browsing this forum: No registered users and 1 guest