mirror of
https://github.com/mostlikely4r/construction-mod.git
synced 2026-01-19 19:24:44 +00:00
842 lines
34 KiB
C#
842 lines
34 KiB
C#
// SaveBuilding.cs
|
|
//
|
|
// This script made possible by a joint effort of DynaBlade and JackTL
|
|
//
|
|
// Functions:
|
|
//
|
|
// saveBuilding(clientId,radius,file[$],quiet[1/0])
|
|
// saveBuildingCentered(clientId,radius,file[$],quiet[1/0],centerAtMinZ[1/0])
|
|
// delBuildingWaypoint()
|
|
// loadBuilding(file[$])
|
|
// saveBuildingTimer(time in seconds,globalEcho[1/0],file[$],useMultipleFiles[1/0]) // No limit on multiple files yet. Beware
|
|
// saveBuildingTimerOn() // <-- for restarting timed saves, does not initialize like saveBuildingTimer()
|
|
// saveBuildingTimerOff()
|
|
// delDupPieces(clientId,radius,quiet[1/0]) // NOTE: There are issues with calling this function a second time before the previous call's deconstruction has finished
|
|
//
|
|
// See functions for (some) comments
|
|
|
|
if ($SaveBuilding::SaveFolder $= "")
|
|
$SaveBuilding::SaveFolder = "Buildings/";
|
|
if ($SaveBuilding::AutoSaveFolder $= "")
|
|
$SaveBuilding::AutoSaveFolder = "Buildings/AutoSave/";
|
|
if ($SaveBuilding::TimerDefaultTime $= "")
|
|
$SaveBuilding::TimerDefaultTime = 5 * 60 * 1000; // 5 minutes. Saving may cause stutter on low-end servers with high number of pieces
|
|
if ($SaveBuilding::QuickDelete $= "")
|
|
$SaveBuilding::QuickDelete = 1;
|
|
|
|
|
|
// See if we want to save the piece
|
|
function saveBuildingCheck(%obj) {
|
|
%save = false;
|
|
%dataBlockName = %obj.getDatablock().getName();
|
|
switch$ (%dataBlockName) {
|
|
case "DeployedSpine":
|
|
%save = true;
|
|
case "DeployedWoodSpine":
|
|
%save = true;
|
|
case "DeployedMSpine":
|
|
%save = true;
|
|
case "DeployedMSpineRing":
|
|
%save = true;
|
|
case "DeployedFloor":
|
|
%save = true;
|
|
case "DeployedWall":
|
|
%save = true;
|
|
case "DeployedwWall":
|
|
%save = true;
|
|
case "DeployedEnergizer":
|
|
%save = true;
|
|
case "DeployedStationInventory":
|
|
%save = true;
|
|
case "DeployedJumpad":
|
|
%save = true;
|
|
case "DeployedEscapePod":
|
|
%save = true;
|
|
case "TelePadDeployedBase":
|
|
%save = true;
|
|
case "TelePadBeam":
|
|
%save = true;
|
|
case "DeployedLTarget":
|
|
%save = true;
|
|
case "DeployedLogoProjector":
|
|
%save = true;
|
|
case "DeployedSwitch":
|
|
%save = true;
|
|
case "DeployedPulseSensor":
|
|
%save = true;
|
|
case "DeployedMotionSensor":
|
|
%save = true;
|
|
case "TurretDeployedBase":
|
|
%save = true;
|
|
case "TurretDeployedFloorIndoor":
|
|
%save = true;
|
|
case "TurretDeployedWallIndoor":
|
|
%save = true;
|
|
case "TurretDeployedCeilingIndoor":
|
|
%save = true;
|
|
case "TurretDeployedOutdoor":
|
|
%save = true;
|
|
case "LaserDeployed":
|
|
%save = true;
|
|
case "MissileRackTurretDeployed":
|
|
%save = true;
|
|
case "DiscTurretDeployed":
|
|
%save = true;
|
|
case "TurretDeployedCamera":
|
|
%save = true;
|
|
case "DeployedLightBase":
|
|
%save = true;
|
|
case "DeployedTripwire":
|
|
%save = true;
|
|
case "DispenserDep":
|
|
%save = true;
|
|
case "AudioDep":
|
|
%save = true;
|
|
case "EmitterDep":
|
|
%save = true;
|
|
}
|
|
if (%dataBlockName $= "StationInventory" && %obj.deployed == true)
|
|
%save = true;
|
|
if (%dataBlockName $= "GeneratorLarge" && %obj.deployed == true)
|
|
%save = true;
|
|
if (%dataBlockName $= "SolarPanel" && %obj.deployed == true)
|
|
%save = true;
|
|
if (%dataBlockName $= "SensorMediumPulse" && %obj.deployed == true)
|
|
%save = true;
|
|
if (%dataBlockName $= "SensorLargePulse" && %obj.deployed == true)
|
|
%save = true;
|
|
if (getSubStr(%dataBlockName,0,18) $= "DeployedForceField")
|
|
%save = true;
|
|
if (getSubStr(%dataBlockName,0,20) $= "DeployedGravityField")
|
|
%save = true;
|
|
if (getSubStr(%dataBlockName,0,12) $= "DeployedTree")
|
|
%save = true;
|
|
if (getSubStr(%dataBlockName,0,13) $= "DeployedCrate")
|
|
%save = true;
|
|
if (getSubStr(%dataBlockName,0,18) $= "DeployedDecoration")
|
|
%save = true;
|
|
return %save;
|
|
}
|
|
|
|
// This function saves a building and its position in the map
|
|
function saveBuilding(%cl,%rad,%file,%quiet,%isAutoSave) {
|
|
if (%quiet == true) {
|
|
$SaveBuilding::Quiet = true;
|
|
}
|
|
else {
|
|
$SaveBuilding::Quiet = false; // Overwrite
|
|
}
|
|
%origCl = %cl;
|
|
if (!isObject(%cl)) {
|
|
if (isObject(nameToID(LocalClientConnection))) {
|
|
%cl = nameToID(LocalClientConnection);
|
|
}
|
|
else {
|
|
if ($CurrentClientId) {
|
|
%cl = $CurrentClientId;
|
|
}
|
|
}
|
|
}
|
|
if (%rad < 1) {
|
|
%rad = 100000;
|
|
}
|
|
%buildingCount = 0;
|
|
if (%file $= "" || %file $= "0") {
|
|
for(%found = true; %found; %buildingCount++ ) {
|
|
%suffix = %buildingCount;
|
|
while (strLen(%suffix) < 5) %suffix = "0" @ %suffix;
|
|
if (%isAutoSave)
|
|
%file = $SaveBuilding::AutoSaveFolder @ $MissionName @ "-" @ %suffix @ ".cs";
|
|
else
|
|
%file = $SaveBuilding::SaveFolder @ %cl.nameBase @ "-" @ $MissionName @ "-" @ %suffix @ ".cs";
|
|
%found = isFile(%file);
|
|
}
|
|
}
|
|
else {
|
|
if (%isAutoSave)
|
|
%file = $SaveBuilding::AutoSaveFolder @ %file;
|
|
else
|
|
%file = $SaveBuilding::SaveFolder @ %file;
|
|
}
|
|
if (isObject(%cl.getControlObject())) {
|
|
%pos = %cl.getControlObject().getPosition();
|
|
}
|
|
if (!%pos) {
|
|
%pos = "0 0 0";
|
|
}
|
|
if (%isAutoSave && (%origCl $= "" || %origCl $= "0"))
|
|
%pos = "0 0 0";
|
|
new fileObject("Building");
|
|
if (!$SaveBuilding::Quiet) {
|
|
warn("Saving to file: \"" @ %file @ "\"");
|
|
}
|
|
Building.openForWrite(%file);
|
|
Building.writeLine("// CONSTRUCTION MOD SAVE FILE");
|
|
Building.writeLine("// Saved by \"" @ getField(%cl.nameBase,0) @ "\"");
|
|
Building.writeLine("// Created in mission \"" @ $MissionName @ "\"");
|
|
Building.writeLine("// Construction " @ $ModVersion);
|
|
Building.writeLine("");
|
|
|
|
$SaveBuilding::Saved = 0;
|
|
$SaveBuilding::Skipped = 0;
|
|
initContainerRadiusSearch(%pos,%rad,$TypeMasks::StaticShapeObjectType | $TypeMasks::ForceFieldObjectType | $TypeMasks::ItemObjectType);
|
|
while((%obj = containerSearchNext()) != 0) {
|
|
%cmp = writeBuildingComponent(%obj);
|
|
if (%cmp !$= "") {
|
|
Building.writeLine(%cmp);
|
|
}
|
|
}
|
|
|
|
if (!$SaveBuilding::Quiet) {
|
|
warn("Saved to file: \"" @ %file @ "\"");
|
|
warn("Saved pieces: " @ $SaveBuilding::Saved);
|
|
warn("Skipped pieces: " @ $SaveBuilding::Skipped);
|
|
}
|
|
|
|
$SaveBuilding::LastFile = %file;
|
|
|
|
Building.close();
|
|
Building.delete();
|
|
return %file;
|
|
}
|
|
|
|
function writeBuildingComponent(%obj) {
|
|
%dataBlockName = %obj.getDatablock().getName();
|
|
%save = false;
|
|
%save = saveBuildingCheck(%obj);
|
|
if (%save == true) {
|
|
if (%dataBlockName $= "DeployedMSpineRing") // Handled by DeployedMSpine
|
|
return;
|
|
if (%dataBlockName $= "TelePadBeam") // Handled by TelePadDeployedBase
|
|
return;
|
|
if (%dataBlockName $= "DeployedLTarget") // Handled by parent object
|
|
return;
|
|
if (!$SaveBuilding::Quiet)
|
|
echo("Saving: " @ %obj @ " Name: " @ %dataBlockName);
|
|
%buildingPiece = "%building = new (" @ %obj.getClassName() @ ") () {";
|
|
%buildingPiece = %buildingPiece @ "datablock = \"" @ %dataBlockName @ "\";";
|
|
if (%obj.position !$= "") %buildingPiece = %buildingPiece @ "position = \"" @ %obj.position @ "\";";
|
|
if (%obj.rotation !$= "") %buildingPiece = %buildingPiece @ "rotation = \"" @ %obj.rotation @ "\";";
|
|
if (%obj.realScale !$= "") %buildingPiece = %buildingPiece @ "scale = \"" @ %obj.realScale @ "\";";
|
|
else {if (%obj.scale !$= "") %buildingPiece = %buildingPiece @ "scale = \"" @ %obj.scale @ "\";";}
|
|
if (%obj.team !$= "") %buildingPiece = %buildingPiece @ "team = \"" @ %obj.team @ "\";";
|
|
if (%obj.ownerGUID !$= "") %buildingPiece = %buildingPiece @ "ownerGUID = \"" @ %obj.ownerGUID @ "\";";
|
|
if (%obj.needsFit) %buildingPiece = %buildingPiece @ "needsfit = \"" @ %obj.needsFit @ "\";";
|
|
if (%obj.grounded) %buildingPiece = %buildingPiece @ "grounded = \"" @ %obj.grounded @ "\";";
|
|
if (%obj.deployed !$= "") %buildingPiece = %buildingPiece @ "deployed = \"" @ %obj.deployed @ "\";";
|
|
if (%obj.impulse !$= "") %buildingPiece = %buildingPiece @ "impulse = \"" @ %obj.impulse @ "\";";
|
|
if (%obj.velocityMod !$= "") %buildingPiece = %buildingPiece @ "velocityMod = \"" @ %obj.velocityMod @ "\";";
|
|
if (%obj.gravityMod !$= "") %buildingPiece = %buildingPiece @ "gravityMod = \"" @ %obj.gravityMod @ "\";";
|
|
if (%obj.appliedForce !$= "") %buildingPiece = %buildingPiece @ "appliedForce = \"" @ %obj.appliedForce @ "\";";
|
|
if (%obj.powerFreq !$= "") %buildingPiece = %buildingPiece @ "powerFreq = \"" @ %obj.powerFreq @ "\";";
|
|
if (%obj.isSwitchedOff !$= "") %buildingPiece = %buildingPiece @ "isSwitchedOff = \"" @ %obj.isSwitchedOff @ "\";";
|
|
if (%obj.switchRadius !$= "") %buildingPiece = %buildingPiece @ "switchRadius = \"" @ %obj.switchRadius @ "\";";
|
|
if (%obj.holoBlock !$= "") %buildingPiece = %buildingPiece @ "holoBlock = \"" @ %obj.holoBlock @ "\";";
|
|
if (%obj.noSlow !$= "") %buildingPiece = %buildingPiece @ "noSlow = \"" @ %obj.noSlow @ "\";";
|
|
if (%obj.static !$= "") %buildingPiece = %buildingPiece @ "static = \"" @ %obj.static @ "\";";
|
|
if (%obj.timed !$= "") %buildingPiece = %buildingPiece @ "timed = \"" @ %obj.timed @ "\";";
|
|
if (%obj.beamRange !$= "") %buildingPiece = %buildingPiece @ "beamRange = \"" @ %obj.beamRange @ "\";";
|
|
if (%obj.tripMode !$= "") %buildingPiece = %buildingPiece @ "tripMode = \"" @ %obj.tripMode @ "\";";
|
|
if (%obj.fieldMode !$= "") %buildingPiece = %buildingPiece @ "fieldMode = \"" @ %obj.fieldMode @ "\";";
|
|
if (%dataBlockName $= "TelePadDeployedBase") {
|
|
if (%obj.frequency !$= "") %buildingPiece = %buildingPiece @ "frequency = \"" @ %obj.frequency @ "\";";
|
|
if (%obj.teleMode !$= "") %buildingPiece = %buildingPiece @ "teleMode = \"" @ %obj.teleMode @ "\";";
|
|
}
|
|
if (%obj.getType() & $TypeMasks::TurretObjectType) {
|
|
if (%obj.isSeeker !$= "") %buildingPiece = %buildingPiece @ "isSeeker = \"" @ %obj.isSeeker @ "\";";
|
|
%barrel = %obj.getMountedImage(0);
|
|
if (%barrel > 0)
|
|
%buildingPiece = %buildingPiece @ "initialBarrel = \"" @ %barrel.getName() @ "\";";
|
|
}
|
|
%buildingPiece = %buildingPiece @ "};";
|
|
if (%obj.getTarget() != -1) %buildingPiece = %buildingPiece @ "setTargetSensorGroup(%building.getTarget()," @ mAbs(%obj.team) @ ");";
|
|
%buildingPiece = %buildingPiece @ "addToDeployGroup(%building);";
|
|
if (%obj.noSlow !$= "") %buildingPiece = %buildingPiece @ "%building.pzone.delete();%building.pzone = \"\";";
|
|
if (%dataBlockName $= "DeployedEnergizer" || %dataBlockName $= "DeployedStationInventory" || %dataBlockName $= "StationInventory"
|
|
|| %dataBlockName $= "TurretDeployedFloorIndoor" || %dataBlockName $= "TurretDeployedWallIndoor" || %dataBlockName $= "TurretDeployedCeilingIndoor"
|
|
|| %dataBlockName $= "TurretDeployedOutdoor" || %dataBlockName $= "DeployedPulseSensor"
|
|
|| %dataBlockName $= "LaserDeployed" || %dataBlockName $= "MissileRackTurretDeployed" || %dataBlockName $= "DiscTurretDeployed") {
|
|
%buildingPiece = %buildingPiece @ "%building.deploy();";
|
|
if (%dataBlockName $= "StationInventory")
|
|
%buildingPiece = %buildingPiece @ "adjustTrigger(%building);";
|
|
}
|
|
if (%obj.getDatablock().rechargeRate > 0 && !%obj.getDatablock().needsPower) %buildingPiece = %buildingPiece @ "%building.setSelfPowered();";
|
|
if (%obj.getType() & $TypeMasks::TurretObjectType)
|
|
%buildingPiece = %buildingPiece @ "%building.setRechargeRate(%building.getDatablock().rechargeRate);";
|
|
if (%obj.getDataBlock().className $= "Generator" || %obj.getDataBlock().className $= "Switch") {
|
|
if (%obj.isSwitchedOff)
|
|
%buildingPiece = %buildingPiece @ "setTargetName(%building.target,addTaggedString(\"Disabled Frequency\" SPC %building.powerFreq));";
|
|
else
|
|
%buildingPiece = %buildingPiece @ "setTargetName(%building.target,addTaggedString(\"Frequency\" SPC %building.powerFreq));";
|
|
if (%dataBlockName $= "DeployedSwitch")
|
|
%buildingPiece = %buildingPiece @ "setTargetSkin(%building.target,'" @ getTaggedString(getTargetSkin(%obj.target)) @ "');";
|
|
if (!%obj.isSwitchedOff)
|
|
%buildingPiece = %buildingPiece @ "%building.playThread($AmbientThread,\"ambient\");";
|
|
else {
|
|
if (%obj.isSwitchedOff)
|
|
// nb: doubles no. of power switches done, when loading switched off gens
|
|
%buildingPiece = %buildingPiece @ "%building.lastState = \"\";%building.getDataBlock().losePower(%building);";
|
|
}
|
|
}
|
|
$SaveBuilding::Saved++;
|
|
// Ugly, but it works. May be cleaned up later.
|
|
if (isObject(%obj.lTarget)) { // We assume none of the later saved sub-objects need decon targets, could make this a subroutine
|
|
%target = %obj.lTarget;
|
|
%targetDataBlock = %target.getDatablock().getName();
|
|
if (!$SaveBuilding::Quiet)
|
|
echo("Saving: " @ %target @ " Name: " @ %targetDataBlock);
|
|
%buildingPiece = %buildingPiece @ "%target = new StaticShape() {";
|
|
%buildingPiece = %buildingPiece @ "datablock = \"" @ %targetDataBlock @ "\";";
|
|
if (%target.position !$= "") %buildingPiece = %buildingPiece @ "position = \"" @ %target.position @ "\";";
|
|
if (%target.rotation !$= "") %buildingPiece = %buildingPiece @ "rotation = \"" @ %target.rotation @ "\";";
|
|
if (%target.scale !$= "") %buildingPiece = %buildingPiece @ "scale = \"" @ %target.scale @ "\";";
|
|
if (%target.team) %buildingPiece = %buildingPiece @ "team = \"" @ %target.team @ "\";";
|
|
%buildingPiece = %buildingPiece @ "lMain = %building;";
|
|
%buildingPiece = %buildingPiece @ "};";
|
|
%buildingPiece = %buildingPiece @ "%building.lTarget = %target;";
|
|
%buildingPiece = %buildingPiece @ "addToDeployGroup(%target);";
|
|
if (%target.getDatablock().rechargeRate > 0 && !%target.getDatablock().needsPower) %buildingPiece = %buildingPiece @ "%building.setSelfPowered();";
|
|
}
|
|
if (%dataBlockName $= "DeployedMSpine") {
|
|
%left = %obj.left;
|
|
%right = %obj.right;
|
|
if (isObject(%left)) {
|
|
%leftDataBlock = %left.getDatablock().getName();
|
|
if (!$SaveBuilding::Quiet)
|
|
echo("Saving: " @ %left @ " Name: " @ %leftDataBlock);
|
|
%buildingPiece = %buildingPiece @ "%left = new StaticShape() {";
|
|
%buildingPiece = %buildingPiece @ "datablock = \"" @ %leftDataBlock @ "\";";
|
|
if (%left.position !$= "") %buildingPiece = %buildingPiece @ "position = \"" @ %left.position @ "\";";
|
|
if (%left.rotation !$= "") %buildingPiece = %buildingPiece @ "rotation = \"" @ %left.rotation @ "\";";
|
|
if (%left.scale !$= "") %buildingPiece = %buildingPiece @ "scale = \"" @ %left.scale @ "\";";
|
|
if (%left.team) %buildingPiece = %buildingPiece @ "team = \"" @ %left.team @ "\";";
|
|
if (%left.needsFit) %buildingPiece = %buildingPiece @ "needsfit = \"" @ %left.needsFit @ "\";";
|
|
%buildingPiece = %buildingPiece @ "};";
|
|
%buildingPiece = %buildingPiece @ "%building.left = %left;";
|
|
%buildingPiece = %buildingPiece @ "addToDeployGroup(%left);";
|
|
if (%left.getDatablock().rechargeRate > 0 && !%left.getDatablock().needsPower) %buildingPiece = %buildingPiece @ "%building.setSelfPowered();";
|
|
$SaveBuilding::Saved++;
|
|
}
|
|
if (isObject(%right)) {
|
|
%rightDataBlock = %right.getDatablock().getName();
|
|
if (!$SaveBuilding::Quiet)
|
|
echo("Saving: " @ %right @ " Name: " @ %rightDataBlock);
|
|
%buildingPiece = %buildingPiece @ "%right = new StaticShape() {";
|
|
%buildingPiece = %buildingPiece @ "datablock = \"" @ %rightDataBlock @ "\";";
|
|
if (%right.position !$= "") %buildingPiece = %buildingPiece @ "position = \"" @ %right.position @ "\";";
|
|
if (%right.rotation !$= "") %buildingPiece = %buildingPiece @ "rotation = \"" @ %right.rotation @ "\";";
|
|
if (%right.scale !$= "") %buildingPiece = %buildingPiece @ "scale = \"" @ %right.scale @ "\";";
|
|
if (%right.team) %buildingPiece = %buildingPiece @ "team = \"" @ %right.team @ "\";";
|
|
if (%right.needsFit) %buildingPiece = %buildingPiece @ "needsfit = \"" @ %right.needsFit @ "\";";
|
|
%buildingPiece = %buildingPiece @ "};";
|
|
%buildingPiece = %buildingPiece @ "%building.right = %right;";
|
|
%buildingPiece = %buildingPiece @ "addToDeployGroup(%right);";
|
|
if (%right.getDatablock().rechargeRate > 0 && !%right.getDatablock().needsPower) %buildingPiece = %buildingPiece @ "%building.setSelfPowered();";
|
|
$SaveBuilding::Saved++;
|
|
}
|
|
}
|
|
else if (%dataBlockName $= "TelePadDeployedBase") {
|
|
%beam = %obj.beam;
|
|
if (isObject(%beam)) {
|
|
%beamDataBlock = %beam.getDatablock().getName();
|
|
if (!$SaveBuilding::Quiet)
|
|
echo("Saving: " @ %beam @ " Name: " @ %beamDataBlock);
|
|
%buildingPiece = %buildingPiece @ "%beam = new StaticShape() {";
|
|
%buildingPiece = %buildingPiece @ "datablock = \"" @ %beamDataBlock @ "\";";
|
|
if (%beam.position !$= "") %buildingPiece = %buildingPiece @ "position = \"" @ %beam.position @ "\";";
|
|
if (%beam.rotation !$= "") %buildingPiece = %buildingPiece @ "rotation = \"" @ %beam.rotation @ "\";";
|
|
if (%beam.scale !$= "") %buildingPiece = %buildingPiece @ "scale = \"" @ %beam.scale @ "\";";
|
|
%buildingPiece = %buildingPiece @ "};";
|
|
%buildingPiece = %buildingPiece @ "%building.beam = %beam;";
|
|
%buildingPiece = %buildingPiece @ "%beam.playThread(0,\"ambient\");";
|
|
%buildingPiece = %buildingPiece @ "%beam.setThreadDir(0,true);";
|
|
%buildingPiece = %buildingPiece @ "%beam.flashThreadDir = true;";
|
|
%buildingPiece = %buildingPiece @ "setTargetName(%building.target,addTaggedString(\"Frequency\" SPC %building.frequency));";
|
|
}
|
|
}
|
|
else if (%dataBlockName $= "DeployedLogoProjector") {
|
|
%holo = %obj.holo;
|
|
if (isObject(%holo)) {
|
|
%holoDataBlock = %holo.getDatablock().getName();
|
|
if (!$SaveBuilding::Quiet)
|
|
echo("Saving: " @ %holo @ " Name: " @ %holoDataBlock);
|
|
%buildingPiece = %buildingPiece @ "%holo = new StaticShape() {";
|
|
%buildingPiece = %buildingPiece @ "datablock = \"" @ %holoDataBlock @ "\";";
|
|
if (%holo.position !$= "") %buildingPiece = %buildingPiece @ "position = \"" @ %holo.position @ "\";";
|
|
if (%holo.rotation !$= "") %buildingPiece = %buildingPiece @ "rotation = \"" @ %holo.rotation @ "\";";
|
|
if (%holo.scale !$= "") %buildingPiece = %buildingPiece @ "scale = \"" @ %holo.scale @ "\";";
|
|
%buildingPiece = %buildingPiece @ "};";
|
|
%buildingPiece = %buildingPiece @ "%building.holo = %holo;";
|
|
%buildingPiece = %buildingPiece @ "%holo.projector = %building;";
|
|
}
|
|
}
|
|
else if (%dataBlockName $= "DeployedLightBase") {
|
|
%light = %obj.light;
|
|
if (isObject(%light)) {
|
|
%lightDataBlock = %light.getDatablock().getName();
|
|
if (!$SaveBuilding::Quiet)
|
|
echo("Saving: " @ %light @ " Name: " @ %lightDataBlock);
|
|
%buildingPiece = %buildingPiece @ "%light = new Item() {";
|
|
%buildingPiece = %buildingPiece @ "datablock = \"" @ %lightDataBlock @ "\";";
|
|
%buildingPiece = %buildingPiece @ "static = true;";
|
|
%buildingPiece = %buildingPiece @ "};";
|
|
%buildingPiece = %buildingPiece @ "%building.light = %light;";
|
|
%buildingPiece = %buildingPiece @ "%light.lightBase = %building;";
|
|
%buildingPiece = %buildingPiece @ "adjustLight(%building);";
|
|
}
|
|
}
|
|
else if (%dataBlockName $= "DeployedTripwire") {
|
|
%tripField = %obj.tripField;
|
|
if (isObject(%tripField)) {
|
|
%tripFieldDataBlock = %tripField.getDatablock().getName();
|
|
if (!$SaveBuilding::Quiet)
|
|
echo("Saving: " @ %tripField @ " Name: " @ %tripFieldDataBlock);
|
|
%buildingPiece = %buildingPiece @ "%tripField = new ForceFieldBare() {";
|
|
%buildingPiece = %buildingPiece @ "datablock = \"" @ %tripFieldDataBlock @ "\";";
|
|
if (%tripField.scale !$= "") %buildingPiece = %buildingPiece @ "scale = \"" @ %tripField.scale @ "\";";
|
|
%buildingPiece = %buildingPiece @ "};";
|
|
%buildingPiece = %buildingPiece @ "%building.tripField = %tripField;";
|
|
%buildingPiece = %buildingPiece @ "%tripField.pzone.delete();%building.pzone = \"\";";
|
|
}
|
|
%tripTrigger = %obj.tripTrigger;
|
|
if (isObject(%tripTrigger)) {
|
|
%tripTriggerDataBlock = %tripTrigger.getDatablock().getName();
|
|
if (!$SaveBuilding::Quiet)
|
|
echo("Saving: " @ %tripTrigger @ " Name: " @ %tripTriggerDataBlock);
|
|
%buildingPiece = %buildingPiece @ "%tripTrigger = new Trigger() {";
|
|
%buildingPiece = %buildingPiece @ "datablock = \"" @ %tripTriggerDataBlock @ "\";";
|
|
if (%tripTrigger.scale !$= "") %buildingPiece = %buildingPiece @ "scale = \"" @ %tripTrigger.scale @ "\";";
|
|
if (%tripTrigger.polyhedron !$= "") %buildingPiece = %buildingPiece @ "polyhedron = \"" @ %tripTrigger.polyhedron @ "\";";
|
|
%buildingPiece = %buildingPiece @ "};";
|
|
%buildingPiece = %buildingPiece @ "%building.tripTrigger = %tripTrigger;";
|
|
%buildingPiece = %buildingPiece @ "%tripTrigger.baseObj = %building;";
|
|
}
|
|
%buildingPiece = %buildingPiece @ "setTargetName(%building.target,addTaggedString(\"Frequency\" SPC %building.powerFreq));";
|
|
%buildingPiece = %buildingPiece @ "%building.deploy();";
|
|
%buildingPiece = %buildingPiece @ "adjustTripwire(%building);";
|
|
}
|
|
else if (%dataBlockName $= "DeployedEscapePod") {
|
|
%buildingPiece = %buildingPiece @ "adjustEscapePod(%building);";
|
|
%buildingPiece = %buildingPiece @ "escapePodLoop(%building);";
|
|
}
|
|
}
|
|
else {
|
|
if (!$SaveBuilding::Quiet) {
|
|
// warn("Skipping: " @ %obj @ " Name: " @ %dataBlockName);
|
|
}
|
|
%buildingPiece = "";
|
|
$SaveBuilding::Skipped++;
|
|
}
|
|
|
|
return %buildingPiece;
|
|
}
|
|
|
|
// This function saves a building and relocates it to the center of the 'map'
|
|
// Optional switch to put center at lowest part of building
|
|
//
|
|
// NB: Position of objects (such as support beams) is their attachment point,
|
|
// not their actual center. This may give some 'strange' results when centering
|
|
// small buildings
|
|
|
|
function saveBuildingCentered(%cl,%rad,%file,%quiet,%centerAtMinZ) {
|
|
if (%quiet == true) {
|
|
$SaveBuilding::Quiet = true;
|
|
}
|
|
else {
|
|
$SaveBuilding::Quiet = false; // Overwrite
|
|
}
|
|
if (!isObject(%cl)) {
|
|
if (isObject(nameToID(LocalClientConnection))) {
|
|
%cl = nameToID(LocalClientConnection);
|
|
}
|
|
else {
|
|
if ($CurrentClientId) {
|
|
%cl = $CurrentClientId;
|
|
}
|
|
}
|
|
}
|
|
if (%rad < 1) {
|
|
%rad = 100000;
|
|
}
|
|
%buildingCount = 0;
|
|
if (%file $= "") {
|
|
for(%found = true; %found; %buildingCount++ ) {
|
|
%suffix = %buildingCount;
|
|
while (strLen(%suffix) < 5) %suffix = "0" @ %suffix;
|
|
%file = $SaveBuilding::SaveFolder @ %cl.nameBase @ "-" @ $MissionName @ "-" @ %suffix @ ".cs";
|
|
%found = isFile(%file);
|
|
}
|
|
}
|
|
else {
|
|
%file = $SaveBuilding::SaveFolder @ %file;
|
|
}
|
|
|
|
if (isObject(%cl.getControlObject())) {
|
|
%pos = %cl.getControlObject().getPosition();
|
|
}
|
|
if (!%pos) {
|
|
%pos = "0 0 0";
|
|
}
|
|
new fileObject("Building");
|
|
if (!$SaveBuilding::Quiet) {
|
|
warn("Saving to file: \"" @ %file @ "\"");
|
|
}
|
|
Building.openForWrite(%file);
|
|
Building.writeLine("// CONSTRUCTION MOD SAVE FILE");
|
|
Building.writeLine("// This building was saved by \"" @ getField(%cl.nameBase,0) @ "\"");
|
|
Building.writeLine("// This building was created in mission \"" @ $MissionName @ "\"");
|
|
Building.writeLine("");
|
|
|
|
$SaveBuilding::Saved = 0;
|
|
$SaveBuilding::Skipped = 0;
|
|
$SaveBuilding::MaxX = 0;
|
|
$SaveBuilding::MaxY = 0;
|
|
$SaveBuilding::MaxZ = 0;
|
|
$SaveBuilding::MinX = 0;
|
|
$SaveBuilding::MinY = 0;
|
|
$SaveBuilding::MinZ = 0;
|
|
|
|
%firstObj = true;
|
|
initContainerRadiusSearch(%pos,%rad,$TypeMasks::StaticShapeObjectType | $TypeMasks::ForceFieldObjectType | $TypeMasks::ItemObjectType);
|
|
while((%obj = containerSearchNext()) != 0) {
|
|
%compPos = checkBuildingComponentCentered(%obj);
|
|
if (%compPos) {
|
|
%x = getWord(%compPos,0);
|
|
%y = getWord(%compPos,1);
|
|
%z = getWord(%compPos,2);
|
|
if (%x > $SaveBuilding::MaxX || %firstObj) {$SaveBuilding::MaxX = %x;}
|
|
if (%y > $SaveBuilding::MaxY || %firstObj) {$SaveBuilding::MaxY = %y;}
|
|
if (%z > $SaveBuilding::MaxZ || %firstObj) {$SaveBuilding::MaxZ = %z;}
|
|
if (%x < $SaveBuilding::MinX || %firstObj) {$SaveBuilding::MinX = %x;}
|
|
if (%y < $SaveBuilding::MinY || %firstObj) {$SaveBuilding::MinY = %y;}
|
|
if (%z < $SaveBuilding::MinZ || %firstObj) {$SaveBuilding::MinZ = %z;}
|
|
%firstObj = false;
|
|
}
|
|
}
|
|
|
|
$SaveBuilding::SizeX = $SaveBuilding::MaxX - $SaveBuilding::MinX;
|
|
$SaveBuilding::SizeY = $SaveBuilding::MaxY - $SaveBuilding::MinY;
|
|
$SaveBuilding::SizeZ = $SaveBuilding::MaxZ - $SaveBuilding::MinZ;
|
|
|
|
$SaveBuilding::CenterX = $SaveBuilding::MinX + ($SaveBuilding::SizeX / 2);
|
|
$SaveBuilding::CenterY = $SaveBuilding::MinY + ($SaveBuilding::SizeY / 2);
|
|
if (!%centerAtMinZ) {$SaveBuilding::CenterZ = $SaveBuilding::MinZ + ($SaveBuilding::SizeZ / 2);}
|
|
else {$SaveBuilding::CenterZ = $SaveBuilding::MinZ;}
|
|
|
|
if (isObject($SaveBuilding::TestWaypoint))
|
|
$SaveBuilding::TestWaypoint.delete();
|
|
$SaveBuilding::TestWaypoint = new WayPoint(SaveBuildingWaypoint) {
|
|
position = $SaveBuilding::CenterX SPC $SaveBuilding::CenterY SPC $SaveBuilding::CenterZ;
|
|
rotation = "1 0 0 0";
|
|
scale = "1 1 1";
|
|
dataBlock = "WayPointMarker";
|
|
team = 0;
|
|
name = "Saved Building Center";
|
|
};
|
|
MissionCleanup.add($SaveBuilding::TestWaypoint);
|
|
|
|
initContainerRadiusSearch(%pos,%rad,$TypeMasks::StaticShapeObjectType | $TypeMasks::ForceFieldObjectType | $TypeMasks::ItemObjectType);
|
|
while((%obj = containerSearchNext()) != 0) {
|
|
%cmp = writeBuildingComponentCentered(%obj);
|
|
if (%cmp !$= "") {
|
|
Building.writeLine(%cmp);
|
|
}
|
|
}
|
|
|
|
if (!$SaveBuilding::Quiet) {
|
|
warn("Saved to file: \"" @ %file @ "\"");
|
|
warn("Saved pieces: " @ $SaveBuilding::Saved);
|
|
warn("Skipped pieces: " @ $SaveBuilding::Skipped);
|
|
}
|
|
|
|
$SaveBuilding::LastFile = %file;
|
|
|
|
Building.close();
|
|
Building.delete();
|
|
return %file;
|
|
}
|
|
|
|
function checkBuildingComponentCentered(%obj) {
|
|
%save = false;
|
|
%save = saveBuildingCheck(%obj);
|
|
if (%save == true) {
|
|
%pos = %obj.position;
|
|
%x = getWord(%pos,0);
|
|
%y = getWord(%pos,1);
|
|
%z = getWord(%pos,2);
|
|
%obj.saveBuilding = true;
|
|
return %x SPC %y SPC %z;
|
|
}
|
|
else {
|
|
%obj.saveBuilding = false;
|
|
return;
|
|
}
|
|
}
|
|
|
|
function writeBuildingComponentCentered(%obj) {
|
|
%dataBlockName = %obj.getDatablock().getName();
|
|
%save = false;
|
|
%save = saveBuildingCheck(%obj);
|
|
if (%save == true) {
|
|
if (!$SaveBuilding::Quiet)
|
|
echo("Saving: " @ %obj @ " Name: " @ %dataBlockName);
|
|
%buildingPiece = "%building = new (" @ %obj.getClassName() @ ") () {";
|
|
%buildingPiece = %buildingPiece @ "datablock = \"" @ %dataBlockName @ "\";";
|
|
%pos = %obj.position;
|
|
%x = getWord(%pos,0)-$SaveBuilding::CenterX;
|
|
%y = getWord(%pos,1)-$SaveBuilding::CenterY;
|
|
%z = getWord(%pos,2)-$SaveBuilding::CenterZ;
|
|
%savePos = %x SPC %y SPC %z;
|
|
if (%obj.position !$= "") %buildingPiece = %buildingPiece @ "position = \"" @ %savePos @ "\";";
|
|
if (%obj.rotation !$= "") %buildingPiece = %buildingPiece @ "rotation = \"" @ %obj.rotation @ "\";";
|
|
if (%obj.realScale !$= "") %buildingPiece = %buildingPiece @ "scale = \"" @ %obj.realScale @ "\";";
|
|
else {if (%obj.scale !$= "") %buildingPiece = %buildingPiece @ "scale = \"" @ %obj.scale @ "\";";}
|
|
if (%obj.impulse !$= "") %buildingPiece = %buildingPiece @ "impulse = \"" @ %obj.impulse @ "\";";
|
|
if (%obj.frequency !$= "") %buildingPiece = %buildingPiece @ "frequency = \"" @ %obj.frequency @ "\";";
|
|
%buildingPiece = %buildingPiece @ "};";
|
|
$SaveBuilding::Saved++;
|
|
}
|
|
else {
|
|
if (!$SaveBuilding::Quiet) {
|
|
// warn("Skipping: " @ %obj @ " Name: " @ %dataBlockName);
|
|
}
|
|
%buildingPiece = "";
|
|
$SaveBuilding::Skipped++;
|
|
}
|
|
|
|
return %buildingPiece;
|
|
}
|
|
|
|
function delBuildingWaypoint() {
|
|
if (isObject($SaveBuilding::TestWaypoint))
|
|
$SaveBuilding::TestWaypoint.delete();
|
|
}
|
|
|
|
function loadBuilding(%file) {
|
|
compile($SaveBuilding::SaveFolder @ %file); // Just in case it bombs out
|
|
exec($SaveBuilding::SaveFolder @ %file);
|
|
}
|
|
|
|
function saveBuildingTimer(%timeInSeconds,%globalEcho,%file,%useMultipleFiles,%isScheduled,%threadCount) {
|
|
if (!%isScheduled) {
|
|
$SaveBuilding::TimerCount++;
|
|
$SaveBuilding::TimerTime = %timeInSeconds * 1000;
|
|
if ($SaveBuilding::TimerTime < 1)
|
|
$SaveBuilding::TimerTime = $SaveBuilding::TimerDefaultTime;
|
|
$SaveBuilding::TimerFile = %file;
|
|
if ($SaveBuilding::TimerFile $= "" || $SaveBuilding::TimerFile $= "0")
|
|
$SaveBuilding::TimerFile = "SaveBuildingTimer.cs";
|
|
if (%useMultipleFiles)
|
|
$SaveBuilding::TimerFile = "";
|
|
$SaveBuilding::TimerGlobalChatEcho = %globalEcho;
|
|
$SaveBuilding::TimerEnabled = true;
|
|
%threadCount = $SaveBuilding::TimerCount;
|
|
}
|
|
if ($SaveBuilding::TimerEnabled == true && $SaveBuilding::TimerCount == %threadCount && isObject("MissionCleanup/Deployables")) {
|
|
%file = saveBuilding(0,0,$SaveBuilding::TimerFile,true,true);
|
|
%timeToNextSave = mFloatLength($SaveBuilding::TimerTime / 60 / 1000,2);
|
|
%timeToNextSaveMinutes = mFloor(%timeToNextSave);
|
|
%timeToNextSaveSeconds = mFloor((%timeToNextSave - %timeToNextSaveMinutes) * 60);
|
|
%timeToNextSave = %timeToNextSaveMinutes @ "m, " @ %timeToNextSaveSeconds @ "s";
|
|
%filespec = "\"" @ %file @ "\"";
|
|
if ($SaveBuilding::TimerFile $= "")
|
|
%filespec = %filespec @ " (using multiple files)";
|
|
warn("-SaveBuildingTimer- Saved to: " @ %filespec @ " - Timer: " @ %timeToNextSave);
|
|
if ($SaveBuilding::TimerGlobalChatEcho)
|
|
MessageAll('msgClient',"\c2Buildings saved. Next save in " @ %timeToNextSave);
|
|
if ($SaveBuilding::TimerTime > 0) // Extra safety
|
|
schedule($SaveBuilding::TimerTime,0,saveBuildingTimer,0,0,0,0,true,%threadCount);
|
|
}
|
|
else {
|
|
warn("-SaveBuildingTimer- Thread " @ %threadCount @ " disabled. Last active thread: " @ $SaveBuilding::TimerCount);
|
|
}
|
|
}
|
|
|
|
// NB: This function does not setup default parameters
|
|
function saveBuildingTimerOn() {
|
|
if ($SaveBuilding::TimerTime < 1) {
|
|
$SaveBuilding::TimerTime = $SaveBuilding::TimerDefaultTime;
|
|
}
|
|
$SaveBuilding::TimerCount++;
|
|
$SaveBuilding::TimerEnabled = true;
|
|
saveBuildingTimer(0,0,0,0,true,$SaveBuilding::TimerCount);
|
|
}
|
|
|
|
function saveBuildingTimerOff() {
|
|
$SaveBuilding::TimerEnabled = false;
|
|
}
|
|
|
|
function delDupPieces(%cl,%rad,%quiet) {
|
|
%randomTime = 10000;
|
|
if (%quiet == true) {
|
|
$SaveBuilding::Quiet = true;
|
|
}
|
|
else {
|
|
$SaveBuilding::Quiet = false; // Overwrite
|
|
}
|
|
if (!isObject(%cl)) {
|
|
if (isObject(nameToID(LocalClientConnection))) {
|
|
%cl = nameToID(LocalClientConnection);
|
|
}
|
|
else {
|
|
if ($CurrentClientId) {
|
|
%cl = $CurrentClientId;
|
|
}
|
|
}
|
|
}
|
|
if (%rad < 1) {
|
|
%rad = 100000;
|
|
}
|
|
if (isObject(%cl.getControlObject())) {
|
|
%pos = %cl.getControlObject().getPosition();
|
|
}
|
|
if (!%pos) {
|
|
%pos = "0 0 0";
|
|
}
|
|
%oldChk = "";
|
|
initContainerRadiusSearch(%pos,%rad,$TypeMasks::StaticShapeObjectType | $TypeMasks::ForceFieldObjectType | $TypeMasks::ItemObjectType);
|
|
while((%obj = containerSearchNext()) != 0) {
|
|
%dataBlockName = %obj.getDatablock().getName();
|
|
%save = saveBuildingCheck(%obj);
|
|
if (%save) {
|
|
// Round down a bit
|
|
%objPos = mFloatLength(getWord(%obj.getPosition(),0),2) SPC mFloatLength(getWord(%obj.getPosition(),1),2) SPC mFloatLength(getWord(%obj.getPosition(),2),2);
|
|
%objRot = mFloatLength(getWord(%obj.rotation,0),2) SPC mFloatLength(getWord(%obj.rotation,1),2) SPC mFloatLength(getWord(%obj.rotation,2),2) SPC mFloatLength(getWord(%obj.rotation,3),2);
|
|
if (%obj.realScale)
|
|
%objScale = %obj.realScale;
|
|
else
|
|
%objScale = %obj.scale;
|
|
if (%dataBlockName $= "DeployedFloor" || %dataBlockName $= "DeployedwWall")
|
|
// This doesn't handle all wWalls, but it helps
|
|
%chk = %dataBlockName SPC %objPos SPC %objScale;
|
|
else
|
|
%chk = %dataBlockName SPC %objPos SPC %objRot SPC %objScale;
|
|
if (%chk $= %oldChk) {
|
|
%deleted++;
|
|
if (!$SaveBuilding::Quiet && %dataBlockName !$= "DeployedMSpineRing")
|
|
warn("Deleting: " @ %oldObj @ " Name: " @ %dataBlockName);
|
|
// from inventoryHud.cs, modified
|
|
%random = getRandom() * %randomTime;
|
|
// Not the best way of doing this..
|
|
if ($SaveBuilding::QuickDelete == true) {
|
|
// Handle special cases
|
|
if (%dataBlockName $= "DeployedMSpine") {
|
|
if (isObject(%oldObj.left)) {
|
|
if (!$SaveBuilding::Quiet)
|
|
warn("Deleting: " @ %oldObj.left @ " Name: " @ %oldObj.left.getDatablock().getName());
|
|
%deleted++;
|
|
remDSurface(%oldObj.left);
|
|
%oldObj.left.delete();
|
|
}
|
|
if (isObject(%oldObj.right)) {
|
|
if (!$SaveBuilding::Quiet)
|
|
warn("Deleting: " @ %oldObj.right @ " Name: " @ %oldObj.right.getDatablock().getName());
|
|
%deleted++;
|
|
remDSurface(%oldObj.right);
|
|
%oldObj.right.delete();
|
|
}
|
|
remDSurface(%oldObj);
|
|
%oldObj.delete();
|
|
}
|
|
else if (%dataBlockName $= "DeployedEscapePod") {
|
|
if (isObject(%oldObj.lTarget)) {
|
|
if (!$SaveBuilding::Quiet)
|
|
warn("Deleting: " @ %oldObj.lTarget @ " Name: " @ %oldObj.lTarget.getDatablock().getName());
|
|
%deleted++;
|
|
remDSurface(%oldObj.lTarget);
|
|
%oldObj.lTarget.delete();
|
|
}
|
|
if (isObject(%oldObj.podVehicle)) {
|
|
if (!$SaveBuilding::Quiet)
|
|
warn("Deleting: " @ %oldObj.podVehicle @ " Name: " @ %oldObj.podVehicle.getDatablock().getName());
|
|
%deleted++;
|
|
%oldObj.podVehicle.delete();
|
|
}
|
|
%oldObj.delete();
|
|
}
|
|
else if (%dataBlockName $= "DeployedMSpineRing") {
|
|
// Nil. Handled by DeployedMSpine
|
|
%deleted--;
|
|
}
|
|
else if (%dataBlockName $= "TelePadBeam") {
|
|
// Nil. Handled by TelePadDeployedBase
|
|
%deleted--;
|
|
}
|
|
else if (%dataBlockName $= "DeployedLTarget") {
|
|
// Nil. Handled by parent object
|
|
%deleted--;
|
|
}
|
|
else {
|
|
if (%oldObj.beam)
|
|
%oldObj.beam.delete();
|
|
if (%oldObj.pzone)
|
|
%oldObj.pzone.delete();
|
|
if (%oldObj.trigger)
|
|
%oldObj.trigger.delete();
|
|
if (%oldObj.lTarget)
|
|
%oldObj.lTarget.delete();
|
|
if (%oldObj.holo)
|
|
%oldObj.holo.delete();
|
|
if (%oldObj.light)
|
|
%oldObj.light.delete();
|
|
if (%oldObj.tripField)
|
|
%oldObj.tripField.delete();
|
|
if (%oldObj.tripTrigger)
|
|
%oldObj.tripTrigger.delete();
|
|
remDSurface(%oldObj);
|
|
%oldObj.delete();
|
|
}
|
|
}
|
|
else {
|
|
// Handle special cases
|
|
if (%dataBlockName $= "DeployedMSpineRing") {
|
|
// Nil. Handled by DeployedMSpine
|
|
}
|
|
else if (%dataBlockName $= "TelePadBeam") {
|
|
// Nil. Handled by TelePadDeployedBase
|
|
}
|
|
else if (%dataBlockName $= "DeployedLTarget") {
|
|
// Nil. Handled by parent object
|
|
}
|
|
else {
|
|
%oldObj.getDataBlock().schedule(%random,"disassemble",0, %oldObj); // Run Item Specific code.
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
%checked++;
|
|
// if (!$SaveBuilding::Quiet)
|
|
// echo("Checking: " @ %obj @ " Name: " @ %dataBlockName);
|
|
}
|
|
%oldChk = %chk;
|
|
%oldObj = %obj;
|
|
}
|
|
else {
|
|
%skipped++;
|
|
// if (!$SaveBuilding::Quiet)
|
|
// warn("Skipping: " @ %obj @ " Name: " @ %dataBlockName);
|
|
}
|
|
}
|
|
|
|
if (!$SaveBuilding::Quiet) {
|
|
warn("Checked pieces: " @ %checked);
|
|
warn("Skipped pieces: " @ %skipped);
|
|
warn("Deleted pieces: " @ %deleted);
|
|
}
|
|
return %randomTime;
|
|
}
|
|
|
|
function updateDeployedCount() {
|
|
Game.clearDeployableMaxes();
|
|
%group = nameToID("MissionCleanup/Deployables");
|
|
%count = %group.getCount();
|
|
for(%i=0;%i<%count;%i++) {
|
|
%obj = %group.getObject(%i);
|
|
%revItem = $ReverseDeployItem[%obj.getDataBlock().getName()];
|
|
if (getWord(%revItem,0) $= "poof")
|
|
%revItem = getWord(%revItem,1);
|
|
if (%revItem !$= "")
|
|
$TeamDeployedCount[%obj.team,%revItem]++;
|
|
}
|
|
}
|