//=====================================================================
// NemesisWINGSvX.
//      ""(§)FrÅgÊd(§)""
//               **Monarch**
//
//              555 ---===CrAzYBoNeS===--- 555
//          Boppolis_The_Dog
//
//
// Thank you Al McElrath for SLV2.
//=====================================================================
/** Shockwave that eminates from a Strangelove detonation.
*/
class StrangeWave extends ShockWave config (NemesisWINGSvX);

#exec AUDIO IMPORT NAME="UT3ExplRemix" FILE=SOUNDS\UT3ExplRemix.wav GROUP="NukeAmb"

#exec TEXTURE IMPORT NAME=thermoSkinRed FILE=thermoSkinRed.bmp GROUP=Skins FLAGS=2 LODSET=2
#exec TEXTURE IMPORT NAME=thermoSkinBlue FILE=thermoSkinBlue.bmp GROUP=Skins FLAGS=2 LODSET=2
#exec TEXTURE IMPORT NAME=thermoSkinGreen FILE=thermoSkinGreen.bmp GROUP=Skins FLAGS=2 LODSET=2
#exec TEXTURE IMPORT NAME=thermoSkinYellow FILE=thermoSkinYellow.bmp GROUP=Skins FLAGS=2 LODSET=2

var() Sound detonateSound;
var() config float shockMult;

// Mesh radius.
var() float meshr;
var() localized string deathStr[25], deathSelfStr[12];
var() name dtype;
var ThermoWave slave;
var() config bool bTeamColored;
var() config bool bGhostPawns, bGhostJets, bGhostNukes, bGhostMissiles;

// Slave is upside down?
var bool bSlaveDown;

var Pawn SecInstigator;
var bool bWasSeeking;

var Util u;


simulated function postBeginPlay() {
	local Actor a;
	local vector hl, hn;

	u = spawn(Class'Util', self);
	u.setDebugLevel(DL_Verbose);

	a = trace(hl, hn, (location + vect(0, 0, -1) * 125), location, false);
	if (a != none) {
		// Set it on the ground. Looks stupid hovering!
		setLocation(hl);
		setRotation(rotator(hn) + rot(-16384, 0, 0));
	}
	
	if (ROLE == Role_Authority)
	{
		if (bTeamColored && Instigator.PlayerReplicationInfo.Team <= 3)
		{
			if (Instigator.PlayerReplicationInfo.Team == 0)
			{
				Spawn(Class'RedNukeCorona');
				MultiSkins[0] = Texture'thermoSkinRed';
			}
			else if (Instigator.PlayerReplicationInfo.Team == 1)
			{
				Spawn(Class'BlueNukeCorona');
				MultiSkins[0] = Texture'thermoSkinBlue';
			}
			else if (Instigator.PlayerReplicationInfo.Team == 2)
			{
				Spawn(Class'GreenNukeCorona');
				MultiSkins[0] = Texture'thermoSkinGreen';
			}
			else
			{
				Spawn(Class'YellowNukeCorona');
				MultiSkins[0] = Texture'thermoSkinYellow';
			}
		}
		else
			Spawn(Class'NukeCorona');

		Spawn(Class'ShockAirBlast');
	}

	if (!level.bDropDetail && level.netmode != NM_DedicatedServer) {
		slave = spawn(Class'ThermoWave',Self);

		// If we're above flat ground, generate another hemisphere.
		if (a == none) {
			// Turn it upside down.
			slave.setRotation(rot(0, 0, -32768));
			//slave.setLocation(location + vect(0, 0, 1) * 20);
			bSlaveDown = true;
		}
	}

	loopAnim('rotate', 0.7);
	super.postBeginPlay();
}

/** Called from postBeginPlay().
*/
simulated function spawnEffects() {
	local float v;

	v = 45 * (shockMult / default.shockMult);

	playSound(detonateSound, SLOT_None, v,,3000);
	//playSound(detonateSound, SLOT_Interface, v,,3000);
	playSound(detonateSound, SLOT_Misc, v,,3000);
	//playSound(detonateSound, SLOT_Talk, v,,3000);
}


simulated function setRadius() {
	shockSize = cos(lifespan) * shockMult;
}


/** This is really for looks. The dedicated server calculates the
	radius in timer (that's when the real work is done).
*/
simulated function tick(float delta) {
	if (level.netmode != NM_DedicatedServer) {
		setRadius();

		scaleGlow = lifespan;
		ambientGlow = default.ambientGlow * (lifespan / default.lifespan);
		drawScale = shockSize;

		if (slave != none) {
			slave.scaleGlow = scaleGlow;
			slave.ambientGlow = slave.default.ambientGlow * (lifespan / default.lifespan);
			slave.drawScale = drawScale;
			if (!bSlaveDown)
				slave.drawScale *= 0.75;
		}
	}
}


