actor SnakeWhipHold : Once {}
actor SnakeWhipHoldTime : WeaponCharge {}
actor SnakeWhipReturn : Once {}
actor SnakeDiedEarly : Once {}
actor DespawnOldWhip : Once {}
actor IsWhipping : Once {}

// Tried to make the cooldown time based on the item
// But that would require some modular work i think
// just take a 8 second cooldown to avoid camping
actor SnakeGrabDelay : PowerUp { powerup.duration 6 }
actor AltfireIsPrettyNeat : PowerUp { powerup.duration 3 }

actor SnakeWhipWep_NormalBar : NormalBar { args 104, 216 }
actor SnakeWhipWep_ScriptBar : ScriptBar {}

actor SnakeWhipWep : BaseMM8BDMWep
{
	Weapon.AmmoUse 2
	Weapon.AmmoGive 28
	weapon.ammotype "SnakeWhipAmmo"

	Weapon.SlotNumber 4

	Inventory.Pickupmessage "$PU_SnakeWhip"
	Obituary "$OB_SnakeWhip"
	Tag "$TAG_SnakeWhip"

	inventory.icon "3WHPICON"

	States
	{
		SpawnLoop:
			3WHP Z 1
			loop

		Ready:
			3WHP A 0 ACS_NamedExecuteWithResult("core_weaponcolor", CLR_SnakeWhip)
			3WHP A 1 A_WeaponReady
			Goto Ready+1

		Select:
			3WHP A 0
			Goto SelectSwap
			
		Deselect:
			3WHP A 0
			Goto DeselectSwap

		Fire:
			3WHP A 0 A_JumpIfNoAmmo("NoAmmo")
			3WHP A 0 A_GiveInventory("IsWhipping",1)
			3WHP A 0 A_GiveInventory("SnakeWhipHold",1)
			3WHP AB 1
			
			TNT1 A 0 A_PlayWeaponSound("weapon/snakewhip")
			TNT1 A 0 A_FireCustomMissile("SnakeWhipAttack",0,1,8,0)
		Goto WhipHold 
		
		WhipHold:
			3WHP C 0 A_JumpIfInventory("SnakeWhipHoldTime",10,"WhipWaitS")
			3WHP C 0 A_JumpIfInventory("SnakeDiedEarly",1,"WhipWaitS")
			3WHP C 1 Offset(10,38)
			3WHP C 2 A_GiveInventory("SnakeWhipHoldTime",1)
			3WHP C 0 A_Refire("WhipHold")
			
		WhipWaitS:
			3WHP A 0 A_TakeInventory("SnakeWhipHold",999)
			3WHP A 0 A_TakeInventory("SnakeDiedEarly",999)
			3WHP A 0 A_TakeInventory("SnakeWhipHoldTime",999)
			3WHP C 1 Offset(5,36)
		Goto WhipWait
		
		WhipWait:
			3WHP C 0 Offset(5,36)
			3WHP C 2 A_GiveInventory("WeaponCharge",1)
			TNT1 A 0 A_JumpIfInventory("WeaponCharge",200,"WhipFinish")
			TNT1 A 0 A_JumpIfInventory("SnakeWhipReturn",1,"WhipFinish")
		loop
		
		WhipFinish:
			TNT1 A 0 A_PlayWeaponSound("weapons/busters/duofistreturn")
			3WHP A 0 A_TakeInventory("SnakeWhipReturn",999)
			3WHP A 0 A_TakeInventory("WeaponCharge",999)
			3WHP A 0 A_TakeInventory("SnakeWhipHold",999)
			3WHP A 0 A_TakeInventory("SnakeDiedEarly",999)
			3WHP A 0 A_TakeInventory("SnakeWhipHoldTime",999)
			3WHP A 0 A_TakeInventory("IsWhipping",1)
			3WHP C 2 Offset(0,32)
			3WHP BAA 2
		Goto Ready+1
		
		Altfire:
			3WHP A 0 A_JumpIfNoAmmo("NoAmmo")
			3WHP A 0 A_GiveInventory("IsWhipping",1)
			3WHP A 0 A_GiveInventory("SnakeWhipHold",1)
			3WHP AB 1
			
			TNT1 A 0 A_PlayWeaponSound("misc/brgstaff")
			TNT1 A 0 A_FireCustomMissile("SnakeWhipAttackAlt",0,1,8,0)
			
			3WHP C 1 A_JumpIfInventory("AltfireIsPrettyNeat",1,"WhipWaitS")
			wait
			
		NoAmmo:
			3WHP A 1 ACS_NamedExecuteAlways("core_noammo",0)
		Goto Ready+1
	}
}

