From 9007aa953250866b786b7ec85c4f38e14eaf1b52 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Tue, 8 Apr 2025 19:50:47 -0500 Subject: [PATCH] basic vehicle eject onDestroyed code leverages Parent to also call the rest of the deletions also fix setdamagedirection for players driving vehicles instead of either on thier own --- .../game/data/DamageModel/DamageModel.tscript | 1 + .../DamageModel/scripts/server/player.tscript | 2 +- .../scripts/server/shapeBase.tscript | 12 +- .../scripts/server/vehicle.tscript | 134 ++++++++++++++++++ 4 files changed, 144 insertions(+), 5 deletions(-) create mode 100644 Templates/BaseGame/game/data/DamageModel/scripts/server/vehicle.tscript diff --git a/Templates/BaseGame/game/data/DamageModel/DamageModel.tscript b/Templates/BaseGame/game/data/DamageModel/DamageModel.tscript index 7e29f7d9e..3268a5b9e 100644 --- a/Templates/BaseGame/game/data/DamageModel/DamageModel.tscript +++ b/Templates/BaseGame/game/data/DamageModel/DamageModel.tscript @@ -21,6 +21,7 @@ function DamageModel::onCreateGameServer(%this) %this.queueExec("./scripts/server/projectile"); %this.queueExec("./scripts/server/weapon"); %this.queueExec("./scripts/server/shapeBase"); + %this.queueExec("./scripts/server/vehicle"); %this.queueExec("./scripts/server/player"); } diff --git a/Templates/BaseGame/game/data/DamageModel/scripts/server/player.tscript b/Templates/BaseGame/game/data/DamageModel/scripts/server/player.tscript index 817ae85c2..b874c9f5c 100644 --- a/Templates/BaseGame/game/data/DamageModel/scripts/server/player.tscript +++ b/Templates/BaseGame/game/data/DamageModel/scripts/server/player.tscript @@ -10,7 +10,7 @@ function PlayerData::damage(%this, %obj, %sourceObject, %position, %damage, %dam %rootObj.applyDamage(%damage); %this.onDamage(%rootObj, %damage); - %this.setDamageDirection(%obj, %sourceObject, %position); + %this.setDamageDirection(%rootObj, %sourceObject, %position); // Deal with client callbacks here because we don't have this // information in the onDamage or onDisable methods diff --git a/Templates/BaseGame/game/data/DamageModel/scripts/server/shapeBase.tscript b/Templates/BaseGame/game/data/DamageModel/scripts/server/shapeBase.tscript index b1aa67448..336f41861 100644 --- a/Templates/BaseGame/game/data/DamageModel/scripts/server/shapeBase.tscript +++ b/Templates/BaseGame/game/data/DamageModel/scripts/server/shapeBase.tscript @@ -128,7 +128,9 @@ function ShapeBaseData::onAdd(%this, %obj) function ShapeBaseData::setDamageDirection(%this, %obj, %sourceObject, %damagePos) { - if (!%obj.client) return; + %client = (%obj.client) ? %obj.client : %obj.getControllingClient(); + if (!%client) return; + if (%damagePos $= "" && isObject(%sourceObject)) { if (%sourceObject.isField(initialPosition)) @@ -153,7 +155,7 @@ function ShapeBaseData::setDamageDirection(%this, %obj, %sourceObject, %damagePo // Rotate damage vector into object space %damageVec = VectorSub(%damagePos, %obj.getWorldBoxCenter()); %damageVec = VectorNormalize(%damageVec); - %damageVec = MatrixMulVector(%obj.client.getCameraObject().getInverseTransform(), %damageVec); + %damageVec = MatrixMulVector(%client.getCameraObject().getInverseTransform(), %damageVec); // Determine largest component of damage vector to get direction %vecComponents = -%damageVec.x SPC %damageVec.x SPC -%damageVec.y SPC %damageVec.y SPC -%damageVec.z SPC %damageVec.z; @@ -169,7 +171,7 @@ function ShapeBaseData::setDamageDirection(%this, %obj, %sourceObject, %damagePo %damageDir = getWord(%vecDirections, %i); } } - commandToClient(%obj.client, 'setDamageDirection', %damageDir); + commandToClient(%client, 'setDamageDirection', %damageDir); } @@ -280,6 +282,8 @@ function ShapeBaseData::onDestroyed(%this, %obj, %state) function ShapeBaseData::onRemove(%this, %obj) { - Parent::onRemove(%this, %obj); + if (isMethod(Parent, "onRemove")) + Parent::onRemove(%this, %obj); + deleteMountchain(%obj); } \ No newline at end of file diff --git a/Templates/BaseGame/game/data/DamageModel/scripts/server/vehicle.tscript b/Templates/BaseGame/game/data/DamageModel/scripts/server/vehicle.tscript new file mode 100644 index 000000000..fec8c9ecd --- /dev/null +++ b/Templates/BaseGame/game/data/DamageModel/scripts/server/vehicle.tscript @@ -0,0 +1,134 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +// Parenting is in place for WheeledVehicleData to VehicleData. This should +// make it easier for people to simply drop in new (generic) vehicles. All that +// the user needs to create is a set of datablocks for the new wheeled vehicle +// to use. This means that no (or little) scripting should be necessary. + +// Special, or unique vehicles however will still require some scripting. They +// may need to override the onAdd() function in order to mount weapons, +// differing tires/springs, etc., almost everything else is taken care of in the +// WheeledVehicleData and VehicleData methods. This helps us by not having to +// duplicate the same code for every new vehicle. + +// In theory this would work for HoverVehicles and FlyingVehicles also, but +// hasn't been tested or fully implemented for those classes -- yet. + +function VehicleData::onAdd(%this, %obj) +{ + %obj.setRechargeRate(%this.rechargeRate); + %obj.setEnergyLevel(%this.MaxEnergy); + %obj.setRepairRate(0); + + if (%obj.mountable || %obj.mountable $= "") + %this.isMountable(%obj, true); + else + %this.isMountable(%obj, false); + + if (%this.nameTag !$= "") + %obj.setShapeName(%this.nameTag); +} + +function VehicleData::onDestroyed(%this, %obj, %state) +{ + //echo("\c4VehicleData::onRemove("@ %this.getName() @", "@ %obj.getClassName() @")"); + // if there are passengers/driver, kick them out + if (!%this.killPassengers) + { + for(%i = 0; %i < %obj.getMountedObjectCount(); %i++) + { + if (%obj.getMountedObject(%i)) + { + %passenger = %obj.getMountedObject(%i); + if (%passenger.isMemberOfClass("Player")) + %passenger.getDataBlock().doDismount(%passenger, true); + } + } + } + Parent::onDestroyed(%this, %obj, %state); +} + +// ---------------------------------------------------------------------------- +// Vehicle player mounting and dismounting +// ---------------------------------------------------------------------------- + +function VehicleData::isMountable(%this, %obj, %val) +{ + %obj.mountable = %val; +} + +function VehicleData::mountPlayer(%this, %vehicle, %player) +{ + //echo("\c4VehicleData::mountPlayer("@ %this.getName() @", "@ %vehicle @", "@ %player.client.nameBase @")"); + + if (isObject(%vehicle) && %vehicle.getDamageState() !$= "Destroyed") + { + %player.startFade(1000, 0, true); + %this.schedule(1000, "setMountVehicle", %vehicle, %player); + %player.schedule(1500, "startFade", 1000, 0, false); + } +} + +function VehicleData::setMountVehicle(%this, %vehicle, %player) +{ + //echo("\c4VehicleData::setMountVehicle("@ %this.getName() @", "@ %vehicle @", "@ %player.client.nameBase @")"); + + if (isObject(%vehicle) && %vehicle.getDamageState() !$= "Destroyed") + { + %node = %this.findEmptySeat(%vehicle, %player); + if (%node >= 0) + { + //echo("\c4Mount Node: "@ %node); + %vehicle.mountObject(%player, %node); + //%player.playAudio(0, MountVehicleSound); + %player.mVehicle = %vehicle; + } + } +} + +function VehicleData::findEmptySeat(%this, %vehicle, %player) +{ + //echo("\c4This vehicle has "@ %this.numMountPoints @" mount points."); + + for (%i = 0; %i < %this.numMountPoints; %i++) + { + %node = %vehicle.getMountNodeObject(%i); + if (%node == 0) + return %i; + } + return -1; +} + +function VehicleData::switchSeats(%this, %vehicle, %player) +{ + for (%i = 0; %i < %this.numMountPoints; %i++) + { + %node = %vehicle.getMountNodeObject(%i); + if (%node == %player || %node > 0) + continue; + + if (%node == 0) + return %i; + } + return -1; +}