// Universal handy function library collection, release 3
// Created by DynaBlade
// All functions used here are made strictly by DynaBlade
// Functions made in the other attached files are made by their respective authors.

$AllObjMask = $TypeMasks::PlayerObjectType | $TypeMasks::VehicleObjectType | $TypeMasks::StationObjectType | $TypeMasks::GeneratorObjectType | $TypeMasks::SensorObjectType | $TypeMasks::TurretObjectType | $TypeMasks::TerrainObjectType | $TypeMasks::InteriorObjectType | $TypeMasks::ForceFieldObjectType | $TypeMasks::StaticObjectType | $TypeMasks::MoveableObjectType | $TypeMasks::DamagableItemObjectType;
$DefaultLOSMask = $TypeMasks::TerrainObjectType | $TypeMasks::InteriorObjectType | $TypeMasks::StaticObjectType;
$CoreObjectMask = $TypeMasks::PlayerObjectType | $TypeMasks::VehicleObjectType | $TypeMasks::StationObjectType | $TypeMasks::GeneratorObjectType | $TypeMasks::SensorObjectType | $TypeMasks::TurretObjectType;

$Pi = 3.1415926535897932846;

$Deployondrop[GPT] = 1;

// ShapeBase/Parent calls
//

function SimObject::getRotation(%obj)
{
     getRotation(%obj);
}

function SimObject::getSlotRotation(%obj, %slot)
{
     getSlotRotation(%obj, %slot);
}

function SimObject::getSlotPosition(%obj, %slot)
{
     getSlotPosition(%obj, %slot);
}

function SimObject::isVehicle(%obj)
{
     isVehicle(%obj);
}

function SimObject::isPlayer(%obj)
{
     isPlayer(%obj);
}

function ShapeBase::zapObject(%obj)
{
     zapObject(%obj);
}

function ShapeBase::zap2Object(%obj)
{
     zap2Object(%obj);
}

function ShapeBase::stopZap(%obj)
{
     stopZap(%obj);
}

function ShapeBase::applyKick(%obj, %force)
{
     applyKick(%obj, %force);
}

function ShapeBase::useEnergy(%obj, %amount)
{
     useEnergy(%obj, %amount);
}

function SimObject::setPosition(%obj, %pos)
{
     setPosition(%obj, %pos);
}

function SimObject::setRotation(%obj, %rot)
{
     setRotation(%obj, %rot);
}

function SimObject::play3D(%obj, %sound)
{
     play3D(%obj, %sound);
}

function ShapeBase::teleportStartFX(%obj)
{
     teleportStartFX(%obj);
}

function ShapeBase::teleportEndFX(%obj)
{
     teleportEndFX(%obj);
}

function ShapeBase::getEyePoint(%obj)
{
     getEyePoint(%obj);
}

function ShapeBase::getMuzzleRaycastPt(%obj, %slot, %dist)
{
     getMuzzleRaycastPt(%obj, %slot, %dist);
}

function ShapeBase::getEyeRaycastPt(%obj, %dist)
{
     getEyeRaycastPt(%obj, %dist);
}

function ShapeBase::getForwardRaycastPt(%obj, %dist)
{
     getForwardRaycastPt(%obj, %dist);
}

function ShapeBase::getMass(%obj)
{
     getMass(%obj);
}

function ShapeBase::getAccel(%obj)
{
     getAccel(%obj);
}

function ShapeBase::getMaxEnergy(%obj)
{
     getMaxEnergy(%obj);
}

function ShapeBase::getMaxDamage(%obj)
{
     getMaxDamage(%obj);
}

function ShapeBase::getDamageLeft(%obj)
{
     getDamageLeft(%obj);
}

function ShapeBase::getDamageLeftPct(%obj)
{
     getDamageLeftPct(%obj);
}

function ShapeBase::getVelToForce(%obj)
{
     getVelToForce(%obj);
}

function ShapeBase::getEnergyPct(%obj)
{
     getEnergyPct(%obj);
}

function ShapeBase::getDamagePct(%obj)
{
     getDamagePct(%obj);
}

function ShapeBase::getTransformAngle(%trans)
{
     getTransformAngle(%trans);
}

// Function library
//

function combineVars(%a, %b, %c)
{
   return %a SPC %b SPC %c;
}

function posFrRaycast(%transform)
{
   %position = getWord(%transform, 1) @ " " @ getWord(%transform, 2) @ " " @ getWord(%transform, 3);
   return %position;
}

function normalFrRaycast(%transform)
{
   %norm = getWord(%transform, 4) @ " " @ getWord(%transform, 5) @ " " @ getWord(%transform, 6);
   return %norm;
}

function getEyePoint(%obj)
{
     %eyePt = getWords(%obj.getEyeTransform(), 0, 2);
     return %eyePt;
}