actor SnakeWhipAmmo : Ammo
{
	inventory.amount 1
	inventory.maxamount 27
	+INVENTORY.IGNORESKILL
}

actor SnakeWhipBase : BasicProjectile
{
// [Trill] Only want to toggle SEEKERMISSILE when needed.
//+SEEKERMISSILE
+SKYEXPLODE
+HITTRACER
Radius 15
Height 15
damage (CallACS("burst_cbm_damage",24))
damagetype "SnakeWhip"
Obituary "$OB_SnakeWhip"
speed 45
reactiontime 14
var int user_tid;
// [Trill] This gets transferred to various FX's
translation "192:198=104:215", "95:89=226:226"
}

actor SnakeWhipAttack : SnakeWhipBase
{
States
{
Spawn:
3WHP E 0
3WHP E 0 ACS_NamedExecuteWithResult("core_drawhookshot", ACS_NamedExecuteWithResult("core_gettarget"), 32, 8, DHS_MAXDIST + 1500)
3WHP E 0 ACS_NamedExecuteAlways("whiptidgiver",0)
Goto SpawnLoop

SpawnLoop:
3WHP E 0 A_SpawnItemEx("ThunderClawPegHelper",8)
3WHP E 1 A_SpawnItemEx("ThunderClawPegHelper",0)
//3WHP E 0 A_GiveInventory("SnakeWhipRedirect",1)
3WHP E 0 A_JumpIfInTargetInventory("ThunderClawSwingWait",1,"Death")
// [Trill] This fixes an online desync
3WHP E 0 A_JumpIfInTargetInventory("SnakeWhipHold", 1, 2)
3WHP E 1 A_JumpIf(true, "ReturningFlagSet")
wait
3WHP E 0 A_GiveInventory("CutterFlag",1)
3WHP E 0 A_JumpIfInventory("CutterFlag",3,"Sound")
Goto SpawnLoop
Sound:
3WHP E 0 A_TakeInventory("CutterFlag",999)
3WHP E 0 A_PlaySound("assists/wirefire")
Goto SpawnLoop

ReturningFlagSet:
3WHP F 0 A_GiveToTarget("AltfireIsPrettyNeat",1)
// [Trill] Only want to toggle SEEKERMISSILE when needed.
3WHP F 0 A_ChangeFlag(SEEKERMISSILE, true)
3WHP F 0 A_ChangeFlag(NOINTERACTION, true)
3WHP F 0 A_ChangeFlag(NOCLIP, true)
3WHP F 0 A_RearrangePointers(0,0,2)
3WHP F 0 A_FaceTarget

ReturnLoop:
3WHP F 0 A_SeekerMissile(90,90,SMF_PRECISE)
3WHP F 0 A_JumpIf(ACS_NamedExecuteWithResult("core_targetexists")==0, "Returned")
3WHP FFF 1 A_JumpIfCloser(60,"Returned")
3WHP E 0 A_PlaySound("assists/wirefire")
loop

Returned:
TNT1 A 1 ACS_NamedExecuteAlways("whipuntider",0)
TNT1 A 0 A_GiveToTarget("SnakeWhipReturn",1)
stop

Death:
XDeath:
Crash:
3WHP F 0 A_GiveToTarget("AltfireIsPrettyNeat",1)
TNT1 A 0 A_SpawnItemEx("SnakeWhipCrackFX", 0, 0, 0, 0, 0, 0, 0, SXF_TRANSFERTRANSLATION)
TNT1 A 0 A_PlaySoundEx("weapon/snakewhipcrack","SoundSlot6")
TNT1 A 0 A_GiveToTarget("SnakeDiedEarly",1)
3WHP F 0 ACS_NamedExecuteAlways("snakewhip_ItemSteal",0)
3WHP F 1
wait
}
}

