ACTOR RandomDemonStaffPickup : PickupBase
{
	States
	{
		Spawn:
			TNT1 A 0
			TNT1 A 0 A_SetUserVar("user_isBDPickupItem", 1)	// mark thing as BorderDoom pickup item
			TNT1 A 0 A_SetUserVar("user_pickupType", ItemType_DemonStaff)	// set pickup type to weapon
			TNT1 A 0 ACS_NamedExecuteAlways("CreateRandomDemonStaffData")
			TNT1 A 0 A_SetSpecial(ACS_ExecuteAlways,901,0,0,0,0)
			goto Waiting
		Waiting:
			DSTP A -1 Bright
			stop
		// called by script. makes the pickup "useable" for a short amount of time so it can be picked up.
		IsUseable:
			TNT1 A 0 A_ChangeFlag("USESPECIAL", TRUE)
			DSTP A 7 Bright
			TNT1 A 0 A_ChangeFlag("USESPECIAL", FALSE)
			goto Waiting
	}
}

ACTOR FixedDemonStaffPickup : RandomDemonStaffPickup
{
	States
	{
		Spawn:
			TNT1 A 0
			TNT1 A 0 A_SetUserVar("user_isBDPickupItem", 1)	// mark thing as BorderDoom pickup item
			TNT1 A 0 A_SetUserVar("user_pickupType", ItemType_DemonStaff)	// set pickup type to weapon
			TNT1 A 0 A_SetSpecial(ACS_ExecuteAlways,901,0,0,0,0)	// script for picking up the item
			DSTP A -1 Bright
			stop
	}
}

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////

ACTOR RealDemonStaff : Weapon
{
	Weapon.BobSpeed 2.0
	Weapon.YAdjust 5

	+INVENTORY.UNDROPPABLE	// should only be dropped by script
	+Weapon.Ammo_Optional	// prevent switching weapons if player doesn't have enough ammo
	+Weapon.CHEATNOTWEAPON	// don't give this weapon when using cheats
	+WEAPON.NOAUTOAIM

	Weapon.AmmoType1 "BDDemonStaffAmmo"
	Tag "Demon Staff"

	States
	{
		Spawn:
			DSTP A -1 Bright
			Stop
		Select:
			TNT1 A 0 A_PlaySound("demonstaff/select", CHAN_AUTO)
			//TNT1 A 0 A_TakeInventory("BDDemonStaffAmmo", 10000)	// remove all ammo
		SelectLoop:
			DSTF A 1 A_Raise
			Loop
		Deselect:
			//TNT1 A 0 A_TakeInventory("BDDemonStaffAmmo", 10000)	// remove all ammo
			TNT1 A 0 A_StopSound(CHAN_WEAPON)
			DSTF A 1 A_Lower
			Loop
		Ready:
			TNT1 A 0 A_JumpIfInventory("BDDemonStaffAmmo", CallACS("GetCurrentDamage"),			"ReadyFull")
			TNT1 A 0 A_StopSound(CHAN_WEAPON)	// stop looping loaded sound if player doesn't have enough ammo anymore
			TNT1 A 0 A_JumpIfInventory("BDDemonStaffAmmo", CallACS("GetCurrentDamage")*0.75,	"Ready75")
			TNT1 A 0 A_JumpIfInventory("BDDemonStaffAmmo", CallACS("GetCurrentDamage")*0.5,		"Ready50")
			TNT1 A 0 A_JumpIfInventory("BDDemonStaffAmmo", CallACS("GetCurrentDamage")*0.25,	"Ready25")
			DSTF A 1 A_WeaponReady(WRF_NOPRIMARY)
			Loop
		ReadyFull:
			TNT1 A 0 A_PlaySound("demonstaff/loaded", CHAN_WEAPON, 1.0, true)
			DSTF TTUUVVWWXXYY 1 Bright A_WeaponReady
			Goto Ready
		Ready75:
			DSTF NNNNOOOOPPPPQQQQRRRRSSSS 1 A_WeaponReady(WRF_NOPRIMARY)
			Goto Ready
		Ready50:
			DSTF HHHHHHHHIIIIIIIIJJJJJJJJ 1 A_WeaponReady(WRF_NOPRIMARY)
			DSTF KKKKKKKKLLLLLLLLMMMMMMMM 1 A_WeaponReady(WRF_NOPRIMARY)
			Goto Ready
		Ready25:
			DSTF BBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCC 1 A_WeaponReady(WRF_NOPRIMARY)
			DSTF DDDDDDDDDDDDDDDDEEEEEEEEEEEEEEEE 1 A_WeaponReady(WRF_NOPRIMARY)
			DSTF FFFFFFFFFFFFFFFFGGGGGGGGGGGGGGGG 1 A_WeaponReady(WRF_NOPRIMARY)
			Goto Ready
		Fire:
			TNT1 A 0 A_JumpIfNoAmmo("Ready")
			TNT1 A 0 A_PlaySound("demonstaff/attack", CHAN_AUTO)
			DSTS A 4 Offset(0, 40)
			DSTS B 4 Offset(0, 40)
			// red screen flash
			TNT1 A 0 A_SetBlend("99 00 00", 1.0, 18)
			// push enemies back
			TNT1 A 0 A_RadiusThrust(5000, 256, RTF_NOTMISSILE)
			// third parameter = false prevents using ammo for each shot
			TNT1 A 0 A_TakeInventory("BDDemonStaffAmmo", CallACS("GetCurrentDamage"))	// remove ammo
			DSTS C 2 Bright A_FireProjectile("BDDemonStaffShot",   0, false)
			DSTS C 2 Bright A_FireProjectile("BDDemonStaffShot",  -5, false)
			DSTS C 0 Bright A_FireProjectile("BDDemonStaffShot",   5, false)
			DSTS C 2 Bright A_FireProjectile("BDDemonStaffShot", -10, false)
			DSTS C 0 Bright A_FireProjectile("BDDemonStaffShot",  10, false)
			DSTS C 2 Bright A_FireProjectile("BDDemonStaffShot", -15, false)
			DSTS C 0 Bright A_FireProjectile("BDDemonStaffShot",  15, false)
			DSTS C 2 Bright A_FireProjectile("BDDemonStaffShot", -20, false)
			DSTS C 0 Bright A_FireProjectile("BDDemonStaffShot",  20, false)
			DSTS C 2 Bright A_FireProjectile("BDDemonStaffShot", -25, false)
			DSTS C 0 Bright A_FireProjectile("BDDemonStaffShot",  25, false)
			DSTS C 2 Bright A_FireProjectile("BDDemonStaffShot", -30, false)
			DSTS C 0 Bright A_FireProjectile("BDDemonStaffShot",  30, false)
			DSTS C 6 Bright Offset(0, 48)
			DSTS D 5 Offset(0, 48)
			DSTS E 5 Offset(0, 44)
			DSTS F 5 Offset(0, 40)
			DSTS G 5 Offset(0, 36)
			DSTS H 5 Offset(0, 32)
			DSTS I 5
			DSTS J 5
			DSTS K 5
			Goto Ready
		AltFire:
			TNT1 A 0 A_GiveInventory("BDDemonStaffSuckLight")	// give helper object so player uses the correct light
			TNT1 A 0 A_PlaySound("demonstaff/suck", CHAN_WEAPON)
			TNT1 A 0 A_GunFlash	// to trigger player "flash-state"
			DSTS L 25 Bright A_RadiusGive("BDSoulSucker", 600.0, RGF_MONSTERS)
			TNT1 A 0 A_TakeInventory("BDDemonStaffSuckLight")
			DSTS M 10
			Goto Ready
	}
}

