trying to make a weapon that strikes differently if it already struck once

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!)
User avatar
bimshwel
Posts: 718
Joined: Tue Jul 15, 2003 5:15 pm
Location: misplaced

trying to make a weapon that strikes differently if it already struck once

Post by bimshwel »

like the fighter punch in hexen. It seems like this SHOULD be easy; having a counter go up when you make a hit and clear after a miss or a second hit.

I tried importing and changing zscript code from fpunchattack but whatever I was doing obviously wasn't right since it was ALWAYS triggering.

Code: Select all

//a simple refire would replay the first slap repeatedly or ALWAYS slap twice

class Slap : Fist //30613  it really does not want a number here
{
default
{
  Weapon.SelectionOrder 3699;
  //DamageType slap;  it doesn't want a damage type either, and as you previously saw, in decorate, it will not apply one
  Weapon.SlotNumber 1;
  Weapon.Kickback 100;
  Weapon.AmmoUse 0;
  Obituary "$OB_MPFIST";
  Tag "$TAG_FIST";
  +WEAPON.WIMPY_WEAPON;
  +WEAPON.MELEEWEAPON;
   +THRUGHOST;
  
  Decal "handscotch";
  }
  States
  {
  Ready:
  tnt1 A 1 A_WeaponReady;
  
    Loop;

  Deselect:
    smap ijk 3;
	tnt1 a 3;
	tnt1 aaaaaa 1 A_Lower(20);
    Loop;
  Select:
  smap llllll 0 a_raise(15);
  smap l 0 a_raise(5);
  smap lmn 3;
    smap nnn 1 A_Raise;
    Loop;
  Fire:
  tnt1 a 3 A_slapAttack; 
  smap a 3 ;
    smap b 3 ;
    smap c 3 ;
	smap d 3 A_FireCustomMissile("Deflecto");

	   TNT1 A 0 A_JumpIfInventory("PowerStrength", 1, "Berseke");
	smap E 2 //A_CustomPunch(5 * random(5, 8), TRUE, 0, "slappo", 64, 0, 0, 0, "dope/fwup");
			{
			int dmg = 5 * random(5,8);
			if (FindInventory("PowerStrength"))
			{
				dmg *= 10;
			}
			A_CustomPunch(dmg, norandom:true, range: meleeRange + 20, meleesound: "*fist");
		}
	smap f 2 ; //A_CustomPunch(5 * random(5, 8), TRUE, 0, "slappo", 64, 0, 0, 0, "dope/fwup");
	
	

	goto afterpunch;
	berzeke:
	smap E 2 A_CustomPunch(20 * random(1, 10), TRUE);
	goto afterpunch;
	afterpunch:
	   smap f 3 ;
   Goto Ready;
   
		fire2:  //if done correctly, slapattack should jump to here ONLY if a single slap has already occurred
	smap g 2 ; //and the sound effect gets played by the previous frame in that circumstance so this doesn't have any code
	smap h 2 ;
   smap A 3 ;
   Goto Ready;
     Spawn:
    CBAL AB 8;
    loop;
	Altfire:
	   grab a 3;
	   grab b 3;
	   grab c 3  A_playsound ("dope/fwit");
	   nope a 4  A_FireCustomMissile("lorp");
	   nope a 20;
	      Goto Ready;
  }
//============================================================================
	//
	// Tryslap
	//
	// Returns true if an actor was slapped, false if not.
	//
	//============================================================================


//12-1-2024 no this is not working.  you do not know what in here raises the "weaponspecial" and the game is treating that as if it is always high enough to trigger the jump

	private action bool Tryslap(double angle, int damage, int power)
	{
		Class<Actor> pufftype;
		FTranslatedLineTarget t;

		double slope = AimLineAttack (angle, 2*DEFMELEERANGE, t, 0., ALF_CHECK3D);
		if (t.linetarget != null)
		{
			if (++weaponspecial >= 2)  //was 3
			{
				damage <<= 1; //should this be 0, since you don't want the first check to do any damage? no this is what happens if the check succeeds
				power *= 3;
				pufftype = "litbit";
				LineAttack (angle, 2*DEFMELEERANGE, slope, damage, 'Melee', pufftype, true, t);
			if (t.linetarget != null)
			//and this that formerly followed both is now inside this one so that there isn't an attack either way
				// The mass threshold has been changed to CommanderKeen's value which has been used most often for 'unmovable' stuff.
				if (t.linetarget.player != null || 
					(t.linetarget.Mass < 10000000 && (t.linetarget.bIsMonster)))
				{
					if (!t.linetarget.bDontThrust)
						t.linetarget.Thrust(power, t.attackAngleFromSource);
				}
				AdjustPlayerAngle(t);
				return true;
			
			}
			else
			{
				pufftype = "blueglob";
			}
			
		}
		return false;
	}