function play3D(%obj, %sound)
{
     serverPlay3D(%sound, %obj.getTransform());
}

function killit(%k)
{
     %k.delete();
}

function testPosition(%obj)
{
     InitContainerRadiusSearch(%obj.getWorldBoxCenter(), 0.5, $DefaultLOSMask);

     while ((%test = ContainerSearchNext()) != 0)
     {
          if(%test)
               return false;
          else
               return true;
     }
}

function createEmitter(%pos, %emitter, %rot)
{
    %dummy = new ParticleEmissionDummy()
    {
          position = %pos;
          rotation = %rot;
          scale = "1 1 1";
          dataBlock = defaultEmissionDummy;
          emitter = %emitter;
          velocity = "1";
    };
    MissionCleanup.add(%dummy);
    return %dummy;
}

function createLifeEmitter(%pos, %emitter, %lifeMS, %rot)
{
    %dummy = createEmitter(%pos, %emitter, %rot);
    MissionCleanup.add(%dummy);
    schedule(%lifeMS, %dummy, "killit", %dummy);
    return %dummy;
}

function sqr(%num)
{
     return %num*%num;
}

function cube(%num)
{
     return %num*%num*%num;
}

function useEnergy(%obj, %amount)
{
   if(isObject(%obj))
   {
      %energy = %obj.getEnergyLevel() - %amount;
      %obj.setEnergyLevel(%energy);
   }
}

function modifyTransform(%trans1, %trans2)
{
     %tpx1 = getWord(%trans1, 0);
     %tpy1 = getWord(%trans1, 1);
     %tpz1 = getWord(%trans1, 2);
     %tpa1 = getWord(%trans1, 3);
     %tpb1 = getWord(%trans1, 4);
     %tpc1 = getWord(%trans1, 5);
     %tpd1 = getWord(%trans1, 6);

     %tpx2 = getWord(%trans2, 0);
     %tpy2 = getWord(%trans2, 1);
     %tpz2 = getWord(%trans2, 2);
     %tpa2 = getWord(%trans2, 3);
     %tpb2 = getWord(%trans2, 4);
     %tpc2 = getWord(%trans2, 5);
     %tpd2 = getWord(%trans2, 6);

     %trans = (%tpx1+%tpx2)@" "@(%tpy1+%tpy2)@" "@(%tpz1+%tpz2)@" "@(%tpa1+%tpa2)@" "@(%tpb1+%tpb2)@" "@(%tpc1+%tpc2)@" "@(%tpd1+%tpd2);
     return %trans;
}

function modifyTri(%trans1, %trans2)
{
     %tpx1 = getWord(%trans1, 0);
     %tpy1 = getWord(%trans1, 1);
     %tpz1 = getWord(%trans1, 2);

     %tpx2 = getWord(%trans2, 0);
     %tpy2 = getWord(%trans2, 1);
     %tpz2 = getWord(%trans2, 2);

     %tri = (%tpx1+%tpx2)@" "@(%tpy1+%tpy2)@" "@(%tpz1+%tpz2);
     return %tri;
}

function modifyQuad(%trans1, %trans2) // assuming for transform rotation
{
     %tpa1 = getWord(%trans1, 3);
     %tpb1 = getWord(%trans1, 4);
     %tpc1 = getWord(%trans1, 5);
     %tpd1 = getWord(%trans1, 6);

     %tpa2 = getWord(%trans2, 3);
     %tpb2 = getWord(%trans2, 4);
     %tpc2 = getWord(%trans2, 5);
     %tpd2 = getWord(%trans2, 6);

     %quad = (%tpa1+%tpa2)@" "@(%tpb1+%tpb2)@" "@(%tpc1+%tpc2)@" "@(%tpd1+%tpd2);
     return %quad;
}

function getTransformAngle(%trans)
{
     return getWord(%trans, 6);
}

function setPosition(%obj, %pos)
{
    %rot = getWords(%obj.getTransform(), 3, 6);
    %trans = %pos@" "@%rot;
    %obj.setTransform(%trans);
}

function setRotation(%obj, %rot)
{
    %pos = getWords(%obj.getTransform(), 0, 2);
    %trans = %pos@" "@%rot;
    %obj.setTransform(%trans);
}

function getSlotPosition(%obj, %slot)
{
    return getWords(%obj.getSlotTransform(%slot), 0, 2);
}

function getSlotRotation(%obj, %slot)
{
    return getWords(%obj.getSlotTransform(%slot), 3, 6);
}

function getRotation(%obj)
{
    return getWords(%obj.getTransform(), 3, 6);
}

function shutdownServer(%time, %msg, %lines)
{
     %left = %time*1000;
     centerPrintAll(%msg, %left, %lines);
     schedule(%left, 0, "quit");
}

