construction-mod/scripts/packs/telepadpack.cs
2025-06-05 12:37:16 +02:00

565 lines
15 KiB
C#

//---------------------------------------------------------
// Deployable Telepad
//---------------------------------------------------------
datablock ShapeBaseImageData(TelePadDeployableImage) {
mass = 1;
emap = true;
shapeFile = "stackable1s.dts";
item = TelePadPack;
mountPoint = 1;
offset = "0 0 0";
deployed = TelePadDeployedBase;
heatSignature = 0;
stateName[0] = "Idle";
stateTransitionOnTriggerDown[0] = "Activate";
stateName[1] = "Activate";
stateScript[1] = "onActivate";
stateTransitionOnTriggerUp[1] = "Idle";
isLarge = true;
maxDepSlope = 360;
deploySound = StationDeploySound;
minDeployDis = 0.5;
maxDeployDis = 5.0;
};
datablock ItemData(TelePadPack) {
className = Pack;
catagory = "Deployables";
shapeFile = "stackable1s.dts";
mass = 1;
elasticity = 0.2;
friction = 0.6;
pickupRadius = 1;
rotate = false;
image = "TelePadDeployableImage";
pickUpName = "a teleport pad pack";
heatSignature = 0;
joint = "2 2 2";
computeCRC = true;
emap = true;
};
datablock SensorData(TelePadBaseSensorObj) {
detects = true;
detectsUsingLOS = true;
detectsPassiveJammed = false;
detectsActiveJammed = false;
detectsCloaked = false;
detectionPings = true;
detectRadius = 10;
};
datablock StaticShapeData(TelePadDeployedBase) : StaticShapeDamageProfile {
className = "teleport";
shapeFile = "nexuscap.dts";
maxDamage = 2.00;
destroyedLevel = 2.00;
disabledLevel = 1.35;
isShielded = true;
energyPerDamagePoint = 250;
maxEnergy = 100;
rechargeRate = 1;
explosion = ShapeExplosion; // DeployablesExplosion;
expDmgRadius = 18.0;
expDamage = 0.1;
expImpulse = 200.0;
dynamicType = $TypeMasks::StationObjectType;
deployedObject = true;
cmdCategory = "DSupport";
cmdIcon = CMDSwitchIcon;
cmdMiniIconName = "commander/MiniIcons/com_switch_grey";
targetNameTag = 'Deployed';
targetTypeTag = 'Teleport Pad';
debrisShapeName = "debris_generic.dts";
debris = DeployableDebris;
heatSignature = 0;
needsPower = true;
humSound = SensorHumSound;
pausePowerThread = true;
sensorData = TelePadBaseSensorObj;
sensorRadius = TelePadBaseSensorObj.detectRadius;
sensorColor = "0 212 45";
firstPersonOnly = true;
lightType = "PulsingLight";
lightColor = "0 1 0 1";
lightTime = 1200;
lightRadius = 6;
};
datablock StaticShapeData(TelePadBeam) {
className = "Station";
catagory = "DSupport";
shapefile = "nexus_effect.dts";
collideable = 1;
needsNoPower = true;
emap="true";
sensorData = TelePadBaseSensorObj;
sensorRadius = TelePadBaseSensorObj.detectRadius;
sensorColor = "0 212 45";
cmdCategory = "DSupport";
targetNameTag = 'Teleport';
targetTypeTag = 'Pad';
lightType = "PulsingLight";
lightColor = "0 1 0 1";
lightTime = 1200;
lightRadius = 6;
};
datablock AudioProfile(TelePadAccessDeniedSound) {
filename = "gui/vote_nopass.wav";
description = AudioClosest3d;
preload = true;
};
datablock AudioProfile(TelePadBeamSound) {
filename = "fx/vehicles/inventory_pad_on.wav";
description = AudioClosest3d;
preload = true;
};
datablock AudioProfile(TelePadPowerUpSound) {
filename = "fx/powered/turret_heavy_activate.wav";
description = AudioClosest3d;
preload = true;
};
datablock AudioProfile(TelePadPowerDownSound) {
filename = "fx/powered/inv_pad_off.wav";
description = AudioClosest3d;
preload = true;
};
datablock ParticleData(TelePadTeleportParticle)
{
dragCoeffiecient = 0.0;
gravityCoefficient = 0.0;
inheritedVelFactor = 0.0;
lifetimeMS = 1200;
lifetimeVarianceMS = 400;
textureName = "special/lightFalloffMono";
useInvAlpha = false;
spinRandomMin = -200.0;
spinRandomMax = 200.0;
colors[0] = "0.5 0.8 0.2 1.0";
colors[1] = "0.6 0.9 0.3 1.0";
colors[2] = "0.7 1.0 0.4 1.0";
sizes[0] = 0.2;
sizes[1] = 0.1;
sizes[2] = 0.05;
times[0] = 0.0;
times[1] = 0.5;
times[2] = 1.0;
};
datablock ParticleEmitterData(TelePadTeleportEmitter)
{
ejectionPeriodMS = 1;
ejectionOffset = 7.0;
periodVarianceMS = 0.0;
ejectionVelocity = 2.0;
velocityVariance = 2.0;
thetaMin = 0.0;
thetaMax = 10.0;
lifetimeMS = 0;
particles = "TelePadTeleportParticle";
};
function TelePadDeployedBase::onDestroyed(%this,%obj,%prevState) {
if (%obj.isRemoved)
return;
%obj.isRemoved = true;
Parent::onDestroyed(%this,%obj,%prevState);
$TeamDeployedCount[%obj.team,TelePadPack]--;
%obj.isRemoved = true;
remDSurface(%obj);
%obj.beam.schedule(150,"delete");
%obj.schedule(500,"delete");
}
function TelePadDeployedBase::disassemble(%data,%plyr,%obj) {
if (isObject(%obj.beam))
%obj.beam.delete();
%obj.isRemoved = true;
disassemble(%data,%plyr,%obj);
}
function TelePadDeployedBase::onGainPowerEnabled(%data,%obj) {
if (shouldChangePowerState(%obj,true)) {
tp_fadeIn(%obj,true);
%obj.playThread($AmbientThread,"ambient");
%obj.setThreadDir($AmbientThread,true);
%obj.playThread($ActivateThread,"transition");
%obj.setThreadDir($ActivateThread,false);
%obj.play3D(TelePadPowerUpSound);
}
Parent::onGainPowerEnabled(%data,%obj);
}
function TelePadDeployedBase::onLosePowerDisabled(%data,%obj) {
if (shouldChangePowerState(%obj,false)) {
tp_fadeOut(%obj,true);
%obj.stopThread($AmbientThread);
%obj.playThread($ActivateThread,"transition");
%obj.setThreadDir($ActivateThread,true);
%obj.play3D(TelePadPowerDownSound);
}
Parent::onLosePowerDisabled(%data,%obj);
}
function TelePadDeployedBase::onCollision(%data,%obj,%col) {
if (%col.justTeleported || %obj.isRemoved)
return;
// verify pad.team is team associated and is on player's team
if (%obj.team != %col.team && %obj.team != 0 && %obj.teleMode != 1 && %obj.frequency > 0) {
%obj.play3D(TelePadAccessDeniedSound);
messageClient(%col.client,'msgClient','\c2Access Denied -- Wrong team.');
%col.justTeleported = true;
schedule(2000,0,"unTeleport",%col);
return;
}
// verify that pad can transmit
if (%obj.teleMode == 3) {
%obj.play3D(TelePadAccessDeniedSound);
messageClient(%col.client,'msgClient','\c2Access Denied -- This pad can only receive.');
%col.justTeleported = true;
schedule(2000,0,"unTeleport",%col);
return;
}
// Discover next pad to teleport to
%dgroup = nameToID(Deployables);
%destPad = 0;
%firstPad = 0;
for(%depIndex = 0; %depIndex < %dgroup.getCount(); %depIndex++) {
%dep = %dgroup.getObject(%depIndex);
if (%dep.getDataBlock().className $= "teleport") {
if (%dep != %obj && %dep.frequency == %obj.frequency && %dep.team == %obj.team && %dep.teleMode != 2) {
if (%dep.isPowered() && %dep.isEnabled() && !(%dep.getEnergyLevel() < %dep.getDataBlock().maxEnergy)) {
if (!%firstPad || %dep < %firstPad)
%firstPad = %dep;
if (%dep > %obj && (!%destPad || %dep < %destPad)) {
%destPad = %dep;
}
}
else
%notEnabled = true;
}
}
}
if (!%destPad)
%destPad = %firstPad;
if (!%obj.isPowered() || !%obj.isEnabled()) {
%obj.play3D(TelePadAccessDeniedSound);
if (!%obj.isPowered() && !%obj.isEnabled())
messageClient(%col.client,'msgClient','\c2Unable to teleport, telepad is damaged and has no power.');
else if (!%obj.isEnabled())
messageClient(%col.client,'msgClient','\c2Unable to teleport, telepad is damaged.');
else if (!%obj.isPowered())
messageClient(%col.client,'msgClient','\c2Unable to teleport, telepad is not powered.');
else
messageClient(%col.client,'msgClient','\c2Unable to teleport, telepad malfunction.');
%col.justTeleported = true;
schedule(2000,0,"unTeleport",%col);
return;
}
if (!%destPad) {
%obj.play3D(TelePadAccessDeniedSound);
if (%notEnabled)
messageClient(%col.client,'msgClient','\c2Unable to teleport, destination is damaged, has no power or is recharging.');
else
messageClient(%col.client,'msgClient','\c2Unable to teleport, no other pads to teleport to.');
%col.justTeleported = true;
schedule(2000,0,"unTeleport",%col);
return;
}
if (tp_isBlocked(%destPad,%col)) {
%obj.play3D(TelePadAccessDeniedSound);
messageClient(%col.client,'msgClient','\c2Unable to teleport, destination is blocked.');
%col.justTeleported = true;
schedule(2000,0,"unTeleport",%col);
return;
}
if (%obj.getEnergyLevel() < %obj.getDataBlock().maxEnergy) {
%obj.play3D(TelePadAccessDeniedSound);
messageClient(%col.client,'msgClient','\c2Unable to teleport, telepad is recharging.');
%col.justTeleported = true;
schedule(2000,0,"unTeleport",%col);
return;
}
// center player on pad
if (!tp_isBlocked(%obj,%col))
tp_adjustPlayer(%obj,%col);
// fade out player
%col.disableMove(true);
pl_fadeOut(%col);
// pad power up effect
tp_fadePadIn(%obj);
tp_fadePadIn(%destPad);
// fade out beams
schedule(600,0,"tp_fadeOut",%obj);
schedule(750,0,"tp_fadeOut",%destPad);
// pad power down effect
schedule(1500,0,"tp_fadePadOut",%obj);
schedule(1550,0,"tp_fadePadOut",%destPad);
// fade in beams
schedule(3000,0,"tp_fadeIn",%obj);
schedule(3050,0,"tp_fadeIn",%destPad);
// Zap energy
%obj.setEnergyLevel(0);
%destPad.setEnergyLevel(0);
%col.justTeleported = true;
messageClient(%col.client,'msgClient',"~wfx/misc/diagnostic_on.wav");
schedule(500,0,"teleport",%col,%destPad,%obj); // schedule their teleportation
tp_emitter(%obj);
}
function tp_isBlocked(%pad,%obj) {
%padPos = %pad.getPosition();
%telePos = vectorAdd(%padPos,vectorScale(realVec(%pad,"0 0 1"),-2.5));
if (containerRayCast(%padPos,%telePos,-1,%pad))
%blocked = true;
if (!$Host::AllowUnderground) {
%terrain = getTerrainHeight2(%telePos);
if (getWord(%telePos,2) < getWord(%terrain,2) || %terrain $= "")
%blocked = true;
}
if (isObject(%obj)) {
%adjust = vectorAdd(vectorScale(vectorNormalize(realVec(%pad,"0 0 1")),-1.35),vectorSub(%obj.getPosition(),%obj.getWorldBoxCenter()));
%pos = vectorAdd(%padPos,%adjust);
if (!$Host::AllowUnderground) {
%terrain = getTerrainHeight2(%pos);
if (getWord(%pos,2) < getWord(%terrain,2) || %terrain $= "")
%blocked = true;
}
if (containerRayCast(%telePos,%pos,-1,%obj))
%blocked = true;
}
return %blocked;
}
// player
function pl_fadeIn(%obj) {
%obj.startFade(500,0,false);
messageClient(%col.client,'msgClient',"~wfx/misc/diagnostic_on.wav");
}
function pl_fadeOut(%obj) {
%obj.startFade(500,0,true);
messageClient(%col.client,'msgClient',"~wfx/misc/diagnostic_on.wav");
}
// beam and sound
function tp_fadeIn(%obj,%silent) {
if (%obj.isPowered() && %obj.isEnabled()) {
if (!%silent)
%obj.play3D(DiscReloadSound);
%obj.beam.startFade(100,0,false);
}
}
function tp_fadeOut(%obj,%silent) {
if (!%silent)
%obj.play3D(TelePadBeamSound);
%obj.beam.startFade(100,0,true);
}
// pad
function tp_fadePadIn(%obj) {
%obj.playThread($ActivateThread,"transition");
%obj.setThreadDir($ActivateThread,true);
}
function tp_fadePadOut(%obj) {
%obj.playThread($ActivateThread,"transition");
%obj.setThreadDir($ActivateThread,false);
}
// fancy emitter
function tp_emitter(%obj) {
%em = new ParticleEmissionDummy() {
scale = "1 1 1";
dataBlock = "defaultEmissionDummy";
emitter = "TelePadTeleportEmitter";
velocity = "1";
};
%adjust = vectorScale(realVec(%obj,"0 0 1"),7);
%em.setTransform(vectorAdd(%obj.getPosition(),%adjust) SPC rotAdd(%obj.getRotation(),"1 0 0" SPC $Pi));
MissionCleanup.add(%em);
%em.schedule(1000,"delete");
}
function unTeleport(%pl) {
if (isObject(%pl))
%pl.justTeleported = false;
}
function teleport(%pl,%destPad,%src) {
%pl.setVelocity("0 0 0"); //slow me down, ive been falling :)
%pl.schedule(500,disableMove,false);
pl_fadeIn(%pl);
schedule(2650,0,"unTeleport",%pl);
if (!isObject(%destPad)) {// lost the destination
messageClient(%pl.client,'msgClient','\c2Lost destination!');
tp_adjustPlayer(%src,%pl);
}
else {
if (%pl.team == %src.team)
messageClient(%pl.client,'msgClient','\c2Teleporting on frequency %1.',%src.frequency);
else
messageClient(%pl.client,'msgClient','\c2Teleporting on ENEMY frequency %1!',%src.frequency);
tp_adjustPlayer(%destPad,%pl);
tp_emitter(%destPad);
}
}
function tp_adjustPlayer(%pad,%obj) {
%adjust = vectorAdd(vectorScale(vectorNormalize(realVec(%pad,"0 0 1")),-1.35),vectorSub(%obj.getPosition(),%obj.getWorldBoxCenter()));
%rot = %obj.getRotation();
%obj.setTransform(vectorAdd(%pad.getPosition(),%adjust) SPC %rot);
}
function tp_adjustBeam(%pad) {
%rot = rotAdd(%pad.getRotation(),"1 0 0" SPC $Pi);
%pad.beam.setTransform(%pad.getPosition() SPC %rot);
}
function TelePadPack::onPickup(%this,%obj,%shape,%amount) {
// created to prevent console errors
}
function TelePadDeployableImage::onDeploy(%item,%plyr,%slot) {
%className = "StaticShape";
%item.surfacePt = vectorAdd(%item.surfacePt,vectorScale(%item.surfaceNrm,0.4));
%playerVector = vectorNormalize(getWord(%plyr.getEyeVector(),1) SPC -1 * getWord(%plyr.getEyeVector(),0) SPC "0");
%item.surfaceNrm2 = %playerVector;
if (vAbs(floorVec(%item.surfaceNrm,100)) $= "0 0 1")
%item.surfaceNrm2 = vectorScale(%playerVector,-1);
else
%item.surfaceNrm2 = vectorNormalize(vectorCross(%item.surfaceNrm,"0 0 1"));
%rot = fullRot(vectorScale(%item.surfaceNrm,-1),%item.surfaceNrm2);
%deplObj = new (%className)() {
dataBlock = TelePadDeployedBase;
scale = "1 1 1";
deployed = true;
teleMode = %plyr.expertSet;
};
// set orientation
%deplObj.setTransform(%item.surfacePt SPC %rot);
// set team, owner, and handle
%deplObj.team = %plyr.client.team;
%deplObj.setOwner(%plyr);
// set power frequency
%deplObj.powerFreq = %plyr.powerFreq;
// set the sensor group if it needs one
if (%deplObj.getTarget() != -1)
setTargetSensorGroup(%deplObj.getTarget(),%plyr.client.team);
// set frequency
%frequency = %plyr.packSet;
if (!%frequency)
%frequency = 1;
%deplObj.frequency = %frequency;
setTargetName(%deplObj.target,addTaggedString("Frequency" SPC %frequency));
// attach beam
%deplObj.beam = new (StaticShape)() {
dataBlock = TelePadBeam;
scale = "1 1 0.4";
};
// set orientation
tp_adjustBeam(%deplObj);
%deplObj.beam.playThread(0,"ambient");
%deplObj.beam.setThreadDir(0,true);
// The flash animation plays forwards, then back automatically,so we have to alternate the thread direcction...
%deplObj.beam.flashThreadDir = true;
%deplObj.beam.base = %deplObj;
// place the deployable in the MissionCleanup/Deployables group (AI reasons)
addToDeployGroup(%deplObj);
//let the AI know as well...
AIDeployObject(%plyr.client,%deplObj);
// play the deploy sound
serverPlay3D(%item.deploySound,%deplObj.getTransform());
// increment the team count for this deployed object
$TeamDeployedCount[%plyr.team,%item.item]++;
addDSurface(%item.surface,%deplObj);
// take the deployable off the player's back and out of inventory
%plyr.unmountImage(%slot);
%plyr.decInventory(%item.item,1);
// Power object
checkPowerObject(%deplObj);
return %deplObj;
}
function TelePadDeployableImage::onMount(%data,%obj,%node) {
%obj.hasTele = true; // set for telecheck
%obj.packSet = 1;
%obj.expertSet = 0;
displayPowerFreq(%obj);
}
function TelePadDeployableImage::onUnmount(%data,%obj,%node) {
%obj.hasTele = "";
%obj.packSet = 0;
%obj.expertSet = 0;
}