datablock AudioProfile(reflectSound)
{
   filename    = "./reflect.wav";
   description = AudioClosest3d;
   preload = true;
};
datablock ParticleData(shieldParticle)
{
	dragCoefficient = 1.75;
	windCoefficient = 0;
	gravityCoefficient = 0;
	inheritedVelFactor = 0;
	constantAcceleration = 0;
	lifetimeMS = 1500;
	lifetimeVarianceMS = 500;
	textureName = "Add-Ons/Projectile_Pong/Square.png";
	spinSpeed = 0;
	spinRandomMin = -300;
	spinRandomMax = 300;
	useInvAlpha = false;
	colors[0]     = "1 1 0.0 0.3";
	colors[1]     = "1 1 0.0 0.3";
	sizes[0] = 0.1;
	sizes[1] = 0.2;
};

datablock ParticleEmitterData(shieldEmitter)
{
   ejectionPeriodMS = 15;
	periodVarianceMS = 0;
	ejectionVelocity = 1.5;
	velocityVariance = 1;
	ejectionOffset = 0.0;
	thetaMin = 0;
	thetaMax = 360;
	phiReferenceVel = 0;
	phiVariance = 360;
	overrideAdvance = false;
   particles = "shieldParticle";

   useEmitterColors = false;

   uiName = "";
};
datablock ParticleData(shieldreflectParticle)
{
   dragCoefficient      = 10;
   gravityCoefficient   = 0.0;
   inheritedVelFactor   = 0.2;
   constantAcceleration = 0.0;
   lifetimeMS           = 20;
   lifetimeVarianceMS   = 10;
   spinSpeed		= 0.0;
	spinRandomMin		= -150.0;
	spinRandomMax		= 150.0;
   textureName          = "Add-Ons/Projectile_Pong/Square.png";
	colors[0]     = "1 1 0.0 0.3";
	colors[1]     = "1 1 0.0 0.3";
	colors[2]     = "1 1 0.0 0.3";

   sizes[0]      = 0.0;
   sizes[1]      = 0.4;
   sizes[2]      = 0.6;

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

datablock ParticleEmitterData(shieldreflectEmitter)
{
   lifeTimeMS = 50;

   ejectionPeriodMS = 1;
   periodVarianceMS = 0;
   ejectionVelocity = 15;
   velocityVariance = 0.0;
   ejectionOffset   = 0.8;
   thetaMin         = 0;
   thetaMax         = 180;
   phiReferenceVel  = 0;
   phiVariance      = 180;
   overrideAdvance = false;
   particles = "shieldreflectParticle";

   uiName = "Pixel Shield";
};
datablock ExplosionData(shieldExplosion)
{
   //explosionShape = "";
   lifeTimeMS = 400;
   
   //emitter[0] = shieldExplosionEmitter;
   //emitter[0] = shieldSparkEmitter;
  // particleEmitter = shieldExplosionEmitter;
   particleDensity = 30;
	particleRadius = 1.0;
   
   faceViewer     = true;
   explosionScale = "1 1 1";

   soundProfile = pushBroomHitSound;

   
   shakeCamera = true;
   cameraShakeFalloff = false;
   camShakeFreq = "2.0 3.0 1.0";
   camShakeAmp = "1.0 1.0 1.0";
   camShakeDuration = 2.5;
   camShakeRadius = 0.0001;

   // Dynamic light
   lightStartRadius = 0;
   lightEndRadius = 0;
   lightStartColor = "0.0 0.0 0.0";
   lightEndColor = "0 0 0";
};
datablock ProjectileData(shieldProjectile)
{
   //projectileShapeName = "~/data/shapes/arrow.dts";
   directDamage        = 0;
   impactImpulse       = 500;
   verticalImpulse     = 500;
   explosion           = shieldExplosion;
   //particleEmitter     = as;

   muzzleVelocity      = 50;
   velInheritFactor    = 1;

   armingDelay         = 0;
   lifetime            = 200;
   fadeDelay           = 70;
   bounceElasticity    = 0;
   bounceFriction      = 0;
   isBallistic         = false;
   gravityMod = 0.0;

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

   uiName = "";
};
datablock ItemData(shieldItem)
{
	category = "Weapon";  // Mission editor category
	className = "Weapon"; // For inventory system

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

	//gui stuff
	uiName = "Reflector Pixel";
	iconName = "./reflect";
	doColorShift = true;
	colorShiftColor = "0.15 0.15 0 1";

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

datablock ShapeBaseImageData(shieldImage)
{
   shapeFile = "./emptyWeapon.dts";
   emap = true;

   mountPoint = 0;
   offset = "0 0 0";
   eyeOffset = 0; //"0.7 1.2 -0.5";
   rotation = eulerToMatrix( "0 0 90" );


   correctMuzzleVector = true;


   className = "WeaponImage";

   item = BowItem;
   ammo = " ";
   projectile = shieldProjectile;
   projectileType = Projectile;

   melee = false;
   armReady = true;

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

	stateName[0]                     = "Activate";
	stateTimeoutValue[0]             = 0.15;
	stateTransitionOnTimeout[0]       = "Ready";
	stateSound[0]					= pixelequip6Sound;

	stateName[1]                     = "Ready";
	stateTransitionOnTriggerDown[1]  = "Fire";
	stateAllowImageChange[1]         = true;
	stateSequence[1]	= "Ready";
	stateTimeoutValue[1]			= 0.01;
	stateTransitionOnTimeout[1]		= "Ready";
	stateEmitter[1] 				= shieldEmitter;
	stateEmitterTime[1]            = 0.05;

	stateName[2]                    = "Fire";
	stateTransitionOnTimeout[2]     = "Smoke";
	stateTimeoutValue[2]            = 0.05;
	stateFire[2]                    = true;
	stateAllowImageChange[2]        = false;
	stateSequence[2]                = "Fire";
	stateScript[2]                  = "onFire";
	stateWaitForTimeout[2]			= true;
	stateSound[2]					= reflectSound;

	stateName[3] = "Smoke";
	stateTimeoutValue[3]            = 0.03;
	stateTransitionOnTimeout[3]     = "Ready";
	stateEmitter[3] 				= shieldReflectEmitter;
	stateEmitterTime[3]            = 0.05;


	stateName[4]			= "Reload";
	stateSequence[4]                = "Reload";
	stateTransitionOnTriggerUp[4]     = "Ready";
	stateSequence[4]	= "Ready";
};
function shieldItem::onAdd(%this, %obj)
{
%obj.canPickup = true;

%obj.playThread(0, rotate);
%obj.rotate = true;
Parent::onAdd(%this, %obj);
}
function shieldImage::onFire(%this, %obj, %slot)
{
	//%obj.setImageAmmo(0, 0); //Disable the gun.
	%client = %obj.client;
	%eye = %client.player.getEyeTransform(); //Because I hate typing it out over and over again.
	%mask = $TypeMasks::ProjectileObjectType; //I was originally planning to make it shove players around, but I decided this should be better for medium-long range encounters.
	InitContainerRadiusSearch(%eye, 12, %mask);
	while(isObject(%Proj = containerSearchNext()))
	{
		if(!miniGameCanDamage(%Proj, %obj) && (isObject(%proj.client.minigame) || isObject(%client.minigame))) //Don't touch it if it's involved in a different minigame
				continue;
		%velAvg = (mAbs(getWord(%proj.getVelocity(), 0)) + mAbs(getWord(%proj.getVelocity(), 1)) + mAbs(getWord(%proj.getVelocity(), 2))) / 3;
		if(!%proj.origVelocity || %proj.origVelocity < %proj.getDatablock().muzzleVelocity / 2) //We don't want too small of an original velocity to base our reflections on, otherwise we couldn't get it above half normal speed.
			%proj.origVelocity = %velAvg; //Speed cap is based on how fast the projectile was at first deflection.
		%repelForce = ((15 - vectorDist(%eye, %proj.getTransform())) / 6) * %velAvg; //Allow us to boost the speed based on what it already is, instead of the default speed.
		if(%repelForce > %proj.origVelocity * 2.25)
			%repelForce = (2.25 * %proj.origVelocity); //We have to cap it at some point.
		if(%repelForce <= %proj.getDatablock().muzzleVelocity / 2)
			%repelForce = (%proj.getDatablock().muzzleVelocity / 2); //Also imposing a minimum.
		%repelDir = vectorNormalize(vectorSub(%proj.getTransform(), %eye));

			%anglediff = vectorSub(%repelDir,vectorNormalize(%client.player.getEyeVector()));
		%anglediffavg = (mAbs(getWord(%angleDiff, 0)) + mAbs(getWord(%angleDiff, 1)) + mAbs(getWord(%angleDiff, 2))) / 3;
		if(%anglediffavg > 0.3) //Makeshift vector angle comparison. It doesn't work as accurately as I wish it did, but I'm not all that good with vectors.
				continue;

		if(vectorDist(%eye, %proj.getTransform()) <= 6 && isObject(%proj.client.player) && %client != %proj.client)
		{
			%ownerDir = vectorNormalize(vectorSub(%proj.client.player.getEyeTransform(), %eye));
			%ownerAngleDiff = vectorSub(%ownerDir, vectorNormalize(%client.player.getEyeVector()));
			%ownerAngleDiffAvg = (mAbs(getWord(%ownerAngleDiff, 0)) + mAbs(getWord(%ownerAngleDiff, 1)) + mAbs(getWord(%ownerAngleDiff, 2))) / 3; //I thought I've seen a cone-search function somewhere before...
			if(%anglediffavg <= 0.5) //If they're out of our sight, we don't send it at them.
				%repelDir = vectorNormalize(vectorSub(%proj.client.player.getEyeTransform(), %proj.getTransform())); //Step in and tell us where it should go.
		}
		
		%newVelocity = vectorScale(%repelDir, %repelForce); //Get our final calculations as to where we should shoot this thing.
		
		serverPlay3d(pixelhitSound, %proj.getPosition());
		%obj.setImageAmmo(0, 1); //Reenable the gun if we actually used it on something
		
		%p = new Projectile() //Because Projectile::Redirect didn't work, and Projectile::SetVelocity doesn't exist for some reason.
		{
			initialVelocity		= %newVelocity;
			origVelocity		= %proj.origVelocity;
			initialPosition		= %proj.getPosition();
			datablock			= %proj.getDatablock();
			sourceObject		= %proj.client.player;
			sourceSlot			= %proj.sourceSlot;
			client				= %client; //Change the owner to us so we can damage the original attacker.
			scale				= %proj.getScale();
		};
		missionCleanup.add(%p);
		%proj.delete(); //Do away with the old one so we don't get facerocketed.
	}
}