//FlakCannon.cs;

datablock AudioProfile(FlakCannonFireSound)
{
   filename    = "./flak_cannon_fire.wav";
   description = AudioDefault3d;
   preload = true;
};

datablock ParticleData(FlakCannonBlastSparkParticle)
{
	dragCoefficient		= 1.0;
	windCoefficient		= 0.0;
	gravityCoefficient	= -0.0;
	inheritedVelFactor	= 0.0;
	constantAcceleration	= 0.0;
	lifetimeMS		= 300;
	lifetimeVarianceMS	= 150;
	spinSpeed		= 10.0;
	spinRandomMin		= -50.0;
	spinRandomMax		= 50.0;
	useInvAlpha		= true;
	animateTexture		= false;
	//framesPerSec		= 1;

	textureName		= "base/data/particles/dot";
	//animTexName		= "~/data/particles/dot";

	// Interpolation variables
   colors[0]     = "1 1 1.0 0.1";
   colors[1]     = "1 1 1.0 0.1";
   colors[2]     = "1 1 1 0.0";

	sizes[0]	= 0.15;
	sizes[1]	= 0.55;
   sizes[2]	= 0.15;

	times[0]	= 0.0;
	times[1]	= 0.1;
   times[2]	= 1.0;
};

datablock ParticleEmitterData(FlakCannonBlastSparkEmitter)
{
   ejectionPeriodMS = 1;
   periodVarianceMS = 0;
   ejectionVelocity = 0;
   velocityVariance = 0.0;
   ejectionOffset   = 0.0;
   thetaMin         = 0;
   thetaMax         = 90;
   phiReferenceVel  = 0;
   phiVariance      = 360;
   overrideAdvance = false;
   particles = "FlakCannonBlastSparkParticle";
};

datablock ParticleData(FlakCannonBlastExplosionParticle)
{
	dragCoefficient		= 1.0;
	windCoefficient		= 0.0;
	gravityCoefficient	= 0;
	inheritedVelFactor	= 0.0;
	constantAcceleration	= 0.0;
	lifetimeMS		= 800;
	lifetimeVarianceMS	= 500;
	spinSpeed		= 5.0;
	spinRandomMin		= -5.0;
	spinRandomMax		= 5.0;
	useInvAlpha		= true;
	animateTexture		= false;
	//framesPerSec		= 1;

	textureName		= "base/data/particles/cloud";
	//animTexName		= "~/data/particles/cloud";

	// Interpolation variables
   colors[0]     = "0.9 0.5 0.0 0.2";
   colors[1]     = "0.0 0.0 0.0 0.2";
   colors[2]     = "0.0 0.0 0.0 0.0";

	sizes[0]	= 6.0;
	sizes[1]	= 7.0;
   sizes[2]	= 1.5;

	times[0]	= 0.0;
	times[1]	= 0.28;
   times[2]	= 1.0;
};

datablock ParticleEmitterData(FlakCannonBlastExplosionEmitter)
{
   ejectionPeriodMS = 7;
   periodVarianceMS = 0;
   lifeTimeMS	   = 21;
   ejectionVelocity = 2;
   velocityVariance = 1.0;
   ejectionOffset   = 1.0;
   thetaMin         = 0;
   thetaMax         = 0;
   phiReferenceVel  = 0;
   phiVariance      = 90;
   overrideAdvance = false;
   particles = "FlakCannonBlastExplosionParticle";
};

datablock ParticleData(FlakCannonBlastExplosionParticle2)
{
	dragCoefficient		= 1.0;
	windCoefficient		= 0.0;
	gravityCoefficient	= -0.0;
	inheritedVelFactor	= 0.0;
	constantAcceleration	= 0.0;
	lifetimeMS		= 2000;
	lifetimeVarianceMS	= 1990;
	spinSpeed		= 10.0;
	spinRandomMin		= -50.0;
	spinRandomMax		= 50.0;
	useInvAlpha		= true;
	animateTexture		= false;
	//framesPerSec		= 1;

	textureName		= "base/data/particles/dot";
	//animTexName		= "~/data/particles/dot";

	// Interpolation variables
   colors[0]     = "1 1 0.0 0.1";
   colors[1]     = "1 1 0.0 0.2";
   colors[2]     = "1 1 1 0.0";

	sizes[0]	= 0.21;
	sizes[1]	= 0.21;
   sizes[2]	= 0.1;

	times[0]	= 0.0;
	times[1]	= 0.1;
   times[2]	= 1.0;
};