simulated function timer() {
	local int i;
	local vector dir;
	local StrangeExpl exp;
	local DamagePuff puff;

	if (level.netmode == NM_DedicatedServer) {
		setRadius();
	} else {
		// Effects.
		if (level.bHighDetailMode && !level.bDropDetail) {
			for (i = 0; i < (shockMult * 0.5); i++) {
				dir = vrand();
				dir.z *= 0.2;
				exp = spawn(class'StrangeExpl',,, location + (dir * meshr * shocksize));
				exp.remoteRole = ROLE_None;
			}
		}
	}

	//if (role == ROLE_Authority)
		vaporize();
}


/** Carcass chunks are the authority on the client.
*/
simulated function vaporize() {
	local Actor victim;
	local float damageScale, dist, moscale;
	local vector dir;
	local bool bGiveDamage, bCB, bKilledSomeone;

	u.debug("vaporize(): shock size: " $ shockSize);

	foreach visibleCollidingActors(class 'Actor', victim, shockSize * meshr, location) {
		if (victim.role == ROLE_Authority) {

			// Maybe someday I'll figure this out.
			if (level.netmode == NM_Client)
				u.debug("vaporize(): victim has authority: " $ u.sname(victim));

			bGiveDamage = True;

			if (victim.IsA('Pawn') && bGhostPawns)
			{
				if (Pawn(victim).PlayerReplicationInfo.Team == Instigator.PlayerReplicationInfo.Team && Pawn(victim)!=Instigator)
					bGiveDamage = False;
			}
			else if (victim.IsA('StrangeShell') && bGhostJets)
			{
				if (StrangeShell(victim).Team == Instigator.PlayerReplicationInfo.Team && StrangeShell(victim).pilot!=Instigator)
					bGiveDamage = False;
			}
			else if (victim.IsA('AntiSlv') && bGhostNukes)
			{
				if (AntiSlv(victim).Instigator.PlayerReplicationInfo.Team == Instigator.PlayerReplicationInfo.Team && AntiSlv(victim).Instigator!=Instigator)
					bGiveDamage = False;
			}
			else if (victim.IsA('CarriedMissile') && bGhostMissiles)
			{
				if (CarriedMissile(victim).Instigator.PlayerReplicationInfo.Team == Instigator.PlayerReplicationInfo.Team && CarriedMissile(victim).Instigator!=Instigator)
					bGiveDamage = False;
			}

			if (bGiveDamage)
			{

			dir = victim.location - location;
			dist = fmax(1, vsize(dir));
			dir = dir/dist + vect(0, 0, 0.3);
			if ((dist > oldShockDistance) || (dir dot victim.velocity <= 0)) {
				moscale = fmax(0, 1100 - 1.1 * dist);

				// Non-pawns don't need death messages.
				if (role == ROLE_Authority && victim.bIsPawn) {
					Pawn(victim).addVelocity(dir * (moscale + 20));

					if (victim == instigator)
						u.setDamageString(deathSelfStr[Rand(ArrayCount(deathSelfStr))], instigator, victim);
					else
					{
						u.setDamageString(deathStr[Rand(ArrayCount(deathStr))], instigator, victim);
						bCB = SecInstigator != None && Pawn(victim).PlayerReplicationInfo.Team != SecInstigator.PlayerReplicationInfo.Team;
						bKilledSomeone = bWasSeeking && Pawn(victim).PlayerReplicationInfo.Team != instigator.PlayerReplicationInfo.Team && VSize(instigator.Location - victim.Location) > class'Strangemutator'.default.LockOnMinDist;
					}
	
					if (SecInstigator != None && victim != SecInstigator && victim != instigator && Pawn(victim).PlayerReplicationInfo.Team != SecInstigator.PlayerReplicationInfo.Team)
					{
						Level.Game.ScoreKill(SecInstigator, Pawn(victim));
						Pawn(victim).DieCount--;
						if (Pawn(victim).PlayerReplicationInfo != None)
							Pawn(victim).PlayerReplicationInfo.Score -= 1;

						if (TournamentPlayer(SecInstigator) != None)
						{
							TournamentPlayer(SecInstigator).ReceiveLocalizedMessage( Class'KillerMessagePlus', 0, SecInstigator.PlayerReplicationInfo, Pawn(victim).PlayerReplicationInfo);

							if (TournamentPlayer(SecInstigator).Level.TimeSeconds - TournamentPlayer(SecInstigator).LastKillTime < 3)
            						{
                						TournamentPlayer(SecInstigator).MultiLevel++;
	
								if (!class'Strangemutator'.default.enableSpecialAnnouncer)
                							TournamentPlayer(SecInstigator).ReceiveLocalizedMessage( class'MultiKillMessage', TournamentPlayer(SecInstigator).MultiLevel );
								else
									TournamentPlayer(SecInstigator).ReceiveLocalizedMessage( class'vxMultiKillMessage', TournamentPlayer(SecInstigator).MultiLevel );
            						} 
            						else
                						TournamentPlayer(SecInstigator).MultiLevel = 0;

							TournamentPlayer(SecInstigator).LastKillTime = TournamentPlayer(SecInstigator).Level.TimeSeconds;
						}
					}

				} else {
					victim.velocity = victim.velocity + dir * (moscale + 20);
				}

				victim.takedamage(moscale, instigator, victim.location - 0.5 * (victim.collisionHeight + victim.collisionRadius) * dir, (1000 * dir), dtype);

			}
			}
		}
	}

	if (bCB)
	{
		if (TournamentPlayer(Instigator) != None)	
			TournamentPlayer(Instigator).ReceiveLocalizedMessage( Class'vxSpecialFragEvent', 2);	//CANNON BALL

		if (TournamentPlayer(SecInstigator) != None)	
			TournamentPlayer(SecInstigator).ReceiveLocalizedMessage( Class'vxSpecialFragEvent', 2);	//CANNON BALL

		Instigator.PlayerReplicationInfo.Score += class'Strangemutator'.default.CannonBallBonus;
		SecInstigator.PlayerReplicationInfo.Score += class'Strangemutator'.default.CannonBallBonus;
	}
	else if (bKilledSomeone && TournamentPlayer(Instigator) != None)
	{
		if (Rand(50) > 25)
			TournamentPlayer(Instigator).ReceiveLocalizedMessage( Class'vxSpecialFragEvent', 9);	//LOCK AND LOAD
		else
			TournamentPlayer(Instigator).ReceiveLocalizedMessage( Class'vxSpecialFragEvent', 10);	//LOCK ON

		Instigator.PlayerReplicationInfo.Score += class'Strangemutator'.default.LockOnBonus;
	}

	oldShockDistance = shockSize * meshr;
}