function velToSingle(%vel, %bool) // this function is also vectorLength :)
{
	%x = getWord(%vel, 0);
	%y = getWord(%vel, 1);
	%z = getWord(%vel, 2);

    if(%bool)
        return mSqrt((%x*%x)+(%y*%y)+(%z*%z));
    else
        return mFloor(mSqrt((%x*%x)+(%y*%y)+(%z*%z)));
}

function MStoKPH(%vel, %bool) // for more accurate conversions
{
    if(%bool)
        return %vel * 3.6;
    else
        return mFloor(%vel * 3.6);
}

function KPHtoMPH(%vel, %bool)
{
    if(%bool)
        return %vel * 0.6214;
    else
        return mFloor(%vel * 0.6214);
}

function vectorNeg(%vec)
{
     %v1 = getWord(%vec, 0) * -1;
     %v2 = getWord(%vec, 1) * -1;
     %v3 = getWord(%vec, 2) * -1;
     return %v1@" "@%v2@" "@%v3; 
}

function vectorClear(%vec) // for you lazy types
{
     return "0 0 0";
}

function vectorCopy(%veca, %vecb) // also for you lazy types
{
     %vecb = getWords(%veca, 0, 2);
     return;
}

function vectorCompare(%va, %vb)
{
   %v1[0] = getWord(%va, 0);
   %v1[1] = getWord(%va, 1);
   %v1[2] = getWord(%va, 2);

   %v2[0] = getWord(%vb, 0);
   %v2[1] = getWord(%vb, 1);
   %v2[2] = getWord(%vb, 2);

   if(%v1[0] != %v2[0] || %v1[1] != %v2[1] || %v1[2] != %v2[2])
      return 0;

   return 1;
}

function vectorToRotZ(%vec) // only for Z rotations
{
   %radian = mAcos(getWord(%vec, 1));
	%angle = (%radian / 0.0175);
	%newrot = " 0 0 1 " @ (270 - %angle);
   return %newrot;
}

function getLOSOffset(%obj, %vec, %dist)
{
   %pos = %obj.getPosition();
   %dir = vectorNormalize(%vec);
   %nvec = vectorScale(%dir, %dist);
   return vectorAdd(%pos, %nvec);
}

function S_vectorNormalize(%vec) // Source code on vectorNormalize
{
	%length = 0;
   %ilength = 0;
   %v[0] = getWord(%vec, 0);
   %v[1] = getWord(%vec, 1);
   %v[2] = getWord(%vec, 2);

	%length = mSqrt((%v[0]*%v[0]) + (%v[1]*%v[1]) + (%v[2]*%v[2]));

	if(%length) // no division by 0 thx :)
	{
		%ilength = 1/%length;
		%v[0] *= %ilength;
		%v[1] *= %ilength;
		%v[2] *= %ilength;
	}

   %nVec = combineVars(%v[0], %v[1], %v[2]);
	return %nVec;
}

function getDistance2D(%a, %b)
{
     %x1 = getWord(%a, 0);
     %y1 = getWord(%b, 0);
     %x2 = getWord(%a, 1);
     %y2 = getWord(%b, 1);
     
     %dist = mSqrt(sqr(%x2 - %x1) + sqr(%y2 - %y1));
     return %dist;
}

function getObjectDistance(%obj1, %obj2)
{
     %obj1b = %obj1.getWorldBoxCenter();
     %obj2b = %obj2.getWorldBoxCenter();

     %tpx1 = getWord(%obj1b, 0);
     %tpy1 = getWord(%obj1b, 1);
     %tpz1 = getWord(%obj1b, 2);

     %tpx2 = getWord(%obj2b, 0);
     %tpy2 = getWord(%obj2b, 1);
     %tpz2 = getWord(%obj2b, 2);

     %dist = mSqrt(sqr(%tpx2 - %tpx1) + sqr(%tpy2 - %tpy1) + sqr(%tpz2 - %tpz1));
     return %dist;
}

function getVectorFromPoints(%pt1, %pt2)
{
     return VectorNormalize(VectorSub(%pt2, %pt1));
}

function getVectorFromObjects(%obj1, %obj2)
{
     %obj1b = %obj1.getWorldBoxCenter();
     %obj2b = %obj2.getWorldBoxCenter();

     return VectorNormalize(VectorSub(%obj2b, %obj1b));
}

function getDistance3D(%ptA, %ptB)
{
     %tpx1 = getWord(%ptA, 0);
     %tpy1 = getWord(%ptA, 1);
     %tpz1 = getWord(%ptA, 2);

     %tpx2 = getWord(%ptB, 0);
     %tpy2 = getWord(%ptB, 1);
     %tpz2 = getWord(%ptB, 2);

     %dist = mSqrt(sqr(%tpx2 - %tpx1) + sqr(%tpy2 - %tpy1) + sqr(%tpz2 - %tpz1));
     return %dist;
}

