From b7e7c780fdd50923b15f3ab093234220698e15fa Mon Sep 17 00:00:00 2001 From: loop <126372784+tribes2@users.noreply.github.com> Date: Tue, 21 Oct 2025 00:27:26 +0100 Subject: [PATCH 1/6] out of ideas tbh --- scripts/SkillSectorGame.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/SkillSectorGame.cs b/scripts/SkillSectorGame.cs index 0e30ab2..2a56d46 100644 --- a/scripts/SkillSectorGame.cs +++ b/scripts/SkillSectorGame.cs @@ -25,7 +25,9 @@ function SkillSector::initGameVars(%game) { function SkillSector::missionLoadDone(%game) { DefaultGame::missionLoadDone(%game); - + + echo("Mission loading..."); + AimTrainerInit(); WaypointWranglerInit(); } From 2425e536c402d8a7e2c91c8a9650507640a70ac2 Mon Sep 17 00:00:00 2001 From: loop <126372784+tribes2@users.noreply.github.com> Date: Tue, 21 Oct 2025 00:51:35 +0100 Subject: [PATCH 2/6] mislabelled game methods --- scripts/SkillSectorGame.cs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/scripts/SkillSectorGame.cs b/scripts/SkillSectorGame.cs index 2a56d46..dab0c11 100644 --- a/scripts/SkillSectorGame.cs +++ b/scripts/SkillSectorGame.cs @@ -15,15 +15,13 @@ exec("scripts/SkillSectorAimTrainer.cs"); exec("scripts/SkillSectorTractorBeam.cs"); exec("scripts/SkillSectorWaypointWrangler.cs"); -package SkillSector { - function none() {} -}; - -function SkillSector::initGameVars(%game) { -} +// package SkillSector { +// function none() {} +// }; -function SkillSector::missionLoadDone(%game) { +function SkillSectorGame::missionLoadDone(%game) +{ DefaultGame::missionLoadDone(%game); echo("Mission loading..."); @@ -32,8 +30,12 @@ function SkillSector::missionLoadDone(%game) { WaypointWranglerInit(); } +function SkillSectorGame::initGameVars(%game) +{ +} + // No longer dispatching 'primary' waypoints because they can't be made semi-permanent. -function SkillSector::clientMissionDropReady(%game, %client) { +function SkillSectorGame::clientMissionDropReady(%game, %client) { messageClient(%client, 'MsgClientReady',"", %game.class); // %game.resetScore(%client); // for(%i = 1; %i <= %game.numTeams; %i++) { From dd0729faa9a5cc38f3f379f768cd8ad18fc13bca Mon Sep 17 00:00:00 2001 From: loop <126372784+tribes2@users.noreply.github.com> Date: Tue, 21 Oct 2025 15:00:23 +0100 Subject: [PATCH 3/6] SSWW: add shutdown functionality to fix a bug where TargetInfo would be emitted in unrelated missions. add some more teleporters, add some placeholders for the medium difficulty aim trainer --- missions/NewbiesNexus.mis | 126 +++++++++++++++++++------ scripts/SkillSectorGame.cs | 13 ++- scripts/SkillSectorWaypointWrangler.cs | 7 ++ 3 files changed, 113 insertions(+), 33 deletions(-) diff --git a/missions/NewbiesNexus.mis b/missions/NewbiesNexus.mis index b4ce1b9..bc7c8fb 100644 --- a/missions/NewbiesNexus.mis +++ b/missions/NewbiesNexus.mis @@ -13,11 +13,11 @@ //--- OBJECT WRITE BEGIN --- new SimGroup(MissionGroup) { - cdTrack = "5"; - powerCount = "0"; - Hunters_timeLimit = "25"; - Team_Hunters_timeLimit = "25"; musicTrack = "ice"; + Team_Hunters_timeLimit = "25"; + powerCount = "0"; + cdTrack = "5"; + Hunters_timeLimit = "25"; new MissionArea(MissionArea) { area = "-1008 -1032 2144 2080"; @@ -54,8 +54,8 @@ new SimGroup(MissionGroup) { squareSize = "8"; position = "-1024 -1024 0"; - hazeDistance = "250"; visibleDistance = "1200"; + hazeDistance = "250"; locked = "true"; }; new NavigationGraph(NavGraph) { @@ -63,14 +63,14 @@ new SimGroup(MissionGroup) { cullDensity = "0.3"; customArea = "0 0 0 0"; - GraphFile = "Scarabrae_nef.nav"; position = "0 0 0 1"; - coverage = "0"; - rotation = "0 0 0 0"; - XDimOverSize = "0"; YDimOverSize = "0"; - scale = "1 1 1"; + GraphFile = "Scarabrae_nef.nav"; + rotation = "0 0 0 0"; conjoinBowlDev = "20"; + coverage = "0"; + scale = "1 1 1"; + XDimOverSize = "0"; locked = "true"; }; new Sky(Sky) { @@ -267,7 +267,7 @@ new SimGroup(MissionGroup) { homingCount = "0"; team = "0"; - Trigger = "4552"; + Trigger = "11698"; Target = "34"; locked = "false"; }; @@ -280,7 +280,7 @@ new SimGroup(MissionGroup) { homingCount = "0"; team = "0"; - Trigger = "4554"; + Trigger = "11700"; Target = "35"; locked = "false"; }; @@ -303,7 +303,7 @@ new SimGroup(MissionGroup) { homingCount = "0"; team = "0"; - Trigger = "4557"; + Trigger = "11703"; Target = "36"; locked = "false"; }; @@ -400,10 +400,10 @@ new SimGroup(MissionGroup) { lockCount = "0"; homingCount = "0"; - Trigger = "4568"; + notReady = "1"; + Trigger = "11714"; Target = "39"; inUse = "Down"; - notReady = "1"; }; new Marker(BankSpawn) { position = "-155.307 126.636 243.233"; @@ -424,10 +424,10 @@ new SimGroup(MissionGroup) { lockCount = "0"; homingCount = "0"; - Desc = "Dynamic Aim Trainer\nShoot moving targets while in the air to score points!\nMove faster to score more points and have fun!"; - Target = "40"; wrangle = "Aim Trainer teleports"; + Target = "40"; destination = "ATMSpawn"; + Desc = "Dynamic Aim Trainer\nShoot moving targets while in the air to score points!\nMove faster to score more points and have fun!"; }; new StaticShape(ATHT) { position = "-170.634 150.644 233.142"; @@ -437,9 +437,9 @@ new SimGroup(MissionGroup) { lockCount = "0"; homingCount = "0"; - Desc = "Aim Trainer\nShoot fast moving targets while in the air to score points!\nMove faster to score more points and have fun!"; Target = "41"; destination = "ATHSpawn"; + Desc = "Aim Trainer\nShoot fast moving targets while in the air to score points!\nMove faster to score more points and have fun!"; }; new StaticShape(ATLT) { position = "-176.634 144.844 233.142"; @@ -449,9 +449,35 @@ new SimGroup(MissionGroup) { lockCount = "0"; homingCount = "0"; - Desc = "Static Aim Trainer\nShoot static targets while in the air to score points!\nMove faster to score more points and have fun!"; Target = "42"; destination = "ATLSpawn"; + Desc = "Static Aim Trainer\nShoot static targets while in the air to score points!\nMove faster to score more points and have fun!"; + }; + new StaticShape(DuelZone) { + position = "-170.634 150.644 233.142"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "BankTeleporter"; + lockCount = "0"; + homingCount = "0"; + + wrangle = "Duel zone teleports"; + Target = "43"; + destination = "undefined"; + Desc = "it\'s time to d-d-d-d-d-d-d-duel"; + }; + new StaticShape(FlagPractice) { + position = "-176.634 117.644 233.142"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "BankTeleporter"; + lockCount = "0"; + homingCount = "0"; + + wrangle = "Flag practice teleports"; + Target = "44"; + destination = "undefined"; + Desc = "it\'s time to d-d-d-d-d-d-d-duel"; }; }; new ForceFieldBare(TractorBeamFront) { @@ -463,10 +489,10 @@ new SimGroup(MissionGroup) { homingCount = "0"; gravityMod = "-2.75"; - originalscale = "10 40 140"; appliedForce = "0 0 0"; - pz = "4575"; + originalscale = "10 40 140"; Target = "-1"; + pz = "11723"; velocityMod = "1.0"; }; new Trigger(BankWaypointZone) { @@ -480,6 +506,16 @@ new SimGroup(MissionGroup) { Target = "45"; }; + new WayPoint() { + position = "-158.549 134.258 252.611"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "WayPointMarker"; + lockCount = "0"; + homingCount = "0"; + name = "The Bank"; + team = "0"; + }; }; new SimGroup(AimTrain) { @@ -541,9 +577,9 @@ new SimGroup(MissionGroup) { lockCount = "0"; homingCount = "0"; - Desc = "\nWelcome back to the Bank!"; - Target = "43"; + Target = "45"; destination = "BankSpawn"; + Desc = "\nWelcome back to the Bank!"; }; new Marker(ATLSpawn) { position = "-546.054 112.086 223.904"; @@ -558,23 +594,55 @@ new SimGroup(MissionGroup) { powerCount = "0"; new Marker(ATMSpawn) { - position = "-203.46 693.682 274.118"; - rotation = "0 0 -1 90"; + position = "-283.86 678.282 266.518"; + rotation = "1 0 0 0"; scale = "1 1 1"; seqNum = "0"; msToNext = "1000"; }; new StaticShape(ATMBankTeleport) { - position = "-197.111 696.524 262.891"; - rotation = "1 0 0 0"; + position = "-284.511 664.298 254.306"; + rotation = "-1 0 0 9.99997"; scale = "1 1 1"; dataBlock = "BankTeleporter"; lockCount = "0"; homingCount = "0"; - Desc = "\nWelcome back to the Bank!"; - Target = "44"; + Target = "46"; destination = "BankSpawn"; + Desc = "\nWelcome back to the Bank!"; + }; + new TSStatic(LeftPlaceholder) { + position = "-419.363 775.104 251.039"; + rotation = "0 0 1 180"; + scale = "1 1 1"; + shapeName = "statue_hmale.dts"; + + placeholder = "1"; + }; + new TSStatic(MidPlaceholder) { + position = "-340.323 809.004 247.674"; + rotation = "0 0 -1 90"; + scale = "1 1 1"; + shapeName = "statue_lfemale.dts"; + + placeholder = "1"; + }; + new TSStatic(RightPlaceholder) { + position = "-229.983 815.217 248.474"; + rotation = "0 0 1 180"; + scale = "1 1 1"; + shapeName = "statue_lfemale.dts"; + + placeholder = "1"; + }; + new TSStatic(JetPlaceholder) { + position = "-210.451 631.718 267.535"; + rotation = "0 0 1 180"; + scale = "1 1 1"; + shapeName = "statue_lfemale.dts"; + + placeholder = "1"; }; }; new SimGroup(AimTrainHigh) { diff --git a/scripts/SkillSectorGame.cs b/scripts/SkillSectorGame.cs index dab0c11..95b71e3 100644 --- a/scripts/SkillSectorGame.cs +++ b/scripts/SkillSectorGame.cs @@ -20,8 +20,7 @@ exec("scripts/SkillSectorWaypointWrangler.cs"); // }; -function SkillSectorGame::missionLoadDone(%game) -{ +function SkillSectorGame::missionLoadDone(%game) { DefaultGame::missionLoadDone(%game); echo("Mission loading..."); @@ -30,8 +29,7 @@ function SkillSectorGame::missionLoadDone(%game) WaypointWranglerInit(); } -function SkillSectorGame::initGameVars(%game) -{ +function SkillSectorGame::initGameVars(%game) { } // No longer dispatching 'primary' waypoints because they can't be made semi-permanent. @@ -49,6 +47,13 @@ function SkillSectorGame::clientMissionDropReady(%game, %client) { DefaultGame::clientMissionDropReady(%game, %client); } + +function SkillSectorGame::gameOver(%game) { + DefaultGame::gameOver(%game); + + WaypointWranglerShutdown(); +} + if ($DEVMODE) { moveMap.unbind(keyboard, "f5"); moveMap.unbind(keyboard, "f6"); diff --git a/scripts/SkillSectorWaypointWrangler.cs b/scripts/SkillSectorWaypointWrangler.cs index d432ec1..8608e6a 100644 --- a/scripts/SkillSectorWaypointWrangler.cs +++ b/scripts/SkillSectorWaypointWrangler.cs @@ -42,6 +42,13 @@ function WaypointWranglerZone::onLeaveTrigger(%this, %trigger, %obj) { function WaypointWranglerZone::onTickTrigger(%this, %trigger) { } +function ShutdownWaypointWrangler() { + %count = ClientGroup.getCount(); + for (%i = 0; %i < %count; %i++) { + cancel(ClientGroup.getObject(%i).wwsched); + } +} + function scanZoneForWaypoints(%group) { for (%i = 0; %i < %group.getCount(); %i++) { %obj = %group.getObject(%i); From bb8b6bd6c8ffd185801fdab9bb529d5551cf9872 Mon Sep 17 00:00:00 2001 From: loop <126372784+tribes2@users.noreply.github.com> Date: Thu, 23 Oct 2025 23:28:24 +0100 Subject: [PATCH 4/6] SSFT: added flag training basics, rename init funcs a little --- .gitignore | 1 + missions/NewbiesNexus.mis | 114 +++++++++++++++------ scripts/SkillSectorAimTrainer.cs | 2 +- scripts/SkillSectorFlagTrainer.cs | 136 +++++++++++++++++++++++++ scripts/SkillSectorGame.cs | 13 ++- scripts/SkillSectorWaypointWrangler.cs | 2 +- 6 files changed, 232 insertions(+), 36 deletions(-) create mode 100644 scripts/SkillSectorFlagTrainer.cs diff --git a/.gitignore b/.gitignore index 15142b1..ac4bed0 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ lighting/ prefs/ gui/ recordings/ +fonts/ Classic* # scripts folder need to be ignored and then exclusions have to be carved out diff --git a/missions/NewbiesNexus.mis b/missions/NewbiesNexus.mis index bc7c8fb..08cd0cc 100644 --- a/missions/NewbiesNexus.mis +++ b/missions/NewbiesNexus.mis @@ -13,10 +13,10 @@ //--- OBJECT WRITE BEGIN --- new SimGroup(MissionGroup) { - musicTrack = "ice"; Team_Hunters_timeLimit = "25"; - powerCount = "0"; + musicTrack = "ice"; cdTrack = "5"; + powerCount = "0"; Hunters_timeLimit = "25"; new MissionArea(MissionArea) { @@ -53,9 +53,9 @@ new SimGroup(MissionGroup) { terrainFile = "Scarabrae_nef.ter"; squareSize = "8"; + hazeDistance = "250"; position = "-1024 -1024 0"; visibleDistance = "1200"; - hazeDistance = "250"; locked = "true"; }; new NavigationGraph(NavGraph) { @@ -65,9 +65,9 @@ new SimGroup(MissionGroup) { position = "0 0 0 1"; YDimOverSize = "0"; + conjoinBowlDev = "20"; GraphFile = "Scarabrae_nef.nav"; rotation = "0 0 0 0"; - conjoinBowlDev = "20"; coverage = "0"; scale = "1 1 1"; XDimOverSize = "0"; @@ -244,8 +244,8 @@ new SimGroup(MissionGroup) { lockCount = "0"; homingCount = "0"; - team = "0"; Target = "33"; + team = "0"; locked = "false"; }; new InteriorInstance() { @@ -266,9 +266,9 @@ new SimGroup(MissionGroup) { lockCount = "0"; homingCount = "0"; - team = "0"; - Trigger = "11698"; Target = "34"; + team = "0"; + Trigger = "20162"; locked = "false"; }; new StaticShape() { @@ -279,9 +279,9 @@ new SimGroup(MissionGroup) { lockCount = "0"; homingCount = "0"; - team = "0"; - Trigger = "11700"; Target = "35"; + team = "0"; + Trigger = "20164"; locked = "false"; }; new InteriorInstance() { @@ -302,9 +302,9 @@ new SimGroup(MissionGroup) { lockCount = "0"; homingCount = "0"; - team = "0"; - Trigger = "11703"; Target = "36"; + team = "0"; + Trigger = "20167"; locked = "false"; }; }; @@ -400,10 +400,10 @@ new SimGroup(MissionGroup) { lockCount = "0"; homingCount = "0"; - notReady = "1"; - Trigger = "11714"; - Target = "39"; inUse = "Down"; + Target = "39"; + Trigger = "20178"; + notReady = "1"; }; new Marker(BankSpawn) { position = "-155.307 126.636 243.233"; @@ -424,10 +424,10 @@ new SimGroup(MissionGroup) { lockCount = "0"; homingCount = "0"; - wrangle = "Aim Trainer teleports"; Target = "40"; - destination = "ATMSpawn"; + wrangle = "Aim Trainer teleports"; Desc = "Dynamic Aim Trainer\nShoot moving targets while in the air to score points!\nMove faster to score more points and have fun!"; + destination = "ATMSpawn"; }; new StaticShape(ATHT) { position = "-170.634 150.644 233.142"; @@ -438,8 +438,8 @@ new SimGroup(MissionGroup) { homingCount = "0"; Target = "41"; - destination = "ATHSpawn"; Desc = "Aim Trainer\nShoot fast moving targets while in the air to score points!\nMove faster to score more points and have fun!"; + destination = "ATHSpawn"; }; new StaticShape(ATLT) { position = "-176.634 144.844 233.142"; @@ -450,23 +450,23 @@ new SimGroup(MissionGroup) { homingCount = "0"; Target = "42"; - destination = "ATLSpawn"; Desc = "Static Aim Trainer\nShoot static targets while in the air to score points!\nMove faster to score more points and have fun!"; + destination = "ATLSpawn"; }; new StaticShape(DuelZone) { - position = "-170.634 150.644 233.142"; + position = "-140.434 150.844 233.142"; rotation = "1 0 0 0"; scale = "1 1 1"; dataBlock = "BankTeleporter"; lockCount = "0"; homingCount = "0"; - wrangle = "Duel zone teleports"; Target = "43"; - destination = "undefined"; + wrangle = "Duel zone teleports"; Desc = "it\'s time to d-d-d-d-d-d-d-duel"; + destination = "undefined"; }; - new StaticShape(FlagPractice) { + new StaticShape(FTT) { position = "-176.634 117.644 233.142"; rotation = "1 0 0 0"; scale = "1 1 1"; @@ -474,10 +474,10 @@ new SimGroup(MissionGroup) { lockCount = "0"; homingCount = "0"; - wrangle = "Flag practice teleports"; Target = "44"; - destination = "undefined"; - Desc = "it\'s time to d-d-d-d-d-d-d-duel"; + wrangle = "Flag Trainer teleport"; + Desc = "Flag Training Zone\nCatch flags! Throw flags!\nWe love flags!"; + destination = "FTSpawn"; }; }; new ForceFieldBare(TractorBeamFront) { @@ -489,10 +489,10 @@ new SimGroup(MissionGroup) { homingCount = "0"; gravityMod = "-2.75"; - appliedForce = "0 0 0"; originalscale = "10 40 140"; Target = "-1"; - pz = "11723"; + appliedForce = "0 0 0"; + pz = "20187"; velocityMod = "1.0"; }; new Trigger(BankWaypointZone) { @@ -578,8 +578,8 @@ new SimGroup(MissionGroup) { homingCount = "0"; Target = "45"; - destination = "BankSpawn"; Desc = "\nWelcome back to the Bank!"; + destination = "BankSpawn"; }; new Marker(ATLSpawn) { position = "-546.054 112.086 223.904"; @@ -602,15 +602,15 @@ new SimGroup(MissionGroup) { }; new StaticShape(ATMBankTeleport) { position = "-284.511 664.298 254.306"; - rotation = "-1 0 0 9.99997"; + rotation = "-1 0 0 12"; scale = "1 1 1"; dataBlock = "BankTeleporter"; lockCount = "0"; homingCount = "0"; Target = "46"; - destination = "BankSpawn"; Desc = "\nWelcome back to the Bank!"; + destination = "BankSpawn"; }; new TSStatic(LeftPlaceholder) { position = "-419.363 775.104 251.039"; @@ -650,5 +650,59 @@ new SimGroup(MissionGroup) { powerCount = "0"; }; }; + new SimGroup(FlagTrain) { + + powerCount = "0"; + + new Marker(FTSpawn) { + position = "284.013 -543.625 261.344"; + rotation = "0 0 -1 90"; + scale = "1 1 1"; + seqNum = "0"; + msToNext = "1000"; + }; + new StaticShape(FTBankTeleport) { + position = "272.726 -537.15 254.086"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "BankTeleporter"; + lockCount = "0"; + homingCount = "0"; + + Target = "47"; + Desc = "\nWelcome back to the Bank!"; + destination = "BankSpawn"; + }; + new StaticShape() { + position = "264.386 -581.653 232.142"; + rotation = "-1 0 0 15"; + scale = "1 1 1"; + dataBlock = "ExteriorFlagStand"; + lockCount = "0"; + homingCount = "0"; + + Target = "-1"; + }; + new StaticShape() { + position = "247.87 -543.343 249.677"; + rotation = "0 1 0 15"; + scale = "1 1 1"; + dataBlock = "ExteriorFlagStand"; + lockCount = "0"; + homingCount = "0"; + + Target = "-1"; + }; + new StaticShape() { + position = "319.348 -598.244 226.873"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "ExteriorFlagStand"; + lockCount = "0"; + homingCount = "0"; + + Target = "-1"; + }; + }; }; //--- OBJECT WRITE END --- diff --git a/scripts/SkillSectorAimTrainer.cs b/scripts/SkillSectorAimTrainer.cs index ecf90db..f156cf3 100644 --- a/scripts/SkillSectorAimTrainer.cs +++ b/scripts/SkillSectorAimTrainer.cs @@ -85,7 +85,7 @@ function DermDummy::damageObject(%data, %targetObject, %sourceObject, %position, // echo("wtf is this then: " @ %this @ " tgt " @ %sourceObject); // } -function AimTrainerInit() { +function InitAimTrainer() { if (!$DEVMODE) { findAndReplacePlaceholders(); } diff --git a/scripts/SkillSectorFlagTrainer.cs b/scripts/SkillSectorFlagTrainer.cs new file mode 100644 index 0000000..2492681 --- /dev/null +++ b/scripts/SkillSectorFlagTrainer.cs @@ -0,0 +1,136 @@ +// TODO: flag cannon +// TODO: flag collide with stand, return to stand +// TODO: flag goals + +// Time in seconds +$FlagTrainerTossReset = 45; +$FlagTrainerGrabReset = 90; + +function Flag::objectiveInit(%data, %flag) { + %flag.originalPosition = %flag.getTransform(); + $flagPos[%flag.team] = %flag.originalPosition; + %flag.isHome = true; + %flag.carrier = 0; + %flag.grabber = 0; +} + +function initFlagStand(%stand) { + // Give the stand a flag + echo("Found a stand"); + %flag = new Item() { + position = %stand.getPosition(); + className = FlagObj; + dataBlock = "FLAG"; + static = false; + rotate = true; + }; + FlagTrain.add(%flag); + %stand.flag = %flag; + %flag.stand = %stand; + if(%flag.stand) { + %flag.stand.getDataBlock().onFlagReturn(%flag.stand); + } +} + +function scanGroupForFlagStands(%group) { + for (%i = 0; %i < %group.getCount(); %i++) { + %obj = %group.getObject(%i); + if (%obj.getClassName() $= "SimGroup") { + scanGroupForFlagStands(%obj); + } else if (%obj.getClassName() $= "StaticShape" && %obj.getDatablock().getName() $= "ExteriorFlagStand") { + initFlagStand(%obj); + } + } +} + +function SkillSectorGame::InitFlagTrainer() { + if ($DEVMODE) { + // echo("Not putting a flags on stands"); + // return; + } + // Find all the flag stands and give them a flag + scanGroupForFlagStands(FlagTrain); +} + +function SkillSectorGame::playerTouchFlag(%game, %player, %flag) { + if (isObject(%player.holdingFlag)) { + echo("Already holding a flag"); + return; + } + if (isObject(%flag.carrier)) { + echo("Can't pick up a flag that's being carried") + return; + } + %game.playerTouchEnemyFlag(%player, %flag); +// %client = %player.client; +// if ((%flag.carrier $= "") && (%player.getState() !$= "Dead")) +// { +// // z0dd - ZOD, 5/07/04. Cancel the lava return. +// if(isEventPending(%obj.lavaEnterThread)) +// cancel(%obj.lavaEnterThread); + +// //flag isn't held and has been touched by a live player +// if (%client.team == %flag.team) +// %game.playerTouchOwnFlag(%player, %flag); +// else +// %game.playerTouchEnemyFlag(%player, %flag); +// } +// // toggle visibility of the flag +// setTargetRenderMask(%flag.waypoint.getTarget(), %flag.isHome ? 0 : 1); +} + +function SkillSectorGame::playerTouchEnemyFlag(%game, %player, %flag) { + %client = %player.client; + %player.holdingFlag = %flag; //%player has this flag + %flag.carrier = %player; //this %flag is carried by %player + %player.mountImage(FlagImage, $FlagSlot, true, 'dsword'); + + %flag.hide(true); + %flag.startFade(0, 0, false); + if(%flag.stand) + %flag.stand.getDataBlock().onFlagTaken(%flag.stand);//animate, if exterior stand + returnFlagAfter(%flag, $FlagTrainerGrabReset, 'GrabReset'); +} + +function SkillSectorGame::dropFlag(%game, %player) +{ + %player.throwObject(%player.holdingFlag); +// if(%player.holdingFlag > 0) +// { +// if (!%player.client.outOfBounds) +// %player.throwObject(%player.holdingFlag); +// else +// %game.boundaryLoseFlag(%player); +// } +} + +function returnFlag(%flag, %reason) { + if (isObject(%flag.carrier)) { + %flag.carrier.unMountImage($FlagSlot); + %flag.hide(false); + %flag.carrier.holdingFlag = 0; // tell the player they've lost the flag + } + %flag.stand.getDataBlock().onFlagReturn(%flag.stand); + %flag.setTransform(%flag.stand.getTransform()); + //messageClient(%flag.carrier.client, 'MsgFlagReturned', '\c0Flag returned (%1)', %reason); + %flag.carrier = 0; +} + +function returnFlagAfter(%flag, %after, %reason) { + cancel(%flag.returnSched); + %flag.returnSched = schedule(%after*1000, 0, returnFlag, %flag, %reason); + //messageClient(%flag.carrier.client, 'MsgFlagReturnCountdown', '\c0Flag will be returned to stand in %1 seconds (%2)', %after, %reason); +} + +function SkillSectorGame::playerDroppedFlag(%game, %player) { + %client = %player.client; + %flag = %player.holdingFlag; + + %player.unMountImage($FlagSlot); + %flag.hide(false); + + %flag.setTransform(%flag.getTransform()); + returnFlagAfter(%flag, $FlagTrainerTossReset, 'TossReset'); + %player.holdingFlag = 0; + %flag.carrier = 0; +} diff --git a/scripts/SkillSectorGame.cs b/scripts/SkillSectorGame.cs index 95b71e3..223511d 100644 --- a/scripts/SkillSectorGame.cs +++ b/scripts/SkillSectorGame.cs @@ -14,9 +14,13 @@ exec("scripts/SkillSectorTeleporter.cs"); exec("scripts/SkillSectorAimTrainer.cs"); exec("scripts/SkillSectorTractorBeam.cs"); exec("scripts/SkillSectorWaypointWrangler.cs"); +exec("scripts/SkillSectorFlagTrainer.cs"); -// package SkillSector { -// function none() {} +// package SkillSectorGame { +// function EditorSaveMissionMenu() { +// // Delete all flags, they're spawned at 'boot' +// parent::EditorSaveMissionMenu(); +// } // }; @@ -25,8 +29,9 @@ function SkillSectorGame::missionLoadDone(%game) { echo("Mission loading..."); - AimTrainerInit(); - WaypointWranglerInit(); + InitAimTrainer(); + InitWaypointWrangler(); + %game.InitFlagTrainer(); } function SkillSectorGame::initGameVars(%game) { diff --git a/scripts/SkillSectorWaypointWrangler.cs b/scripts/SkillSectorWaypointWrangler.cs index 8608e6a..3548c58 100644 --- a/scripts/SkillSectorWaypointWrangler.cs +++ b/scripts/SkillSectorWaypointWrangler.cs @@ -90,7 +90,7 @@ function scanGroupForWWZ(%group) { } } -function WaypointWranglerInit() { +function InitWaypointWrangler() { // Reset WPZone system $WPZNextFree = 0; $WPZones[0] = 0; From 9ffd8008d49dc8ba4d458f69a94ba71fb17caea4 Mon Sep 17 00:00:00 2001 From: loop <126372784+tribes2@users.noreply.github.com> Date: Fri, 24 Oct 2025 01:43:24 +0100 Subject: [PATCH 5/6] SSFT: added flag cannon functionality, flag collide with stand 'return' --- missions/NewbiesNexus.mis | 88 +++++++++++++++++++++---------- scripts/SkillSectorFlagTrainer.cs | 84 ++++++++++++++++------------- scripts/SkillSectorGame.cs | 2 + 3 files changed, 109 insertions(+), 65 deletions(-) diff --git a/missions/NewbiesNexus.mis b/missions/NewbiesNexus.mis index 08cd0cc..fdfe2f7 100644 --- a/missions/NewbiesNexus.mis +++ b/missions/NewbiesNexus.mis @@ -13,11 +13,11 @@ //--- OBJECT WRITE BEGIN --- new SimGroup(MissionGroup) { - Team_Hunters_timeLimit = "25"; musicTrack = "ice"; cdTrack = "5"; powerCount = "0"; Hunters_timeLimit = "25"; + Team_Hunters_timeLimit = "25"; new MissionArea(MissionArea) { area = "-1008 -1032 2144 2080"; @@ -53,8 +53,8 @@ new SimGroup(MissionGroup) { terrainFile = "Scarabrae_nef.ter"; squareSize = "8"; - hazeDistance = "250"; position = "-1024 -1024 0"; + hazeDistance = "250"; visibleDistance = "1200"; locked = "true"; }; @@ -64,13 +64,13 @@ new SimGroup(MissionGroup) { customArea = "0 0 0 0"; position = "0 0 0 1"; - YDimOverSize = "0"; conjoinBowlDev = "20"; - GraphFile = "Scarabrae_nef.nav"; rotation = "0 0 0 0"; coverage = "0"; scale = "1 1 1"; XDimOverSize = "0"; + YDimOverSize = "0"; + GraphFile = "Scarabrae_nef.nav"; locked = "true"; }; new Sky(Sky) { @@ -244,8 +244,8 @@ new SimGroup(MissionGroup) { lockCount = "0"; homingCount = "0"; - Target = "33"; team = "0"; + Target = "33"; locked = "false"; }; new InteriorInstance() { @@ -266,9 +266,9 @@ new SimGroup(MissionGroup) { lockCount = "0"; homingCount = "0"; - Target = "34"; team = "0"; - Trigger = "20162"; + Trigger = "34762"; + Target = "34"; locked = "false"; }; new StaticShape() { @@ -279,9 +279,9 @@ new SimGroup(MissionGroup) { lockCount = "0"; homingCount = "0"; - Target = "35"; team = "0"; - Trigger = "20164"; + Trigger = "34764"; + Target = "35"; locked = "false"; }; new InteriorInstance() { @@ -302,9 +302,9 @@ new SimGroup(MissionGroup) { lockCount = "0"; homingCount = "0"; - Target = "36"; team = "0"; - Trigger = "20167"; + Trigger = "34767"; + Target = "36"; locked = "false"; }; }; @@ -400,10 +400,10 @@ new SimGroup(MissionGroup) { lockCount = "0"; homingCount = "0"; + notReady = "1"; + Trigger = "34778"; inUse = "Down"; Target = "39"; - Trigger = "20178"; - notReady = "1"; }; new Marker(BankSpawn) { position = "-155.307 126.636 243.233"; @@ -424,10 +424,10 @@ new SimGroup(MissionGroup) { lockCount = "0"; homingCount = "0"; - Target = "40"; - wrangle = "Aim Trainer teleports"; Desc = "Dynamic Aim Trainer\nShoot moving targets while in the air to score points!\nMove faster to score more points and have fun!"; + wrangle = "Aim Trainer teleports"; destination = "ATMSpawn"; + Target = "40"; }; new StaticShape(ATHT) { position = "-170.634 150.644 233.142"; @@ -437,9 +437,9 @@ new SimGroup(MissionGroup) { lockCount = "0"; homingCount = "0"; - Target = "41"; Desc = "Aim Trainer\nShoot fast moving targets while in the air to score points!\nMove faster to score more points and have fun!"; destination = "ATHSpawn"; + Target = "41"; }; new StaticShape(ATLT) { position = "-176.634 144.844 233.142"; @@ -449,9 +449,9 @@ new SimGroup(MissionGroup) { lockCount = "0"; homingCount = "0"; - Target = "42"; Desc = "Static Aim Trainer\nShoot static targets while in the air to score points!\nMove faster to score more points and have fun!"; destination = "ATLSpawn"; + Target = "42"; }; new StaticShape(DuelZone) { position = "-140.434 150.844 233.142"; @@ -461,10 +461,10 @@ new SimGroup(MissionGroup) { lockCount = "0"; homingCount = "0"; - Target = "43"; - wrangle = "Duel zone teleports"; Desc = "it\'s time to d-d-d-d-d-d-d-duel"; + wrangle = "Duel zone teleports"; destination = "undefined"; + Target = "43"; }; new StaticShape(FTT) { position = "-176.634 117.644 233.142"; @@ -474,10 +474,10 @@ new SimGroup(MissionGroup) { lockCount = "0"; homingCount = "0"; - Target = "44"; - wrangle = "Flag Trainer teleport"; Desc = "Flag Training Zone\nCatch flags! Throw flags!\nWe love flags!"; + wrangle = "Flag Trainer teleport"; destination = "FTSpawn"; + Target = "44"; }; }; new ForceFieldBare(TractorBeamFront) { @@ -489,10 +489,10 @@ new SimGroup(MissionGroup) { homingCount = "0"; gravityMod = "-2.75"; - originalscale = "10 40 140"; - Target = "-1"; appliedForce = "0 0 0"; - pz = "20187"; + originalscale = "10 40 140"; + pz = "34787"; + Target = "-1"; velocityMod = "1.0"; }; new Trigger(BankWaypointZone) { @@ -577,9 +577,9 @@ new SimGroup(MissionGroup) { lockCount = "0"; homingCount = "0"; - Target = "45"; Desc = "\nWelcome back to the Bank!"; destination = "BankSpawn"; + Target = "45"; }; new Marker(ATLSpawn) { position = "-546.054 112.086 223.904"; @@ -608,9 +608,9 @@ new SimGroup(MissionGroup) { lockCount = "0"; homingCount = "0"; - Target = "46"; Desc = "\nWelcome back to the Bank!"; destination = "BankSpawn"; + Target = "46"; }; new TSStatic(LeftPlaceholder) { position = "-419.363 775.104 251.039"; @@ -669,9 +669,9 @@ new SimGroup(MissionGroup) { lockCount = "0"; homingCount = "0"; - Target = "47"; Desc = "\nWelcome back to the Bank!"; destination = "BankSpawn"; + Target = "47"; }; new StaticShape() { position = "264.386 -581.653 232.142"; @@ -703,6 +703,40 @@ new SimGroup(MissionGroup) { Target = "-1"; }; + new StaticShape() { + position = "164.875 -615.487 223.553"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "ExteriorFlagStand"; + lockCount = "0"; + homingCount = "0"; + + Target = "-1"; + }; + new StaticShape() { + position = "264.341 -564.157 241.442"; + rotation = "-1 0 0 40"; + scale = "1 1 1"; + dataBlock = "ExteriorFlagStand"; + lockCount = "0"; + homingCount = "0"; + + flagvel = "0 -25 40"; + cannon = "1"; + Target = "-1"; + }; + new StaticShape() { + position = "310.537 -493.475 229.386"; + rotation = "0.67341 0 0.739269 100"; + scale = "1 1 1"; + dataBlock = "ExteriorFlagStand"; + lockCount = "0"; + homingCount = "0"; + + flagvel = "15 30 40"; + cannon = "1"; + Target = "-1"; + }; }; }; //--- OBJECT WRITE END --- diff --git a/scripts/SkillSectorFlagTrainer.cs b/scripts/SkillSectorFlagTrainer.cs index 2492681..b75a24e 100644 --- a/scripts/SkillSectorFlagTrainer.cs +++ b/scripts/SkillSectorFlagTrainer.cs @@ -1,10 +1,9 @@ -// TODO: flag cannon -// TODO: flag collide with stand, return to stand // TODO: flag goals // Time in seconds $FlagTrainerTossReset = 45; $FlagTrainerGrabReset = 90; +$FlagTrainerCannonInterval = 25; function Flag::objectiveInit(%data, %flag) { %flag.originalPosition = %flag.getTransform(); @@ -14,6 +13,12 @@ function Flag::objectiveInit(%data, %flag) { %flag.grabber = 0; } +function SkillSectorGame::flagStandCollision(%game, %dataBlock, %obj, %colObj) { + if (%colObj.getDatablock().getName() $= "FLAG" && !%colObj.isHome) { + returnFlag(%colObj, 'StandCollide'); + } +} + function initFlagStand(%stand) { // Give the stand a flag echo("Found a stand"); @@ -30,6 +35,23 @@ function initFlagStand(%stand) { if(%flag.stand) { %flag.stand.getDataBlock().onFlagReturn(%flag.stand); } + if (%stand.cannon) { + // Stand is a flag cannon! Fire the missiles! + $Cannons[$CannonCount] = %stand; + $CannonCount++; + flagCannon(%stand); + } +} + +function flagCannon(%stand) { + // Fire flag and schedule another flag fire + %flag = %stand.flag; + if (isObject(%flag)) { + %flag.setVelocity(%stand.flagvel); + cancel(%stand.cannonSched); // don't allow accidental re-queue + %stand.cannonSched = schedule($FlagTrainerCannonInterval*1000, 0, flagCannon, %stand); + returnFlagAfter(%flag, $FlagTrainerCannonInterval-2, 'CannonReset'); + } } function scanGroupForFlagStands(%group) { @@ -46,62 +68,45 @@ function scanGroupForFlagStands(%group) { function SkillSectorGame::InitFlagTrainer() { if ($DEVMODE) { // echo("Not putting a flags on stands"); - // return; + return; } + $CannonCount = 0; // Find all the flag stands and give them a flag scanGroupForFlagStands(FlagTrain); } +function SkillSectorGame::ShutdownFlagTrainer() { + for (%i = 0; %i < $CannonCount; %i++) { + cancel($Cannons[%i].cannonSched); + } +} + function SkillSectorGame::playerTouchFlag(%game, %player, %flag) { if (isObject(%player.holdingFlag)) { - echo("Already holding a flag"); + messageClient(%player.client, 'MsgFlagAlready', '\c0You\'re already holding a flag - don\'t be greedy!'); return; } if (isObject(%flag.carrier)) { - echo("Can't pick up a flag that's being carried") + echo("Can't pick up a flag that's being carried"); return; } %game.playerTouchEnemyFlag(%player, %flag); -// %client = %player.client; -// if ((%flag.carrier $= "") && (%player.getState() !$= "Dead")) -// { -// // z0dd - ZOD, 5/07/04. Cancel the lava return. -// if(isEventPending(%obj.lavaEnterThread)) -// cancel(%obj.lavaEnterThread); - -// //flag isn't held and has been touched by a live player -// if (%client.team == %flag.team) -// %game.playerTouchOwnFlag(%player, %flag); -// else -// %game.playerTouchEnemyFlag(%player, %flag); -// } -// // toggle visibility of the flag -// setTargetRenderMask(%flag.waypoint.getTarget(), %flag.isHome ? 0 : 1); } function SkillSectorGame::playerTouchEnemyFlag(%game, %player, %flag) { %client = %player.client; - %player.holdingFlag = %flag; //%player has this flag - %flag.carrier = %player; //this %flag is carried by %player + %player.holdingFlag = %flag; + %flag.carrier = %player; %player.mountImage(FlagImage, $FlagSlot, true, 'dsword'); - %flag.hide(true); - %flag.startFade(0, 0, false); - if(%flag.stand) - %flag.stand.getDataBlock().onFlagTaken(%flag.stand);//animate, if exterior stand + %flag.hide(true); + %flag.startFade(0, 0, false); + if(%flag.stand) %flag.stand.getDataBlock().onFlagTaken(%flag.stand); returnFlagAfter(%flag, $FlagTrainerGrabReset, 'GrabReset'); } -function SkillSectorGame::dropFlag(%game, %player) -{ +function SkillSectorGame::dropFlag(%game, %player) { %player.throwObject(%player.holdingFlag); -// if(%player.holdingFlag > 0) -// { -// if (!%player.client.outOfBounds) -// %player.throwObject(%player.holdingFlag); -// else -// %game.boundaryLoseFlag(%player); -// } } function returnFlag(%flag, %reason) { @@ -110,16 +115,19 @@ function returnFlag(%flag, %reason) { %flag.hide(false); %flag.carrier.holdingFlag = 0; // tell the player they've lost the flag } - %flag.stand.getDataBlock().onFlagReturn(%flag.stand); + if(%flag.stand) %flag.stand.getDataBlock().onFlagReturn(%flag.stand); + %flag.setVelocity("0 0 0"); %flag.setTransform(%flag.stand.getTransform()); - //messageClient(%flag.carrier.client, 'MsgFlagReturned', '\c0Flag returned (%1)', %reason); + %flag.isHome = true; + //messageClient(%flag.carrier.client, 'MsgFlagReturned', '\c0Flag returned (%1)', %reason); // Kinda annoying, players will figure this out eventually %flag.carrier = 0; } function returnFlagAfter(%flag, %after, %reason) { + %flag.isHome = false; // happens whenever player tosses or picks up flag. also happens when cannon fires cancel(%flag.returnSched); %flag.returnSched = schedule(%after*1000, 0, returnFlag, %flag, %reason); - //messageClient(%flag.carrier.client, 'MsgFlagReturnCountdown', '\c0Flag will be returned to stand in %1 seconds (%2)', %after, %reason); + //messageClient(%flag.carrier.client, 'MsgFlagReturnCountdown', '\c0Flag will be returned to stand in %1 seconds (%2)', %after, %reason); // Kinda annoying, players will figure this out eventually } function SkillSectorGame::playerDroppedFlag(%game, %player) { diff --git a/scripts/SkillSectorGame.cs b/scripts/SkillSectorGame.cs index 223511d..74cec09 100644 --- a/scripts/SkillSectorGame.cs +++ b/scripts/SkillSectorGame.cs @@ -57,6 +57,8 @@ function SkillSectorGame::gameOver(%game) { DefaultGame::gameOver(%game); WaypointWranglerShutdown(); + %game.ShutdownFlagTrainer(); + // deactivatePackage(SkillSectorGame); } if ($DEVMODE) { From 2bbf5c658f166446b91b78e27dae54407d85fd33 Mon Sep 17 00:00:00 2001 From: loop <126372784+tribes2@users.noreply.github.com> Date: Sun, 26 Oct 2025 18:35:44 +0000 Subject: [PATCH 6/6] Update README.md to refocus on core components so I can finish this project and quit Tribes 2, minor changes --- README.md | 45 +++++--------------------- scripts/SkillSectorGame.cs | 5 ++- scripts/SkillSectorTeleporter.cs | 2 +- scripts/SkillSectorWaypointWrangler.cs | 8 +++++ 4 files changed, 21 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index 11c2b19..cbbe8a1 100644 --- a/README.md +++ b/README.md @@ -4,49 +4,20 @@ SkillSector is a game mode for Tribes 2 for building skills you will need to pla # Mode plan Building on the concepts seen in the [Training Grounds](https://github.com/jakraska/Tribes-2-Training-Grounds/) game mode by [jakraska](https://github.com/jakraska), SkillSector hopes to achieve the following features for the following modes.\ -#### Movement and shooting - - [ ] Flying aim training, multiple difficulty levels +#### Aim training + - [x] Static aim training + - [ ] Dynamic aim training + - [ ] LakRabbit aim training +#### Duelling - [ ] Human duel arena(s) - [ ] Robot duel arena(s) #### Flag handling - - [ ] Flag toss practice - - [ ] Baseball machine flag catch practice (CTF, TR2) - - [ ] Human flag practice (CTF, TR2) + - [x] Flag toss practice + - [x] Baseball machine flag catch practice (CTF, TR2) + - [x] Human flag practice (CTF, TR2) #### Toys - [ ] Grav cycle racing - [ ] Ski racing -# Modes -## Flying aim training -### Beginner difficulty -Static targets. Shots will only count when the player is... - - In the air - - Travelling at a minimum velocity - -Different weapons will have different scores based on their 'ease' of hitting a static target.\ -Static targets will be both on the ground and in the air.\ -Hitting a static target with splash damage will count, but won't grant much score compared to a direct hit. - -### Moderate difficulty -Moving targets. Splash damage does not count. Same rules as previous. - -### Advanced difficulty -Fast moving targets. Same rules as previous. - -## Human duel arena(s) -Humans should be able to schedule a duel between themselves. I like the way that TG did it. - -## Robot duel arena(s) -Humans should be able to select from various difficulty robots for dueling. - -## Flag toss/catch practice -Flag tossing and flag catching require a fair bit of practice. Doing so manually or between players - #### auxiliary todo list / odds and ends - noIndividualDamage could be set for the roof's power stations, making it possible to annoy other players by disabling FloatingBank's inventory station(s) - - -# map ideas -# twin towers 9/11 map is a good meme - -# flying aim training thinking \ No newline at end of file diff --git a/scripts/SkillSectorGame.cs b/scripts/SkillSectorGame.cs index 74cec09..ce7e929 100644 --- a/scripts/SkillSectorGame.cs +++ b/scripts/SkillSectorGame.cs @@ -37,6 +37,10 @@ function SkillSectorGame::missionLoadDone(%game) { function SkillSectorGame::initGameVars(%game) { } +function SkillSectorGame::onClientLeaveGame(%client) { + CLWaypointWrangler(%client); +} + // No longer dispatching 'primary' waypoints because they can't be made semi-permanent. function SkillSectorGame::clientMissionDropReady(%game, %client) { messageClient(%client, 'MsgClientReady',"", %game.class); @@ -52,7 +56,6 @@ function SkillSectorGame::clientMissionDropReady(%game, %client) { DefaultGame::clientMissionDropReady(%game, %client); } - function SkillSectorGame::gameOver(%game) { DefaultGame::gameOver(%game); diff --git a/scripts/SkillSectorTeleporter.cs b/scripts/SkillSectorTeleporter.cs index ae2831c..ff2ade8 100644 --- a/scripts/SkillSectorTeleporter.cs +++ b/scripts/SkillSectorTeleporter.cs @@ -38,7 +38,7 @@ function BankTeleporter::onCollision(%data, %obj, %collider) { messageClient(%collider.client, 'MsgStationDenied', '\c2Teleporter is recharging please stand by. ~wfx/powered/nexus_deny.wav'); return; } - messageClient(%collider.client, 'MsgTeleportStart', '\c2Teleporter is calculating transport coherence... ~wfx/misc/nexus_idle.wav'); + //messageClient(%collider.client, 'MsgTeleportStart', '\c2Teleporter is calculating transport coherence... ~wfx/misc/nexus_idle.wav'); %collider.setVelocity("0 0 0"); %collider.setMoveState(true); %collider.startFade(1000, 0, true); diff --git a/scripts/SkillSectorWaypointWrangler.cs b/scripts/SkillSectorWaypointWrangler.cs index 3548c58..4d59155 100644 --- a/scripts/SkillSectorWaypointWrangler.cs +++ b/scripts/SkillSectorWaypointWrangler.cs @@ -42,6 +42,11 @@ function WaypointWranglerZone::onLeaveTrigger(%this, %trigger, %obj) { function WaypointWranglerZone::onTickTrigger(%this, %trigger) { } +function CLWaypointWrangler(%client) { + // cancel any ongoing waypoint wrangler scheduler + cancel(%client.wwsched); +} + function ShutdownWaypointWrangler() { %count = ClientGroup.getCount(); for (%i = 0; %i < %count; %i++) { @@ -112,9 +117,12 @@ function WWDispatch(%client, %zoneIndex) { for (%i = 1; %i < $WPZPoints[%zoneIndex, 0]+1; %i++) { showWaypoint(%client, $WPZPoints[%zoneIndex, %i]); } + cancel(%client.wwsched); // can't be dispatched for more than one zone at once %client.wwsched = schedule(1900, 0, WWDispatch, %client, %zoneIndex); } +// This function is unnecessarily expensive, this lookup could be done by attaching the zone and index to the trigger. +// I'm also too lazy to re-write it now function WWStartWaypointDispatch(%client, %zone) { // echo("zone count:" @ $WPZNextFree); for (%i = 0; %i < $WPZNextFree; %i++) {