enum {
	DND_ATF_NOAMMOTAKE = 1,						// does not take ammo
	DND_ATF_NOATTACKTRIGGER = 2,				// does not run attack check code ---- use for things that make multi proj attacks that are different proj
	DND_ATF_NOAMMOGAINCHECK = 4,				// broader variant of the above, skips ammo gain check (probably handled outside etc. for multi ammo taking weapons)
	DND_ATF_CANFIRECIRCLE = 8,					// attack can be fired around a circle
	DND_ATF_USEGRAVITY = 16,
	DND_ATF_ISHITSCAN = 32,
};

enum {
	DND_ARG_DAMAGE,
	DND_ARG_DAMAGETYPE,
	DND_ARG_DAMAGEFLAGS,
	DND_ARG_WEAPONID
};

enum {
	DND_ARG_SHOTGUNPELLETS = 2,
	DND_ARG_SHOTGUNDAMAGE = 3,
	DND_ARG_SHOTGUNTEMP = 4
};

enum {
	DND_PULLF_CANPULLDEAD = 1,
	DND_PULLF_REVERSEDIR = 2
};

const int CACHE_SHIFT = 9;
const int DTYPE_SHIFT = 12;
const int DPCT_SHIFT = 17;

const int SPELL_DMG_SHIFT = 16;
const int SPELL_ID_SHIFT = 21;

Actor DnD_ShotgunDamageHolder : DnD_Info { }
Actor DnD_PoisonStacks : DnD_Info { }
Actor DnD_ChillStacks: DnD_Info { }
Actor DnD_FreezeTimer : DnD_Info { }
Actor DnD_IgniteTimer : DnD_Info { }
Actor DnD_OverloadTimer : DnD_Info { }
Actor DnD_OverloadDamage : DnD_Info { }
Actor DnD_OverloadLockTime : PowerProtection {
	damagefactor "normal", 1.0
	powerup.duration -2
}

Actor DnD_OverloadZapCandidate : PowerProtection {
	damagefactor "normal", 1.0
	powerup.duration 3
}

Actor DnD_OverloadZapGiver : DnD_Activator {
	States {
		Pickup:
			TNT1 A 0 A_RadiusGive("DnD_OverloadZapCandidate", 512 + radius, RGF_MONSTERS, 1)
		Stop
	}
}

Actor DnD_BasePuff {
	+MISSILE // fast owner transfer, puffs require a delayed script for this, this way they dont
	+PUFFGETSOWNER
	+PUFFONACTORS
	+HITTRACER
	+MTHRUSPECIES
	+NODAMAGETHRUST
	+NOGRAVITY
	Height 1
	Radius 1
	
	var int user_hitcount;
	
	States {
		Spawn:
			TNT1 AAAA 0
			// takes dmg and damage type as args 0 and 1 respectively
			TNT1 A 1 A_CheckFlag("NOBLOOD", "SpawnPuff", AAPTR_TRACER)
		Stop
		Crash:
			TNT1 A 0 A_SpawnDebris("SparkPuff", 1)
			TNT1 A 0 A_SpawnItemEx("WallHitSpark", 0, 0, 0, 0, 0, 0, 0, SXF_NOCHECKPOSITION | SXF_CLIENTSIDE)
			PUFF A 4 bright A_PlaySound("puff/ric")
			PUFF B 4
			PUFF CD 4
		stop
		SpawnPuff:
			TNT1 A 35 A_Jump(256, "HitNoBlood")
		Wait
	}
}

Actor DnD_BaseRailPuff {
	Species "Player"
	Height 2
	Radius 1
	+ALWAYSPUFF
	+PUFFGETSOWNER
	+NODAMAGETHRUST
	+PUFFONACTORS
	+HITTRACER
	+MTHRUSPECIES
	+NOGRAVITY
	
	var int user_hitcount;
	
	States {
		Spawn:
			TNT1 AAAA 0
			TNT1 A 1 A_CheckFlag("NOBLOOD", "SpawnPuff", AAPTR_TRACER)
		Stop
		Crash:
			TNT1 A 1
		stop
		SpawnPuff:
			TNT1 A 35 A_Jump(256, "HitNoBlood")
		Wait
	}
}

Actor DnD_DataDummy {
	PROJECTILE
	Height 1
	Radius 1
	var int user_hitcount;
	+NOINTERACTION
	+NOCLIP
	States {
		Spawn:
			TNT1 A 1
			TNT1 A 0 A_TakeFromTarget("DnD_DummySpawned", 1)
		Stop
	}
}

Actor DnD_DummySpawned : DnD_Boolean { }

Actor DnD_BaseProjectile {
	PROJECTILE
	+HITTRACER
	+MTHRUSPECIES
	+NODAMAGETHRUST
	+DONTBLAST
	Damage 0
	
	var int user_hitcount;
	var int user_wepid;
	
	States {
		Spawn:
			TNT1 A 0 NoDelay ACS_NamedExecuteWithResult("DnD Projectile Checks")//A_GiveInventory("DnD_Projectile_SpawnChecks", 1)
			TNT1 A 35 A_Jump(256, "SpawnState")
		Wait
	}
}

Actor DnD_CullSuccess : PowerProtection {
	damagefactor "normal", 1.0
	Powerup.Duration 18
}

Actor DnD_CritToken : PowerProtection {
	damagefactor "normal", 1.0
	Powerup.Duration 2
}

// The first TNT1A 0 is needed, NoDelay doesn't work properly with fastprojectiles
Actor DnD_BaseFastProjectile : FastProjectile {
	PROJECTILE
	+HITTRACER
	+MTHRUSPECIES
	+DONTBLAST
	+NODAMAGETHRUST
	Damage 0
	
	var int user_hitcount;
	
	States {
		Spawn:
			TNT1 A 0
			TNT1 A 0 ACS_NamedExecuteWithResult("DnD Projectile Checks")
			TNT1 A 35 A_Jump(256, "SpawnState")
		Wait
	}
}