datablock ParticleEmitterData(FlakCannonBlastExplosionEmitter2)
{
   ejectionPeriodMS = 4;
   periodVarianceMS = 0;
   lifetimeMS       = 120;
   ejectionVelocity = 9;
   velocityVariance = 9.0;
   ejectionOffset   = 1.0;
   thetaMin         = 0;
   thetaMax         = 90;
   phiReferenceVel  = 0;
   phiVariance      = 360;
   overrideAdvance = false;
   particles = "FlakCannonBlastExplosionParticle2";
};

datablock ExplosionData(FlakCannonBlastExplosion)
{
   //explosionShape = "Add-Ons/Weapon_Rocket Launcher/explosionSphere1.dts";
   lifeTimeMS = 150;

   soundProfile = FlakCannonBlastExplodesound;

   emitter[0] = FlakCannonBlastExplosionEmitter2;
   //emitter[1] = "";
   //emitter[2] = "";
   //emitter[0] = "";

   particleEmitter = FlakCannonBlastExplosionEmitter;
   particleDensity = 20;
//   particleDensity = 0;
   particleRadius = 1.0;

   faceViewer     = true;
   explosionScale = "1 1 1";

   shakeCamera = false;
   camShakeFreq = "7.0 8.0 7.0";
   camShakeAmp = "1.0 1.0 1.0";
   camShakeDuration = 0.5;
   camShakeRadius = 15.0;

   // Dynamic light
   lightStartRadius = 0;
   lightEndRadius = 0;
   lightStartColor = "0.45 0.3 0.1";
   lightEndColor = "0 0 0";

   //impulse
   impulseRadius = 8;
   impulseForce = 1000;

   damageRadius = 8;
   radiusDamage = 20;

	uiName = "Flak Cloud";
};

AddDamageType("FlakCannonDirect",   '<bitmap:add-ons/Weapon_Package_Explosive2/CI_Grenade_launcher> %1',    '%2 <bitmap:add-ons/Weapon_Package_Explosive2/CI_Grenade_launcher> %1',1,1);
datablock ProjectileData(FlakCannonProjectile)
{
   projectileShapeName = "./grenade_projectile.2.dts";
   directDamage        = 100;
   directDamageType = $DamageType::FlakCannonDirect;
   radiusDamageType = $DamageType::FlakCannonDirect;
   impactImpulse	   = 1000;
   verticalImpulse	   = 1000;
   explosion           = flakcannonBlastExplosion;
   particleEmitter     = GrenadeSmokeEmitter;

   brickExplosionRadius = 3;
   brickExplosionImpact = false;          //destroy a brick if we hit it directly?
   brickExplosionForce  = 50;             
   brickExplosionMaxVolume = 76;          //max volume of bricks that we can destroy
   brickExplosionMaxVolumeFloating = 98;  //max volume of bricks that we can destroy if they aren't connected to the ground (should always be >= brickExplosionMaxVolume)

   muzzleVelocity      = 60;
   velInheritFactor    = 0.0;

   armingDelay         = 1500;
   lifetime            = 1500;
   fadeDelay           = 1500;
   bounceElasticity    = 0.9;
   bounceFriction      = 0.0;
   isBallistic         = true;
   gravityMod = 0.2;
   explodeOnPlayerImpact = true;
   explodeondeath = true;

   hasLight    = false;
   lightRadius = 5.0;
   lightColor  = "1 0.5 0.0";

   uiName = "Flak Round";

	//PrjEmit System Fields
	PrjEmit_enabled = 1;
	PrjEmit_projectile = FlakCannonSparkProjectile;
	PrjEmit_velocity = 20;
	PrjEmit_maxemits = 190;
	PrjEmit_ticktime = 200;
	PrjEmit_ammount = 4;
};

