
actor VagrantColonySpot 16018
{
    -SOLID
    -SHOOTABLE
    +NOBLOCKMAP
        
    States
    {
        Spawn:
            TNT1 A 0
            TNT1 A 1  Thing_ChangeTID(0, 558) //558 is VAGRANTCOLONYSPOT_TID
            TNT1 A -1
            Wait
        SpawnColonyMaybe:
            TNT1 A 0
            TNT1 A 1 A_Jump(48, "SpawnColony")
            TNT1 A 1 A_Jump(256, "Spawn")
        SpawnColony:
            TNT1 A 0
            TNT1 A 0 A_Jump(256, "SpawnVagrantImpColony", "SpawnVagrantGruntColony", "SpawnVagrantCyberdemonColony")
            TNT1 A 0 A_Jump(256, "Spawn")
            goto Spawn
        SpawnVagrantGruntColony:
            TNT1 A 0 A_SpawnItemEx("VagrantGruntColony", 0.0, 0.0, 0.0, 0, 0, 0)
            goto Spawn
        SpawnVagrantImpColony:
            TNT1 A 0 A_SpawnItemEx("VagrantImpColony", 0.0, 0.0, 0.0, 0, 0, 0)
            goto Spawn
        SpawnVagrantCyberdemonColony:
            TNT1 A 0 A_SpawnItemEx("VagrantCyberdemonColony", 0.0, 0.0, 0.0, 0, 0, 0)
            goto Spawn
    }
}