actor SnakeWhipCrackFX : BasicGraphicEffect
{
scale 4
translation "192:198=104:215"
States
{
// [Trill] Fixed to have team colors
SpawnFrame:
3WHP G 0
3WHP GHIJ 1
stop
}
}

actor SnakeWhipAttackAlt : SnakeWhipAttack
{
States
{
Spawn:
3WHP E 0
3WHP E 0 ACS_NamedExecuteWithResult("core_drawhookshot", ACS_NamedExecuteWithResult("core_gettarget"), 32, 8, DHS_MAXDIST + 1500)
3WHP E 0 ACS_NamedExecuteAlways("whiptidgiver",0)
Goto SpawnLoop

SpawnLoop:
3WHP E 0 A_SpawnItemEx("ThunderClawPegHelper",8)
3WHP E 1 A_SpawnItemEx("ThunderClawPegHelper",0)
3WHP E 0 A_Countdown
loop

ReturningFlagSet:
3WHP F 0 A_GiveToTarget("AltfireIsPrettyNeat",1)
// [Trill] Only want to toggle SEEKERMISSILE when needed.
3WHP F 0 A_ChangeFlag(SEEKERMISSILE, true)
3WHP F 0 A_ChangeFlag(NOINTERACTION, true)
3WHP F 0 A_ChangeFlag(NOCLIP, true)
3WHP F 0 A_RearrangePointers(0,0,2)
3WHP F 0 A_FaceTarget

ReturnLoop:
3WHP F 0 A_SeekerMissile(90,90,SMF_PRECISE)
3WHP F 0 A_JumpIf(ACS_NamedExecuteWithResult("core_targetexists")==0, "Returned")
3WHP FFF 1 A_JumpIfCloser(60,"Returned")
3WHP E 0 A_PlaySound("assists/wirefire")
loop

Returned:
TNT1 A 1 ACS_NamedExecuteAlways("whipuntider",0)
TNT1 A 0 A_GiveToTarget("SnakeWhipReturn",1)
stop

Death:
XDeath:
Crash:
3WHP F 0 A_GiveToTarget("AltfireIsPrettyNeat",1)
TNT1 A 0 A_SpawnItemEx("SnakeWhipCrackFX", 0, 0, 0, 0, 0, 0, 0, SXF_TRANSFERTRANSLATION)
TNT1 A 0 A_PlaySoundEx("weapon/snakewhipcrack","SoundSlot6")
TNT1 A 0 A_GiveToTarget("SnakeDiedEarly",1)
TNT1 A 0 A_JumpIf(ceilingz-z<=25,"SwingCheck")
3WHP F 0 ACS_NamedExecuteAlways("snakewhip_ItemSteal",0)
3WHP F 1
wait
SwingCheck:
3WHP F 0 A_JumpIfInTargetInventory("SnakeWhipAmmo",2,"Swing")
Goto ReturningFlagSet
Swing:
TNT1 A 0 A_TakeFromTarget("SnakeWhipAmmo",2)
TNT1 A 0 ACS_NamedExecuteAlways("core_thunderclawpeg", 0, 70)
3WHP FFFFFFFF 1 A_Stop
Goto ReturningFlagSet
}
}

actor SnakeWhipAttackFX : DuoPunchFX{scale 2.5 translation "95:89=226:226"}
actor SnakeWhipAttackAltFX : SnakeWhipAttackFX{}
actor SWReturnMasterFX : SnakeWhipAttackFX {}

actor SnakeNudge : CustomInventory
{
    States
    {
    Pickup:
        TNT1 A 0 A_JumpIf(velx != 0 || vely != 0, "NoNudge")
        TNT1 A 0 A_ChangeVelocity(5, 0, 0, CVF_RELATIVE)
    NoNudge:
		TNT1 A 0
        stop
    }
}