Actor DnD_RippingBegan : DnD_Boolean { }

Actor DnD_PuffTest : DnD_Activator {
	States {
		Pickup:
			TNT1 A 0 A_FireBullets(0, 0, 1, 0, "DnD_BasePuff")
		Stop
	}
}

Actor DnD_ExplosiveBase {
	PROJECTILE
	Damage 0
	+HITTRACER
	+MTHRUSPECIES
	+NODAMAGETHRUST
	+DONTBLAST
	
	var int user_count;
	var int user_expdmg;
	var int user_expradius;
	var int user_fullexpradius;
	var int user_expflags;
	
	const int r_f = 80;
	
	States {
		Spawn:
			TNT1 A 0 NoDelay ACS_NamedExecuteWithResult("DnD Projectile Checks", 0, 1)//A_GiveInventory("DnD_Projectile_SpawnChecks", 1)
			TNT1 A 35 A_Jump(256, "SpawnState")
		Wait
		DoExplosionDamage:
			//"####" "#" 0 ACS_NamedExecuteWithResult("DnD Do Explosion Damage", user_expdmg, user_expradius, user_fullexpradius, user_damagetype)
			// we do this to ensure no damage falloff, we're gonna extract real damage out later
			"####" "#" 0 ACS_NamedExecuteWithResult("DnD Prep Explosion")
			"####" "#" 0 A_Explode(100, user_expradius, 1, 0, user_fullexpradius)
			"####" "#" 35 A_Jump(256, "ContinueFromExplosion")
		Wait
		FinishExplosion:
			"####" "#" 0 A_JumpIf(ACS_NamedExecuteWithResult("DnD Check Explosion Repeat"), "ExplodeRepeat")
		Stop
		ExplodeRepeat:
			// resets timers so explosions that depend on those dont mess up when repeating
			"####" "#" 0 A_SetUserVar("user_count", 0)
			"####" "#" 0 A_Scream
		Goto DoExplosionDamage
	}
}

Actor DnD_ExplosiveBase_ForPets {
	PROJECTILE
	+HITTRACER
	+MTHRUSPECIES
	+NODAMAGETHRUST
	+DONTBLAST
	
	var int user_expdmg;
	var int user_expradius;
	var int user_fullexpradius;
	var int user_expflags;
	
	const int r_f = 80;
	
	States {
		// for pets check master's inventory
		Spawn:
			TNT1 A 0 NoDelay ACS_NamedExecuteWithResult("DnD Projectile Checks", 1)//A_GiveInventory("DnD_Projectile_SpawnChecks_Pets", 1)
			TNT1 A 35 A_Jump(256, "SpawnState")
		Wait
		DoExplosionDamage:
			"####" "#" 0 ACS_NamedExecuteWithResult("DnD Prep Explosion")
			"####" "#" 0 A_Explode(100, user_expradius, 1, 0, user_fullexpradius)
			"####" "#" 35 A_Jump(256, "ContinueFromExplosion")
		Wait
	}
}

Actor MakeGhostHitter : DnD_Activator {
	States {
		Pickup:
			TNT1 A 0 A_ChangeFlag("THRUGHOST", 0)
		Stop
	}
}

// because zandro doesnt have a working implementation of SetActorFlag...
Actor ApplyNetherMaskBuff : DnD_Activator {
	States {
		Pickup:
			TNT1 A 0 A_ChangeFlag("THRUGHOST", 0)
			//TNT1 A 0 A_ChangeFlag("FORCERADIUSDMG", 1)
			//TNT1 A 0 A_CheckFlag("RIPPER", "FlipRipper")
		Stop
		FlipRipper:
			TNT1 A 0 A_ChangeFlag("RIPPER", 0)
			TNT1 A 0 A_ChangeFlag("THRUACTORS", 1)
		Stop
	}
}

Actor ApplyNoReflect : DnD_Activator {
	States {
		Pickup:
			TNT1 A 0 A_ChangeFlag("DONTREFLECT", 1)
		Stop
	}
}

Actor ApplyForceRadiusDMG : DnD_Activator {
	States {
		Pickup:
			TNT1 A 0 A_ChangeFlag("FORCERADIUSDMG", 1)
		Stop
	}
}

Actor DnD_TestExploder : DnD_ExplosiveBase {
	Height 6
	Radius 3
	Speed 40
	Damage 0
	States {
		Spawn:
			SARG A 1
		Loop
		Death:
			TNT1 A 0 A_SetUserVar("user_expdmg", 50)
			TNT1 A 0 A_SetUserVar("user_expradius", 192)
			TNT1 A 0 A_SetUserVar("user_fullexpradius", 0)
			SARG H 4
		Goto DoExplosionDamage
		ContinueFromExplosion:
			SARG IJK 4
		Stop
	}
}

Actor DnD_TestShitter : DnD_Activator {
	States {
		Pickup:
			TNT1 A 0 A_FireCustomMissile("DnD_TestExploder", -2, 0)
			TNT1 A 0 A_FireCustomMissile("DnD_TestExploder", 2, 0)
		Stop
	}
}

Actor HitboxParticle {
	Scale 0.75
	Radius 1
	Height 1
	+NOCLIP
	+NOINTERACTION
	States {
		spawn:
			SPRK S 70
		stop
	}
}

Actor HitboxParticle2 : HitboxParticle {
	States {
		spawn:
			SPRK T 70
		stop
	}
}