actor VagrantImpColony
{
    Health 800
    Mass 0x7FFFFFFF
    +ISMONSTER //For master/child
    -SHOOTABLE //Gets set to be shootable in Idle state
    +SOLID
    Radius 24
    Height 38
    
    DropItem "LootBox"
    
    const int kMaxImps = 4;
    var int user_num_walls_built;
    var int user_max_child_colonies;
    //var int user_max_monsters;
    
    States
    {
        Spawn:
            TNT1 A 0
            TNT1 A 1  Thing_ChangeTID(0, 558) //558 is VAGRANTCOLONYSPOT_TID - We trigger child colony generation off this guy
            TNT1 A 0 A_Jump(256, "InitUserVars")
            goto InitUserVars
        InitUserVars:
            TNT1 A 0 A_SetUserVar("user_num_walls_built", 0)
            TNT1 A 0 A_SetUserVar("user_max_child_colonies", 4)
            //TNT1 A 0 A_SetUserVar("user_max_monsters", 5)
            TNT1 A 0 A_Jump(256, "StartBuilding")
            goto StartBuilding
        StartBuilding:
        SpawnFloor:
            //TNT1 A 10 A_UnsetSolid //Dont block the floor - we're at z=0 so we're blocking it
            //TNT1 A 2 A_SpawnItemEx("CFloor", 0.0, 0.0, 0.0, 0,0,0, 0, SXF_SETMASTER)
            //TNT1 A 5 ThrustThingZ(0, 4, 0, 1) //Move ourselves on top of the floor
            //TNT1 A 0 A_SetSolid //Block other stuff again :-)
            TNT1 A 35
            TNT1 A 0 A_Jump(256, "BuildWall")
            goto BuildWall
        BuildWall:
            TNT1 A 20
            TNT1 A 2 A_SpawnItemEx("CSkullBox", 96.0, 96.0, 96.0, 0,0,0, 0, SXF_SETMASTER)
            TNT1 A 2 A_SpawnItemEx("CSkullBox", 96.0, 48.0, 96.0, 0,0,0, 0, SXF_SETMASTER)
            TNT1 A 2 A_SpawnItemEx("CSkullBox", 96.0, -48.0, 96.0, 0,0,0, 0, SXF_SETMASTER)
            //TNT1 A 2 A_SpawnItemEx("CBox", 96.0, -96.0, 96.0, 0,0,0, 0, SXF_SETMASTER)

            TNT1 A 20
            TNT1 A 2 A_SpawnItemEx("CSkullBox", 96.0, 96.0, 96.0, 0,0,0, 0, SXF_SETMASTER)
            TNT1 A 2 A_SpawnItemEx("CSkullBox", 96.0, 48.0, 96.0, 0,0,0, 0, SXF_SETMASTER)
            TNT1 A 2 A_SpawnItemEx("CSkullBox", 96.0, -48.0, 96.0, 0,0,0, 0, SXF_SETMASTER)
            //TNT1 A 2 A_SpawnItemEx("CBox", 96.0, -96.0, 96.0, 0,0,0, 0, SXF_SETMASTER)

            TNT1 A 20
            TNT1 A 2 A_SpawnItemEx("CSkullBox", 96.0, 96.0, 96.0, 0,0,0, 0, SXF_SETMASTER)
            TNT1 A 2 A_SpawnItemEx("CSkullBox", 96.0, 48.0, 96.0, 0,0,0, 0, SXF_SETMASTER)
            TNT1 A 2 A_SpawnItemEx("CSkullBox", 96.0, -48.0, 96.0, 0,0,0, 0, SXF_SETMASTER)
            //TNT1 A 2 A_SpawnItemEx("CBox", 96.0, -96.0, 96.0, 0,0,0, 0, SXF_SETMASTER)
            
           
            TNT1 A 3 A_JumpIf(user_num_walls_built == 2, "BuildDoor")
            TNT1 A 1 A_JumpIf(user_num_walls_built == 2, "BuildDoor")

            //Fill middle section
            TNT1 A 20
            TNT1 A 2 A_SpawnItemEx("CSkullBox", 96.0, 0.0,  0.0, 0,0,0, 0, SXF_SETMASTER)
            TNT1 A 3 A_Jump(128, 3)
            TNT1 A 2 A_SpawnItemEx("CGlassBox", 96.0, 0.0, 48.0, 0,0,0, 0, SXF_SETMASTER)
            TNT1 A 3 A_Jump(255, 2)
            TNT1 A 2 A_SpawnItemEx("CSkullBox", 96.0, 0.0,  48.0, 0,0,0, 0, SXF_SETMASTER)
            TNT1 A 2 A_SpawnItemEx("CSkullBox", 96.0, 0.0,  96.0, 0,0,0, 0, SXF_SETMASTER)
            TNT1 A 3 A_Jump(256, "IncrementAndCheckLoop")
            TNT1 A 3 A_Jump(256, "IncrementAndCheckLoop")

        BuildDoor:
            TNT1 A 20
            TNT1 A 2 A_SpawnItemEx("CDoor", 96.0, 0.0, 0.0, 0,0,0, 0, SXF_SETMASTER)
            TNT1 A 10 A_SpawnItemEx("CSkullBox", 96.0, 0.0, 96.0, 0,0,0, 0, SXF_SETMASTER)

        
        IncrementAndCheckLoop:
            TNT1 A 0 A_SetAngle(angle + 90)
            TNT1 A 0 A_SetUserVar("user_num_walls_built", user_num_walls_built + 1)
            TNT1 A 0 A_JumpIf(user_num_walls_built < 4, "BuildWall")
            TNT1 A 0 A_Jump(256, "SpawnCeiling")

        SpawnCeiling:
            TNT1 A 10
            TNT1 A 2 A_SpawnItemEx("CFloor", 0.0, 0.0, 144.0, 0,0,0, 0, SXF_SETMASTER)
            TNT1 A 0 A_Jump(256, "SpawnTurretMaybe")

        SpawnTurretMaybe:
            TNT1 A 3
            TNT1 A 3 A_Jump(128, "SpawnPopulation")
            TNT1 A 0 A_SpawnItemEx("EnemySentryGun", 96.0, 0.0, 160.0, 0,0,0, 0, SXF_SETMASTER) 
            TNT1 A 0 A_Jump(256, "SpawnPopulation")
        
        SpawnPopulation:    
            TNT1 A 0 A_SpawnItemEx("VagrantImp", 256.0, 0.0, 0.0, 0, 0, 0, random(0,65535), 
                                    SXF_SETMASTER)
            CBOX A 0 //A_SetTranslucent(0.0)
            CBOX A 350
            TNT1 A 0 A_Jump(256, "SpawnChild")
        SpawnChild:
            TNT1 A 0
            TNT1 A 0 A_SpawnItemEx("VagrantImp", 256.0, 0.0, 0.0, 0, 0, 0, random(0,65535), 
                                    SXF_SETMASTER)    
            TNT1 A 0 A_Jump(256, "Idle")
            goto Idle
        Idle:
            TNT1 A 0 
            TNT1 A 0 A_SetShootable
            CBOX A 700 //Spawn another imp every 20 seconds, up to a maximum
            TNT1 A 0 A_JumpIfInventory("ChildCounter", kMaxImps, "Idle") // user_max_monsters, "Idle")
            TNT1 A 0 A_Jump(255, "SpawnChild")
            Loop
            
        SpawnColonyMaybe:
            TNT1 A 0
            //Don't make more than the max child colonies
            CBOX A 0 A_JumpIfInventory("ChildColonyCounter", user_max_child_colonies, "Idle")
            CBOX A 1 A_Jump(255 /*64*/, "SpawnColony")
            CBOX A 1 A_Jump(255, "Idle")
            goto Idle
        SpawnColony:
            CBOX A 0 
            CBOX A 0 A_SpawnItemEx("VagrantImpColonyProjectile", 0.0, 0.0, 64.0, 5.0,0,0, random(0,65535), SXF_SETMASTER)
            //CBOX A 0 A_CustomMissile("VagrantImpColonyProjectile", 16.0, 0.0, random(0, 65535), CMF_AIMDIRECTION)
            CBOX A 0
            goto Idle 
 
        Death:
            TNT1 A 0
            TNT1 A 3 A_SpawnItemEx("WoodShrapnelSpawner", 0, 0, 0, 0, 0, 0, 0, SXF_CLIENTSIDE)
            TNT1 A 5 A_Quake(8, 35, 0, 2048.0)
            TNT1 A 0 A_Fall
            TNT1 A 10 A_KillChildren
            TNT1 A 10 A_DamageChildren(2048, "Axe")
            stop
    }
}




