From 47cf0088b74c369606d0cae245480f38caab4090 Mon Sep 17 00:00:00 2001 From: ChocoTaco Date: Fri, 8 Nov 2019 13:39:27 -0500 Subject: [PATCH] Added --- Classic/scripts/inventory.cs | 634 ++++++++++++++++++++++++++ Classic/scripts/packs/repairpack.cs | 677 ++++++++++++++++++++++++++++ 2 files changed, 1311 insertions(+) create mode 100644 Classic/scripts/inventory.cs create mode 100644 Classic/scripts/packs/repairpack.cs diff --git a/Classic/scripts/inventory.cs b/Classic/scripts/inventory.cs new file mode 100644 index 0000000..f945b3e --- /dev/null +++ b/Classic/scripts/inventory.cs @@ -0,0 +1,634 @@ +//---------------------------------------------------------------------------- + +// Item Datablocks +// image = Name of mounted image datablock +// onUse(%this,%object) + +// Item Image Datablocks +// item = Name of item inventory datablock + +// ShapeBase Datablocks +// max[Item] = Maximum amount that can be caried + +// ShapeBase Objects +// inv[Item] = Count of item in inventory +//---------------------------------------------------------------------------- + +$TestCheats = 0; + +function serverCmdUse(%client,%data) +{ + // Item names from the client must converted + // into DataBlocks + // %data = ItemDataBlock[%item]; + if(isObject(%client.player)) // z0dd - ZOD, 5/18/03. Console spam fix + %client.getControlObject().use(%data); +} + +function serverCmdThrow(%client,%data) +{ + // Item names from the client must converted + // into DataBlocks + // %data = ItemDataBlock[%item]; + + //----------------------------------------------------------------------- + // z0dd - ZOD, 4/18/02. Let one keybind handle all grenade types. + if(isObject(%client.player)) // z0dd - ZOD, 5/18/03. Console spam fix + { + if(%data $= Grenade) + { + // figure out which grenade type you're using + for(%x = 0; $InvGrenade[%x] !$= ""; %x++) + { + if(%client.getControlObject().inv[$NameToInv[$InvGrenade[%x]]] > 0) + { + %data = $NameToInv[$InvGrenade[%x]]; + break; + } + } + %client.getControlObject().throw(%data); + } + else if(%data $= Mine) + { + for(%x = 0; $InvMine[%x] !$= ""; %x++) + { + if(%client.getControlObject().inv[$NameToInv[$InvMine[%x]]] > 0) + { + %data = $NameToInv[$InvMine[%x]]; + break; + } + } + %client.getControlObject().throw(%data); + } + else if(%data $= "Ammo") + { + %weapon = %client.getControlObject().getMountedImage($WeaponSlot); + if(%weapon !$= "") + { + if(%weapon.ammo !$= "") + %client.getControlObject().throw(%weapon.ammo); + else + return; + } + } + else + %client.getControlObject().throw(%data); + } +} + +function serverCmdThrowWeapon(%client,%data) +{ + // Item names from the client must converted + // into DataBlocks + // %data = ItemDataBlock[%item]; + if(isObject(%client.player)) // z0dd - ZOD, 5/18/03. Console spam fix + %client.getControlObject().throwWeapon(); +} + +function serverCmdThrowPack(%client,%data) +{ + if(isObject(%client.player)) // z0dd - ZOD, 5/18/03. Console spam fix + %client.getControlObject().throwPack(); +} + +function serverCmdTogglePack(%client,%data) +{ + // this function is apparently never called + %client.getControlObject().togglePack(); +} + +function serverCmdThrowFlag(%client) +{ + //Game.playerDroppedFlag(%client.player); + Game.dropFlag(%client.player); +} + +function serverCmdSelectWeaponSlot( %client, %data ) +{ + if(isObject(%client.player)) // z0dd - ZOD, 5/18/03. Console spam fix + %client.getControlObject().selectWeaponSlot( %data ); +} + +function serverCmdCycleWeapon( %client, %data ) +{ + if(isObject(%client.player)) // z0dd - ZOD, 5/18/03. Console spam fix + %client.getControlObject().cycleWeapon( %data ); +} + +function serverCmdStartThrowCount(%client, %data) +{ + %client.player.throwStart = getSimTime(); +} + +$maxThrowStr = 2.2; // z0dd - ZOD, 8/6/02. New throw str features + +function serverCmdEndThrowCount(%client, %data) +{ + if(%client.player.throwStart == 0) + return; + + // --------------------------------------------------------------- + // z0dd - ZOD, 8/6/02. New throw str features + %throwStrength = (getSimTime() - %client.player.throwStart) / 150; + if(%throwStrength > $maxThrowStr) + %throwStrength = $maxThrowStr; + else if(%throwStrength < 0.5) + %throwStrength = 0.5; + // --------------------------------------------------------------- + + %throwScale = %throwStrength / 2; + %client.player.throwStrength = %throwScale; + + %client.player.throwStart = 0; +} + +// -------------------------------------------------------------------- +// z0dd - ZOD, 9/27/02. No buildup power. Rewrote function +function serverCmdthrowMaxEnd(%client, %data) +{ + %client.player.throwStrength = $maxThrowStr / 2; +} +// -------------------------------------------------------------------- + +function ShapeBase::throwWeapon(%this) +{ + if(Game.shapeThrowWeapon(%this)) { + %image = %this.getMountedImage($WeaponSlot); + %this.throw(%image.item); + %this.client.setWeaponsHudItem(%image.item, 0, 0); + } +} + +function ShapeBase::throwPack(%this) +{ + if(isObject(%this)) // z0dd - ZOD, 5/18/03. Console spam fix + { + %image = %this.getMountedImage($BackpackSlot); + %this.throw(%image.item); + %this.client.setBackpackHudItem(%image.item, 0); + } +} + +function ShapeBase::throw(%this,%data) +{ + if(!isObject(%data)) + return false; + + if (%this.inv[%data.getName()] > 0) { + + // save off the ammo count on this item + if( %this.getInventory( %data ) < $AmmoIncrement[%data.getName()] ) + %data.ammoStore = %this.getInventory( %data ); + else + %data.ammoStore = $AmmoIncrement[%data.getName()]; + + // Throw item first... + %this.throwItem(%data); + if($AmmoIncrement[%data.getName()] !$= "") + %this.decInventory(%data,$AmmoIncrement[%data.getName()]); + else + %this.decInventory(%data,1); + return true; + } + return false; +} + +function ShapeBase::use(%this, %data) +{ + //if(%data.class $= "Weapon") { + // error("ShapeBase::use " @ %data); + //} + if(isObject(%this) && %data !$= "") // z0dd - ZOD, 5/18/03. Console spam fix + { + if(%data $= Grenade) + { + // figure out which grenade type you're using + for(%x = 0; $InvGrenade[%x] !$= ""; %x++) { + if(%this.inv[$NameToInv[$InvGrenade[%x]]] > 0) + { + %data = $NameToInv[$InvGrenade[%x]]; + break; + } + } + } + else if(%data $= Mine) // z0dd - ZOD, 5/18/03. For more mine types + { + // figure out which mine type you're using + for(%m = 0; $InvMine[%m] !$= ""; %m++) { + if(%this.inv[$NameToInv[$InvMine[%m]]] > 0) + { + %data = $NameToInv[$InvMine[%m]]; + break; + } + } + } + else if(%data $= "Backpack") { + %pack = %this.getMountedImage($BackpackSlot); + // if you don't have a pack but have placed a satchel charge, detonate it + if(!%pack && (%this.thrownChargeId > 0) && %this.thrownChargeId.armed ) + { + %this.playAudio( 0, SatchelChargeExplosionSound ); + schedule( 600, %this, "detonateSatchelCharge", %this ); // z0dd - ZOD, 8/24/02. Time after pressing fire that satchel blows. Was 800 + return true; + } + return false; + } + else if(%data $= Beacon) + { + %data.onUse(%this); + if (%this.inv[%data.getName()] > 0) + return true; + } + + // default case + if (%this.inv[%data.getName()] > 0) { + %data.onUse(%this); + return true; + } + return false; + } +} + +function ShapeBase::pickup(%this,%obj,%amount) +{ + %data = %obj.getDatablock(); + %delta = %this.incInventory(%data,%amount); + + if (%delta) + %data.onPickup(%obj,%this,%delta); + return %delta; +} + +function ShapeBase::hasInventory(%this, %data) +{ + // changed because it was preventing weapons cycling correctly (MES) + return (%this.inv[%data] > 0); +} + +function ShapeBase::maxInventory(%this, %data) +{ + //error("ShapeBase::maxInventory( " @ %this.client.nameBase @ ", " @ %data @ " )"); + if(isObject(%data)) // z0dd - ZOD, 5/18/03. Console spam fix + { + if($TestCheats) + return 999; + else + return %this.getDatablock().max[%data.getName()]; + } +} + +function ShapeBase::incInventory(%this, %data, %amount) +{ + if(isObject(%data)) // z0dd - ZOD, 5/18/03. Console spam fix + { + %max = %this.maxInventory(%data); + %cv = %this.inv[%data.getName()]; + if (%cv < %max) { + if (%cv + %amount > %max) + %amount = %max - %cv; + + %this.setInventory(%data,%cv + %amount); + %data.incCatagory(%this); // Inc the players weapon count + return %amount; + } + return 0; + } +} + +function ShapeBase::decInventory(%this,%data,%amount) +{ + %name = %data.getName(); + %cv = %this.inv[%name]; + if (%cv > 0) { + if (%cv < %amount) + %amount = %cv; + %this.setInventory(%data,%cv - %amount, true); + %data.decCatagory(%this); // Dec the players weapon count + return %amount; + } + return 0; +} + +function SimObject::decCatagory(%this) +{ + //function was added to reduce console err msg spam +} + +function SimObject::incCatagory(%this) +{ + //function was added to reduce console err msg spam +} + +function ShapeBase::setInventory(%this,%data,%value,%force) +{ + if (!isObject(%data)) + return; + + %name = %data.getName(); + if (%value < 0) + %value = 0; + else + { + if (!%force) + { + // Impose inventory limits + %max = %this.maxInventory(%data); + if (%value > %max) + %value = %max; + } + } + if (%this.inv[%name] != %value) + { + %this.inv[%name] = %value; + %data.onInventory(%this,%value); + + if ( %data.className $= "Weapon" ) + { + if ( %this.weaponSlotCount $= "" ) + %this.weaponSlotCount = 0; + + %cur = -1; + for ( %slot = 0; %slot < %this.weaponSlotCount; %slot++ ) + { + if ( %this.weaponSlot[%slot] $= %name ) + { + %cur = %slot; + break; + } + } + + if ( %cur == -1 ) + { + // Put this weapon in the next weapon slot: + if ( %this.weaponSlot[%this.weaponSlotCount - 1] $= "TargetingLaser" ) + { + %this.weaponSlot[%this.weaponSlotCount - 1] = %name; + %this.weaponSlot[%this.weaponSlotCount] = "TargetingLaser"; + } + else + %this.weaponSlot[%this.weaponSlotCount] = %name; + %this.weaponSlotCount++; + } + else + { + // Remove the weapon from the weapon slot: + for ( %i = %cur; %i < %this.weaponSlotCount - 1; %i++ ) + %this.weaponSlot[%i] = %this.weaponSlot[%i + 1]; + %this.weaponSlot[%i] = ""; + %this.weaponSlotCount--; + } + } + + %this.getDataBlock().onInventory(%data,%value); + } + return %value; +} + +function ShapeBase::getInventory(%this,%data) +{ + if ( isObject( %data ) ) + return( %this.inv[%data.getName()] ); + else + return( 0 ); +} + +// z0dd - ZOD, 9/13/02. Streamlined. +function ShapeBase::hasAmmo( %this, %weapon ) +{ + if(%weapon $= LaserRifle) + return( %this.getInventory( EnergyPack ) ); + + if (%weapon.image.ammo $= "") + { + if (%weapon $= TargetingLaser) + { + return( false ); + } + else + { + return( true ); + } + } + else + { + return( %this.getInventory( %weapon.image.ammo ) > 0 ); + } +} + +function SimObject::onInventory(%this, %obj) +{ + //function was added to reduce console error msg spam +} + +function ShapeBase::throwItem(%this,%data) +{ + %item = new Item() { + dataBlock = %data; + rotation = "0 0 1 " @ (getRandom() * 360); + }; + + %item.ammoStore = %data.ammoStore; + MissionCleanup.add(%item); + %this.throwObject(%item); +} + +function ShapeBase::throwObject(%this,%obj) +{ + //------------------------------------------------------------------ + // z0dd - ZOD, 4/15/02. Allow respawn switching during tourney wait. + if(!$MatchStarted) + return; + //------------------------------------------------------------------ + + // z0dd - ZOD, 5/26/02. Remove anti-hover so flag can be thrown properly + if(%obj.getDataBlock().getName() $= "Flag") + { + %obj.static = false; + // z0dd - ZOD - SquirrelOfDeath, 10/02/02. Hack for flag collision bug. + if(Game.Class $= CTFGame || Game.Class $= PracticeCTFGame) + %obj.searchSchedule = Game.schedule(10, "startFlagCollisionSearch", %obj); + } + //------------------------------------------------------------------ + + %srcCorpse = (%this.getState() $= "Dead"); // z0dd - ZOD, 4/14/02. Flag tossed from corpse + //if the object is being thrown by a corpse, use a random vector + if (%srcCorpse && %obj.getDataBlock().getName() !$= "Flag") // z0dd - ZOD, 4/14/02. Except for flags.. + { + %vec = (-1.0 + getRandom() * 2.0) SPC (-1.0 + getRandom() * 2.0) SPC getRandom(); + %vec = vectorScale(%vec, 10); + } + else // else Initial vel based on the dir the player is looking + { + %eye = %this.getEyeVector(); + %vec = vectorScale(%eye, 20); + } + + // Add a vertical component to give the item a better arc + %dot = vectorDot("0 0 1",%eye); + if (%dot < 0) + %dot = -%dot; + %vec = vectorAdd(%vec,vectorScale("0 0 12",1 - %dot)); // z0dd - ZOD, 9/10/02. 10 was 8 + + // Add player's velocity + %vec = vectorAdd(%vec,%this.getVelocity()); + %pos = getBoxCenter(%this.getWorldBox()); + + //since flags have a huge mass (so when you shoot them, they don't bounce too far) + //we need to up the %vec so that you can still throw them... + if (%obj.getDataBlock().getName() $= "Flag") + { + %vec = vectorScale(%vec, (%srcCorpse ? 40 : 75)); // z0dd - ZOD, 4/14/02. Throw flag force. Value was 40 + // ------------------------------------------------------------ + // z0dd - ZOD, 9/27/02. Delay on grabbing flag after tossing it + %this.flagTossWait = true; + %this.schedule(1000, resetFlagTossWait); + // ------------------------------------------------------------ + } + + // + %obj.setTransform(%pos); + %obj.applyImpulse(%pos,%vec); + %obj.setCollisionTimeout(%this); + %data = %obj.getDatablock(); + + %data.onThrow(%obj,%this); + + //call the AI hook + AIThrowObject(%obj); +} + +function ShapeBase::clearInventory(%this) +{ + // z0dd - ZOD, 5/18/03. Auto cleanup of weapons and ammo. Streamline + for(%i = 0; %i < $WeaponsHudCount; %i++) + { + %this.setInventory($WeaponsHudData[%i, itemDataName], 0); + if($WeaponsHudData[%i, ammoDataName] !$= "") + %this.setInventory($WeaponsHudData[%i, ammoDataName], 0); + } + for(%i = 0; $InvGrenade[%i] !$= ""; %i++) + %this.setInventory($NameToInv[$InvGrenade[%i]], 0); + + for(%i = 0; $InvMine[%i] !$= ""; %i++) + %this.setInventory($NameToInv[$InvMine[%i]], 0); + + %this.setInventory(RepairKit, 0); + %this.setInventory(Beacon, 0); + + // take away any pack the player has + %curPack = %this.getMountedImage($BackpackSlot); + if(%curPack > 0) + %this.setInventory(%curPack.item, 0); +} + +//---------------------------------------------------------------------------- +function ShapeBase::cycleWeapon( %this, %data ) +{ + if ( %this.weaponSlotCount == 0 ) + return; + + %slot = -1; + if ( %this.getMountedImage($WeaponSlot) != 0 ) + { + %curWeapon = %this.getMountedImage($WeaponSlot).item.getName(); + for ( %i = 0; %i < %this.weaponSlotCount; %i++ ) + { + //error("curWeaponName == " @ %curWeaponName); + if ( %curWeapon $= %this.weaponSlot[%i] ) + { + %slot = %i; + break; + } + } + } + + if ( %data $= "prev" ) + { + // Previous weapon... + if ( %slot == 0 || %slot == -1 ) + { + %i = %this.weaponSlotCount - 1; + %slot = 0; + } + else + %i = %slot - 1; + } + else + { + // Next weapon... + if ( %slot == ( %this.weaponSlotCount - 1 ) || %slot == -1 ) + { + %i = 0; + %slot = ( %this.weaponSlotCount - 1 ); + } + else + %i = %slot + 1; + } + + %newSlot = -1; + while ( %i != %slot ) + { + if ( %this.weaponSlot[%i] !$= "" + && %this.hasInventory( %this.weaponSlot[%i] ) + && %this.hasAmmo( %this.weaponSlot[%i] ) ) + { + // player has this weapon and it has ammo or doesn't need ammo + %newSlot = %i; + break; + } + + if ( %data $= "prev" ) + { + if ( %i == 0 ) + %i = %this.weaponSlotCount - 1; + else + %i--; + } + else + { + if ( %i == ( %this.weaponSlotCount - 1 ) ) + %i = 0; + else + %i++; + } + } + + if ( %newSlot != -1 ) + %this.use( %this.weaponSlot[%newSlot] ); +} + +//---------------------------------------------------------------------------- +function ShapeBase::selectWeaponSlot( %this, %data ) +{ + if ( %data < 0 || %data > %this.weaponSlotCount + || %this.weaponSlot[%data] $= "" || %this.weaponSlot[%data] $= "TargetingLaser" ) + return; + + %this.use( %this.weaponSlot[%data] ); +} + +//---------------------------------------------------------------------------- + +function serverCmdGiveAll(%client) +{ + if($TestCheats) + { + %player = %client.player; + // z0dd - ZOD, 5/18/03. Auto increment of weapons and ammo. Streamline + for(%i = 0; %i < $WeaponsHudCount; %i++) + { + %player.setInventory($WeaponsHudData[%i, itemDataName], 1); + if($WeaponsHudData[%i, ammoDataName] !$= "") + %player.setInventory($WeaponsHudData[%i, ammoDataName], 999); + } + for(%i = 0; $InvGrenade[%i] !$= ""; %i++) + %player.setInventory($NameToInv[$InvGrenade[%i]], 0); + + for(%i = 0; $InvMine[%i] !$= ""; %i++) + %player.setInventory($NameToInv[$InvMine[%i]], 0); + + %player.setInventory(RepairKit, 999); + %player.setInventory(Beacon, 999); + %player.setInventory(RocketCannonAmmo, 999); + } +} diff --git a/Classic/scripts/packs/repairpack.cs b/Classic/scripts/packs/repairpack.cs new file mode 100644 index 0000000..18e3853 --- /dev/null +++ b/Classic/scripts/packs/repairpack.cs @@ -0,0 +1,677 @@ +//-------------------------------------------------------------------------- +// Repair Pack +// can be used by any armor type +// when activated, gives user a "repair gun" that can be used to +// repair a damaged object or player. If there is no target in +// range for the repair gun, the user is repaired. + +//-------------------------------------------------------------------------- +// Sounds & feedback effects + +datablock EffectProfile(RepairPackActivateEffect) +{ + effectname = "packs/packs.repairPackOn"; + minDistance = 2.5; + maxDistance = 2.5; +}; + +datablock EffectProfile(RepairPackFireEffect) +{ + effectname = "packs/repair_use"; + minDistance = 2.5; + maxDistance = 5.0; +}; + +datablock AudioProfile(RepairPackActivateSound) +{ + filename = "fx/packs/packs.repairPackOn.wav"; + description = AudioClosest3d; + preload = true; + effect = RepairPackActivateEffect; +}; + +datablock AudioProfile(RepairPackFireSound) +{ + filename = "fx/packs/repair_use.wav"; + description = CloseLooping3d; + preload = true; + effect = RepairPackFireEffect; +}; + +//-------------------------------------------------------------------------- +// Projectile + +datablock RepairProjectileData(DefaultRepairBeam) +{ + sound = RepairPackFireSound; + + beamRange = 10; + beamWidth = 0.15; + numSegments = 20; + texRepeat = 0.20; + blurFreq = 10.0; + blurLifetime = 1.0; + cutoffAngle = 25.0; + + textures[0] = "special/redbump2"; + textures[1] = "special/redflare"; +}; + + +//------------------------------------------------------------------------- +// shapebase datablocks + +datablock ShapeBaseImageData(RepairPackImage) +{ + shapeFile = "pack_upgrade_repair.dts"; + item = RepairPack; + mountPoint = 1; + offset = "0 0 0"; + emap = true; + + gun = RepairGunImage; + + 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(RepairPack) +{ + className = Pack; + catagory = "Packs"; + shapeFile = "pack_upgrade_repair.dts"; + mass = 1; + elasticity = 0.2; + friction = 0.6; + pickupRadius = 2; + rotate = true; + image = "RepairPackImage"; + pickUpName = "a repair pack"; + + lightOnlyStatic = true; + lightType = "PulsingLight"; + lightColor = "1 0 0 1"; + lightTime = 1200; + lightRadius = 4; + + computeCRC = true; + emap = true; +}; + +//-------------------------------------------------------------------------- +// Repair Gun + +datablock ShapeBaseImageData(RepairGunImage) +{ + shapeFile = "weapon_repair.dts"; + offset = "0 0 0"; + + usesEnergy = true; + minEnergy = 3; + cutOffEnergy = 3.1; + emap = true; + + repairFactorPlayer = 0.002; // <--- attention DaveG! + repairFactorObject = 0.0055; // <--- attention DaveG! // z0dd - ZOD, 7/20/02. was 0.004 + + 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] = "Repair"; + stateTransitionOnNoAmmo[3] = "Deactivate"; + stateTransitionOnTriggerUp[3] = "Deactivate"; + + stateName[4] = "Repair"; + stateSound[4] = RepairPackFireSound; + stateScript[4] = "onRepair"; + stateSpinThread[4] = FullSpeed; + stateAllowImageChange[4] = false; + stateSequence[4] = "activate"; + stateFire[4] = true; + stateEnergyDrain[4] = 9; + stateTimeoutValue[4] = 0.2; + stateTransitionOnTimeOut[4] = "Repair"; + 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 RepairPackImage::onUnmount(%data, %obj, %node) +{ + // dismount the repair 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() $= "RepairGunImage") + %obj.unmountImage($WeaponSlot); + + // if the player was repairing something when the pack was thrown, stop repairing it + if(%obj.repairing != 0) + stopRepairing(%obj); +} + +function RepairPackImage::onActivate(%data, %obj, %slot) +{ + // don't activate the pack if player is piloting a vehicle + if(%obj.isPilot()) + { + %obj.setImageTrigger(%slot, false); + return; + } + // z0dd - ZOD, 5/19/03. Make sure their wearing a repair pack. + if(%obj.getMountedImage($BackpackSlot) != 0) + { + if(%obj.getMountedImage($BackpackSlot).getName() $= "RepairPackImage") + { + if(!isObject(%obj.getMountedImage($WeaponSlot)) || %obj.getMountedImage($WeaponSlot).getName() !$= "RepairGunImage") + { + messageClient(%obj.client, 'MsgRepairPackOn', '\c2Repair pack activated.'); + + // make sure player's arm thread is "look" + %obj.setArmThread(look); + + // mount the repair gun + %obj.mountImage(RepairGunImage, $WeaponSlot); + // clientCmdsetRepairReticle found in hud.cs + commandToClient(%obj.client, 'setRepairReticle'); + } + } + else + %obj.setImageTrigger(%slot, false); + } +} + +function RepairPackImage::onDeactivate(%data, %obj, %slot) +{ + //called when the player hits the "pack" key again (toggle) + %obj.setImageTrigger(%slot, false); + // if repair gun was mounted, unmount it + if(%obj.getMountedImage($WeaponSlot).getName() $= "RepairGunImage") + %obj.unmountImage($WeaponSlot); +} + +function RepairGunImage::onMount(%this,%obj,%slot) +{ + %obj.setImageAmmo(%slot,true); + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + commandToClient( %obj.client, 'setRepairPackIconOn' ); +} + +function RepairGunImage::onUnmount(%this,%obj,%slot) +{ + // called when player switches to another weapon + + // stop repairing whatever player was repairing + if(%obj.repairing) + stopRepairing(%obj); + + %obj.setImageTrigger(%slot, false); + // "turn off" the repair pack -- player needs to hit the "pack" key to + // activate the repair gun again + %obj.setImageTrigger($BackpackSlot, false); + // z0dd - ZOD, 9/29/02. Removed T2 demo code from here + commandToClient( %obj.client, 'setRepairPackIconOff' ); +} + +function RepairGunImage::onActivateReady(%this, %obj, %slot) +{ + %obj.errMsgSent = false; + %obj.selfRepairing = false; + %obj.repairing = 0; + %obj.setImageLoaded(%slot, false); +} + +function RepairGunImage::onValidate(%this, %obj, %slot) +{ + // this = repairgunimage datablock + // obj = player wielding the repair gun + // slot = weapon slot + + if(%obj.getEnergyLevel() <= %this.cutOffEnergy) + { + stopRepairing(%obj); + return; + } + // z0dd - ZOD, 5/19/03. Make sure their wearing a repair pack. + if(%obj.getMountedImage($BackpackSlot) != 0) + { + if(%obj.getMountedImage($BackpackSlot).getName() $= "RepairPackImage") + { + %repGun = %obj.getMountedImage(%slot); + // muzVec is the vector coming from the repair gun's "muzzle" + %muzVec = %obj.getMuzzleVector(%slot); + // muzNVec = normalized muzVec + %muzNVec = VectorNormalize(%muzVec); + %repairRange = DefaultRepairBeam.beamRange; + // scale muzNVec to the range the repair 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::PlayerObjectType | $TypeMasks::VehicleObjectType | + $TypeMasks::StaticShapeObjectType | $TypeMasks::TurretObjectType | + $TypeMasks::InteriorObjectType; + + // 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 repaired at all + // -- mission specific flag set on the object + if(!%obj.errMsgSent) + { + messageClient(%obj.client, 'MsgRepairPackIrrepairable', '\c2Target is not repairable.', %repTgt); + %obj.errMsgSent = true; + } + // if player was repairing something, stop the repairs -- we're done + if(%obj.repairing) + stopRepairing(%obj); + } + else if(%repTgt.getDamageLevel()) + { + // yes, it's damaged + if(%repTgt != %obj.repairing) + { + if(isObject(%obj.repairing)) + stopRepairing(%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) + stopRepairing(%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)) + stopRepairing(%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) + stopRepairing(%obj); + + if(isObject(%obj.repairing)) + stopRepairing(%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 repair.'); + %obj.errMsgSent = true; + } + stopRepairing(%obj); + } + } + else + { + // z0dd - ZOD, 5/19/03. No repair pack on their back, unmount gun. + %obj.setImageTrigger(%slot, false); + %obj.unmountImage(%slot); + } + } + else + { + // z0dd - ZOD, 5/19/03. No repair pack on their back, unmount gun. + %obj.setImageTrigger(%slot, false); + %obj.unmountImage(%slot); + } +} + +function RepairGunImage::onRepair(%this,%obj,%slot) +{ + // this = repairgunimage datablock + // obj = player wielding the repair gun + // slot = weapon slot + + if(%obj.getEnergyLevel() <= %this.cutOffEnergy) + { + stopRepairing(%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 + stopRepairing(%obj); + } + else + { + %target.repairedBy = %obj.client; //keep track of who last repaired this item + if(%obj.repairing == %obj) + { + // player is self-repairing + if(%obj.getDamageLevel()) + { + if(!%obj.selfRepairing) + { + // no need for a projectile, just send a message and up the repair rate + messageClient(%obj.client, 'MsgRepairPackPlayerSelfRepair', '\c2Repairing self.'); + %obj.selfRepairing = true; + startRepairing(%obj, true); + } + } + else + { + messageClient(%obj.client, 'MsgRepairPackSelfDone', '\c2Repairs completed on self.'); + stopRepairing(%obj); + %obj.errMsgSent = true; + } + } + 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::PlayerObjectType | $TypeMasks::VehicleObjectType | + $TypeMasks::StaticShapeObjectType | $TypeMasks::TurretObjectType; + + //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); + // is the target damaged? + if(%repTgt.getDamageLevel()) + { + 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', '\c2Repairing %1.', %tgtName, %repTgt); + startRepairing(%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', '\c2Repairing %1.', %tgtName, %repTgt); + startRepairing(%obj, false); + } + } + // z0dd - ZOD, 8/9/03. It's enabled, award points + //if(%repTgt.getDamageState() $= "Enabled") + // Game.objectRepaired(%repTgt, %tgtName); + } + 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', '\c2Repairs completed.'); + // z0dd - ZOD, 8/9/03. Award for enabling item, so this is too late + Game.objectRepaired(%repTgt, %tgtName); + } + %obj.errMsgSent = true; + stopRepairing(%obj); + } + } + else + { + // whoops, we lost our target + messageClient(%obj.client, 'MsgRepairPackLostTarget', '\c2Repair target no longer in range.'); + stopRepairing(%obj); + } + } + } +} + +function RepairGunImage::onDeactivate(%this,%obj,%slot) +{ + stopRepairing(%obj); +} + +function stopRepairing(%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; + } + } + %player.repairing = 0; + %player.repairingRate = 0; + %player.setImageTrigger($WeaponSlot, false); + %player.setImageLoaded($WeaponSlot, false); +} + +function startRepairing(%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() + RepairGunImage.repairFactorPlayer); + %player.selfRepairing = true; + %player.repairingRate = RepairGunImage.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 = DefaultRepairBeam; + 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.lastProjectile = %player.repairProjectile; + // End z0dd - ZOD + // ---------------------------------------------------- + MissionCleanup.add(%player.repairProjectile); + } +} +// z0dd - ZOD, 5/18/03. Removed functions, created parent. Streamline. +//function RepairPack::onPickup(%this, %obj, %shape, %amount) +//{ + // created to prevent console errors +//}