mirror of
https://github.com/Ragora/T2-AAConstruction.git
synced 2026-01-19 19:44:48 +00:00
1194 lines
45 KiB
PHP
Executable file
1194 lines
45 KiB
PHP
Executable file
//--------------------------------------------------------------------------
|
|
// Deconstruct Gun / Construction Tool
|
|
// Originally from Hammer Mod. Changed and redone for LuCiD MoD.
|
|
// Also Changed again and redone for Construction Mod.
|
|
// All changes made by LuCiD from LuCiD MoD & Mostlikely or JackTL from Construction Mod.
|
|
|
|
//Phantom139: Defining it as a function removes the UE on weapon reload for scope failure
|
|
function buildDeconList() {
|
|
$ReverseDeployItem[DeployedStationInventory] = InventoryDeployable;
|
|
$ReverseDeployItem[DeployedMotionSensor] = MotionSensorDeployable;
|
|
$ReverseDeployItem[DeployedPulseSensor] = PulseSensorDeployable;
|
|
$ReverseDeployItem[TurretDeployedOutdoor] = TurretOutdoorDeployable;
|
|
$ReverseDeployItem[TurretDeployedFloorIndoor] = TurretIndoorDeployable;
|
|
$ReverseDeployItem[TurretDeployedWallIndoor] = TurretIndoorDeployable;
|
|
$ReverseDeployItem[TurretDeployedCeilingIndoor] = TurretIndoorDeployable;
|
|
$ReverseDeployItem[TurretDeployedBase] = TurretBasePack;
|
|
$ReverseDeployItem[TurretDeployedCamera] = CameraGrenade;
|
|
$ReverseDeployItem[TelePadDeployedBase] = TelePadPack;
|
|
$ReverseDeployItem[DeployedSpine] = "poof spineDeployable";
|
|
$ReverseDeployItem[DeployedSpine2] = "poof spineDeployable";
|
|
$ReverseDeployItem[DeployedSpine3] = "poof spineDeployable";
|
|
$ReverseDeployItem[DeployedWoodSpine] = "poof spineDeployable";
|
|
$ReverseDeployItem[Deployedfloor] = "poof floorDeployable";
|
|
$ReverseDeployItem[Deployedwall] = "poof wallDeployable";
|
|
$ReverseDeployItem[Deployedwwall] = "poof wwallDeployable";
|
|
$ReverseDeployItem[Deployedmspine] = "poof mspineDeployable";
|
|
$ReverseDeployItem[DeployedDoor] = "poof DoorDeployable";
|
|
$ReverseDeployItem[DeployedEnergizer] = EnergizerDeployable;
|
|
$ReverseDeployItem[Deployedmspinering] = "poof nothing";
|
|
$ReverseDeployItem[DiscTurretDeployed] = DiscTurretDeployable;
|
|
$ReverseDeployItem[StationInventory] = LargeInventoryDeployable;
|
|
$ReverseDeployItem[DeployedJumpad] = JumpadDeployable;
|
|
$ReverseDeployItemDeployedBeacon = Beacon;
|
|
$ReverseDeployItem[DeployedLogoProjector] = LogoProjectorDeployable;
|
|
$ReverseDeployItem[LaserDeployed] = TurretLaserDeployable;
|
|
$ReverseDeployItem[MissileRackTurretDeployed] = TurretMissileRackDeployable;
|
|
$ReverseDeployItem[SensorMediumPulse] = MediumSensorDeployable;
|
|
$ReverseDeployItem[SensorLargePulse] = LargeSensorDeployable;
|
|
$ReverseDeployItem[DeployedLightBase] = "LightDeployable";
|
|
$ReverseDeployItem[DeployedTripwire] = "TripwireDeployable";
|
|
$ReverseDeployItem[DeployedEscapePod] = "EscapePodDeployable";
|
|
$ReverseDeployItem[EmitterDep] = "poof EmitterDepPack";
|
|
$ReverseDeployItem[AudioDep] = "poof AudioDepPack";
|
|
$ReverseDeployItem[DispenserDep] = "poof DispenserDepPack";
|
|
|
|
$ReverseDeployItem[DeployedCardPack] = "CardPackDeployable";
|
|
$ReverseDeployItem[SpawnPointDeployedBase] = "SpawnPointPack";
|
|
$ReverseDeployItem[Deployedwaypoint] = "waypointDeployable";
|
|
$ReverseDeployItem[DeployedProjectileTurret] = "projectileDeployable";
|
|
$ReverseDeployItem[DeployedPTurret] = "PTurretDeployable";
|
|
|
|
$ReverseDeployItem[Mpm_Anti_TurretDeployed] = "TurretMpm_Anti_Deployable";
|
|
$ReverseDeployItem[DeployableVehiclePadBottom] = "VehiclePadPack";
|
|
$ReverseDeployItem[DeployableVehiclePad] = "VehiclePadPack";
|
|
$ReverseDeployItem[DeployableVehicleStation] = "VehiclePadPack";
|
|
$ReverseDeployItem[DeployableVehiclePad2] = "VehiclePadPack";
|
|
$ReverseDeployItem[PotPipe] = "poof";
|
|
$ReverseDeployItem[EmitterDep] = "poof EmitterDepPack";
|
|
$ReverseDeployItem[AudioDep] = "poof AudioDepPack";
|
|
$ReverseDeployItem[DispenserDep] = "poof DispenserDepPack";
|
|
$ReverseDeployItem[Mpm_Beacon_Ghost] = "poof";
|
|
$ReverseDeployItem[DetonationDep] = "DetonationDepPack";
|
|
$ReverseDeployItem[DetonationDepArm] = "DetonationDepPack";
|
|
$ReverseDeployItem[DeployedWaypoint] = "WaypointDeployable";
|
|
|
|
//[most]
|
|
|
|
for (%i = 0;%i < 23;%i++)
|
|
$ReverseDeployItemDeployedForcefield[%i] = "ForceFieldDeployable";
|
|
for (%i = 0;%i < 5;%i++)
|
|
$ReverseDeployItemDeployedGravityField[%i] = "GravityFieldDeployable";
|
|
for (%i = 0;%i < 14;%i++)
|
|
$ReverseDeployItemDeployedTree[%i] = "TreeDeployable";
|
|
for (%i = 0;%i < 13;%i++)
|
|
$ReverseDeployItemDeployedCrate[%i] = "CrateDeployable";
|
|
for (%i = 0;%i < 17;%i++)
|
|
$ReverseDeployItemDeployedDecoration[%i] = "DecorationDeployable";
|
|
// power
|
|
$ReverseDeployItem[GeneratorLarge] = GeneratorDeployable;
|
|
$ReverseDeployItem[SolarPanel] = SolarPanelDeployable;
|
|
$ReverseDeployItem[DeployedSwitch] = SwitchDeployable;
|
|
// DeconTarget
|
|
$ReverseDeployItem[DeployedLTarget] = "poof";
|
|
}
|
|
buildDeconList();
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
// Sounds
|
|
datablock AudioProfile(ConstructionToolSwitchSound) {
|
|
filename = "fx/packs/packs.repairPackOn.wav";
|
|
description = AudioClosest3d;
|
|
preload = true;
|
|
};
|
|
|
|
datablock AudioProfile(ConstructionToolFireSound) {
|
|
filename = "fx/misc/downloading.wav";
|
|
description = CloseLooping3d;
|
|
preload = true;
|
|
};
|
|
|
|
//--------------------------------------------------------------------------
|
|
// Projectile
|
|
|
|
datablock RepairProjectileData(ConstructionToolBeam) {
|
|
sound = ElfFireWetSound;
|
|
|
|
beamRange = 100;
|
|
beamWidth = 0.15;
|
|
numSegments = 20;
|
|
texRepeat = 0.20;
|
|
blurFreq = 10.0;
|
|
blurLifetime = 1.0;
|
|
cutoffAngle = 25.0;
|
|
|
|
textures[0] = "special/ELFLightning";
|
|
textures[1] = "skins/flaregreen";
|
|
};
|
|
|
|
//-------------------------------------------------------------------------
|
|
// shapebase datablocks
|
|
|
|
datablock ItemData(ConstructionTool) {
|
|
className = Weapon;
|
|
catagory = "Spawn Items";
|
|
shapeFile = "weapon_shocklance.dts";
|
|
image = ConstructionToolImage;
|
|
mass = 1;
|
|
elasticity = 0.2;
|
|
friction = 0.6;
|
|
pickupRadius = 2;
|
|
rotate = true;
|
|
pickUpName = "a construction tool";
|
|
|
|
lightOnlyStatic = true;
|
|
lightType = "PulsingLight";
|
|
lightColor = "0 1 0 1";
|
|
lightTime = 1200;
|
|
lightRadius = 4;
|
|
|
|
//computeCRC = true;
|
|
emap = true;
|
|
};
|
|
|
|
//--------------------------------------------------------------------------
|
|
// Construction Tool
|
|
|
|
datablock ShapeBaseImageData(ConstructionToolImage) {
|
|
shapeFile = "weapon_shocklance.dts";
|
|
offset = "0 0 0";
|
|
|
|
item = ConstructionTool;
|
|
usesEnergy = true;
|
|
|
|
minEnergy = 3;
|
|
|
|
cutOffEnergy = 3.1;
|
|
emap = true;
|
|
|
|
stateName[0] = "Activate";
|
|
stateTransitionOnTimeout[0] = "ActivateReady";
|
|
stateTimeoutValue[0] = 0.25;
|
|
stateSound[0] = ConstructionToolSwitchSound;
|
|
|
|
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] = "PerformAction";
|
|
stateTransitionOnNoAmmo[3] = "Deactivate";
|
|
stateTransitionOnTriggerUp[3] = "Deactivate";
|
|
|
|
stateName[4] = "PerformAction";
|
|
stateSound[4] = ConstructionToolFireSound;
|
|
stateScript[4] = "onPerformAction";
|
|
stateSpinThread[4] = FullSpeed;
|
|
stateAllowImageChange[4] = false;
|
|
stateSequence[4] = "activate";
|
|
stateFire[4] = true;
|
|
stateEnergyDrain[4] = 16;
|
|
stateTimeoutValue[4] = 0.2;
|
|
stateTransitionOnTimeOut[4] = "PerformAction";
|
|
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 ConstructionToolImage::onActivate(%this,%obj,%slot) {
|
|
}
|
|
|
|
function ConstructionToolImage::onActivateReady(%this,%obj,%slot) {
|
|
%obj.errMsgSent = false;
|
|
}
|
|
|
|
function ConstructionToolImage::onValidate(%this,%obj,%slot) {
|
|
switch (%obj.constructionToolMode) {
|
|
case 0: // disassemble
|
|
onValidateDisassemble(%this,%obj,%slot);
|
|
case 1: // rotate
|
|
onValidateRotate(%this,%obj,%slot);
|
|
case 2: // advanced rotate
|
|
onValidateAdvancedRotate(%this,%obj,%slot);
|
|
case 3: // power management
|
|
onValidatePowerManagement(%this,%obj,%slot);
|
|
}
|
|
}
|
|
|
|
function ConstructionToolImage::onPerformAction(%this,%obj,%slot) {
|
|
// this = ConstructionToolImage datablock
|
|
// obj = player wielding the construction tool
|
|
// slot = weapon slot
|
|
|
|
if (%obj.getEnergyLevel() <= %this.cutOffEnergy) {
|
|
if (%obj.performing > 0)
|
|
stopPerforming(%obj);
|
|
return;
|
|
}
|
|
|
|
// reset the flag that indicates an error message has been sent
|
|
%obj.errMsgSent = false;
|
|
|
|
switch (%obj.constructionToolMode) {
|
|
case 0: // disassemble
|
|
onPerformDisassemble(%this,%obj,%slot);
|
|
case 1: // rotate
|
|
onPerformRotate(%this,%obj,%slot);
|
|
case 2: // advanced rotate
|
|
onPerformAdvancedRotate(%this,%obj,%slot);
|
|
case 3: // power management
|
|
onPerformPowerManagement(%this,%obj,%slot);
|
|
}
|
|
}
|
|
|
|
function ConstructionToolImage::onDeactivate(%this,%obj,%slot) {
|
|
%obj.setImageTrigger(%slot, false);
|
|
if (%obj.performing > 0) {
|
|
stopPerforming(%obj);
|
|
messageClient(%player.client, 'msgClient', '\c2Construction Tool stopped.');
|
|
}
|
|
%obj.errMsgSent = false;
|
|
}
|
|
|
|
function ConstructionToolImage::onMount(%this,%obj,%slot) {
|
|
if (!$Host::TournamentMode) {
|
|
%curWeap = ( %obj.getMountedImage($WeaponSlot) == 0 ) ? "" : %obj.getMountedImage($WeaponSlot).getName().item.pickUpName;
|
|
BottomPrint(%obj.client, "Now using " @ %curWeap, 2, 1 );
|
|
}
|
|
%obj.errMsgSent = false;
|
|
%obj.client.setWeaponsHudActive(%this.item);
|
|
%obj.usingConstructionTool = true;
|
|
if (!%obj.constructionToolMode)
|
|
%obj.constructionToolMode = 0;
|
|
if (!%obj.constructionToolMode2)
|
|
%obj.constructionToolMode2 = 0;
|
|
WeaponImage::onMount(%this,%obj,%slot);
|
|
}
|
|
|
|
function ConstructionToolImage::onUnmount(%data, %obj, %slot) {
|
|
%obj.usingConstructionTool = false;
|
|
%obj.setImageTrigger(%slot, false);
|
|
if (%obj.performing > 0) {
|
|
stopPerforming(%obj);
|
|
messageClient(%player.client, 'msgClient', '\c2Construction Tool stopped.');
|
|
}
|
|
%obj.errMsgSent = false;
|
|
Parent::deconstruct(%data, %obj, %slot);
|
|
WeaponImage::onUnmount(%data, %obj, %slot);
|
|
}
|
|
|
|
function ConstructionTool::onPickup(%this, %obj, %shape, %amount) {
|
|
// created to prevent console errors
|
|
}
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// Common functions
|
|
// --------------------------------------------------------------------------------
|
|
|
|
function startPerforming(%player) {
|
|
// %player = the player who was using the construction tool
|
|
%initialDirection = %player.getMuzzleVector($WeaponSlot);
|
|
%initialPosition = %player.getMuzzlePoint($WeaponSlot);
|
|
|
|
//else
|
|
%performTime = 100;
|
|
|
|
%player.performTime = %performTime;
|
|
// Temporary (hopefully) fix
|
|
%data = %player.performing.getDataBlock();
|
|
%dataBlockName = %data.getName();
|
|
if (%data.className !$= "forcefield" && %data.className !$= "gravityfield") {
|
|
%player.constructionToolProjectile = new RepairProjectile() {
|
|
dataBlock = ConstructionToolBeam;
|
|
initialDirection = %initialDirection;
|
|
initialPosition = %initialPosition;
|
|
sourceObject = %player;
|
|
sourceSlot = $WeaponSlot;
|
|
targetObject = %player.performing;
|
|
};
|
|
MissionCleanup.add(%player.constructionToolProjectile);
|
|
}
|
|
%hTgt = %player.performing;
|
|
%hTgt.beingPerformed = true;
|
|
}
|
|
|
|
function stopPerforming(%player) {
|
|
// %player = the player who was using the construction tool
|
|
%hTgt = %player.performing;
|
|
if (%player.performing > 0) {
|
|
if (isObject(%player.constructionToolProjectile))
|
|
%player.constructionToolProjectile.delete();
|
|
}
|
|
%hTgt.beingPerformed = false;
|
|
%player.constructionToolProjectile = 0;
|
|
%player.performing = 0;
|
|
%player.performTime = 0;
|
|
%player.errMsgSent = true;
|
|
%player.setImageTrigger($WeaponSlot, false);
|
|
%player.setImageLoaded($WeaponSlot, false);
|
|
%client = %player.client;
|
|
if (%client.CampingThread)
|
|
cancel(%client.campingThread);
|
|
return;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// Disassemble functions
|
|
// --------------------------------------------------------------------------------
|
|
function onValidateDisassemble(%this,%obj,%slot) {
|
|
%hGun = %obj.getMountedImage(%slot);
|
|
// muzVec is the vector coming from the construction tool's "muzzle"
|
|
%muzVec = %obj.getMuzzleVector(%slot);
|
|
// muzNVec = normalized muzVec
|
|
%muzNVec = VectorNormalize(%muzVec);
|
|
%beamRange = ConstructionToolBeam.beamRange;
|
|
// scale muzNVec to the range the repair beam can reach
|
|
%muzScaled = VectorScale(%muzNVec, %beamRange);
|
|
// 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::InteriorObjectType | $TypeMasks::StaticShapeObjectType | $TypeMasks::VehicleObjectType | $TypeMasks::ForceFieldObjectType | $TypeMasks::ItemObjectType;
|
|
// 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
|
|
%hTgt = firstWord(%scanTarg);
|
|
// can it be dissed? is it already being tooled?
|
|
if ($ReverseDeployItem[%hTgt.getDataBlock().getName()] !$= "" && !%hTht.beingPerformed)
|
|
%canPerform = true;
|
|
// Only deconstruct deployed items, not base ones
|
|
%dataBlockName = %hTgt.getDataBlock().getName();
|
|
if (%canPerform == true && (
|
|
%dataBlockName $= "StationInventory" ||
|
|
%dataBlockName $= "GeneratorLarge" ||
|
|
%dataBlockName $= "SolarPanel" ||
|
|
%dataBlockName $= "SensorMediumPulse" ||
|
|
%dataBlockName $= "SensorLargePulse"
|
|
))
|
|
if (%hTgt.deployed != true)
|
|
%canPerform = false;
|
|
if (%canPerform == true) {
|
|
// yes, it's disassembleable
|
|
if (%hTgt != %obj.performing) {
|
|
if (isObject(%obj.performing))
|
|
stopPerforming(%obj);
|
|
%obj.performing = %hTgt;
|
|
startPerforming(%obj);
|
|
}
|
|
// setting imageLoaded to true sends us to deconstruct state (function onPerformAction)
|
|
%obj.setImageLoaded(%slot, true);
|
|
}
|
|
else {
|
|
// there is a target in range, but it's not disable
|
|
if (!%obj.errMsgSent) {
|
|
messageClient(%obj.client, 'msgClient', '\c2You can\'t deconstruct that.');
|
|
%obj.errMsgSent = true;
|
|
}
|
|
// if player was Disassembling something, stop the disassembling -- we're done
|
|
if (%obj.performing > 0)
|
|
stopPerforming(%obj);
|
|
}
|
|
}
|
|
else {
|
|
// there is no target in range
|
|
if (!%obj.errMsgSent) {
|
|
// send an error message only once
|
|
messageClient(%obj.client, 'msgClient', '\c2No target to deconstruct.');
|
|
%obj.errMsgSent = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
function onPerformDisassemble(%this,%obj,%slot) {
|
|
%target = %obj.performing;
|
|
if (!%target) {
|
|
// no target -- whoops! never mind
|
|
stopPerforming(%obj);
|
|
return;
|
|
}
|
|
if (%obj.constructionToolMode2 == 0)
|
|
%cascade = 0;
|
|
else
|
|
%cascade = 1;
|
|
%hGun = %obj.getMountedImage(%slot);
|
|
// muzVec is the vector coming from the construction tool's "muzzle"
|
|
%muzVec = %obj.getMuzzleVector(%slot);
|
|
// muzNVec = normalized muzVec
|
|
%muzNVec = VectorNormalize(%muzVec);
|
|
%beamRange = ConstructionToolBeam.beamRange;
|
|
// scale muzNVec to the range the repair beam can reach
|
|
%muzScaled = VectorScale(%muzNVec, %beamRange);
|
|
// 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::InteriorObjectType | $TypeMasks::StaticShapeObjectType | $TypeMasks::VehicleObjectType | $TypeMasks::ForceFieldObjectType | $TypeMasks::ItemObjectType;
|
|
// 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
|
|
%hTgt = firstWord(%scanTarg);
|
|
// can it be dissed? is it already being tooled?
|
|
if ($ReverseDeployItem[%hTgt.getDataBlock().getName()] !$= "" && !%hTht.beingPerformed)
|
|
%canPerform = true;
|
|
// Only deconstruct deployed items, not base ones
|
|
%dataBlockName = %hTgt.getDataBlock().getName();
|
|
if (%canPerform == true && (
|
|
%dataBlockName $= "StationInventory" ||
|
|
%dataBlockName $= "GeneratorLarge" ||
|
|
%dataBlockName $= "SolarPanel" ||
|
|
%dataBlockName $= "SensorMediumPulse" ||
|
|
%dataBlockName $= "SensorLargePulse"
|
|
))
|
|
if (%hTgt.deployed != true)
|
|
%canPerform = false;
|
|
if (%canPerform == true) {
|
|
// yes, it's disassembleable
|
|
if (%hTgt != %obj.performing) { // its not what we were originally dising
|
|
if (isObject(%obj.performing)) {
|
|
stopPerforming(%obj);
|
|
%obj.performing = %hTgt;
|
|
startPerforming(%obj);
|
|
}
|
|
}
|
|
else { // continue dising
|
|
%obj.performTime = %obj.performTime - 120;
|
|
if (%obj.performTime < 0) { // we have a dis!
|
|
if (%hTgt.isRemoved)
|
|
return; // Avoid duplicate disassemblies
|
|
if (%hTgt.team != %obj.team && !(%obj.client.isAdmin || %obj.client.isSuperAdmin)) {
|
|
messageClient(%obj.client, 'msgClient', '\c2Deconstruction failed! Wrong team!~wfx/powered/nexus_deny.wav');
|
|
stopPerforming(%obj);
|
|
return;
|
|
}
|
|
if ($Host::OnlyOwnerDeconstruct == 1 && %hTgt.getOwner() != %obj.client && !(%obj.client.isAdmin || %obj.client.isSuperAdmin)) {
|
|
if (isObject(%hTgt.getOwner()))
|
|
messageClient(%obj.client, 'msgClient', '\c2Deconstruction failed! This belongs to %1!~wfx/powered/nexus_deny.wav', %hTgt.getOwner().nameBase);
|
|
else
|
|
messageClient(%obj.client, 'msgClient', '\c2Deconstruction failed! Not your stuff!~wfx/powered/nexus_deny.wav');
|
|
stopPerforming(%obj);
|
|
return;
|
|
}
|
|
stopPerforming(%obj);
|
|
if (%cascade && $Host::OnlyOwnerCascade == 1 && %hTgt.getOwner() != %obj.client && !(%obj.client.isAdmin || %obj.client.isSuperAdmin))
|
|
messageClient(%obj.client, 'msgClient', '\c2Cascade failed! Not your stuff!~wfx/powered/nexus_deny.wav');
|
|
else {
|
|
if ((%hTgt.getType() & $TypeMasks::StaticShapeObjectType) && %hTgt.getDamageLeftPct() < (0.25 + ((getRandom() * 0.2) - 0.1))) {
|
|
if ($Host::InvincibleDeployables == 1 && %hTgt.getDamageLeftPct() <= 0) {
|
|
// %hTgt.setDamageLevel(%hTgt.getDataBlock().maxDamage - 0.01);
|
|
%hTgt.setDamageLevel(0); // Make sure we can blow it up..
|
|
}
|
|
%hTgt.damageFailedDecon = true;
|
|
%hTgt.schedule(100,setDamageState,Destroyed);
|
|
messageClient(%obj.client, 'msgClient', '\c2Deconstruction failed!~wfx/powered/nexus_deny.wav');
|
|
}
|
|
else {
|
|
%hTgt.getDataBlock().disassemble(%obj, %hTgt); // Run Item Specific code.
|
|
if (%cascade)
|
|
cascade(%hTgt,true);
|
|
if (%hTgt.getDataBlock().getName() $= "DeployedLTarget" && isObject(%hTgt.lMain))
|
|
%revItem = %hTgt.lMain.getDataBlock().getName();
|
|
else
|
|
%revItem = %hTgt.getDataBlock().getName();
|
|
%newPack = $ReverseDeployItem[%revItem];
|
|
if (getWord(%newPack,0) !$= "poof") {
|
|
%npack = new Item() {
|
|
dataBlock = %newPack;
|
|
};
|
|
MissionCleanup.add(%npack);
|
|
%npack.schedulePop();
|
|
if (%newPack $= "ForceFieldDeployable" || %newPack $= "GravityFieldDeployable" || %newPack $= "DecorationDeployable")
|
|
%pos = %hTgt.getWorldBoxCenter();
|
|
else
|
|
%pos = %hTgt.getPosition();
|
|
%npack.setTransform(getWords(%scanTarg,1,3) SPC "0 0 1" SPC (getRandom() * ($Pi * 2)));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
stopPerforming(%obj);
|
|
}
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// Rotate functions
|
|
// --------------------------------------------------------------------------------
|
|
|
|
function onValidateRotate(%this,%obj,%slot) {
|
|
%hGun = %obj.getMountedImage(%slot);
|
|
// muzVec is the vector coming from the construction tool's "muzzle"
|
|
%muzVec = %obj.getMuzzleVector(%slot);
|
|
// muzNVec = normalized muzVec
|
|
%muzNVec = VectorNormalize(%muzVec);
|
|
%beamRange = ConstructionToolBeam.beamRange;
|
|
// scale muzNVec to the range the repair beam can reach
|
|
%muzScaled = VectorScale(%muzNVec, %beamRange);
|
|
// 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::InteriorObjectType | $TypeMasks::StaticShapeObjectType | $TypeMasks::VehicleObjectType | $TypeMasks::ForceFieldObjectType | $TypeMasks::ItemObjectType;
|
|
// 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
|
|
%hTgt = firstWord(%scanTarg);
|
|
// can it be rotated? is it already being tooled?
|
|
if ($ReverseDeployItem[%hTgt.getDataBlock().getName()] !$= "" && !%hTht.beingPerformed)
|
|
%canPerform = true;
|
|
// Only rotate deployed items, not base ones
|
|
%dataBlockName = %hTgt.getDataBlock().getName();
|
|
if (%dataBlockName $= "DeployedLTarget" && !isObject(%hTgt.lMain))
|
|
%canPerform = false;
|
|
if (%canPerform == true && (
|
|
%dataBlockName $= "StationInventory" ||
|
|
%dataBlockName $= "GeneratorLarge" ||
|
|
%dataBlockName $= "SolarPanel" ||
|
|
%dataBlockName $= "SensorMediumPulse" ||
|
|
%dataBlockName $= "SensorLargePulse"
|
|
))
|
|
if (%hTgt.deployed != true)
|
|
%canPerform = false;
|
|
if (%canPerform == true) {
|
|
// yes, it's rotatable
|
|
if (%hTgt != %obj.performing) {
|
|
if (isObject(%obj.performing))
|
|
stopPerforming(%obj);
|
|
%obj.performing = %hTgt;
|
|
startPerforming(%obj);
|
|
}
|
|
// setting imageLoaded to true sends us to rotate state (function onPerformAction)
|
|
%obj.setImageLoaded(%slot, true);
|
|
}
|
|
else {
|
|
// there is a target in range, but it's not rotatable
|
|
if (!%obj.errMsgSent) {
|
|
messageClient(%obj.client, 'msgClient', '\c2You can\'t rotate that.');
|
|
%obj.errMsgSent = true;
|
|
}
|
|
// if player was rotating something, stop the rotating -- we're done
|
|
if (%obj.performing > 0)
|
|
stopPerforming(%obj);
|
|
}
|
|
}
|
|
else {
|
|
// there is no target in range
|
|
if (!%obj.errMsgSent) {
|
|
// send an error message only once
|
|
messageClient(%obj.client, 'msgClient', '\c2No target to rotate.');
|
|
%obj.errMsgSent = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
function onPerformRotate(%this,%obj,%slot) {
|
|
%target = %obj.performing;
|
|
if (!%target) {
|
|
// no target -- whoops! never mind
|
|
stopPerforming(%obj);
|
|
return;
|
|
}
|
|
if (%obj.constructionToolMode2 == 0)
|
|
%rotVal = 1;
|
|
else
|
|
%rotVal = -1;
|
|
%hGun = %obj.getMountedImage(%slot);
|
|
// muzVec is the vector coming from the construction tool's "muzzle"
|
|
%muzVec = %obj.getMuzzleVector(%slot);
|
|
// muzNVec = normalized muzVec
|
|
%muzNVec = VectorNormalize(%muzVec);
|
|
%beamRange = ConstructionToolBeam.beamRange;
|
|
// scale muzNVec to the range the repair beam can reach
|
|
%muzScaled = VectorScale(%muzNVec, %beamRange);
|
|
// 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::InteriorObjectType | $TypeMasks::StaticShapeObjectType | $TypeMasks::VehicleObjectType | $TypeMasks::ForceFieldObjectType | $TypeMasks::ItemObjectType;
|
|
// 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
|
|
%hTgt = firstWord(%scanTarg);
|
|
// can it be rotated? is it already being tooled?
|
|
if ($ReverseDeployItem[%hTgt.getDataBlock().getName()] !$= "" && !%hTht.beingPerformed)
|
|
%canPerform = true;
|
|
// Only rotate deployed items, not base ones
|
|
%dataBlockName = %hTgt.getDataBlock().getName();
|
|
if (%dataBlockName $= "DeployedLTarget" && !isObject(%hTgt.lMain))
|
|
%canPerform = false;
|
|
if (%canPerform == true && (
|
|
%dataBlockName $= "StationInventory" ||
|
|
%dataBlockName $= "GeneratorLarge" ||
|
|
%dataBlockName $= "SolarPanel" ||
|
|
%dataBlockName $= "SensorMediumPulse" ||
|
|
%dataBlockName $= "SensorLargePulse"
|
|
))
|
|
if (%hTgt.deployed != true)
|
|
%canPerform = false;
|
|
if (%canPerform == true) {
|
|
// yes, it's rotatable
|
|
if (%hTgt != %obj.performing) { // its not what we were originally rotating
|
|
if (isObject(%obj.performing)) {
|
|
stopPerforming(%obj);
|
|
%obj.performing = %hTgt;
|
|
startPerforming(%obj);
|
|
}
|
|
}
|
|
else { // continue rotating
|
|
%obj.performTime = %obj.performTime - 120;
|
|
if (%obj.performTime < 0) { // we have a rot!
|
|
if (%hTgt.team != %obj.team && !(%obj.client.isAdmin || %obj.client.isSuperAdmin)) {
|
|
messageClient(%obj.client, 'msgClient', '\c2Rotate failed! Wrong team!~wfx/powered/nexus_deny.wav');
|
|
stopPerforming(%obj);
|
|
return;
|
|
}
|
|
if ($Host::OnlyOwnerRotate == 1 && %hTgt.getOwner() != %obj.client && !(%obj.client.isAdmin || %obj.client.isSuperAdmin)) {
|
|
messageClient(%obj.client, 'msgClient', '\c2Rotate failed! Not your stuff!~wfx/powered/nexus_deny.wav');
|
|
stopPerforming(%obj);
|
|
return;
|
|
}
|
|
//
|
|
if(!isSet(%obj.client.RotateAngle)) {
|
|
//%obj.client.RotateAngle = $Pi / 8;
|
|
%obj.client.RotateAngle = 22.5;
|
|
%angle = (%obj.client.RotateAngle * ($Pi / 180)) * %rotVal;
|
|
}
|
|
else {
|
|
%angle = (%obj.client.RotateAngle * ($Pi / 180)) * %rotVal;
|
|
}
|
|
//
|
|
stopPerforming(%obj);
|
|
%obj = firstWord(%scanTarg);
|
|
%vec1 = posFromRaycast(%scanTarg);
|
|
%vec2 = normalFromRaycast(%scanTarg);
|
|
pullObject(%obj,%vec1,%vec2,%angle,"0 0 0");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
stopPerforming(%obj);
|
|
}
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// Advanced rotate functions
|
|
// --------------------------------------------------------------------------------
|
|
|
|
function onValidateAdvancedRotate(%this,%obj,%slot) {
|
|
%m2 = %obj.constructionToolMode2;
|
|
if (%m2 == 2 || %m2 == 3 || %m2 == 4 || %m2 == 5) {
|
|
%obj.setImageLoaded(%slot, true);
|
|
return;
|
|
}
|
|
|
|
%hGun = %obj.getMountedImage(%slot);
|
|
// muzVec is the vector coming from the construction tool's "muzzle"
|
|
%muzVec = %obj.getMuzzleVector(%slot);
|
|
// muzNVec = normalized muzVec
|
|
%muzNVec = VectorNormalize(%muzVec);
|
|
%beamRange = ConstructionToolBeam.beamRange;
|
|
// scale muzNVec to the range the repair beam can reach
|
|
%muzScaled = VectorScale(%muzNVec, %beamRange);
|
|
// 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::InteriorObjectType | $TypeMasks::StaticShapeObjectType | $TypeMasks::VehicleObjectType | $TypeMasks::ForceFieldObjectType | $TypeMasks::ItemObjectType;
|
|
// 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
|
|
%hTgt = firstWord(%scanTarg);
|
|
// can it be selected? is it already being tooled?
|
|
if ($ReverseDeployItem[%hTgt.getDataBlock().getName()] !$= "" && !%hTht.beingPerformed)
|
|
%canPerform = true;
|
|
// Only select deployed items, not base ones
|
|
%dataBlockName = %hTgt.getDataBlock().getName();
|
|
if (%dataBlockName $= "DeployedLTarget" && !isObject(%hTgt.lMain))
|
|
%canPerform = false;
|
|
if (%canPerform == true && (
|
|
%dataBlockName $= "StationInventory" ||
|
|
%dataBlockName $= "GeneratorLarge" ||
|
|
%dataBlockName $= "SolarPanel" ||
|
|
%dataBlockName $= "SensorMediumPulse" ||
|
|
%dataBlockName $= "SensorLargePulse"
|
|
))
|
|
if (%hTgt.deployed != true)
|
|
%canPerform = false;
|
|
if (!$Host::AllowUnderground) {
|
|
if (%dataBlockName $= "TelePadDeployedBase")
|
|
%canPerform = false;
|
|
}
|
|
if (%canPerform == true) {
|
|
// yes, it's selectable
|
|
if (%hTgt != %obj.performing) {
|
|
if (isObject(%obj.performing))
|
|
stopPerforming(%obj);
|
|
%obj.performing = %hTgt;
|
|
startPerforming(%obj);
|
|
}
|
|
// setting imageLoaded to true sends us to select state (function onPerformAction)
|
|
%obj.setImageLoaded(%slot, true);
|
|
}
|
|
else {
|
|
// there is a target in range, but it's not selectable
|
|
if (!%obj.errMsgSent) {
|
|
messageClient(%obj.client, 'msgClient', '\c2You can\'t select/rotate that.');
|
|
%obj.errMsgSent = true;
|
|
}
|
|
// if player was selecting something, stop the selecting -- we're done
|
|
if (%obj.performing > 0)
|
|
stopPerforming(%obj);
|
|
}
|
|
}
|
|
else {
|
|
// there is no target in range
|
|
if (!%obj.errMsgSent) {
|
|
// send an error message only once
|
|
messageClient(%obj.client, 'msgClient', '\c2No target to select/rotate.');
|
|
%obj.errMsgSent = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
function onPerformAdvancedRotate(%this,%obj,%slot) {
|
|
// Account for lag, and make gun a bit less trigger happy
|
|
%m2 = %obj.constructionToolMode2;
|
|
if (%m2 == 2 || %m2 == 3 || %m2 == 4 || %m2 == 5) {
|
|
if (getSimTime() < (%obj.constructionToolTime + 500))
|
|
return;
|
|
}
|
|
else {
|
|
if (getSimTime() < (%obj.constructionToolTime + 500) && %obj.performTime < 0)
|
|
return;
|
|
}
|
|
%obj.constructionToolTime = getSimTime();
|
|
|
|
// Load rotation list
|
|
%list = %obj.rotList;
|
|
|
|
// Validate list
|
|
%size = getWordCount(%list);
|
|
for(%id = 0; %id < %size; %id++) {
|
|
if (!isObject(getWord(%list,%id)))
|
|
%badIDs = %badIDs SPC %id;
|
|
}
|
|
%list = listDel(%list,trim(%badIDs));
|
|
|
|
if (!%list) // Is there a rotation list?
|
|
%list = %obj; // Set player as center.
|
|
|
|
// Save list
|
|
%obj.rotList = %list;
|
|
|
|
if (%obj.rotSpeed == 0) // So players can rotate without specifically setting rotSpeed
|
|
%obj.rotSpeed = 1;
|
|
|
|
if (%obj.constructionToolMode2 == 2) {
|
|
%obj.rotSpeed++;
|
|
if (%obj.rotSpeed > 3)
|
|
%obj.rotSpeed = -3;
|
|
if (%obj.rotSpeed == 0)
|
|
%obj.rotSpeed = 1;
|
|
%mod = lev(%obj.rotSpeed) * 5 * mPow(3,mAbs(%obj.rotSpeed) -1);
|
|
bottomPrint(%obj.client,"Rotation speed set to:" SPC %mod SPC " degrees per tick",2,1);
|
|
return;
|
|
}
|
|
else if(%obj.constructionToolMode2 == 3) {
|
|
%angle =lev(%obj.rotSpeed) * 5 * mPow(3,mAbs(%obj.rotSpeed) -1) / 180 * $Pi;
|
|
%mod = lev(%obj.rotSpeed) * 5 * mPow(3,mAbs(%obj.rotSpeed) -1);
|
|
rotateSection(getWord(%list,0),%list,"0 0 1" SPC %angle);
|
|
%obj.constructionToolTime = %obj.constructionToolTime + (getWordCount(%list) * 100);
|
|
bottomPrint(%obj.client,getWordCount(%list) SPC "objects rotated" SPC %mod SPC " degrees (wait " @ mFloor((%obj.constructionToolTime - getSimTime()) / 1000) @ " seconds)",2,1);
|
|
return;
|
|
}
|
|
else if(%obj.constructionToolMode2 == 4) {
|
|
for(%id = 0; %id < getWordCount(%list); %id++) {
|
|
%obj = getWord(%list,%id);
|
|
%obj.startFade(400,%id * 100,0);
|
|
if (isObject(%obj.lMain))
|
|
%obj.lMain.startFade(400,%id * 100,0);
|
|
}
|
|
bottomPrint(%obj.client,getWordCount(%list) SPC "objects selected including the rotation center",2,1);
|
|
return;
|
|
}
|
|
else if(%obj.constructionToolMode2 == 5) {
|
|
%list = "";
|
|
%obj.rotList = %list;
|
|
bottomPrint(%obj.client,"All objects removed from rotation list - player set as rotation center",2,1);
|
|
return;
|
|
}
|
|
|
|
%target = %obj.performing;
|
|
if (!%target) {
|
|
// no target -- whoops! never mind
|
|
stopPerforming(%obj);
|
|
return;
|
|
}
|
|
%hGun = %obj.getMountedImage(%slot);
|
|
// muzVec is the vector coming from the construction tool's "muzzle"
|
|
%muzVec = %obj.getMuzzleVector(%slot);
|
|
// muzNVec = normalized muzVec
|
|
%muzNVec = VectorNormalize(%muzVec);
|
|
%beamRange = ConstructionToolBeam.beamRange;
|
|
// scale muzNVec to the range the repair beam can reach
|
|
%muzScaled = VectorScale(%muzNVec, %beamRange);
|
|
// 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::InteriorObjectType | $TypeMasks::StaticShapeObjectType | $TypeMasks::VehicleObjectType | $TypeMasks::ForceFieldObjectType | $TypeMasks::ItemObjectType;
|
|
// 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
|
|
%hTgt = firstWord(%scanTarg);
|
|
// can it be selected? is it already being tooled?
|
|
if ($ReverseDeployItem[%hTgt.getDataBlock().getName()] !$= "" && !%hTht.beingPerformed)
|
|
%canPerform = true;
|
|
// Only select deployed items, not base ones
|
|
%dataBlockName = %hTgt.getDataBlock().getName();
|
|
if (%dataBlockName $= "DeployedLTarget" && !isObject(%hTgt.lMain))
|
|
%canPerform = false;
|
|
if (%canPerform == true && (
|
|
%dataBlockName $= "StationInventory" ||
|
|
%dataBlockName $= "GeneratorLarge" ||
|
|
%dataBlockName $= "SolarPanel" ||
|
|
%dataBlockName $= "SensorMediumPulse" ||
|
|
%dataBlockName $= "SensorLargePulse"
|
|
))
|
|
if (%hTgt.deployed != true)
|
|
%canPerform = false;
|
|
if (!$Host::AllowUnderground) {
|
|
if (%dataBlockName $= "TelePadDeployedBase")
|
|
%canPerform = false;
|
|
}
|
|
if (%canPerform == true) {
|
|
// yes, it's selectable
|
|
if (%hTgt != %obj.performing) { // its not what we were originally selecting
|
|
if (isObject(%obj.performing)) {
|
|
stopPerforming(%obj);
|
|
%obj.performing = %hTgt;
|
|
startPerforming(%obj);
|
|
}
|
|
}
|
|
else { // continue selecting
|
|
%obj.performTime = %obj.performTime - 120;
|
|
if (%obj.performTime < 0) { // we have a select!
|
|
if (%hTgt.team != %obj.team && !(%obj.client.isAdmin || %obj.client.isSuperAdmin)) {
|
|
messageClient(%obj.client, 'msgClient', '\c2Select failed! Wrong team!~wfx/powered/nexus_deny.wav');
|
|
stopPerforming(%obj);
|
|
return;
|
|
}
|
|
if ($Host::OnlyOwnerRotate == 1 && %hTgt.getOwner() != %obj.client && !(%obj.client.isAdmin || %obj.client.isSuperAdmin)) {
|
|
messageClient(%obj.client, 'msgClient', '\c2Select failed! Not your stuff!~wfx/powered/nexus_deny.wav');
|
|
stopPerforming(%obj);
|
|
return;
|
|
}
|
|
if (%obj.constructionToolMode2 == 0) {
|
|
if (%hTgt == getWord(%list,0)) { // Is it already the center?
|
|
%list = listReplace(%list,%obj,0); // Replace player as center
|
|
bottomPrint(%obj.client,"Object deselected as center",2,1);
|
|
}
|
|
else {
|
|
// Remove it from the list if it was in the list to start with.
|
|
%loc = findWord(%list,%hTgt);
|
|
if (%loc !$= "")
|
|
%list = listDel(%list,%loc);
|
|
%list = listReplace(%list,%hTgt,0); // Replace player as center
|
|
bottomPrint(%obj.client,"Object selected as center",2,1);
|
|
}
|
|
%hTgt.startFade(400,%id * 100,0);
|
|
if (isObject(%hTgt.lMain))
|
|
%hTgt.lMain.startFade(400,%id * 100,0);
|
|
}
|
|
else if (%obj.constructionToolMode2 == 1) {
|
|
if (%hTgt == getWord(%list,0))
|
|
bottomPrint(%obj.client,"Object is already center of rotation",2,1);
|
|
else {
|
|
%loc = findWord(%list,%hTgt);
|
|
if (%loc !$= "") { // Is it already in the list?
|
|
%list = listDel(%list,%loc);
|
|
bottomPrint(%obj.client,"Object deselected",2,1);
|
|
}
|
|
else {
|
|
%tempList = %list;
|
|
%list = %tempList SPC %hTgt;
|
|
bottomPrint(%obj.client,"Object Selected",2,1);
|
|
}
|
|
}
|
|
%hTgt.startFade(400,%id * 100,0);
|
|
if (isObject(%hTgt.lMain))
|
|
%hTgt.lMain.startFade(400,%id * 100,0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
stopPerforming(%obj);
|
|
%obj.rotList = %list;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// Power management functions
|
|
// --------------------------------------------------------------------------------
|
|
|
|
function onValidatePowerManagement(%this,%obj,%slot) {
|
|
|
|
%m2 = %obj.constructionToolMode2;
|
|
if (%m2 == 1 || %m2 == 2) {
|
|
%obj.setImageLoaded(%slot, true);
|
|
return;
|
|
}
|
|
|
|
%hGun = %obj.getMountedImage(%slot);
|
|
// muzVec is the vector coming from the construction tool's "muzzle"
|
|
%muzVec = %obj.getMuzzleVector(%slot);
|
|
// muzNVec = normalized muzVec
|
|
%muzNVec = VectorNormalize(%muzVec);
|
|
%beamRange = ConstructionToolBeam.beamRange;
|
|
// scale muzNVec to the range the repair beam can reach
|
|
%muzScaled = VectorScale(%muzNVec, %beamRange);
|
|
// 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::InteriorObjectType | $TypeMasks::StaticShapeObjectType | $TypeMasks::VehicleObjectType | $TypeMasks::ForceFieldObjectType | $TypeMasks::ItemObjectType;
|
|
// 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
|
|
%hTgt = firstWord(%scanTarg);
|
|
// can it be used? is it already being tooled?
|
|
if ($ReverseDeployItem[%hTgt.getDataBlock().getName()] !$= "" && !%hTht.beingPerformed)
|
|
%canPerform = true;
|
|
// Only use deployed items, not base ones
|
|
%dataBlockName = %hTgt.getDataBlock().getName();
|
|
if (%dataBlockName $= "DeployedLTarget" && !isObject(%hTgt.lMain))
|
|
%canPerform = false;
|
|
if (%canPerform == true && (
|
|
%dataBlockName $= "StationInventory" ||
|
|
%dataBlockName $= "GeneratorLarge" ||
|
|
%dataBlockName $= "SolarPanel" ||
|
|
%dataBlockName $= "SensorMediumPulse" ||
|
|
%dataBlockName $= "SensorLargePulse"
|
|
))
|
|
if (%hTgt.deployed != true)
|
|
%canPerform = false;
|
|
if (%canPerform == true) {
|
|
// yes, it's usable
|
|
if (%hTgt != %obj.performing) {
|
|
if (isObject(%obj.performing))
|
|
stopPerforming(%obj);
|
|
%obj.performing = %hTgt;
|
|
startPerforming(%obj);
|
|
}
|
|
// setting imageLoaded to true sends us to use state (function onPerformAction)
|
|
%obj.setImageLoaded(%slot, true);
|
|
}
|
|
else {
|
|
// there is a target in range, but it's not usable
|
|
if (!%obj.errMsgSent) {
|
|
messageClient(%obj.client, 'msgClient', '\c2You can\'t use that.');
|
|
%obj.errMsgSent = true;
|
|
}
|
|
// if player was using something, stop it -- we're done
|
|
if (%obj.performing > 0)
|
|
stopPerforming(%obj);
|
|
}
|
|
}
|
|
else {
|
|
// there is no target in range
|
|
if (!%obj.errMsgSent) {
|
|
// send an error message only once
|
|
messageClient(%obj.client, 'msgClient', '\c2No target to use.');
|
|
%obj.errMsgSent = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
function onPerformPowerManagement(%this,%obj,%slot) {
|
|
// Account for lag, and make gun a bit less trigger happy
|
|
%m2 = %obj.constructionToolMode2;
|
|
if (%m2 == 1 || %m2 == 2) {
|
|
if (getSimTime() < (%obj.constructionToolTime + 500))
|
|
return;
|
|
}
|
|
else {
|
|
if (getSimTime() < (%obj.constructionToolTime + 500) && %obj.performTime < 0)
|
|
return;
|
|
}
|
|
%obj.constructionToolTime = getSimTime();
|
|
|
|
if (%obj.constructionToolMode2 == 1) {
|
|
%obj.powerFreq++;
|
|
if (%obj.powerFreq > upperPowerFreq(%obj))
|
|
%obj.powerFreq = 1;
|
|
displayPowerFreq(%obj);
|
|
return;
|
|
}
|
|
else if (%obj.constructionToolMode2 == 2) {
|
|
%obj.powerFreq--;
|
|
if (%obj.powerFreq < 1)
|
|
%obj.powerFreq = upperPowerFreq(%obj);
|
|
displayPowerFreq(%obj);
|
|
return;
|
|
}
|
|
|
|
%target = %obj.performing;
|
|
if (!%target) {
|
|
// no target -- whoops! never mind
|
|
stopPerforming(%obj);
|
|
return;
|
|
}
|
|
|
|
%hGun = %obj.getMountedImage(%slot);
|
|
// muzVec is the vector coming from the construction tool's "muzzle"
|
|
%muzVec = %obj.getMuzzleVector(%slot);
|
|
// muzNVec = normalized muzVec
|
|
%muzNVec = VectorNormalize(%muzVec);
|
|
%beamRange = ConstructionToolBeam.beamRange;
|
|
// scale muzNVec to the range the repair beam can reach
|
|
%muzScaled = VectorScale(%muzNVec, %beamRange);
|
|
// 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::InteriorObjectType | $TypeMasks::StaticShapeObjectType | $TypeMasks::VehicleObjectType | $TypeMasks::ForceFieldObjectType | $TypeMasks::ItemObjectType;
|
|
// 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
|
|
%hTgt = firstWord(%scanTarg);
|
|
// can it be used? is it already being tooled?
|
|
if ($ReverseDeployItem[%hTgt.getDataBlock().getName()] !$= "" && !%hTht.beingPerformed)
|
|
%canPerform = true;
|
|
// Only use deployed items, not base ones
|
|
%dataBlockName = %hTgt.getDataBlock().getName();
|
|
if (%dataBlockName $= "DeployedLTarget" && !isObject(%hTgt.lMain))
|
|
%canPerform = false;
|
|
if (%canPerform == true && (
|
|
%dataBlockName $= "StationInventory" ||
|
|
%dataBlockName $= "GeneratorLarge" ||
|
|
%dataBlockName $= "SolarPanel" ||
|
|
%dataBlockName $= "SensorMediumPulse" ||
|
|
%dataBlockName $= "SensorLargePulse"
|
|
))
|
|
if (%hTgt.deployed != true)
|
|
%canPerform = false;
|
|
if (%canPerform == true) {
|
|
// yes, it's usable
|
|
if (%hTgt != %obj.performing) { // its not what we were originally using
|
|
if (isObject(%obj.performing)) {
|
|
stopPerforming(%obj);
|
|
%obj.performing = %hTgt;
|
|
startPerforming(%obj);
|
|
}
|
|
}
|
|
else { // continue using
|
|
%obj.performTime = %obj.performTime - 120;
|
|
if (%obj.performTime < 0) { // we have a use!
|
|
if (%hTgt.team != %obj.team && !(%obj.client.isAdmin || %obj.client.isSuperAdmin)) {
|
|
messageClient(%obj.client, 'msgClient', '\c2Use failed! Wrong team!~wfx/powered/nexus_deny.wav');
|
|
stopPerforming(%obj);
|
|
return;
|
|
}
|
|
if ($Host::OnlyOwnerDeconstruct == 1 && %hTgt.getOwner() != %obj.client && !(%obj.client.isAdmin || %obj.client.isSuperAdmin)) {
|
|
if (isObject(%hTgt.getOwner()))
|
|
messageClient(%obj.client, 'msgClient', '\c2Use failed! This belongs to %1!~wfx/powered/nexus_deny.wav', %hTgt.getOwner().nameBase);
|
|
else
|
|
messageClient(%obj.client, 'msgClient', '\c2Use failed! Not your stuff!~wfx/powered/nexus_deny.wav');
|
|
stopPerforming(%obj);
|
|
return;
|
|
}
|
|
if (%obj.constructionToolMode2 == 0) {
|
|
if (%hTgt.getDataBlock().className !$= "Generator") {
|
|
messageClient(%obj.client, 'msgClient', '\c2Use failed! Not a generator!~wfx/powered/nexus_deny.wav');
|
|
stopPerforming(%obj);
|
|
return;
|
|
}
|
|
else {
|
|
%r = toggleGenerator(%hTgt);
|
|
%r1 = firstWord(%r);
|
|
%r2 = getTaggedString(getWord(%r,1));
|
|
%r3 = getWord(%r,2);
|
|
if (%r1 == -2)
|
|
messageClient(%obj.client, 'msgClient', '\c2Use failed! %1 is damaged!~wfx/powered/nexus_deny.wav',%r2);
|
|
else if (%r1 == -3)
|
|
messageClient(%obj.client, 'msgClient', '\c2Must wait %1 seconds before toggling power state.',mCeil(%r3/1000));
|
|
else if (%r1 == 1)
|
|
messageClient(%obj.client, 'msgClient', '\c2%1 switched off.',%r2);
|
|
else if (%r1 == 2)
|
|
messageClient(%obj.client, 'msgClient', '\c2%1 switched on.',%r2);
|
|
stopPerforming(%obj);
|
|
return;
|
|
}
|
|
}
|
|
if (%obj.constructionToolMode2 == 3) {
|
|
// if (%hTgt.powerFreq !$= "" || %hTgt.getDataBlock().needsPower) {
|
|
%numLines = 1;
|
|
if (%hTgt.powerFreq !$= "")
|
|
%msg = "Power frequency is " @ %hTgt.powerFreq @ ", power is " @ (%hTgt.isPowered() ? ((%hTgt.powerCount > 0) ? (%hTgt.powerCount) : "On") : "OFF");
|
|
else
|
|
%msg = "Item does not have power frequency set";
|
|
if (%hTgt.getOwner().nameBase !$= "") {
|
|
%numLines++;
|
|
%msg = %msg @ "\nThis belongs to " @ %hTgt.getOwner().nameBase;
|
|
}
|
|
if (%obj.client.isAdmin || %obj.client.isSuperAdmin) {
|
|
%numLines++;
|
|
%msg = %msg @ "\n [Owner Clientid]:" SPC %hTgt.getOwner() SPC "[Object id]:" SPC %htgt;
|
|
}
|
|
bottomPrint(%obj.client,%msg,2,%numLines);
|
|
stopPerforming(%obj);
|
|
// }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
stopPerforming(%obj);
|
|
%obj.rotList = %list;
|
|
}
|
|
|
|
//By Phantom139
|
|
function isSet(%v)
|
|
{
|
|
return (%v !$= "");
|
|
}
|