actor ChildColonyCounter : Inventory {
    Inventory.MaxAmount 5
}

actor ChildCounter : Inventory {
    Inventory.MaxAmount 10
}

actor VagrantGruntColony : VagrantImpColony
{
    const int kMaxGrunts = 5;
    States
    {
        InitUserVars:
            TNT1 A 0 A_SetUserVar("user_num_walls_built", 0)
            TNT1 A 0 A_SetUserVar("user_max_child_colonies", 4)
            //TNT1 A 0 A_SetUserVar("user_max_monsters", 5)
            TNT1 A 0 A_Jump(256, "StartBuilding")
            goto StartBuilding

        Idle:
            TNT1 A 0 
            TNT1 A 0 A_SetShootable
            CBOX A 700 //Spawn another imp every 20 seconds, up to a maximum
            TNT1 A 0 A_JumpIfInventory("ChildCounter", kMaxGrunts, "Idle") // user_max_monsters, "Idle")
            TNT1 A 0 A_Jump(255, "SpawnChild")
            Loop

        SpawnPopulation:    
            TNT1 A 0 A_SpawnItemEx("VagrantGrunt", 256.0, 0.0, 0.0, 0, 0, 0, random(0,65535),
                                    SXF_SETMASTER)
            CBOX A 0 //A_SetTranslucent(0.0)
            CBOX A 350
            TNT1 A 0 A_Jump(256, "Idle")
            goto Idle
        SpawnChild:
            TNT1 A 0
            TNT1 A 0 A_SpawnItemEx("VagrantGrunt", 256.0, 0.0, 0.0, 0, 0, 0, random(0,65535),
                                    SXF_SETMASTER)        
            TNT1 A 0 A_Jump(256, "Idle")
            goto Idle
        SpawnColony:
            CBOX A 0
            CBOX A 0 A_SpawnItemEx("VagrantGruntColonyProjectile", 0.0, 0.0, 64.0, 5.0,0,0, random(0,65535), SXF_SETMASTER)
            CBOX A 0
            TNT1 A 0 A_Jump(256, "Idle")
            goto Idle
    }
}