simulated function destroyed() {
	local vector loc;

	if (level.netmode != NM_DedicatedServer) {
		if (!level.bDropDetail)
			spawn(Class'BlackCloud');
	}
	super.destroyed();
}



// end

defaultproperties
{
     detonateSound=Sound'UT3ExplRemix'
     shockMult=17.000000
     meshr=50.000000
     deathStr(0)="%o got pwned by %k."
	deathStr(1)="%k tested a Nuke on %o."
	deathStr(2)="%k heard %o squeaking."
	deathStr(3)="%k gave %o a little present."
	deathStr(4)="%o just woke up with %k blast."
	deathStr(5)="%k showed to %o how it is done."
	deathStr(6)="%k showed no mercy when blowing %o up."
	deathStr(7)="%o thought that %k was just taking a pee."
	deathStr(8)="%o was vaporized by %ks nuclear fart."
	deathStr(9)="No %o. %k wasn't botting."
	deathStr(10)="%o saw %opa flesh getting burned by %k new toy."
	deathStr(11)="%k introduced to %o %kpa new friend."
	deathStr(12)="%k laughed at %os face when blowing %oop up."
	deathStr(13)="Ooohhh, %k made %o cry..."
	deathStr(14)="%k guarantees that %o had no time to feel pain."
	deathStr(15)="%k heard %o screaming like a bitch."
	deathStr(16)="%o got erradicated by %k new weapon."
	deathStr(17)="%o got terminated by %k super weapon."
	deathStr(18)="%o got slaughtered by %k."
	deathStr(19)="%o last words to %k were: Ouch!"
	deathStr(20)="%o fell in love by %ks nuke."
	deathStr(21)="%o was caught by %k leetness."
	deathStr(22)="%o lost the nuclear combat to %k."
	deathStr(23)="%k just said Hi! to %o."
	deathStr(24)="%k just owned %o."
     deathSelfStr(0)="%k blew %kopself into tiny chunks."
	deathSelfStr(1)="%k should go back playing Doom."
	deathSelfStr(2)="The whole server heard %ks silly cries of pain."
	deathSelfStr(3)="%k made 'chili' out from %kopself."
	deathSelfStr(4)="Bulldog barfs at %ks silly suicide."
	deathSelfStr(5)="%k owned %kopself."
	deathSelfStr(6)="%k nuked %kopself like if there was no tomorrow."
	deathSelfStr(7)="%k had a nuclear orgasm."
	deathSelfStr(8)="%k thought he could survive to %kpa own nuke."
	deathSelfStr(9)="%k should learn how to use a nuke properly."
	deathSelfStr(10)="%k knows now the feeling of being 'nuked'."
	deathSelfStr(11)="%k showed everyone what NOT to do with a nuke."
     dtype=SpecialDamage
     LifeSpan=1.000000
     Mesh=SkeletalMesh'SLV2Models.thermo'
     AmbientGlow=180
     SoundVolume=244
     bTeamColored=True
     bGhostPawns=True
     bGhostMissiles=True
}