datablock ProjectileData(FlakCannonSparkProjectile)
{
//   projectileShapeName = "./nailgrenadedeployed.dts";
   directDamage        = 10;
   directDamageType  = $DamageType::Generic;
   radiusDamageType  = $DamageType::Generic;
   impactImpulse	   = 200;
   verticalImpulse	   = 200;
   particleEmitter     = FlakCannonBlastSparkEmitter;
   explosion           = FlakCannonBlastExplosion;

   muzzleVelocity      = 29;
   velInheritFactor    = 1;
   explodeOnDeath = true;

   brickExplosionRadius = 1;
   brickExplosionImpact = true;          //destroy a brick if we hit it directly?
   brickExplosionForce  = 10;             
   brickExplosionMaxVolume = 10;          //max volume of bricks that we can destroy
   brickExplosionMaxVolumeFloating = 20;  //max volume of bricks that we can destroy if they aren't connected to the ground (should always be >= brickExplosionMaxVolume)

   explodeOnDeath = true;
   armingDelay         = 00; 
   lifetime            = 70;
   fadeDelay           = 70;
   bounceElasticity    = 0.6;
   bounceFriction      = 0.1;
   isBallistic         = true;
   gravityMod = 0.8;

   hasLight    = false;
   lightRadius = 3.0;
   lightColor  = "0 0 0.5";
};

//////////
// item //
//////////
datablock ItemData(FlakCannonItem)
{
	category = "Weapon";  // Mission editor category
	className = "Weapon"; // For inventory system

	 // Basic Item Properties
   	shapeFile = "./CALIBRE_CANNON.DTS";
	rotate = false;
	mass = 1;
	density = 0.2;
	elasticity = 0.2;
	friction = 0.6;
	emap = true;

	//gui stuff
	uiName = "Flak Cannon";
	iconName = "./grenadelauncher";
	doColorShift = true;
	colorShiftColor = "0.20 0.20 0.2 1.000";

	 // Dynamic properties defined by the scripts
	image = FlakCannonImage;
	canDrop = true;

	maxAmmo = 1;
	canReload = 1;
};