actor VagrantCyberdemonColony : VagrantImpColony
{

    DropItem "LootBox"
    DropItem "LootBox"
    DropItem "LootBox"
    Health 1300         //A bit more heatlth than the regular one...

    const int kMaxCyberdemonsPerColony = 1;
    const int kFloors = 2;
    States
    {
        InitUserVars:
            TNT1 A 0 A_SetUserVar("user_num_walls_built", 0)
            TNT1 A 0 A_SetUserVar("user_max_child_colonies", -1) // No children for cyberdemon
            TNT1 A 0 A_Jump(256, "StartBuilding")
            goto StartBuilding

        Idle:
            TNT1 A 0
            TNT1 A 0 A_SetShootable
            CBOX A 700 //Spawn another imp every 20 seconds, up to a maximum
            TNT1 A 0 A_JumpIfInventory("ChildCounter", kMaxCyberdemonsPerColony, "Idle") // user_max_monsters, "Idle")
            TNT1 A 0 A_Jump(255, "SpawnChild")
            Loop

        IncrementAndCheckLoop:
            TNT1 A 0 A_SetAngle(angle + 90)
            TNT1 A 0 A_SetUserVar("user_num_walls_built", user_num_walls_built + 1)
            TNT1 A 0 A_JumpIf(user_num_walls_built < 4*kFloors, "BuildWall")
            TNT1 A 0 A_Jump(256, "SpawnCeiling")

        BuildWall:
            TNT1 A 20
            TNT1 A 2 A_SpawnItemEx("CStoneBox", 96.0, 96.0, 256.0, 0,0,0, 0, SXF_SETMASTER)
            TNT1 A 2 A_SpawnItemEx("CSkullBox", 96.0, 48.0, 256.0, 0,0,0, 0, SXF_SETMASTER)
            TNT1 A 2 A_SpawnItemEx("CSkullBox", 96.0, 0.0, 256.0, 0,0,0, 0, SXF_SETMASTER)
            TNT1 A 2 A_SpawnItemEx("CSkullBox", 96.0, -48.0, 256.0, 0,0,0, 0, SXF_SETMASTER)
            //TNT1 A 2 A_SpawnItemEx("CBox", 96.0, -96.0, 256.0, 0,0,0, 0, SXF_SETMASTER)

            TNT1 A 20
            TNT1 A 2 A_SpawnItemEx("CStoneBox", 96.0, 96.0, 256.0, 0,0,0, 0, SXF_SETMASTER)
            TNT1 A 2 A_SpawnItemEx("CBodiesBox", 96.0, 48.0, 256.0, 0,0,0, 0, SXF_SETMASTER)
            TNT1 A 2 A_SpawnItemEx("CBodiesBox", 96.0, 0.0, 256.0, 0,0,0, 0, SXF_SETMASTER)
            TNT1 A 2 A_SpawnItemEx("CBodiesBox", 96.0, -48.0, 256.0, 0,0,0, 0, SXF_SETMASTER)
            //TNT1 A 2 A_SpawnItemEx("CBox", 96.0, -96.0, 256.0, 0,0,0, 0, SXF_SETMASTER)

            TNT1 A 20
            TNT1 A 2 A_SpawnItemEx("CStoneBox", 96.0, 96.0, 256.0, 0,0,0, 0, SXF_SETMASTER)
            TNT1 A 2 A_SpawnItemEx("CBodiesBox", 96.0, 48.0, 256.0, 0,0,0, 0, SXF_SETMASTER)
            TNT1 A 2 A_SpawnItemEx("CBodiesBox", 96.0, 0.0, 256.0, 0,0,0, 0, SXF_SETMASTER)
            TNT1 A 2 A_SpawnItemEx("CBodiesBox", 96.0, -48.0, 256.0, 0,0,0, 0, SXF_SETMASTER)
            //TNT1 A 2 A_SpawnItemEx("CBox", 96.0, -96.0, 256.0, 0,0,0, 0, SXF_SETMASTER)

            //No door for cyberdemons, to make them harder!

            TNT1 A 3 A_Jump(256, "IncrementAndCheckLoop")
            TNT1 A 3 A_Jump(256, "IncrementAndCheckLoop")

        SpawnCeiling:
            TNT1 A 10
            TNT1 A 2 A_SpawnItemEx("CFloor", 0.0, 0.0, 300.0, 0,0,0, 0, SXF_SETMASTER)
            TNT1 A 0 A_Jump(256, "SpawnTurretMaybe")

        SpawnTurretMaybe:
            TNT1 A 3
            TNT1 A 3 A_Jump(128, "SpawnPopulation")
            TNT1 A 0 A_SpawnItemEx("EnemySentryGun", 96.0, 0.0, 160.0, 0,0,0, 0, SXF_SETMASTER)
            TNT1 A 0 A_Jump(256, "SpawnPopulation")

        SpawnPopulation:
            TNT1 A 0 A_SpawnItemEx("VagrantCyberdemon", 256.0, 0.0, 0.0, 0, 0, 0, random(0,65535),
                                    SXF_SETMASTER)
            CBOX A 350
            TNT1 A 0 A_Jump(256, "Idle")
            goto Idle
        SpawnChild:
            TNT1 A 0
            TNT1 A 0 A_SpawnItemEx("VagrantCyberdemon", 256.0, 0.0, 0.0, 0, 0, 0, random(0,65535),
                                    SXF_SETMASTER)
            TNT1 A 0 A_Jump(256, "Idle")
            goto Idle
        SpawnColony:
            CBOX A 0 //Really disabled child colonies for the cyberdemon
            CBOX A 0
            TNT1 A 0 A_Jump(256, "Idle")
            goto Idle
    }
}