datablock ShockLanceProjectileData(FXZap)
{
   directDamage        = 0;
   radiusDamageType    = $DamageType::Default;
   kickBackStrength    = 0;
   velInheritFactor    = 0;
   sound               = "";

   zapDuration = 1.0;
   impulse = 0;
   boltLength = 14.0;
   extension = 14.0;            // script variable indicating distance you can shock people from
   lightningFreq = 50.0;
   lightningDensity = 18.0;
   lightningAmp = 0.25;
   lightningWidth = 0.05;


   boltSpeed[0] = 2.0;
   boltSpeed[1] = -0.5;

   texWrap[0] = 1.5;
   texWrap[1] = 1.5;

   startWidth[0] = 0.3;
   endWidth[0] = 0.6;
   startWidth[1] = 0.3;
   endWidth[1] = 0.6;

   texture[0] = "special/shockLightning01";
   texture[1] = "special/shockLightning02";
   texture[2] = "special/shockLightning03";
   texture[3] = "special/ELFBeam";
};

datablock ShockLanceProjectileData(FXPulse)
{
   directDamage        = 0;
   radiusDamageType    = $DamageType::Default;
   kickBackStrength    = 0;
   velInheritFactor    = 0;
   sound               = "";

   zapDuration = 1.0;
   impulse = 0;
   boltLength = 14.0;
   extension = 14.0;            // script variable indicating distance you can shock people from
   lightningFreq = 50.0;
   lightningDensity = 18.0;
   lightningAmp = 0.25;
   lightningWidth = 0.05;


   boltSpeed[0] = 2.0;
   boltSpeed[1] = -0.5;

   texWrap[0] = 1.5;
   texWrap[1] = 1.5;

   startWidth[0] = 0.3;
   endWidth[0] = 0.6;
   startWidth[1] = 0.3;
   endWidth[1] = 0.6;

   texture[0] = "special/nonlingradient";
   texture[1] = "special/nonlingradient";
   texture[2] = "special/nonlingradient";
   texture[3] = "special/nonlingradient";
};

function zapObject(%obj)
{
     %obj.zap = new ShockLanceProjectile()
     {
          dataBlock        = "fxzap"; 
          initialDirection = "0 0 0";
          initialPosition  = %obj.getWorldBoxCenter();
          sourceObject     = %obj;
          sourceSlot       = 0;
          targetId         = %obj;
     };
     MissionCleanup.add(%obj.zap);
}

function zap2Object(%obj)
{
     %obj.zap = new ShockLanceProjectile()
     {
          dataBlock        = "fxpulse";
          initialDirection = "0 0 0";
          initialPosition  = %obj.getWorldBoxCenter();
          sourceObject     = %obj;
          sourceSlot       = 0;
          targetId         = %obj;
     };
     MissionCleanup.add(%obj.zap);
}

function stopZap(%obj)
{
     if(isObject(%obj))
     {
          if(isObject(%obj.zap))
               %obj.zap.delete();
     }
}

datablock ParticleData(TeleporterParticle)
{
   dragCoeffiecient     = 0.0;
   gravityCoefficient   = -0.5;
   inheritedVelFactor   = 0.0;

   lifetimeMS           = 100;
   lifetimeVarianceMS   = 50;

   textureName          = "particleTest";

   useInvAlpha = false;
   spinRandomMin = -160.0;
   spinRandomMax = 160.0;

   animateTexture = true;
   framesPerSec = 15;


   animTexName[0]       = "special/Explosion/exp_0016";
   animTexName[1]       = "special/Explosion/exp_0018";
   animTexName[2]       = "special/Explosion/exp_0020";
   animTexName[3]       = "special/Explosion/exp_0022";
   animTexName[4]       = "special/Explosion/exp_0024";
   animTexName[5]       = "special/Explosion/exp_0026";
   animTexName[6]       = "special/Explosion/exp_0028";
   animTexName[7]       = "special/Explosion/exp_0030";
   animTexName[8]       = "special/Explosion/exp_0032";

   colors[0]     = "1 1 1 1";
   colors[1]     = "0.75  0.75 1.0";
   colors[2]     = "0.5 0.5 0.5 0.0";
   sizes[0]      = 0.5;
   sizes[1]      = 1;
   sizes[2]      = 2.5;
   times[0]      = 0.0;
   times[1]      = 0.7;
   times[2]      = 1.0;
};

datablock ParticleEmitterData(TeleporterEmitter)
{
   ejectionPeriodMS = 3;
   periodVarianceMS = 0;
   ejectionVelocity = 6;
   velocityVariance = 2.9;
   ejectionOffset   = 0.0;
   thetaMin         = 0;
   thetaMax         = 5;
   phiReferenceVel  = 0;
   phiVariance      = 360;
   overrideAdvances = false;
   particles = "TeleporterParticle";
};