////////////////
//weapon image//
////////////////
datablock ShapeBaseImageData(FlakCannonImage)
{
   // Basic Item properties
   	shapeFile = "./CALIBRE_CANNON.DTS";
   emap = true;

   // Specify mount point & offset for 3rd person, and eye offset
   // for first person rendering.
   mountPoint = 0;
   offset = "0 0 0";
   eyeOffset = 0; //"0.7 1.2 -0.5";
   rotation = eulerToMatrix( "0 0 0" );

   // When firing from a point offset from the eye, muzzle correction
   // will adjust the muzzle vector to point to the eye LOS point.
   // Since this weapon doesn't actually fire from the muzzle point,
   // we need to turn this off.  
   correctMuzzleVector = true;

   // Add the WeaponImage namespace as a parent, WeaponImage namespace
   // provides some hooks into the inventory system.
   className = "WeaponImage";

   // Projectile && Ammo.
   item = FlakCannonItem;
   ammo = " ";
   projectile = FlakCannonProjectile;
   projectileType = Projectile;

   //melee particles shoot from eye node for consistancy
   melee = false;
   //raise your arm up or not
   armReady = true;
   minShotTime = 700;   //minimum time allowed between shots (needed to prevent equip/dequip exploit)

   doColorShift = true;
   colorShiftColor = FlakCannonItem.colorShiftColor;//"0.400 0.196 0 1.000";

   //casing = " ";

   // Images have a state system which controls how the animations
   // are run, which sounds are played, script callbacks, etc. This
   // state system is downloaded to the client so that clients can
   // predict state changes and animate accordingly.  The following
   // system supports basic ready->fire->reload transitions as
   // well as a no-ammo->dryfire idle state.

   // Initial start up state
	stateName[0]                     = "Activate";
	stateTimeoutValue[0]             = 0.35;
	stateScript[0]                  = "onActivate";
	stateSequence[0]                = "Reload";
	stateSound[0]					= weaponSwitchSound;
	stateTransitionOnTimeout[0]       = "FireLoadCheckA";

	stateName[1]                     = "Ready";
	stateTransitionOnTriggerDown[1]  = "Fire";
	stateAllowImageChange[1]         = true;
	stateTransitionOnNoAmmo[1]		= "ReloadStart";
	stateScript[1]                  = "onReady";

	stateName[2]                    = "Fire";
	stateTransitionOnTimeout[2]     = "Delay";
	stateTimeoutValue[2]            = 0.01;
	stateFire[2]                    = true;
	stateAllowImageChange[2]        = false;
	stateEmitter[2]			  = shotgunExplosionRingEmitter;
	stateEmitterTime[2]		  = 0.03;
	stateSequence[2]                  = "Fire";
	stateScript[2]                  = "onFire";
	stateSound[2]					= FlakCannonFireSound;
	stateWaitForTimeout[2]			= true;

	stateName[3]			= "Delay";
	stateTransitionOnTimeout[3]     = "ReloadStart";
	stateTimeoutValue[3]            = 0.1;
	stateSequence[3]                  = "Reload";
	stateEmitterTime[3]				= 0.03;
	stateEmitterNode[3]				= "muzzleNode";
	
	stateName[4]				= "LoadCheckA";
	stateScript[4]				= "onLoadCheck";
	stateTimeoutValue[4]			= 0.01;
	stateTransitionOnTimeout[4]		= "LoadCheckB";
	
	stateName[5]				= "LoadCheckB";
	stateTransitionOnAmmo[5]		= "Ready";
	stateTransitionOnNoAmmo[5]		= "Reload";

	stateName[6]				= "Reload";
	stateTimeoutValue[6]			= 1.2;
	stateScript[6]				= "onReloadStart";
	stateTransitionOnTimeout[6]		= "Wait";
	stateWaitForTimeout[6]			= true;
	
	stateName[7]				= "Wait";
	stateTimeoutValue[7]			= 0.4;
	stateScript[7]				= "onReloadWait";
	stateTransitionOnTimeout[7]		= "Reloaded";
	
	stateName[8]				= "FireLoadCheckA";
	stateScript[8]				= "onLoadCheck";
	stateTimeoutValue[8]			= 0.01;
	stateTransitionOnTimeout[8]		= "FireLoadCheckB";
	
	stateName[9]				= "FireLoadCheckB";
	stateTransitionOnAmmo[9]		= "Ready";
	stateTransitionOnNoAmmo[9]		= "ReloadStart";
	
	stateName[10] 				= "Smoke";
	stateEmitterTime[10]			= 0.3;
	stateEmitterNode[10]			= "muzzleNode";
	stateTimeoutValue[10]			= 0.2;
	stateTransitionOnTimeout[10]		= "Halt";
	stateTransitionOnTriggerDown[10]	= "Fire";
	
	stateName[11] 				= "ReloadSmoke";
	stateEmitterTime[11]			= 0.3;
	stateEmitterNode[11]			= "muzzleNode";
	stateTimeoutValue[11]			= 0.2;
	stateTransitionOnTimeout[11]		= "Reload";
	
	stateName[12]				= "Reloaded";
	stateTimeoutValue[12]			= 0.1;
	stateScript[12]				= "onReloaded";
	stateTransitionOnTimeout[12]		= "Activate";

	stateName[13]			= "Halt";
	stateTransitionOnTimeout[13]     = "Ready";
	stateTimeoutValue[13]            = 0.9;
	stateEmitterTime[13]				= 0.48;
	stateEmitterNode[13]				= "muzzleNode";
	stateScript[13]                  = "onHalt";

	stateName[14]                     = "ReloadStart";
	stateTransitionOnTimeout[14]  = "ReloadStartB";
	stateTimeoutValue[14]            = 0.1;
	stateAllowImageChange[14]         = false;

	stateName[15]                     = "ReloadStartB";
	stateTransitionOnTimeout[15]  = "LoadCheckA";
	stateAllowImageChange[15]         = true;
};

