[ZScript] Drop Item Code Problems

Fri Feb 18, 2022 5:12 pm

Greetings, everyone!

As always, I thank everyone that stops by to help. You folks are the best. Thank you so much for all of your help.


I had a post up about trying to mess with Spawn controls. I had already been messing with it for several days, but further experimentation with some things has invalidated a few statements I made, so I decided to make a whole new thread rather than go through and issue redactions to things.

After further messing around with my code, I found that *NONE* of my Drop Handlers were behaving as they should be! The way things were/are going, when the OnDrop(Owner)/DetachFromOwner is fired off, it does drop the specific item the code is attached to, however, it doesn't properly drop any of the other items.


It should work like this:

-Fire OnDrop(Owner)/DetachFromOwner
-Discard the Holster Equipment straight in front of the Player with some force and velocity
-Discard the firearm that was in the holster somewhat towards the player's feet
-Discard the reserve ammunition for that firearm either at the player's feet, or close by.

What it's doing instead:

-Fire OnDrop(Owner)/DetachFromOwner
-Discard the Holster Equipment as desired
-Spawn both the Firearm AND the Ammo at the X-Y-Z coordinates of the last time the OnDrop was fired. For a new game, this seems to be 0-0-0.

I surmise something is terribly wrong with my Drop Handler, or the OnDrop(Owner)/DetachFromOwner call. I'm no ZScript expert, hence why I'm here, so I can't seem to diagnose what's going on.

My first solution is to attempt to bring all of the Discard functions under one roof, so to speak, so that I can press one button, and discard EVERYTHING desired in one go, in one chunk of code, without jumping around.

Here are the relevant codes I'm trying to stitch together. First, the handler for the new Weapon Type I have to use to make everything function as desired:

Code:
class GWeaponDM : Weapon
{
   action void DropCurrentAmmo (class<Inventory> AmmoReserve, class<Inventory> AmmoToDrop)
   {
         int AmmoHeld = CountInv(AmmoToDrop);
         int AmmoSpare = CountInv(AmmoReserve);
         TakeInventory(AmmoToDrop, AmmoHeld);
         while (AmmoHeld > 0)
         {.
            Ammo DroppedAmmo = Ammo(Spawn(AmmoToDrop, Pos, NO_REPLACE)); // Spawn the new Mag
            DroppedAmmo.Amount = 1;
            DroppedAmmo.DropTime = 30;
            DroppedAmmo.Angle = 12;
            DroppedAmmo.VelFromAngle(5);
            DroppedAmmo.Vel.Z = 2.;
            DroppedAmmo.bNoGravity = false;
            DroppedAmmo.bSpecial = DroppedAmmo.bSolid = false;
            DroppedAmmo.ClearCounters();
            AmmoHeld = AmmoHeld - 1;
         }
         TakeInventory(AmmoToDrop, AmmoSpare);
      }
}


This controls dropping ammo. The "action void" section, I found, can be slotted into different places to grant it Ammo Drop functionality.

Next, the code for dropping the equipment:

Code:
class DropHandler3 : EventHandler
{
   override void NetworkProcess(ConsoleEvent e)
    {
      if (e.Name ~== "DropHip" && playeringame[e.Player])
        {
            let pp = players[e.Player].mo;
         HipBase HipItem = HipBase(pp.FindInventory("HipBase",true));
         if (HipItem)
         {
               pp.A_Log(TEXTCOLOR_RED .. "Hip Equipment dropped");
               let copy = HipBase(pp.Spawn (HipItem.Gear1Type, pp.Pos, NO_REPLACE));
               if (copy == null)
                {
               pp.A_Log(TEXTCOLOR_RED .. "Error in gear drop, invalid gear type name");
                }
               else
               {
             
               copy.SetOrigin(pp.Pos + (0, 0, 10.), false);
               copy.Angle = pp.Angle;
               copy.VelFromAngle(5.);
               copy.Vel.Z = 1.;
               copy.Vel += pp.Vel;
               copy.bNoGravity = false;
               copy.ClearCounters();   
               copy.DropTime = 30;
               copy.bSpecial = copy.bSolid = false;
               
               HipItem.Destroy();
               }
         
         }   
        }
    }
}


Okay, so, my first hurdle is trying to mate these two somehow. I don't know if I can straight up integrate them into the same function, or if I have to make a NEW function that calls them both independently.

My second hurdle is making one of these codes drop the weapon in question. Ideally, I would like the second code to do this, by identifying if a specific item is in inventory, then getting rid of it. I came up with this (FLAWED) code:

