
class ZBaseMetalShield : Actor
{
	int Sxoffset;
	int Syoffset;
	int Szoffset;
	int Sxattackoffset;
	int Syattackoffset;
	int Szattackoffset;
	double Sbrokenhealth;
	bool Sappendix;
	int Sxoffsetap;
	int Syoffsetap;
	int Szoffsetap;
	string bullethitsound;
	string cracksound;

	ZBaseMetalShield apshield;
	Actor parentshield;

	bool shieldalive;

	virtual void SpawnHitDebris()
	{
		self.A_SpawnDebris("DukeMechParticle", mult_v: 1.0);
	}

	override void PostBeginPlay()
	{
		Super.PostBeginPlay();

		bullethitsound = "metal/hit";
		cracksound = "metal/land";

		shieldalive = true;

		if (!Sappendix) {
			Actor a = self;
			apshield = ZBaseMetalShield(Spawn("MetalShield", a.pos));
	  		apshield.master = a.master;
			apshield.A_SetSize(a.radius, a.height);
  			apshield.Sxoffset = Sxoffsetap;
	  		apshield.Syoffset = Syoffsetap;
  			apshield.Szoffset = Szoffsetap;
			apshield.Sappendix = true;
			apshield.parentshield = a;
		}
	}

	override int DamageMobj(Actor inflictor, Actor source, int damage, Name mod, int flags, double angle)
    	{
		if(master && source && source==master) return 0;

		if(inflictor && inflictor.GetClass() is 'Doom_ArchvileFireShield') damage = 0;

		int realdamage = self.ApplyDamageFactor(mod, damage);

		if(master && source && source!=master && master.health>0)
		{
	        	if(mod == 'Bullet' || mod == 'Chaingun' || mod == 'MightyBoot')
        		{
				SpawnHitDebris();
				self.A_PlaySound(bullethitsound);
				master.DamageMobj(inflictor, source, 0, "ShieldSingleHit", flags, angle);
        		}
        		else if(mod == 'FireChaingun')
	        	{
				SpawnHitDebris();
				self.A_PlaySound(bullethitsound);
				master.DamageMobj(inflictor, source, 0, "ShieldSingleHit", flags, angle);
				realdamage = realdamage + self.ApplyDamageFactor("BulletFlame", damage);
			}
        		else if(mod == 'Shotgun' || mod == 'SSG')
	        	{
				SpawnHitDebris();
				self.A_PlaySound(bullethitsound,random[RIDMONSTER](1,7));
				master.DamageMobj(inflictor, source, 0, "ShieldMultiHit", flags, angle);
	        	}
        		else if(mod == 'ExplosiveShotgun')
	        	{
				SpawnHitDebris();
				self.A_PlaySound(bullethitsound,random[RIDMONSTER](1,7));
				master.DamageMobj(inflictor, source, 0, "ShieldMultiHit", flags, angle);
				realdamage = realdamage + self.ApplyDamageFactor("ShellExplosion", damage);
	        	}
        		else if(mod == 'Plasma' || mod == 'RocketExplosion')
        		{
				SpawnHitDebris();
        		}

			if (Sappendix && parentshield) {
				parentshield.DamageMobj(inflictor, source, realdamage, "AppendixShield", flags, angle);
			}
		}

	        return super.DamageMobj(inflictor, source, realdamage, "none", flags, angle);
	}

	override void Tick()
	{
		Super.Tick();

		if(!master) Destroy();

		if (master && shieldalive) {
			if (!Sappendix) {
				if(master.health < 1) {
					shieldalive = false;
					self.A_Die();
				}
				else if(self.health < 1) {
					shieldalive = false;
					master.A_SetInventory("MasterShieldState", 2);
					self.A_Die();
				}
				else if (self.health <= Sbrokenhealth) {
					let mastershieldstate = master.FindInventory("MasterShieldState");
					if (mastershieldstate==null || mastershieldstate.Amount==0) {
						SpawnHitDebris();
						SpawnHitDebris();
						SpawnHitDebris();
						self.A_PlaySound(cracksound);
					}
					master.A_SetInventory("MasterShieldState", 1);
				}

				let masterattacking = master.FindInventory("MasterAttacking");
				if (masterattacking!=null && masterattacking.Amount>0) {
					self.A_Warp(AAPTR_MASTER, Sxattackoffset, Syattackoffset, Szattackoffset - (master.GetFloorTerrain().footclip*!master.bFLOAT), 0, WARPF_NOCHECKPOSITION|WARPF_BOB);
				} else {
					self.A_Warp(AAPTR_MASTER, Sxoffset, Syoffset, Szoffset - (master.GetFloorTerrain().footclip*!master.bFLOAT), 0, WARPF_NOCHECKPOSITION|WARPF_BOB);
				}

				if (master.health>0 && master.bINVULNERABLE==false) {
					self.bINVULNERABLE=0; self.bNODAMAGE=0; self.bNOPAIN=0; self.bTHRUACTORS=0; self.bGHOST=0; self.ThruBits=0;
				} else {
					self.bINVULNERABLE=1; self.bNODAMAGE=1; self.bNOPAIN=1; self.bTHRUACTORS=1; self.bGHOST=1; self.ThruBits=1;
				}
			} else {
				if(master.health < 1) Destroy();

				if(!parentshield) Destroy();

				if (parentshield) {
					if(parentshield.health < 1) Destroy();

					self.A_Warp(AAPTR_MASTER, Sxoffset, Syoffset, Szoffset - (master.GetFloorTerrain().footclip*!master.bFLOAT), 0, WARPF_NOCHECKPOSITION|WARPF_BOB);

					if (master.health>0 && master.bINVULNERABLE==false) {
						self.bINVULNERABLE=0; self.bNODAMAGE=0; self.bNOPAIN=0; self.bTHRUACTORS=0; self.bGHOST=0; self.ThruBits=0;
					} else {
						self.bINVULNERABLE=1; self.bNODAMAGE=1; self.bNOPAIN=1; self.bTHRUACTORS=1; self.bGHOST=1; self.ThruBits=1;
					}
				}
			}
		}
	}

}

class ZAltShield1 : ZBaseMetalShield
{
	override void SpawnHitDebris()
	{
		self.A_SpawnProjectile("FlameTrails1", random[RIDFX](5, 65), random[RIDFX](-20, 20), random[RIDFX](0, 360), CMF_AIMDIRECTION|CMF_BADPITCH, random[RIDFX](60, 90));
	}

	override void PostBeginPlay()
	{
		Actor.PostBeginPlay();

		bullethitsound = "dirt/hit";
		cracksound = "metal/land";

		shieldalive = true;

		if (!Sappendix) {
			Actor a = self;
			apshield = ZBaseMetalShield(Spawn("AltShield1", a.pos));
	  		apshield.master = a.master;
			apshield.A_SetSize(a.radius, a.height);
  			apshield.Sxoffset = Sxoffsetap;
	  		apshield.Syoffset = Syoffsetap;
  			apshield.Szoffset = Szoffsetap;
			apshield.Sappendix = true;
			apshield.parentshield = a;
		}
	}

}