ACTOR BDDemonStaffShot
{
	Speed 17
	Height 8
	Damage 1
	DamageType "Fire"
	Projectile
	+RIPPER		// go through enemies, do damage every tic
	+SEEKERMISSILE	// from the wiki: "This is only used as a hint to the game."
	+SCREENSEEKER	// shots that currently have no target ("tracer") will only look for targets within the shooter's field of vision
	BounceType Hexen	// bounce off of ceilings, floors and walls
	-ALLOWBOUNCEONACTORS	// both need to be set to avoid the projecile exploding when hitting a target. MUST be defined AFTER setting the BounceType.
	-BOUNCEONACTORS
	//DeathSound "MageStaffExplode"
	RenderStyle Translucent
	Alpha 0.8
	ReactionTime 40

	States
	{
		Spawn:
			MSP2 ABCD 2 Bright A_SeekerMissile(2, 10, SMF_LOOK)
			TNT1 A 0 A_Countdown	// counts down "ReactionTime" value and destroys projecile if zero is reached
			Loop
		Death:
			MSP2 E 4 Bright A_SetTranslucent(1, 1)	// looks better than standard translucency
			MSP2 F 5 Bright A_Explode(80, 192, 0)
			MSP2 GH 5 Bright
			MSP2 I 4 Bright
			Stop
	}
}

ACTOR BDDemonStaffAmmo : Ammo
{
	Inventory.MaxAmount 999
	+IGNORESKILL
}

// given to monsters to suck their souls
ACTOR BDSoulSucker : CustomInventory
{
	States
	{
		Spawn:
			TNT1 A -1
			stop
		Pickup:
			TNT1 A 0
			TNT1 A 1 ACS_NamedExecuteAlways("LaunchSoulTransfer")
			fail	// remove to prevent stacking up items
	}
}

// flying soul which gives the player demon staff ammo
ACTOR BDTransferredSoul
{
	Speed 12.0
	Radius 8
	Height 8
	Damage 0
	Projectile
	RenderStyle Translucent
	Alpha 0.6
	+SEEKERMISSILE	// from the wiki: "This is only used as a hint to the game."
	+THRUACTORS	// don't collide with any actors

	States
	{
		Spawn:
			// every tic the projectile stops completely, faces the player and accelerates again. this way it moves towards the player all the time.
			TNT1 A 0 A_Stop
			TNT1 A 0 A_FaceTracer
			SBS1 A 1 Bright A_SeekerMissile(2, 90, SMF_PRECISE)
			//TNT1 A 0 A_SetSpeed(speed+0.2)
			TNT1 A 0 A_SetSpeed(min(speed*1.02, 48.0))	// speed increases every tic by 2% (with a maximum of 4x speed)
			TNT1 A 0 A_JumpIfTracerCloser(radius*2, "HitTargetPlayer")
			TNT1 A 0 A_JumpIfHealthLower(1, "Death", AAPTR_TRACER)	// remove souls if targeted player dies
			Loop
		Death:
			SBS1 A 1 Bright
			Stop
		HitTargetPlayer:
			TNT1 A 0 A_GiveInventory("BDDemonStaffAmmo", damage, AAPTR_TRACER)
			stop
	}
}

// ---------------------

// light helper object - given by Demon Staff when altfiring. used by player class's Missile firing state.
ACTOR BDDemonStaffSuckLight : Inventory
{
	Inventory.Amount 1
	Inventory.MaxAmount 1
}

///////////////////////////////
// EQUIPPABLE DEMON STAFFS
///////////////////////////////

ACTOR RealDemonStaff0 : RealDemonStaff
{
	Weapon.SlotNumber 1
}

ACTOR RealDemonStaff1 : RealDemonStaff
{
	Weapon.SlotNumber 2
}

ACTOR RealDemonStaff2 : RealDemonStaff
{
	Weapon.SlotNumber 3
}