const float VAGRANT_COLONY_WANDER_RADIUS = 1024.0;

actor VagrantImp : DoomZImp
{
  Tag "Vagrant Imp"
  MaxTargetRange 512.0

  var int user_origx;
  var int user_origy;
  
  States
  {
  Spawn:
	TNT1 A 0 //dummy frame

        //Stick close to where we spawned:
        TNT1 A 0 A_SetUserVar("user_origx", x)
        TNT1 A 0 A_SetUserVar("user_origy", y)
        TNT1 A 0 A_GiveInventory("ChildCounter", 1, AAPTR_MASTER)

	TNT1 A 35 //Let the monster drop to the ground since we spawn
			  //them way above ground level so they don't get stuck
			  //in the floor.
	TNT1 A 0 A_SetTranslucent(0.0, 2)
	TROO M 6 A_SetTranslucent(0.2, 2)
	TROO M 6 A_SetTranslucent(0.4, 2)
	TROO M 6 A_SetTranslucent(0.6, 2)
	TROO M 6 A_SetTranslucent(0.8, 2)
	TROO M 6 A_SetTranslucent(1.0, 0) //opaque
	TROO MLKJI 7 //Play death animation in reverse so it looks
	              //like it's coming out of the ground
   Idle:
   SpawnLook:
    TROO A 0 A_JumpIf(x > user_origx+VAGRANT_COLONY_WANDER_RADIUS, "WanderBackIn")
    TROO A 0 A_JumpIf(y > user_origy+VAGRANT_COLONY_WANDER_RADIUS, "WanderBackIn")
    TROO A 0 A_JumpIf(x < user_origx-VAGRANT_COLONY_WANDER_RADIUS, "WanderBackIn")
    TROO A 0 A_JumpIf(y < user_origy-VAGRANT_COLONY_WANDER_RADIUS, "WanderBackIn")
    TROO A 0 A_LookEx(0, 0, 1024.0, 2048.0, 0, "See")
	TROO AABBCCDD 8 A_Wander
    TROO A 0 A_Jump(64, "Chill")
    loop
  Chill:
    TROO AABB 15
    goto SpawnLook
  WanderBackIn:
    TNT1 A 0
    //A_FaceMaster needs Zandronum 3.0, so we do this swapping trick:
    //Set the master to be the target, and keep the master pointer.
    TROO A 0 A_RearrangePointers(AAPTR_MASTER, AAPTR_DEFAULT, AAPTR_DEFAULT)
    TROO A 0 A_FaceTarget
    TROO ABABABABABABAB 4 A_Chase("", "")
    //Clear the target 
    TROO A 0 A_RearrangePointers(AAPTR_NULL, AAPTR_DEFAULT, AAPTR_DEFAULT)
    goto Idle
  See:
 	//Randomly decide to attack your base or not
	//TNT1 A 0 A_Jump(200, 2) //200/256 chance of not changing state
	//TNT1 A 0 ACS_ExecuteAlways(502, 0)
	//Only check to remove ourselves and change attack modes every 6 seconds
    TROO AABBCCDD 4 A_Chase
    TROO AABBCCDD 4 A_Chase
    TROO AABBCCDD 4 A_Chase
    TROO AABBCCDD 4 A_Chase
    TROO AABBCCDD 4 A_Chase
    TROO AABBCCDD 4 A_Chase
	TROO A 0 A_CheckSight("Idle")
    loop
  Death:
    TNT1 A 0 
    TNT1 A 0 A_TakeInventory("ChildCounter", 1, 0, AAPTR_MASTER)
    goto Super::Death
  XDeath:
    TNT1 A 0
    TNT1 A 0 A_TakeInventory("ChildCounter", 1, 0, AAPTR_MASTER)
    goto Super::XDeath

  }
}