function teleportStartFX(%obj)
{
     if(%obj.holdingFlag)
     {
          %client = %obj.client;
          %flag = %obj.holdingFlag;
          %flag.setVelocity("0 0 0");
          %flag.setTransform(%obj.getWorldBoxCenter());
          %flag.setCollisionTimeout(%obj);
          %obj.throwObject(%flag);
          messageClient(%obj.client, 'MsgNoTeleFlag', '\c1You cannot teleport with the flag.');
     }

     %obj.playShieldEffect("0 0 1");
     %obj.setCloaked(true);
     %obj.startFade( 1000, 0, true );
     %obj.play3D(TeleportSound);

     %particles = createEmitter(%obj.getPosition(), "TeleporterEmitter");
     schedule(2500, 0, "killit", %particles);
}

function teleportEndFX(%obj)
{
     %obj.setCloaked(false);
     %obj.playShieldEffect("0 0 1");
     %obj.startFade(1000, 0, false );
     %obj.play3D(UnTeleportSound);
     %obj.particleFX.delete();

     %particles = createEmitter(%obj.getPosition(), "TeleporterEmitter");
     schedule(2500, 0, "killit", %particles);
}

function getMuzzleRaycastPt(%obj, %slot, %dist)
{
     %vec = %obj.getMuzzleVector(%slot);
     %pos = %obj.getMuzzlePoint(%slot);
     %nVec = VectorNormalize(%vec);
     %scVec = VectorScale(%nVec, %dist);
     %end = VectorAdd(%pos, %scVec);
     %searchResult = containerRayCast(%pos, %end, $TypeMasks::TerrainObjectType | $TypeMasks::InteriorObjectType | $TypeMasks::PlayerObjectType | $TypeMasks::VehicleObjectType | $TypeMasks::StaticShapeObjectType | $TypeMasks::TurretObjectType | $TypeMasks::ItemObjectType, 0);
     %raycastPt = posFrRaycast(%searchResult);
     %raycastPt.raycast = %searchResult;
     
     return %raycastPt;
}

function getEyeRaycastPt(%obj, %dist)
{
     %vec = %obj.getEyeVector();
     %pos = %obj.getEyePoint();
     %nVec = VectorNormalize(%vec);
     %scVec = VectorScale(%nVec, %dist);
     %end = VectorAdd(%pos, %scVec);
     %searchResult = containerRayCast(%pos, %end, $TypeMasks::TerrainObjectType | $TypeMasks::InteriorObjectType | $TypeMasks::PlayerObjectType | $TypeMasks::VehicleObjectType | $TypeMasks::StaticShapeObjectType | $TypeMasks::TurretObjectType | $TypeMasks::ItemObjectType, 0);
     %raycastPt = posFrRaycast(%searchResult);
     %raycastPt.raycast = %searchResult;
     
     return %raycastPt;
}

function getForwardRaycastPt(%obj, %dist)
{
     %vec = %obj.getForwardVector();
     %pos = %obj.getWorldBoxCenter();
     %nVec = VectorNormalize(%vec);
     %scVec = VectorScale(%nVec, %dist);
     %end = VectorAdd(%pos, %scVec);
     %searchResult = containerRayCast(%pos, %end, $TypeMasks::TerrainObjectType | $TypeMasks::InteriorObjectType | $TypeMasks::PlayerObjectType | $TypeMasks::VehicleObjectType | $TypeMasks::StaticShapeObjectType | $TypeMasks::TurretObjectType | $TypeMasks::ItemObjectType, 0);
     %raycastPt = posFrRaycast(%searchResult);
     %raycastPt.raycast = %searchResult;
     
     return %raycastPt;
}

function applyKick(%obj, %force)
{
    %vec = VectorScale(%obj.getMuzzleVector(0), %force);
    %obj.applyImpulse(%obj.getTransform(), %vec);
}

function getMass(%obj)
{
    return %obj.getDatablock().mass;
}

function getMaxEnergy(%obj)
{
    return %obj.getDatablock().maxEnergy;
}

function getMaxDamage(%obj)
{
    return %obj.getDatablock().maxDamage;
}

function getEnergyPct(%obj)
{
   return %obj.getEnergyLevel() / %obj.getMaxEnergy();
}

function getDamagePct(%obj)
{
   return %obj.getDamageLevel() / %obj.getMaxDamage();
}

function getDamageLeft(%obj)
{
   return %obj.getMaxDamage() - %obj.getDamageLevel();
}

function getDamageLeftPct(%obj)
{
   return %obj.getDamageLeft() / %obj.getMaxDamage();
}

