T2-BoL/scripts/packs/miningTool.cs

618 lines
22 KiB
PHP
Raw Permalink Normal View History

//--------------------------------------------------------------------------
// Mining Tool
// can be used by any armor type
// when activated, gives user a "mining tool" that can be used to
// mine rocks that contain various minerals that can be sold or
// used by miner to build weapons, armor, and other objects.
//
// Note: Although this could've been intergrated into the repair gun
// somehow (technically still repairs), it's been built as a seperate
// pack for "balancing".
//--------------------------------------------------------------------------
// Projectile
datablock RepairProjectileData(MiningBeam)
{
sound = RepairPackFireSound;
beamRange = 10;
beamWidth = 0.33;
numSegments = 20;
texRepeat = 0.20;
blurFreq = 10.0;
blurLifetime = 1.0;
cutoffAngle = 25.0;
textures[0] = "special/ELFBeam";
textures[1] = "special/BlueImpact";
};
//-------------------------------------------------------------------------
// shapebase datablocks
datablock ShapeBaseImageData(MiningToolImage)
{
shapeFile = "pack_upgrade_repair.dts";
item = MiningTool;
mountPoint = 1;
offset = "0 0 0";
emap = true;
gun = MiningToolGunImage;
stateName[0] = "Idle";
stateTransitionOnTriggerDown[0] = "Activate";
stateName[1] = "Activate";
stateScript[1] = "onActivate";
stateSequence[1] = "fire";
stateSound[1] = RepairPackActivateSound;
stateTransitionOnTriggerUp[1] = "Deactivate";
stateName[2] = "Deactivate";
stateScript[2] = "onDeactivate";
stateTransitionOnTimeout[2] = "Idle";
};
datablock ItemData(MiningTool)
{
className = Pack;
catagory = "Packs";
shapeFile = "pack_upgrade_repair.dts";
mass = 1;
elasticity = 0.2;
friction = 0.6;
pickupRadius = 2;
rotate = true;
image = "MiningToolImage";
pickUpName = "a mining tool";
lightOnlyStatic = true;
lightType = "PulsingLight";
lightColor = "0 0 1 0";
lightTime = 1200;
lightRadius = 2.5; //It's just a mining tool folks..
computeCRC = true;
emap = true;
};
//--------------------------------------------------------------------------
// Mining Gun
datablock ShapeBaseImageData(MiningToolGunImage)
{
shapeFile = "weapon_repair.dts";
offset = "0 0 0";
usesEnergy = true;
minEnergy = 3;
cutOffEnergy = 3.1;
emap = true;
repairFactorPlayer = 0.002; // <--- attention DaveG!
repairFactorObject = 0.004; // <--- attention DaveG!
stateName[0] = "Activate";
stateTransitionOnTimeout[0] = "ActivateReady";
stateTimeoutValue[0] = 0.25;
stateName[1] = "ActivateReady";
stateScript[1] = "onActivateReady";
stateSpinThread[1] = Stop;
stateTransitionOnAmmo[1] = "Ready";
stateTransitionOnNoAmmo[1] = "ActivateReady";
stateName[2] = "Ready";
stateSpinThread[2] = Stop;
stateTransitionOnNoAmmo[2] = "Deactivate";
stateTransitionOnTriggerDown[2] = "Validate";
stateName[3] = "Validate";
stateTransitionOnTimeout[3] = "Validate";
stateTimeoutValue[3] = 0.2;
stateEnergyDrain[3] = 3;
stateSpinThread[3] = SpinUp;
stateScript[3] = "onValidate";
stateIgnoreLoadedForReady[3] = true;
stateTransitionOnLoaded[3] = "Mine";
stateTransitionOnNoAmmo[3] = "Deactivate";
stateTransitionOnTriggerUp[3] = "Deactivate";
stateName[4] = "Mine";
stateSound[4] = RepairPackFireSound;
stateScript[4] = "onMine";
stateSpinThread[4] = FullSpeed;
stateAllowImageChange[4] = false;
stateSequence[4] = "activate";
stateFire[4] = true;
stateEnergyDrain[4] = 9;
stateTimeoutValue[4] = 0.2;
stateTransitionOnTimeOut[4] = "Mine";
stateTransitionOnNoAmmo[4] = "Deactivate";
stateTransitionOnTriggerUp[4] = "Deactivate";
stateTransitionOnNotLoaded[4] = "Validate";
stateName[5] = "Deactivate";
stateScript[5] = "onDeactivate";
stateSpinThread[5] = SpinDown;
stateSequence[5] = "activate";
stateDirection[5] = false;
stateTimeoutValue[5] = 0.2;
stateTransitionOnTimeout[5] = "ActivateReady";
};
function MiningToolImage::onUnmount(%data, %obj, %node)
{
// dismount the mining gun if the player had it mounted
// need the extra "if" statement to avoid a console error message
if(%obj.getMountedImage($WeaponSlot))
if(%obj.getMountedImage($WeaponSlot).getName() $= "MiningToolGunImage")
%obj.unmountImage($WeaponSlot);
// if the player was repairing something when the pack was thrown, stop repairing it
if(%obj.repairing != 0)
stopMining(%obj);
}
function MiningToolImage::onActivate(%data, %obj, %slot)
{
// don't activate the pack if player is piloting a vehicle
if(%obj.isPilot())
{
%obj.setImageTrigger(%slot, false);
return;
}
if(!isObject(%obj.getMountedImage($WeaponSlot)) || %obj.getMountedImage($WeaponSlot).getName() !$= "MiningToolGunImage")
{
messageClient(%obj.client, 'MsgRepairPackOn', '\c2Mining Tool activated.');
// make sure player's arm thread is "look"
%obj.setArmThread(look);
// mount the repair gun
%obj.mountImage(MiningToolGunImage, $WeaponSlot);
// clientCmdsetRepairReticle found in hud.cs
commandToClient(%obj.client, 'setRepairReticle');
}
}
function MiningToolImage::onDeactivate(%data, %obj, %slot)
{
//called when the player hits the "pack" key again (toggle)
%obj.setImageTrigger(%slot, false);
// if mining gun was mounted, unmount it
if(%obj.getMountedImage($WeaponSlot).getName() $= "MiningToolGunImage")
%obj.unmountImage($WeaponSlot);
}
function MiningToolGunImage::onMount(%this,%obj,%slot)
{
%obj.setImageAmmo(%slot,true);
if ( !isDemo() )
commandToClient( %obj.client, 'setRepairPackIconOn' );
}
function MiningToolGunImage::onUnmount(%this,%obj,%slot)
{
// called when player switches to another weapon
// stop mining whatever player was mining
if(%obj.repairing)
stopMining(%obj);
%obj.setImageTrigger(%slot, false);
// "turn off" the mining tool -- player needs to hit the "pack" key to
// activate the mining gun again
%obj.setImageTrigger($BackpackSlot, false);
if ( !isDemo() )
commandToClient( %obj.client, 'setRepairPackIconOff' );
}
function MiningToolGunImage::onActivateReady(%this,%obj,%slot)
{
%obj.errMsgSent = false;
%obj.selfRepairing = false;
%obj.repairing = 0;
%obj.setImageLoaded(%slot, false);
}
function MiningToolGunImage::onValidate(%this,%obj,%slot)
{
// this = miningtoolimage datablock
// obj = player wielding the repair gun
// slot = weapon slot
if(%obj.getEnergyLevel() <= %this.cutOffEnergy)
{
stopMining(%obj);
return;
}
%repGun = %obj.getMountedImage(%slot);
// muzVec is the vector coming from the mining gun's "muzzle"
%muzVec = %obj.getMuzzleVector(%slot);
// muzNVec = normalized muzVec
%muzNVec = VectorNormalize(%muzVec);
%repairRange = DefaultRepairBeam.beamRange;
// scale muzNVec to the range the mining beam can reach
%muzScaled = VectorScale(%muzNVec, %repairRange);
// muzPoint = the actual point of the gun's "muzzle"
%muzPoint = %obj.getMuzzlePoint(%slot);
// rangeEnd = muzzle point + length of beam
%rangeEnd = VectorAdd(%muzPoint, %muzScaled);
// search for just about anything that can be damaged as well as interiors
%searchMasks = $TypeMasks::StaticShapeObjectType;
// search for objects within the beam's range that fit the masks above
%scanTarg = ContainerRayCast(%muzPoint, %rangeEnd, %searchMasks, %obj);
// screen out interiors
if(%scanTarg && !(%scanTarg.getType() & $TypeMasks::InteriorObjectType))
{
// a target in range was found
%repTgt = firstWord(%scanTarg);
// is the prospective target damaged?
if(%repTgt.notRepairable)
{
// this is an object that cant be mined at all
// -- mission specific flag set on the object
if(!%obj.errMsgSent)
{
messageClient(%obj.client, 'MsgRepairPackIrrepairable', '\c2Target cannot be mined.', %repTgt);
%obj.errMsgSent = true;
}
// if player was repairing something, stop the repairs -- we're done
if(%obj.repairing)
stopMining(%obj);
}
else if(%repTgt.getDamageLevel())
{
// yes, it's damaged
if(%repTgt != %obj.repairing)
{
if(isObject(%obj.repairing))
stopMining(%obj);
%obj.repairing = %repTgt;
}
// setting imageLoaded to true sends us to repair state (function onRepair)
%obj.setImageLoaded(%slot, true);
}
else
{
// there is a target in range, but it's not damaged
if(!%obj.errMsgSent)
{
// if the target isn't damaged, send a message to that effect only once
messageClient(%obj.client, 'MsgRepairPackNotDamaged', '\c2Target is not damaged.', %repTgt);
%obj.errMsgSent = true;
}
// if player was repairing something, stop the repairs -- we're done
if(%obj.repairing)
stopMining(%obj);
}
}
//AI hack - too many things influence the aiming, so I'm going to force the repair object for bots only
else if (%obj.client.isAIControlled() && isObject(%obj.client.repairObject))
{
%repTgt = %obj.client.repairObject;
%repPoint = %repTgt.getAIRepairPoint();
if (%repPoint $= "0 0 0")
%repPoint = %repTgt.getWorldBoxCenter();
%repTgtVector = VectorNormalize(VectorSub(%muzPoint, %repPoint));
%aimVector = VectorNormalize(VectorSub(%muzPoint, %rangeEnd));
//if the dot product is very close (ie. we're aiming in the right direction)
if (VectorDot(%repTgtVector, %aimVector) > 0.85)
{
//do an LOS to make sure nothing is in the way...
%scanTarg = ContainerRayCast(%muzPoint, %repPoint, %searchMasks, %obj);
if (firstWord(%scanTarg) == %repTgt)
{
// yes, it's damaged
if(isObject(%obj.repairing))
stopMining(%obj);
%obj.repairing = %repTgt;
// setting imageLoaded to true sends us to repair state (function onRepair)
%obj.setImageLoaded(%slot, true);
}
}
}
else if(%obj.getDamageLevel())
{
// there is no target in range, but the player is damaged
// check to see if we were repairing something before -- if so, stop repairing old target
if(%obj.repairing != 0)
if(%obj.repairing != %obj)
stopMining(%obj);
if(isObject(%obj.repairing))
stopMining(%obj);
%obj.repairing = %obj;
// quick, to onRepair!
%obj.setImageLoaded(%slot, true);
}
else
{
// there is no target in range, and the player isn't damaged
if(!%obj.errMsgSent)
{
// send an error message only once
messageClient(%obj.client, 'MsgRepairPackNoTarget', '\c2No target to mine.');
%obj.errMsgSent = true;
}
stopMining(%obj);
}
}
function MiningToolGunImage::onMine(%this,%obj,%slot)
{
// this = repairgunimage datablock
// obj = player wielding the repair gun
// slot = weapon slot
if(%obj.getEnergyLevel() <= %this.cutOffEnergy)
{
stopMining(%obj);
return;
}
// reset the flag that indicates an error message has been sent
%obj.errMsgSent = false;
%target = %obj.repairing;
if(!%target)
{
// no target -- whoops! never mind
stopMining(%obj);
}
else
{
// make sure we still have a target -- more vector fun!!!
%muzVec = %obj.getMuzzleVector(%slot);
%muzNVec = VectorNormalize(%muzVec);
%repairRange = DefaultRepairBeam.beamRange;
%muzScaled = VectorScale(%muzNVec, %repairRange);
%muzPoint = %obj.getMuzzlePoint(%slot);
%rangeEnd = VectorAdd(%muzPoint, %muzScaled);
%searchMasks = $TypeMasks::StaticShapeObjectType;
//AI hack to help "fudge" the repairing stuff...
if (%obj.client.isAIControlled() && isObject(%obj.client.repairObject) && %obj.client.repairObject == %obj.repairing)
{
%repTgt = %obj.client.repairObject;
%repPoint = %repTgt.getAIRepairPoint();
if (%repPoint $= "0 0 0")
%repPoint = %repTgt.getWorldBoxCenter();
%repTgtVector = VectorNormalize(VectorSub(%muzPoint, %repPoint));
%aimVector = VectorNormalize(VectorSub(%muzPoint, %rangeEnd));
//if the dot product is very close (ie. we're aiming in the right direction)
if (VectorDot(%repTgtVector, %aimVector) > 0.85)
%scanTarg = ContainerRayCast(%muzPoint, %repPoint, %searchMasks, %obj);
}
else
%scanTarg = ContainerRayCast(%muzPoint, %rangeEnd, %searchMasks, %obj);
if (%scanTarg)
{
%pos = getWords(%scanTarg, 1, 3);
%obstructMask = $TypeMasks::InteriorObjectType | $TypeMasks::TerrainObjectType;
%obstruction = ContainerRayCast(%muzPoint, %pos, %obstructMask, %obj);
if (%obstruction)
%scanTarg = "0";
}
if(%scanTarg)
{
// there's still a target out there
%repTgt = firstWord(%scanTarg);
if (%repTgt.mineral $= "")
{
messageClient(%obj.client, 'MsgMineFail',"\c2Rock is empty as of now. Check back later.");
%obj.errMsgSent = true;
stopMining(%obj);
return;
}
// is the target damaged?
if(%repTgt.getDamageLevel())
{
%obj.client.collected = %obj.client.collected + %obj.getRepairRate() + MiningToolGunImage.repairFactorPlayer;
%obj.client.units[%obj.repairing.mineral] = %obj.client.units[%obj.repairing.mineral] + %obj.client.collected;
if(%repTgt != %obj.repairing)
{
// the target is not the same as the one we were just repairing
// stop repairing old target, start repairing new target
stopRepairing(%obj);
if(isObject(%obj.repairing))
stopRepairing(%obj);
%obj.repairing = %repTgt;
// extract the name of what player is repairing based on what it is
// if it's a player, it's the player's name (duh)
// if it's an object, look for a nametag
// if object has no nametag, just say what it is (e.g. generatorLarge)
if(%repTgt.getClassName() $= Player)
%tgtName = getTaggedString(%repTgt.client.name);
else if(%repTgt.getGameName() !$= "")
%tgtName = %repTgt.getGameName();
else
%tgtName = %repTgt.getDatablock().getName();
messageClient(%obj.client, 'MsgRepairPackRepairingObj', '\c2Mining rock.. (%3)', %tgtName, %repTgt, %repTgt.mineral);
startMining(%obj, false);
}
else
{
// it's the same target as last time
// changed to fix "2 players can't repair same object" bug
if(%obj.repairProjectile == 0)
{
if(%repTgt.getClassName() $= Player)
%tgtName = getTaggedString(%repTgt.client.name);
else if(%repTgt.getGameName() !$= "")
%tgtName = %repTgt.getGameName();
else
%tgtName = %repTgt.getDatablock().getName();
messageClient(%obj.client, 'MsgRepairPackRepairingObj', '\c2Mining Rock.. (%3)', %tgtName, %repTgt, %repTgt.mineral);
startMining(%obj, false);
}
}
}
else
{
%rateOfRepair = %this.repairFactorObject;
if(%repTgt.getClassName() $= Player)
{
%tgtName = getTaggedString(%repTgt.client.name);
%rateOfRepair = %this.repairFactorPlayer;
}
else if(%repTgt.getGameName() !$= "")
%tgtName = %repTgt.getGameName();
else
%tgtName = %repTgt.getDatablock().getName();
if(%repTgt != %obj.repairing)
{
// it isn't the same object we were repairing previously
messageClient(%obj.client, 'MsgRepairPackNotDamaged', '\c2%1 is not damaged.', %tgtName);
}
else
{
// same target, but not damaged -- we must be done
messageClient(%obj.client, 'MsgRepairPackDone', '\c2Rock ran out of minerals.');
stopMining(%obj); //Push this through to make sure client gets minerals..
Game.objectRepaired(%repTgt, %tgtName);
}
%obj.errMsgSent = true;
stopMining(%obj);
}
}
else
{
// whoops, we lost our target
messageClient(%obj.client, 'MsgRepairPackLostTarget', '\c2No target to mine.');
stopMining(%obj);
}
}
}
function MiningToolGunImage::onDeactivate(%this,%obj,%slot)
{
stopMining(%obj);
}
function stopMining(%player)
{
// %player = the player who was using the repair pack
if(%player.selfRepairing)
{
// there is no projectile for self-repairing
%player.setRepairRate(%player.getRepairRate() - %player.repairingRate);
%player.selfRepairing = false;
}
else if(%player.repairing > 0)
{
// player was repairing something else
//if(%player.repairing.beingRepaired > 0)
//{
// don't decrement this stuff if it's already at 0 -- though it shouldn't be
//%player.repairing.beingRepaired--;
%player.repairing.setRepairRate(%player.repairing.getRepairRate() - %player.repairingRate);
//}
if(%player.repairProjectile > 0)
{
// is there a repair projectile? delete it
%player.repairProjectile.delete();
%player.repairProjectile = 0;
}
}
if (!%player.errMsgSent && isObject(%player.repairing) && %player.repairing.mineral !$= "") //Ok, player stopped mining. Give the player his/her WTF they mined.
{
%client = %player.client;
%mineral = %player.repairing.mineral;
%collected = %player.client.collected;
%total = %client.units[%mineral];
%obj = %player.repairing;
messageClient(%player.client,'msgMiningCollect','\c2Collected %1 units of %2. You now have %3 units of %2.',%collected,%mineral,%total);
}
%player.client.collected = 0;
%player.repairing = 0;
%player.repairingRate = 0;
%player.setImageTrigger($WeaponSlot, false);
%player.setImageLoaded($WeaponSlot, false);
}
function startMining(%player, %self)
{
// %player = the player who was using the repair pack
// %self = boolean -- is player repairing him/herself?
if(%self)
{
// one repair, hold the projectile
%player.setRepairRate(%player.getRepairRate() + MiningToolGunImage.repairFactorPlayer);
%player.selfRepairing = true;
%player.repairingRate = MiningToolGunImage.repairFactorPlayer;
}
else
{
//if(%player.repairing.beingRepaired $= "")
// %player.repairing.beingRepaired = 1;
//else
// %player.repairing.beingRepaired++;
//AI hack...
if (%player.client.isAIControlled() && %player.client.repairObject == %player.repairing)
{
%initialPosition = %player.getMuzzlePoint($WeaponSlot);
%initialDirection = VectorSub(%initialPosition, %player.repairing.getWorldBoxCenter());
}
else
{
%initialDirection = %player.getMuzzleVector($WeaponSlot);
%initialPosition = %player.getMuzzlePoint($WeaponSlot);
}
if(%player.repairing.getClassName() $= Player)
%repRate = RepairGunImage.repairFactorPlayer;
else
%repRate = RepairGunImage.repairFactorObject;
%player.repairing.setRepairRate(%player.repairing.getRepairRate() + %repRate);
%player.repairingRate = %repRate;
%player.repairProjectile = new RepairProjectile() {
dataBlock = MiningBeam;
initialDirection = %initialDirection;
initialPosition = %initialPosition;
sourceObject = %player;
sourceSlot = $WeaponSlot;
targetObject = %player.repairing;
};
// ----------------------------------------------------
// z0dd - ZOD, 5/27/02. Fix lingering projectile bug
if(isObject(%player.lastProjectile))
%player.lastProjectile.delete();
%player.HP = %player.repairing.getDamageLevel(); //Is used when player stops 'mining'
%player.lastProjectile = %player.repairProjectile;
// End z0dd - ZOD
// ----------------------------------------------------
MissionCleanup.add(%player.repairProjectile);
}
}
function MiningTool::onPickup(%this, %obj, %shape, %amount)
{
// created to prevent console errors
}