actor VagrantGrunt : ZombieMan
{
  Tag "Vagrant Grunt"
  MaxTargetRange 700.0
  DropItem "ZombieManLoot"

  var int user_origx;
  var int user_origy;
  
  States
  {
  Spawn:
	TNT1 A 0 //dummy frame
	TNT1 A 35 //Let the monster drop to the ground since we spawn
			  //them way above ground level so they don't get stuck
			  //in the floor.
	TNT1 A 0 A_SetTranslucent(0.0, 2)
	POSS L 6 A_SetTranslucent(0.2, 2)
	POSS L 6 A_SetTranslucent(0.4, 2)
	POSS L 6 A_SetTranslucent(0.6, 2)
	POSS L 6 A_SetTranslucent(0.8, 2)
	POSS L 6 A_SetTranslucent(1.0, 0) //opaque
	POSS LKJI 7 //Play death animation in reverse so it looks
	              //like it's coming out of the ground

    //Stick close to where we spawned:
    TNT1 A 0 A_SetUserVar("user_origx", x)
    TNT1 A 0 A_SetUserVar("user_origy", y)
    TNT1 A 0 A_GiveInventory("ChildCounter", 1, AAPTR_MASTER)
   Idle:
   SpawnLook:
    POSS A 0 A_JumpIf(x > user_origx+VAGRANT_COLONY_WANDER_RADIUS, "WanderBackIn")
    POSS A 0 A_JumpIf(y > user_origy+VAGRANT_COLONY_WANDER_RADIUS, "WanderBackIn")
    POSS A 0 A_JumpIf(x < user_origx-VAGRANT_COLONY_WANDER_RADIUS, "WanderBackIn")
    POSS A 0 A_JumpIf(y < user_origy-VAGRANT_COLONY_WANDER_RADIUS, "WanderBackIn")
    POSS A 0 A_LookEx(0, 0, 1024.0, 2048.0, 0, "See")
	POSS AABBCCDD 8 A_Wander
    POSS A 0 A_Jump(64, "Chill")
    loop
  Chill:
    POSS AABB 15
    goto SpawnLook
  WanderBackIn:
    TNT1 A 0
    //A_FaceMaster needs Zandronum 3.0, so we do this swapping trick:
    //Set the master to be the target, and keep the master pointer.
    POSS A 0 A_RearrangePointers(AAPTR_MASTER, AAPTR_DEFAULT, AAPTR_DEFAULT)
    POSS A 0 A_FaceTarget
    POSS ABABABABABABAB 4 A_Chase("", "")
    //Clear the target
    POSS A 0 A_RearrangePointers(AAPTR_NULL, AAPTR_DEFAULT, AAPTR_DEFAULT)
    goto Idle
  See:
 	//Randomly decide to attack your base or not
	//TNT1 A 0 A_Jump(200, 2) //200/256 chance of not changing state
	//TNT1 A 0 ACS_ExecuteAlways(502, 0)
	//Only check to remove ourselves and change attack modes every 6 seconds
    POSS AABBCCDD 4 A_Chase
    POSS AABBCCDD 4 A_Chase
    POSS AABBCCDD 4 A_Chase
    POSS AABBCCDD 4 A_Chase
    POSS AABBCCDD 4 A_Chase
    POSS AABBCCDD 4 A_Chase
	POSS A 0 A_CheckSight("Idle")
    loop
    Death:
        TNT1 A 0
        TNT1 A 0 A_GiveToTarget("ZombieManKillXP", 1)
        TNT1 A 0 A_Jump(256, "Death.NoXP")
        goto Death.NoXP
    XDeath:
        TNT1 A 0
        TNT1 A 0 A_GiveToTarget("ZombieManKillXP", 1)
        TNT1 A 0 A_TakeInventory("ChildCounter", 1, 0, AAPTR_MASTER)
        POSS M 5
        POSS N 5 A_XScream
        POSS O 5 A_NoBlocking
        POSS PQRST 5
        POSS U -1
        Stop
    Death.NoXP:
    Death.SentryTurret:
        TNT1 A 0
        TNT1 A 0 A_TakeInventory("ChildCounter", 1, 0, AAPTR_MASTER)
          POSS H 5
          POSS I 5 A_Scream
          POSS J 5 A_NoBlocking
          POSS K 5
          POSS L 350
          Stop

          POSS M 5
          POSS N 5 A_XScream
          POSS O 5 A_NoBlocking
          POSS PQRST 5
          POSS U 350
          Stop
  }
}