function getAccel(%obj)
{
    %vel = vectorScale(%obj.getVelocity(), 0.01);
    schedule(1, 0, "returnAccel", %obj, %vel);
}

function returnAccel(%obj, %vel1)
{
    %vel = vectorScale(%obj.getVelocity(), 0.01);
    return vectorScale(vectorSub(%vel, %vel1), 0.01); // a = dv/dt
}

function getVelToForce(%obj)
{
    %accel = %obj.getAccel();
    %mass = %obj.getMass();
    return vectorScale(%accel, %mass);
}

function getTowForce(%obj, %target)
{
    %accel = %obj.getAccel();
    %mass = %target.getMass();
    return vectorScale(%accel, %mass);
}

function setFlightCeiling(%val)
{
    %missionArea = nameToID("MissionGroup/MissionArea");

    if(%missionArea != -1)
        %missionArea.FlightCeiling = %val;
}

function reload(%script)
{
    exec(%script);
    %count = ClientGroup.getCount();

    for(%i = 0; %i < %count; %i++)
    {
        %cl = ClientGroup.getObject(%i);

        if(!%cl.isAIControlled()) // no sending bots datablocks.. LOL
            %cl.transmitDataBlocks(0); // all clients on server
    }
}

function isVehicle(%obj)
{
    if(isObject(%obj))
    {
        %data = %obj.getDataBlock();
        %className = %data.className;

        if(%className $= WheeledVehicleData || %className $= FlyingVehicleData || %className $= HoverVehicleData)
            return true;
        else
            return false;
    }
}

function isPlayer(%obj)
{
    if(isObject(%obj))
    {
        %data = %obj.getDataBlock();
        %className = %data.className;

        if(%className $= Armor)
            return true;
        else
            return false;
    }
}

function changeServerHostname(%name)
{
   $Host::GameName = %name;
}

function changeServerAllowAliases(%bool)
{
   $Host::NoSmurfs = %bool;
}

function changeServerPlayerCount(%num)
{
   $Host::MaxPlayers = %num;
}

function changeAdminPassword(%pass)
{
   if(%pass)
      $Host::AdminPassword = %pass;
   else
      $Host::AdminPassword = "";
}

function changeServerPassword(%pass)
{
   if(%pass)
      $Host::Password = %pass;
   else
      $Host::Password = "";
}

function setServerPrefs(%name, %aliases, %admin, %password, %num)
{
   $Host::CRCTextures = 0;
   if(%name !$= "")
      changeServerHostname(%name);
   if(%aliases !$= "")
      changeServerAllowAliases(%aliases);
   if(%num !$= "")
      changeServerPlayerCount(%num);

   changeAdminPassword(%admin);
   changeServerPassword(%password);
}


function dropstuff(%team)
{
   %teamn = "Team" @ %team;
   %group = nameToId("MissionGroup/Teams/"@ %teamn @"/spawnspheres");
   %spheres = %group.getCount();
   %stuff = $Gotstuff[%team];
   //echo("dropping" SPC %group);
   %rsphere = (getRandom() * %spheres) -1;
   %obj = %group.getObject(%rsphere);
   %fixedshpere = %obj;
 for (%i = 0; %i < %stuff; %i++)
   {
   %droppack = "base" @ $stuff[%i,%team] @ "pack";
   //echo("dropping" SPC %droppack);
   /// Do we have GPT(S)?   if so.. drop at a random one.
   if (gotsphere(%team))
   {
   %rsphere = (getRandom() * %spheres) -1;
   %obj = %group.getObject(%rsphere);
   }
   else
     %obj = %fixedshpere;

   %location = Properland(%obj);
if ($Deployondrop[$stuff[%i,%team]])
   {
   %xy = GetWord(PosFromtransform(%obj.Gettransform()),0) SPC GetWord(PosFromtransform(%obj.Gettransform()),1);
   %h = GetHeight(%xy SPC 0)+((getRandom()*10)-5)+50;
   %location =  %xy SPC %h;
   }
   // old stuff
   //%location = PosFromtransform(%obj.Gettransform());
   %rang = GetWord(%Location,3);
   %dist = GetWord(%Location,4);
   %scale = packscale(%droppack);
   %pack = new (Item)()  //GeneratorStation
   {
      dataBlock = %droppack;
      position = %location;
      rotation = %rang;
      Scale = %scale;
   };
   %pack.GTWID = $GTWID[%i,%team];
   //echo(packscale(%droppack));
   if ($Deployondrop[$stuff[%i,%team]])
       {

       %pack.willdeploy = 1;
       %pack.team = %team;
       %pack.needshow = 1;
       %pteam = "Team" @ %pack.team;
       %pgroup = nameToId("MissionGroup/Teams/"@ %pteam @"/Base0");
       %pgroup.add(%deplObj);	

       // set all clients control to their player
       //%count = ClientGroup.getCount();
       //for( %i = 0; %i < %count; %i++ )
       //{
       //%cl = ClientGroup.getObject(%i);
       //if(%cl.camera.mode $= "pre-game" && %cl.team == %pack.team)
       //%game.forceObserver( %cl, "no-spawn-power" );
       //}
       

       }
   %xy =  MCos(%rang) * %dist SPC MSin(%rang) * %dist;
   if ($evasedrop)
       %pack.applyImpulse(%pack.getTransform(), %xy SPC "0");
 
   //FirePoof(%pack,2500);
   $TeamDeployedCount[%team, %droppack]--;
   Brakesystem(%pack,30,50,800);
   }
}


