From 1e6ad89251d4376b254254780f7d3baf2bbdb787 Mon Sep 17 00:00:00 2001 From: ChocoTaco Date: Wed, 18 Jun 2025 17:22:29 -0400 Subject: [PATCH] Create spawnDir.cs --- Classic/scripts/autoexec/spawnDir.cs | 107 +++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 Classic/scripts/autoexec/spawnDir.cs diff --git a/Classic/scripts/autoexec/spawnDir.cs b/Classic/scripts/autoexec/spawnDir.cs new file mode 100644 index 0000000..2f3b0cd --- /dev/null +++ b/Classic/scripts/autoexec/spawnDir.cs @@ -0,0 +1,107 @@ +// points players in the diretion of the enemy flag home position when outdoors +// Script By: DarkTiger +// version 1.0 + +function CTFGame::pickTeamSpawn(%game, %team) { + return %game.pickTeamSpawnRot(%team); +} +function LCTFGame::pickTeamSpawn(%game, %team) { + return %game.pickTeamSpawnRot(%team); +} +function SCtFGame::pickTeamSpawn(%game, %team) { + return %game.pickTeamSpawnRot(%team); +} + +function DefaultGame::pickTeamSpawnRot(%game, %team){ +// early exit if no nav graph + if (!navGraphExists()) + { + echo("No navigation graph is present. Build one."); + return -1; + } + + for (%attempt = 0; %attempt < 20; %attempt++) + { + // finds a random spawn sphere + // selects inside/outside on this random sphere + // if the navgraph exists, then uses it to grab a random node as spawn + // location/rotation + %sphere = %game.selectSpawnSphere(%team); + if (%sphere == -1) + { + echo("No spawn spheres found for team " @ %team); + return -1; + } + + %zone = %game.selectSpawnZone(%sphere); + %useIndoor = %zone; + %useOutdoor = !%zone; + if (%zone) + %area = "indoor"; + else + %area = "outdoor"; + + %radius = %sphere.radius; + %sphereTrans = %sphere.getTransform(); + %sphereCtr = getWord(%sphereTrans, 0) @ " " @ getWord(%sphereTrans, 1) @ " " @ getWord(%sphereTrans, 2); //don't need full transform here, just x, y, z + //echo("Selected Sphere is " @ %sphereCtr @ " with a radius of " @ %radius @ " meters. Selecting from " @ %area @ " zone."); + + %avoidThese = $TypeMasks::VehicleObjectType | $TypeMasks::MoveableObjectType | + $TypeMasks::PlayerObjectType | $TypeMasks::TurretObjectType; + + for (%tries = 0; %tries < 10; %tries++) + { + %nodeIndex = navGraph.randNode(%sphereCtr, %radius, %useIndoor, %useOutdoor); + if (%nodeIndex >= 0) + { + %loc = navGraph.randNodeLoc(%nodeIndex); + %adjUp = VectorAdd(%loc, "0 0 1.0"); // don't go much below + + if (ContainerBoxEmpty( %avoidThese, %adjUp, 2.0)) + break; + } + } + + if (%nodeIndex >= 0) + { + %loc = navGraph.randNodeLoc(%nodeIndex); + if (%zone)//spawn indoors + { + %fpos = getWords($TeamFlag[%team == 1 ? 2 : 1].originalPosition,0,2); + %flos = containerRayCast(vectorAdd(%loc,"0 0 1"), vectorAdd(%fpos, "0 0 1"), $TypeMasks::InteriorObjectType | $TypeMasks::StaticTSObjectType | $TypeMasks::ForceFieldObjectType); + if(%flos){// do we have anything inbetween us and the flag if not face it + if(vectorDist(%loc, getWords(%flos,1,3)) < 25){ + //error("indoor" SPC %loc); + %trns = %loc @ " 0 0 1 0"; + %spawnLoc = whereToLook(%trns); + return %spawnLoc; + } + } + //error("outdoor" SPC %loc); + %rot = %game.selectSpawnDir(%loc, %team, %zone); + %spawnLoc = %loc @ %rot; + return %spawnLoc; + } + //error("outdoor" SPC %loc); + %rot = %game.selectSpawnDir(%loc, %team, %zone); + %spawnLoc = %loc @ %rot; + return %spawnLoc; + } + } +} + +//face flag when spawn +function DefaultGame::selectSpawnDir(%game, %loc, %team, %zone){ + %team = %team == 1 ? 2 : 1; + %fpos = getWords($TeamFlag[%team].originalPosition,0,2); + //this used only when spawn loc is not on an interior. This points spawning player to the ctr of spawnshpere + %fpos = setWord(%fpos, 2, 0); + %loc = setWord(%loc, 2, 0); + + if(VectorDist(%loc, %fpos) == 0) + return " 0 0 1 0 "; + + %vec = VectorNormalize(VectorSub(%fpos, %loc)); + %angle = mAcos(getWord(%vec, 1)); + return (%loc < %fpos) ? (" 0 0 1 " @ %angle) : (" 0 0 1 " @ -%angle);// this works some how +}