[ACS/DEC] Multiple projectiles and invisibility

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!)
Post Reply
User avatar
Boondorl
Posts: 138
Joined: Wed Jul 11, 2018 10:57 pm

[ACS/DEC] Multiple projectiles and invisibility

Post by Boondorl »

Is there a way to keep multiple projectiles grouped when the enemy firing them is doing so at an invisible player? For instance, I have a Revenant that fires two projectiles at the same time. It works fine normally, but when the player is invisible, the rockets will go off in two different random directions due to the inaccuracy calculation being different between each instance of A_CustomMissile.

Edit: Working solution found. I'll just paste the relevant bits:

Code: Select all

Actor 64Arachnotron : Arachnotron replaces Arachnotron
{
   ...

	+SEEINVISIBLE // See ShadowMissile for custom inaccuracy state
	
	var int user_angle;
	
	States
	{
      ...

		Missile:
			TNT1 A 0 A_SetUserVar("user_angle", 0)
			BSPI A 20 Bright A_FaceTarget
			TNT1 A 0 A_CheckFlag("SHADOW", "ShadowMissile", AAPTR_TARGET) // Check to see if the target is invisible
			TNT1 A 0 A_PlaySound("weapons/plasmaf", CHAN_WEAPON)
			TNT1 A 0 A_CustomMissile(ArachnotronPlasma, 25, -12, 0, CMF_AIMOFFSET)
			TNT1 A 0 A_CustomMissile(ArachnotronPlasma, 25, 12, 0, CMF_AIMOFFSET)
			BSPI E 8 Bright A_FaceTarget
			TNT1 A 0 A_SpidRefire
			Goto Missile + 2
			
		// Custom inaccuracy state since A_CustomMissile recalculates the angle each call, making multiple projectiles a nightmare
		ShadowMissile:
			TNT1 A 0 A_SetUserVar("user_angle", random(-40, 40))
			TNT1 A 0 A_FaceTarget // Reset the enemy angle
			TNT1 A 0 A_PlaySound("weapons/plasmaf", CHAN_WEAPON)
			TNT1 A 0 A_CustomMissile(ArachnotronPlasma, 25, -12, user_angle, CMF_AIMOFFSET)
			TNT1 A 0 A_CustomMissile(ArachnotronPlasma, 25, 12, user_angle, CMF_AIMOFFSET)
			BSPI E 8 Bright A_SetAngle(angle + user_angle) // Random turning to match aim (should come after A_CustomMissile calls)
			TNT1 A 0 A_SpidRefire
			Goto Missile + 2

       ...
	}
}
So, the Doom 64 Arachnotron fires two plasma balls at once. Normally A_CustomMissile works fine, but will calculate accuracy at each individual call meaning if the target has the SHADOW flag, bullet hell will ensue. This makes a nightmarish power up even more of a nightmare to deal with. So, to get by this, I'm using SEEINVISIBLE to skip the engine's calculation and using user_angle to keep track of my own range (-40 to 40 is an estimate based off what I read from the source code). So, we simply check if the target is invisible, and if it is, randomize the aim. Since we call A_FaceTarget before firing, it's important to set the demon's angle after firing. It also guarantees the demon's angle will always reset to look at the player every time a shot is fired, hence why angle + user_angle gives no issues.

Why do it this way? Zandronum compatibility, mostly. It's also easier than messing around with ZScript, but I'd still just recommend using ZScript if you don't care about Zandronum.
Post Reply

Return to “Scripting”