function Brakesystem(%obj,%height,%time,%amount)
{
if((!isObject(%obj)) || (%amount < 0))
return "";

%pos = posFromTransform(%obj.getTransform());
%vec = %obj.getVelocity();
%aheight = GetWord(%pos,2) - GetHeight(%pos);
%hspeed = GetWord(%vec,2);
if (VectorLen(%vec) > 10)    
    FirePoof(%obj,100);

//%goodh = 0.5*(Mpow(%hspeed,2)/0.9);
if (%aheight < %height && GetWord(%vec,2) < -4)
{
%amount--;
%hspeed = GetWord(%vec,2);
%lower = -1 * %hspeed / 5;
%vec = VectorAdd(%vec,"0 0" SPC %lower);
%obj.setVelocity(%vec);
JetPoof(%obj,50);
if (%aheight > 20)
	%obj.playAudio(0, BrakeSound);
}
%obj.setVelocity(%vec);
if (%aheight > 3)
	schedule(%time,0,"Brakesystem",%obj, %height,%time,%amount);

else if (%obj.willdeploy)
{
%obj.surfacenrm = Posfromtransform(%obj.GetTransform());
%obj.surfacePT = "0 0 1";
%obj.schedule(500, "delete");
DeployGPT(%obj);
}
}


function DeployGPT(%item)
{
%className = "StaticShape";
//Player

   %Dplacement = Posfromtransform(%item.getTransform());
   %Dplacement = GetWord(%Dplacement,0) SPC GetWord(%Dplacement,1) SPC GetHeight(%Dplacement);
   %deplObj = new (%className)()  //SensorLargePulse Station
   {
      dataBlock = FlipFlop;
      position = %Dplacement;
      rotation = "1 0 0 0";
   };

   %deplObj.GTWID = %item.GTWID;

   %deplObj.team = %item.Team;
   //%deplObj.owner = %client;

   %team = "Team" @ %item.team;
   %group = nameToId("MissionGroup/Teams/"@ %team @"/Base0");

   %group.add(%deplObj);	

   %deplObj.playThread($PowerThread,"Power");
 
   if(%deplObj.getTarget() != -1)
      setTargetSensorGroup(%deplObj.getTarget(), %item.team);

   %Dtransform = %Dplacement SPC "1 0 0 0";
   %deplObj.setTransform(%Dtransform);
   
   %group.powerinit();

   //%DeplObj.setRechargeRate(%DeplObj.getDatablock().rechargeRate);

   
   // place the deployable in the MissionCleanup/Deployables group (AI reasons)
  
   //addToDeployGroup(%deplObj);

   //let the AI know as well...
  
   AIDeployObject(%item, %deplObj);

   //Associate all the bunker parts together for damage/repair purposes.
   
   // play the deploy sound
   serverPlay3D(ItemPickupSound, %deplObj.getTransform());

   // increment the team count for this deployed object

   //$TeamDeployedCount[%plyr.team, %item.item]++;
   //%deplObj.dSurfaceNrm = %surfaceNrm;
   %deplObj.deploy();

//if (%item.surface.getClassName() $= TerrainBlock)
	//%DeplObj.setDamageLevel(%DeplObj.getMaxDamage()/2);
  CheckSpawn();
  $GTWGame.misSaveGame();
 //echo (%deplObj);
   return %deplObj;

}


datablock AudioProfile(BrakeSound)
{
   filename    = "fx/vehicles/shrike_boost.wav";
   description = AudioDefault3d;
   preload = true;
   //effect = ScoutFlyerThrustEffect;
};

function FirePoof(%obj,%time)
{
if(!isObject(%obj))
{
 echo("NO POS set for function: FirePoof(%pos, %time");
}
%pos = posFromTransform(%obj.getTransform());
%firePoof = new ParticleEmissionDummy()
            {
		       position = getWord(%pos,0) @ " " @ getWord(%pos,1) @ " " @ getWord(%pos,2) - 0.75;
		       rotation = "1 0 0 0";
         		dataBlock = "defaultEmissionDummy";
         		lockCount = "0";
         		homingCount = "0";
                        emitter = "FireballAtmosphereEmitter";
         		velocity = "1";
         	};

          MissionCleanup.add(%firePoof);

  
          %firePoof.schedule(%time, "delete");
}