	//============================================================================
	//
	// A_slapAttack
	//
	//============================================================================

	action void A_slapAttack()
	{
		if (player == null)
		{
			return;
		}

		int damage = random[FighterAtk](40, 55); //under the current setup THIS un-multiplied damage should never happen
		for (int i = 0; i < 16; i++)
		{
			if (Tryslap(angle + i*(45./16), damage, 2) || //this may be doubling the previous value
				Tryslap(angle - i*(45./16), damage, 2))
			{ // hit something
				if (weaponspecial >= 2) //originally was 3
				{
					weaponspecial = 0;
					player.SetPsprite(PSP_WEAPON, player.ReadyWeapon.FindState("Fire2"));
					A_StartSound ("*fistgrunt", CHAN_VOICE);
				}
				return;
			}
		}
		// didn't find any creatures, so try to strike any walls
		weaponspecial = 0;

		double slope = AimLineAttack (angle, DEFMELEERANGE, null, 0., ALF_CHECK3D);
		LineAttack (angle, DEFMELEERANGE, slope, damage, 'Melee', "greenglob", true);
	}
	
}

Indeed I couldn't see anything in there that appeared to be RAISING the "weaponspecial" number, just looking at it and setting it to zero.
I looked up some solutions on this forum and they seem foremost concerned with the effect of the punch or how it checks for targets, not what triggers the alternate attack. this one almost makes sense to me; I can see the ARGs and all that, but I couldn't get that to do what I wanted either.

/////////////ehhhdit are people just annoyed by my questions now? well fortunately i found a hacky way around this.
here is one that "works" though it doesn't care if it strikes or not, and maybe that isn't important. this allows for more varied animation i suppose, also. Not nearly as diluted as my inefficient coding compromises usually end up being.

Code: Select all

ACTOR Slap : Fweapfist 30613
{
  Weapon.SelectionOrder 3699
    States
    {
	spawn:
	gngb mnop 10
	loop
	Select:
	  smap nnnnnn 0 a_raise(15)
  smap n 0 a_raise(5)
  smap n 3 A_SetArg(0, 0)
  smap op 3
    smap ppp 1 A_Raise
		wait
	Ready:
		smap A 1 A_WeaponReady
		Loop
	Deselect:
	smak k 0 a_jumpif(args[1]>0, "des2")
		smap klm 3
		tnt1 a 3
		tnt1 aaaaaa 1 A_Lower(20)
		Loop
		des2:
		smap rtu 2
		tnt1 aaaaaa 1 A_Lower(20)
		loop
    Fire:
        TNT1 A 0 A_JumpIf(Args[0]>0, "fire2")
		smap a 0 A_SetArg(1, 0)
		smap B 2 A_startsound ("dope/fwit")
        smap C 2
        smap D 2 A_CustomPunch(5 * random(5, 8), TRUE, 0, "skappo", 64, 0, 0, 0, "dope/fwup") 
		smap c 0 A_FireCustomMissile("Deflecto")
        smap e 2 A_SetArg(1, 1)
        smap f 2 A_SetArg(0, 1) 
        Goto Ready2
	ready2:
		smap q 1 A_WeaponReady
		loop
    Fire2:
		smap g 0  A_startsound ("dope/fwit")
        smap g 2  A_SetArg(0, 0)//	A_SetuserVar("user_slap", 0) 
        smap h 2  A_CustomPunch(random(5,8), true, 0, "skappo", 64, 0, 0, 0, "dope/fwup")
		smap i 0  A_FireCustomMissile("Deflecto")
		smap i 2  
		smap j 2  
		smap a 2 A_refire
		smap l 0 A_SetArg(1, 0) //now this is to make sure the correct deselect is shown
		Goto Ready
           }
}
OH maybe "puffgetsowner" would have made the zrrion method work for me. eh much too late now, but maybe I will find another use for it later.

Return to “Scripting”