actor VagrantCyberdemon : Cyberdemon
{
  Tag "Vagrant Cyberdemon"
  MaxTargetRange 512.0

  var int user_origx;
  var int user_origy;

  States
  {
  Spawn:
        TNT1 A 0 //dummy frame
        TNT1 A 35 //Let the monster drop to the ground since we spawn
                          //them way above ground level so they don't get stuck
                          //in the floor.
        TNT1 A 0 A_SetTranslucent(0.0, 2)
        CYBR P 6 A_SetTranslucent(0.2, 2)
        CYBR P 6 A_SetTranslucent(0.4, 2)
        CYBR P 6 A_SetTranslucent(0.6, 2)
        CYBR P 6 A_SetTranslucent(0.8, 2)
        CYBR P 6 A_SetTranslucent(1.0, 0) //opaque
        CYBR PONMLKJIH 3 //Play death animation in reverse so it looks
                      //like it's coming out of the ground

        //Stick close to where we spawned:
        TNT1 A 0 A_SetUserVar("user_origx", x)
        TNT1 A 0 A_SetUserVar("user_origy", y)
        TNT1 A 0 A_GiveInventory("ChildCounter", 1, AAPTR_MASTER)
   Idle:
   SpawnLook:
        CYBR A 0 A_JumpIf(x > user_origx+VAGRANT_COLONY_WANDER_RADIUS, "WanderBackIn")
        CYBR A 0 A_JumpIf(y > user_origy+VAGRANT_COLONY_WANDER_RADIUS, "WanderBackIn")
        CYBR A 0 A_JumpIf(x < user_origx-VAGRANT_COLONY_WANDER_RADIUS, "WanderBackIn")
        CYBR A 0 A_JumpIf(y < user_origy-VAGRANT_COLONY_WANDER_RADIUS, "WanderBackIn")
        CYBR A 0 A_LookEx(0, 0, 1024.0, 2048.0, 0, "See")
        CYBR AABBCCDD 8 A_Wander
        CYBR A 0 A_Jump(64, "Chill")
        loop
  Chill:
    CYBR AABB 15
    goto SpawnLook
  WanderBackIn:
    TNT1 A 0
    //A_FaceMaster needs Zandronum 3.0, so we do this swapping trick:
    //Set the master to be the target, and keep the master pointer.
    CYBR A 0 A_RearrangePointers(AAPTR_MASTER, AAPTR_DEFAULT, AAPTR_DEFAULT)
    CYBR A 0 A_FaceTarget
    CYBR ABABABABABABAB 4 A_Chase("", "")
    //Clear the target
    CYBR A 0 A_RearrangePointers(AAPTR_NULL, AAPTR_DEFAULT, AAPTR_DEFAULT)
    goto Idle
  See:
    //Randomly decide to attack your base or not
    //TNT1 A 0 A_Jump(200, 2) //200/256 chance of not changing state
    //TNT1 A 0 ACS_ExecuteAlways(502, 0)
    //Only check to remove ourselves and change attack modes every 6 seconds
    CYBR A 4 A_Hoof
    CYBR ABB 4 A_Chase
    CYBR D 4 A_Metal
    CYBR D 4 A_Chase
    CYBR A 4 A_Hoof
    CYBR ABB 4 A_Chase
    CYBR D 4 A_Metal
    CYBR D 4 A_Chase
    CYBR A 4 A_Hoof
    CYBR ABB 4 A_Chase
    CYBR D 4 A_Metal
    CYBR D 4 A_Chase
    CYBR A 4 A_Hoof
    CYBR ABB 4 A_Chase
    CYBR D 4 A_Metal
    CYBR D 4 A_Chase
    CYBR A 4 A_Hoof
    CYBR ABB 4 A_Chase
    CYBR D 4 A_Metal
    CYBR D 4 A_Chase
    CYBR A 4 A_Hoof
    CYBR ABB 4 A_Chase
    CYBR D 4 A_Metal
    CYBR D 4 A_Chase
    CYBR A 0 A_CheckSight("Idle")
    loop
    Death:
        TNT1 A 0 A_GiveToTarget("CyberdemonKillXP", 1)
    Death.NoXP:
    Death.SentryTurret:
      TNT1 A 0
      TNT1 A 0 A_TakeInventory("ChildCounter", 1, 0, AAPTR_MASTER)
      CYBR H 10
      CYBR I 10 A_Scream
      CYBR JKL 10
      CYBR M 10 A_NoBlocking
      CYBR NO 10
      CYBR P 30
      CYBR P 350 A_BossDeath
      Stop
  }
}