function JetPoof(%obj,%time)
{
if(!isObject(%obj))
{
 echo("NO POS set for function: FirePoof(%pos, %time");
}
%pos = posFromTransform(%obj.getTransform());
%firePoof = new ParticleEmissionDummy()
            {
		       position = getWord(%pos,0) @ " " @ getWord(%pos,1) @ " " @ getWord(%pos,2) - 1.75;
		       rotation = "1 0 0 -1.57";
         		dataBlock = "defaultEmissionDummy";
         		lockCount = "0";
         		homingCount = "0";
                        emitter = "FlyerJetEmitter";
         		velocity = "1";
         	};

          MissionCleanup.add(%firePoof);

  
          %firePoof.schedule(%time, "delete");
}


function GetHeight(%loc)
{
%mask = $AllObjMask;
%start = GetWord(%loc,0) SPC GetWord(%loc,1) SPC 10000; 
%end = GetWord(%loc,0) SPC GetWord(%loc,1) SPC -10000;
%res = containerRayCast(%start, %end, %mask, 0);         
if(%res)
	  {
	  return GetWord(%res,3);
	  }
else
	echo ("Your wierd");
return "";
}

function GetTerHeight(%loc)
{
%mask = $TypeMasks::TerrainObjectType;
%start = GetWord(%loc,0) SPC GetWord(%loc,1) SPC 10000; 
%end = GetWord(%loc,0) SPC GetWord(%loc,1) SPC -10000;
%res = containerRayCast(%start, %end, %mask, 0);         
if(%res)
	  {
	  return GetWord(%res,3);
	  }
else
	echo ("Your wierd");
return "";
}

function FirstTer(%loc)
{
%mask = $AllObjMask;
%start = GetWord(%loc,0) SPC GetWord(%loc,1) SPC 10000; 
%end = GetWord(%loc,0) SPC GetWord(%loc,1) SPC -10000;
%res = containerRayCast(%start, %end, %mask, 0);         
%ress = GetWord(%res,0);
%got = GetWord(%res,0) SPC GetWord(%res,1) SPC GetWord(%res,2);
InitContainerRadiusSearch(%got, 3, %mask );
  %test = containerSearchNext();
   if(%ress.getClassName() $= TerrainBlock)
   {
      %test = containerSearchNext();
      if (%test)
         return "";
   }
return %ress.getClassName() $= TerrainBlock;
}

function Properland(%obj)
{
   %radius = Getspawnrad(%obj);   
   %rang = getRandom() * $Pi * 2;
   %rdist = getRandom() * %radius;
   %pos = Posfromtransform(%obj.GetTransform());   
   %xy = GetWord(%pos,0) + MCos(%rang) * %rdist SPC GetWord(%pos,1) + MSin(%rang) * %rdist; 
   %z = GetHeight(%xy SPC 0)+((getRandom()*100)-50)+200;
   echo(%z);
   %displace = %xy SPC %z;
   %location = %displace;
 //if (!FirstTer(%location))
 //return Properland(%obj);
 return %location SPC %rang SPC (%radius-%dist);
}

function debris(%obj)  
{
%x = (getRandom() * 0.4) - 0.2;
%y = (getRandom() * 0.4) - 0.2;
%z = getRandom() / 2;
%vec = %x SPC %y SPC %z;
%pos = VectorAdd(posFromTransform(%obj.getTransform()), VectorScale(%vec, 3));
%p = new (GrenadeProjectile)()
	 {
	 dataBlock        = DeployableFireball;
         initialDirection = %vec;
	 initialPosition  = %pos;
         sourceObject     = %source;
         sourceSlot       = 1;
         vehicleObject    = %obj;
         };
}


function Getspawnrad(%obj)
{
if (%obj.sphere)
       {
       %sphere = %obj.sphere;
       %emiter = %obj;
       }
else 
	{
	%sphere = %obj;
        %emiter = %obj.emiter;
	}

if (%obj.mysphere)
	{
	if (%emiter.isPowered())
           return %emiter.GetDataBlock().spawnradius;
        else 
            return %emiter.GetDataBlock().nopowerspawnradius;
	}    
else
   return %sphere.radius;   
}

function gotsphere(%team)
{
%teamn = "Team" @ %team;
%group = nameToId("MissionGroup/Teams/"@ %teamn @"/spawnspheres");
%spheres = %group.getCount();
%scount = 0;
if (!%spheres)
   return "";
for (%i = 0; %i < %spheres; %i++)
    {
    %sphere = %group.getObject(%i);
    if (%sphere.mysphere)
       %scount++;
    }
   return %scount;
}