Code:
class DropHandler3A : EventHandler
{
   override void NetworkProcess(ConsoleEvent e)
    {
      if (e.Name ~== "SuperDropHip" && playeringame[e.Player])
        {
         let pp = players[e.Player].mo;
         HipBase HipItem = HipBase(pp.FindInventory("HipBase",true));
         GWeaponDM HipWep1 = GWeaponDM(pp.FindInventory("XM27HH",true));
         GWeaponDM HipWep2 = GWeaponDM(pp.FindInventory("M33HH",true));
         if (HipItem)
           {
               pp.A_Log(TEXTCOLOR_RED .. "Hip Holster dropped");
               let copy = HipBase(pp.Spawn (HipItem.Gear1Type, pp.Pos, NO_REPLACE));
               if (copy == null)
              {
               pp.A_Log(TEXTCOLOR_RED .. "Error in gear drop, invalid gear type name");
              }
               else
              {
             
               copy.SetOrigin(pp.Pos + (0, 0, 10.), false);
               copy.Angle = pp.Angle;
               copy.VelFromAngle(5.);
               copy.Vel.Z = 1.;
               copy.Vel += pp.Vel;
               copy.bNoGravity = false;
               copy.ClearCounters();   
               copy.DropTime = 30;
               copy.bSpecial = copy.bSolid = false;
               
               HipItem.Destroy();
               }
            }
           
     if (HipWep1)
         {
               pp.A_Log(TEXTCOLOR_RED .. "Discarded XM27");
               let copyg = GweaponDM(pp.Spawn ("XM27Empty", pp.Pos, NO_REPLACE));
               if (copyg == null)
                {
               pp.A_Log(TEXTCOLOR_RED .. "Error in gun drop, invalid gun type name");
                }
               else
               {
             
               copyg.SetOrigin(pp.Pos + (0, 0, 10.), false);
               copyg.Angle = pp.Angle;
               copyg.VelFromAngle(5.);
               copyg.Vel.Z = 1.;
               copyg.Vel += pp.Vel;
               copyg.bNoGravity = false;
               copyg.ClearCounters();   
               copyg.DropTime = 30;
               copyg.bSpecial = copyg.bSolid = false;
               
               HipWep1.Destroy();
               }
               
         }
     if (HipWep2)
         {
               pp.A_Log(TEXTCOLOR_RED .. "Discarded M33");
               let copys = GweaponDM(pp.Spawn ("M33Empty", pp.Pos, NO_REPLACE));
               if (copys == null)
                {
               pp.A_Log(TEXTCOLOR_RED .. "Error in gun drop, invalid gun type name");
                }
               else
               {
             
               copys.SetOrigin(pp.Pos + (0, 0, 10.), false);
               copys.Angle = pp.Angle;
               copys.VelFromAngle(5.);
               copys.Vel.Z = 1.;
               copys.Vel += pp.Vel;
               copys.bNoGravity = false;
               copys.ClearCounters();   
               copys.DropTime = 30;
               copys.bSpecial = copys.bSolid = false;
               
               HipWep2.Destroy();
               }
          }   
        }
    }
}


When I try to fire THAT code, nothing happens at all. I don't know what I'm doing wrong, there. I do have "SuperDropHip" properly defined in KEYCONF (I think):

Code:
addmenukey "Discard Hip Equip." geardrop2
alias geardrop2 "netevent \"SuperDropHip\""
DefaultBind i geardrop2


So, yeah, I have... zero idea what I'm doing wrong. I would, as always, greatly appreciate any help I can get. I'm totally stumped at this point, I've tried everything else - reconfiguring the OnDrop(Owner) from the Item itself, trying to stitch these two codes together, trying to force a DECORATE Actor to deal with it.. I really have nowhere else I can try to take things. I simply haven't learnt ZScript that well, yet.

As a final note, here's the OnDrop section that each piece of equipment has:

Code:
Override void DetachFromOwner()
{
    Super.OnDrop(owner);

            for (int i = 0; i < AMMO_TYPES.Size(); i++)
            {
                DecreaseCapacity(owner, AMMO_TYPES[i], AMMO_INCREMENTS[i]);
                DropCurrentAmmo("M33RM","M33RM");
            }

        if(owner)
            owner.Spawn("M33Empty");
            owner.TakeInventory("M33HH",2);
    }


Yes, the call to DropCurrentAmmo is properly defined elsewhere in the code (this code is for the inheritable Inventory Item that these things work from):

Code:
class HipBase : Inventory
{
        int HipAmt;
        Name Gear1Type;
        Property Gear1Type : Gear1Type;
        Property HipAmt : HipAmt;
       
override bool TryPickup (in out Actor toucher)
   {
      Inventory HIPItem = toucher.FindInventory("HipBase", 1);
      If (!HIPItem)
      {
         return Super.TryPickup(Toucher);
      }
      else
      {
         return false;
      }
      return false;
   }

      action void DropCurrentAmmo (class<Inventory> AmmoReserve, class<Inventory> AmmoToDrop)
 
   {
         int AmmoHeld = CountInv(AmmoToDrop);
         int AmmoSpare = CountInv(AmmoReserve);
         TakeInventory(AmmoToDrop, AmmoHeld);
         while (AmmoHeld > 0)
         {
            Ammo DroppedAmmo = Ammo(Spawn(AmmoToDrop, Pos, NO_REPLACE));
            DroppedAmmo.Amount = 1;
            DroppedAmmo.DropTime = 30;
            DroppedAmmo.Angle = Angle;
            DroppedAmmo.VelFromAngle(5.);
            DroppedAmmo.Vel.Z = 1.;
            DroppedAmmo.bNoGravity = false;
            DroppedAmmo.bSpecial = DroppedAmmo.bSolid = false;
            DroppedAmmo.ClearCounters();
            AmmoHeld = AmmoHeld - 1;
         }
         TakeInventory(AmmoToDrop, AmmoSpare);
      }

}



If there's another, simpler solution, I'm all for it. I simply don't know how to proceed from here. At all. Thanks to anyone that stops by to help!