function FlakCannonProjectile::onCollision(%this,%obj,%col,%fade,%pos,%normal)
{
	serverPlay3D(FlakCannonBounceSound,%obj.getTransform());
	
	for(%i=0;%i<getRandom(3,5);%i++)
	{
		%a=getRandom(0,360)/360*2*$pi;
		%b=getRandom(0,360)/360*2*$pi;
		
		%vec=mcos(%a) SPC msin(%a) SPC mcos(%b);
		
		%p=new Projectile()
		{
			datablock=FlakCannonSparkProjectile;
			
			initialVelocity=vectorScale(%vec,200);
			initialPosition=%obj.getPosition();
			
			client = %prj.client;
			sourceObject=%obj.sourceobject;
			sourceSlot=%obj.sourceslot;
		};
	}
	
	Parent::onCollision(%this,%obj,%col,%fade,%pos,%normal);
}

function FlakCannonImage::onFire(%this, %obj, %slot)
{
	Parent::OnFire(%this, %obj, %slot);
	if($Pref::Server::TTAmmo == 0 || $Pref::Server::TTAmmo == 1)
	{
	commandToClient(%obj.client,'bottomPrint',"<just:right><font:impact:24><color:fff000>Explosive Rounds <font:impact:34>\c6" @ %obj.toolAmmo[%obj.currTool] @ " / " @ %obj.client.quantity["bombrounds"] @ "", 4, 2, 3, 4); 
	}
	%obj.toolAmmo[%obj.currTool]--;

	%obj.playThread(2, plant);

		%p = new Projectile()
		{
			datablock 			= %projectile;
			initialVelocity 	= %velocity;
			initialPosition 	= %obj.getMuzzlePoint(%slot);
			sourceObject 		= %obj;
			sourceSlot 			= %slot;
			client 				= %obj.client;
			scale				= %obj.scale;
			CNT					= 90;
		};
}

function FlakCannonProjectile::onAdd(%this,%obj,%slot)
{
		schedule(getRandom(100,110),"takeShot",%p);
		MissionCleanup.add(%p);
}

function FlakCannonProjectile::takeShot(%db,%prj)
{
	initContainerRadiusSearch(%prj.getPosition(),32,$TypeMasks::PlayerObjectType);
	while(1)
	{
		%search=containerSearchNext();
		if(%prj.client==%search.client)
		{
			continue;
		}
		
		%mg=%prj.client.minigame;
		%mc=%search.client.minigame;
		%mgo=isObject(%mg);
		%mco=isObject(%mco);
		
		if(%mgo == %mco == 1)
		{
			if(%mg!$=%mc)
			{
				continue;
			}
		}
		
		if(isObject(%search))
		{
			%obj=%search;
		}
		break;
	}
	if(!isObject(%obj)) {%prj.delete();return;}
	
	%pos=vectorAdd(%obj.getPosition(),"0 0 "@ getWord(%obj.getScale(),2)*1.8);
	
	%vec=vectorSub(%pos,%prj.getPosition());
	%vec=vectorScale(vectorNormalize(%vec),FlakCannonSparkProjectile.muzzleVelocity);
	
	%p = new Projectile()
	{
		initialVelocity		= 28;
		initialPosition		= %prj.getPosition();
		datablock			= FlakCannonSparkProjectile;
		sourceObject		= %prj.client.player;
		sourceSlot			= %prj.sourceSlot;
		client				= %prj.client;
		scale				= %prj.getScale();
		CNT					= prj.CNT++;
	};
	if(%prj.CNT<22) {schedule(getRandom(100,110),"takeShot",%p);}
}

