/**
 * Base Actor for non-inventory/weapon things in Square.
 * This actor class should be extended.
 */
class SquareActor : Actor
{
	/**
	 * A handy extension of A_SpawnItemEx that spawns multiple actors at once.
	 * Returns the number of actors successfully spawned.
	 */
	int SQ_SpawnMultiple(class<Actor> classtype, int spawnCount = 1, Vector2 xofs = (0,0), Vector2 yofs = (0,0), Vector2 zofs = (0,0), Vector2 xvel = (0,0), Vector2 yvel = (0,0), Vector2 zvel = (0,0), Vector2 angle = (0,0), int flags = 0, int failchance = 0, int tid = 0)
	{
		int spawnedCount = 0;
		for(int i = 0; i < spawnCount; i++) {
			if(A_SpawnItemEx(classtype,
				frandom[SquareEffectRandom](xofs.x, xofs.y),
				frandom[SquareEffectRandom](yofs.x, yofs.y),
				frandom[SquareEffectRandom](zofs.x, zofs.y),
				frandom[SquareEffectRandom](xvel.x, xvel.y),
				frandom[SquareEffectRandom](yvel.x, yvel.y),
				frandom[SquareEffectRandom](zvel.x, zvel.y),
				frandom[SquareEffectRandom](angle.x, angle.y),
				flags,
				failchance,
				tid)) {
				spawnedCount++;
			}
		}
		return spawnedCount;
	}
}

/**
 * Base Square Voice-Over object characteristics.
 * "Given" to players via enemies or scripts.
 * This actor class should be extended.
 */
class SquareVO : CustomInventory
{
	Default
	{
		+INVENTORY.QUIET;
		+INVENTORY.ALWAYSPICKUP;
		+INVENTORY.AUTOACTIVATE;
	}

	States
	{
	Spawn:
		TNT1 A -1;
		Stop;
	Pickup:
		TNT1 A 0 ResolveState('PlaySound'); // Virtual Jump (for overriding)
		Stop;
	PlaySound:
		TNT1 A 0 ACS_NamedExecuteAlways('VO_Jabber', 0, args[0], args[1]);
		Stop;
	}
}


/**********************************
 * All Monsters
 **********************************/
class SquareMonster : Actor
{
	Default
	{
		Monster;
		Health 100;
		Radius 20;
		Height 48;
		Speed 8;
		FastSpeed 16;
		MaxStepHeight 16;
		Mass 1000;
		PainChance 64;
		BloodType 'SquareBlood';
		PainSound 'monster/pain';

		+NEVERRESPAWN;
		+NOINFIGHTING;
		+RANDOMIZE; // stagger most A_Look calls on spawn

		MaxTargetRange 2048;
	}

	States
	{
	Death.Massacre:
		RIPM A -1 A_RipInPeace();
		Stop;
	}

	void A_RipInPeace()
	{
		A_NoBlocking();
		A_StopSound(5); // for tritankles
		self.bFloatBob = false;
		self.bNoGravity = false;
	}
}

/** NOTHING! */

class Nothing : Actor {}