////////////////////////////////////////////////////
// PROJECTILES                                    //
// Only needed if you want to have child colonies //
////////////////////////////////////////////////////


actor VagrantImpColonyProjectile : DoomZMonsterSpawnerProjectile
{
    Speed 4
    Radius 192
    +ISMONSTER //Needed for master/child here???
    
    States
    {
		ReallySpawnMonster:
            TNT1 A 0
            TNT1 A 1 A_UnsetSolid //So we don't block the spawning below
            TNT1 A 0 A_Fall
            //We need the SXF_NOCHECKPOSITION here for some reason, but it's OK.
            //Colonies won't end up overlapping with stuff because the Radius
            //of this projectile is big enough and the logic in SpawnMonster
            //kills us if we overlap with something.
			TNT1 A 5 A_SpawnItemEx("VagrantImpChildColony", 0.0, 0.0, 512.0, 0,0,0, 90*random(0,3), SXF_TRANSFERPOINTERS | SXF_ABSOLUTEANGLE | SXF_NOCHECKPOSITION)
			Stop    
    }
}





actor VagrantGruntColonyProjectile : DoomZMonsterSpawnerProjectile
{
    Speed 4
    Radius 192
    +ISMONSTER //Needed for master/child here???
    
    States
    {
        ReallySpawnMonster:
            TNT1 A 0
            TNT1 A 1 A_UnsetSolid //So we don't block the spawning below
            TNT1 A 0 A_Fall
            //We need the SXF_NOCHECKPOSITION here for some reason, but it's OK.
            //Colonies won't end up overlapping with stuff because the Radius
            //of this projectile is big enough and the logic in SpawnMonster
            //kills us if we overlap with something.
            TNT1 A 5 A_SpawnItemEx("VagrantGruntChildColony", 0.0, 0.0, 512.0, 0,0,0, 90*random(0,3), SXF_TRANSFERPOINTERS | SXF_ABSOLUTEANGLE | SXF_NOCHECKPOSITION)
			Stop    
    }
}




////////////////////////////////////
// CHILD COLONIES                 //
////////////////////////////////////
///
/// These are secondary colonies that crop up 
/// around a colony. The difference is that these secondary
/// colonies won't create any children of their own.
////////////////////////////////////


actor VagrantImpChildColony : VagrantImpColony
{
    States
    {
        InitUserVars:
            TNT1 A 0 A_GiveInventory("ChildColonyCounter", 1, AAPTR_MASTER)
            //Clear the master so we don't die
            //when the master colony dies
            TNT1 A 0 A_RearrangePointers(AAPTR_NULL, AAPTR_NULL, AAPTR_NULL) 
            TNT1 A 0 A_SetUserVar("user_num_walls_built", 0)
            TNT1 A 0 A_SetUserVar("user_max_child_colonies", -1) //Must be -1 and not 0 because 0 is a special case for A_JumpIfInventory
            TNT1 A 0 Thing_ChangeTID(0, 0) //Nix our TID
            TNT1 A 100 //Let it drop to the group
            TNT1 A 0 A_Jump(256, "BuildWall")
            goto BuildWall
        SpawnColony:
            stop
    }
}

actor VagrantGruntChildColony : VagrantGruntColony
{
    States
    {
        InitUserVars:
            TNT1 A 0
            TNT1 A 0 A_GiveInventory("ChildColonyCounter", 1, AAPTR_MASTER)
            //Clear the master so we don't die
            //when the master colony dies
            TNT1 A 0 A_RearrangePointers(AAPTR_NULL, AAPTR_NULL, AAPTR_NULL) 
            TNT1 A 0 A_SetUserVar("user_num_walls_built", 0)
            TNT1 A 0 A_SetUserVar("user_max_child_colonies", -1)   //Must be -1 and not 0 because 0 is a special case for A_JumpIfInventory
            TNT1 A 0 Thing_ChangeTID(0, 0) //Nix our TID
            TNT1 A 100 //Let it drop to the group
            TNT1 A 0 A_Jump(256, "BuildWall")
            goto BuildWall
        SpawnColony:
            stop
    }
}