function FlakCannonImage::onReloadStart(%this,%obj,%slot)
{
    if(%obj.client.quantity["bombrounds"] >= 1)
	{
	
	%obj.playThread(2, shiftdown);
            		serverPlay3D(block_PlantBrick_Sound,%obj.getPosition());
	}
	if($Pref::Server::TTAmmo == 0 || $Pref::Server::TTAmmo == 1)
	{
	commandToClient(%obj.client,'bottomPrint',"<just:right><font:impact:24><color:fff000>Explosive Rounds <font:impact:34>\c6" @ %obj.toolAmmo[%obj.currTool] @ " / " @ %obj.client.quantity["bombrounds"] @ "", 4, 2, 3, 4); 
	}
}

function FlakCannonImage::onHalt(%this,%obj,%slot)
{
	if($Pref::Server::TTAmmo == 0 || $Pref::Server::TTAmmo == 1)
	{
	commandToClient(%obj.client,'bottomPrint',"<just:right><font:impact:24><color:fff000>Explosive Rounds <font:impact:34>\c6" @ %obj.toolAmmo[%obj.currTool] @ " / " @ %obj.client.quantity["bombrounds"] @ "", 4, 2, 3, 4); 
	}
}

function FlakCannonImage::onActivate(%this,%obj,%slot)
{
	if($Pref::Server::TTAmmo == 0 || $Pref::Server::TTAmmo == 1)
	{
	commandToClient(%obj.client,'bottomPrint',"<just:right><font:impact:24><color:fff000>Explosive Rounds <font:impact:34>\c6" @ %obj.toolAmmo[%obj.currTool] @ " / " @ %obj.client.quantity["bombrounds"] @ "", 4, 2, 3, 4); 
	}
}

function FlakCannonImage::onReady(%this,%obj,%slot)
{
	if($Pref::Server::TTAmmo == 0 || $Pref::Server::TTAmmo == 1)
	{
	commandToClient(%obj.client,'bottomPrint',"<just:right><font:impact:24><color:fff000>Explosive Rounds <font:impact:34>\c6" @ %obj.toolAmmo[%obj.currTool] @ " / " @ %obj.client.quantity["bombrounds"] @ "", 4, 2, 3, 4); 
	}
}

function FlakCannonImage::onReloadWait(%this,%obj,%slot)
{
    if(%obj.client.quantity["bombrounds"] >= 1)
	{
		%obj.playThread(2,plant);
            		serverPlay3D(block_MoveBrick_Sound,%obj.getPosition());
	}
	if($Pref::Server::TTAmmo == 0 || $Pref::Server::TTAmmo == 1)
	{
	commandToClient(%obj.client,'bottomPrint',"<just:right><font:impact:24><color:fff000>Explosive Rounds <font:impact:34>\c6" @ %obj.toolAmmo[%obj.currTool] @ " / " @ %obj.client.quantity["bombrounds"] @ "", 4, 2, 3, 4); 
	}
}

function FlakCannonImage::onReloaded(%this,%obj,%slot)
{
	%this.onLoadCheck(%obj,%slot);
    if(%obj.client.quantity["bombrounds"] >= 1)
	{
	if($Pref::Server::TTAmmo == 0 || $Pref::Server::TTAmmo == 1)
	{
	commandToClient(%obj.client,'bottomPrint',"<just:right><font:impact:24><color:fff000>Explosive Rounds <font:impact:34>\c6" @ %obj.toolAmmo[%obj.currTool] @ " / " @ %obj.client.quantity["bombrounds"] @ "", 4, 2, 3, 4); 
		%obj.client.quantity["bombrounds"]--;
	}
		%obj.toolAmmo[%obj.currTool]++;
            		serverPlay3D(block_PlantBrick_Sound,%obj.getPosition());
	}
}