2015-08-30 06:30:29 +00:00
//--------------------------------------------------------------------------
// 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
}