diff --git a/missions/NewbiesNexus.mis b/missions/NewbiesNexus.mis index 3abbaaf..78f038e 100644 --- a/missions/NewbiesNexus.mis +++ b/missions/NewbiesNexus.mis @@ -13,11 +13,11 @@ //--- OBJECT WRITE BEGIN --- new SimGroup(MissionGroup) { - musicTrack = "ice"; Team_Hunters_timeLimit = "25"; - cdTrack = "5"; - Hunters_timeLimit = "25"; powerCount = "0"; + cdTrack = "5"; + musicTrack = "ice"; + Hunters_timeLimit = "25"; new MissionArea(MissionArea) { area = "-1008 -1032 2144 2080"; @@ -63,14 +63,14 @@ new SimGroup(MissionGroup) { cullDensity = "0.3"; customArea = "0 0 0 0"; + GraphFile = "Scarabrae_nef.nav"; + conjoinBowlDev = "20"; position = "0 0 0 1"; coverage = "0"; rotation = "0 0 0 0"; XDimOverSize = "0"; - GraphFile = "Scarabrae_nef.nav"; - YDimOverSize = "0"; scale = "1 1 1"; - conjoinBowlDev = "20"; + YDimOverSize = "0"; locked = "true"; }; new Sky(Sky) { @@ -267,7 +267,7 @@ new SimGroup(MissionGroup) { homingCount = "0"; team = "0"; - Trigger = "7610"; + Trigger = "4552"; Target = "34"; locked = "false"; }; @@ -280,7 +280,7 @@ new SimGroup(MissionGroup) { homingCount = "0"; team = "0"; - Trigger = "7612"; + Trigger = "4554"; Target = "35"; locked = "false"; }; @@ -303,7 +303,7 @@ new SimGroup(MissionGroup) { homingCount = "0"; team = "0"; - Trigger = "7615"; + Trigger = "4557"; Target = "36"; locked = "false"; }; @@ -400,10 +400,10 @@ new SimGroup(MissionGroup) { lockCount = "0"; homingCount = "0"; + Trigger = "4568"; notReady = "1"; - Trigger = "7626"; - inUse = "Down"; Target = "39"; + inUse = "Down"; }; new Marker(BankSpawn) { position = "-155.307 126.636 243.233"; @@ -412,22 +412,67 @@ new SimGroup(MissionGroup) { seqNum = "0"; msToNext = "1000"; }; - new StaticShape() { - position = "-176.434 144.844 233.142"; - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "BankTeleporter"; - 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 SimGroup(Teleporters) { + + powerCount = "2"; + + new StaticShape() { + position = "-175.467 149.497 233.142"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "BankTeleporter"; + 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!"; + destination = "ATMSpawn"; + }; + new StaticShape() { + position = "-170.634 150.644 233.142"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "BankTeleporter"; + 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!"; + destination = "ATHSpawn"; + }; + new StaticShape() { + position = "-176.634 144.844 233.142"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "BankTeleporter"; + 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!"; + destination = "ATLSpawn"; + }; }; new ForceFieldBare(TractorBeamFront) { position = "-142.101 65.701 103.021"; rotation = "1 0 0 0"; scale = "10 40 140"; dataBlock = "TractorBeamFF"; - velocityMod = "1.0"; + lockCount = "0"; + homingCount = "0"; + gravityMod = "-2.75"; + pz = "4575"; appliedForce = "0 0 0"; + Target = "-1"; + originalscale = "10 40 140"; + velocityMod = "1.0"; + }; + new Trigger(BankWaypointZone) { + position = "-158.549 134.258 240.811"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "WaypointWranglerZone"; + lockCount = "0"; + homingCount = "0"; + polyhedron = "0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 -0.0000000 -1.0000000 -0.0000000 -0.0000000 -0.0000000 1.0000000"; }; }; new SimGroup(AimTrain) { @@ -490,9 +535,8 @@ new SimGroup(MissionGroup) { lockCount = "0"; homingCount = "0"; - destination = "BankSpawn"; - Target = "42"; Desc = "\nWelcome back to the Bank!"; + destination = "BankSpawn"; }; new Marker(ATLSpawn) { position = "-546.054 112.086 223.904"; @@ -502,6 +546,34 @@ new SimGroup(MissionGroup) { msToNext = "1000"; }; }; + new SimGroup(AimTrainMed) { + + powerCount = "0"; + + new Marker(ATMSpawn) { + position = "-203.46 693.682 274.118"; + rotation = "0 0 -1 90"; + scale = "1 1 1"; + seqNum = "0"; + msToNext = "1000"; + }; + new StaticShape(ATMBankTeleport) { + position = "-197.111 696.524 262.891"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "BankTeleporter"; + lockCount = "0"; + homingCount = "0"; + + Target = "44"; + Desc = "\nWelcome back to the Bank!"; + destination = "BankSpawn"; + }; + }; + new SimGroup(AimTrainHigh) { + + powerCount = "0"; + }; }; }; //--- OBJECT WRITE END --- diff --git a/scripts/SkillSectorAimTrainer.cs b/scripts/SkillSectorAimTrainer.cs index 17ae56a..ecf90db 100644 --- a/scripts/SkillSectorAimTrainer.cs +++ b/scripts/SkillSectorAimTrainer.cs @@ -43,6 +43,7 @@ function atsessionCheck(%player) { // $DamageType::Default= 0; $DamageType::Blaster= 1; $DamageType::Plasma= 2; $DamageType::Bullet= 3; $DamageType::Disc= 4; $DamageType::Grenade= 5; $DamageType::Laser= 6; $DamageType::ELF= 7; $DamageType::Mortar= 8; $DamageType::Missile= 9; $DamageType::ShockLance= 10; $DamageType::Mine= 11; $DamageType::Explosion= 12; $DamageType::Impact= 13; // Object to object collisions $DamageType::Ground= 14; // Object to ground collisions $DamageType::Turret= 15; function calcScore(%targetObject, %sourceObject, %damageType, %damage, %position) { + // This is kinda half assed. But what more do you really need? %score = %damage * 100; %directHitOnly = !$AimTrainLowDummies.isMember(%targetObject); switch$(%damageType) { @@ -84,6 +85,12 @@ function DermDummy::damageObject(%data, %targetObject, %sourceObject, %position, // echo("wtf is this then: " @ %this @ " tgt " @ %sourceObject); // } +function AimTrainerInit() { + if (!$DEVMODE) { + findAndReplacePlaceholders(); + } +} + function findAndReplacePlaceholders() { // This is not re-entrant safe, don't call it more than once! $AimTrainLowDummies = new SimSet(); @@ -112,8 +119,3 @@ function findAndReplacePlaceholders() { } %trash.delete(); } - -// Don't replace placeholder entities in development mode -if ($DEVMODE == 0) { - findAndReplacePlaceholders(); -} diff --git a/scripts/SkillSectorGame.cs b/scripts/SkillSectorGame.cs index 66674e2..f996c12 100644 --- a/scripts/SkillSectorGame.cs +++ b/scripts/SkillSectorGame.cs @@ -8,6 +8,42 @@ // Leave it on when editing the map, leave it off when playing the game. $DEVMODE = 1; +// Load the various modes, datablocks and functions. +exec("scripts/SkillSectorTeleporter.cs"); +exec("scripts/SkillSectorAimTrainer.cs"); +exec("scripts/SkillSectorTractorBeam.cs"); +exec("scripts/SkillSectorWaypointWrangler.cs"); + +package SkillSector { + function none() {} +}; + +function SkillSector::initGameVars(%game) { + AimTrainerInit(); + WaypointWranglerInit(); +} + +// No longer dispatching 'primary' waypoints because they can't be made semi-permanent. +function SkillSector::clientMissionDropReady(%game, %client) { + messageClient(%client, 'MsgClientReady',"", %game.class); +// %game.resetScore(%client); +// for(%i = 1; %i <= %game.numTeams; %i++) { +// $Teams[%i].score = 0; +// messageClient(%client, 'MsgCTFAddTeam', "", %i, %game.getTeamName(%i), $flagStatus[%i], $TeamScore[%i]); +// } + //%game.populateTeamRankArray(%client); + //messageClient(%client, 'MsgYourRankIs', "", -1); + messageClient(%client, 'MsgMissionDropInfo', '\c0You are in mission %1 (%2).', $MissionDisplayName, $MissionTypeDisplayName, $ServerName); +// WWDispatchWaypoints(%client); + DefaultGame::clientMissionDropReady(%game, %client); +} + +if ($DEVMODE) { + moveMap.bind(keyboard, "f5", dc); + moveMap.bind(keyboard, "f6", ssrl); + ObserverHUDWeaponList.delete(); +} + // thanks DarkTiger (you can prob list them all via datablockGroup.getCount(); and iterate them all and do echo %obj.getName();) function dumpDatablockNames() { for (%i = 0; %i < datablockgroup.getCount(); %i += 1) { @@ -27,13 +63,3 @@ function ssrl() { function dc() { disconnect(); } - -if ($DEVMODE) { - moveMap.bind(keyboard, "f5", disconnect); - ObserverHUDWeaponList.delete(); -} - -// Load the various modes, datablocks and functions. -exec("scripts/SkillSectorTeleporter.cs"); -exec("scripts/SkillSectorAimTrainer.cs"); -exec("scripts/SkillSectorTractorBeam.cs"); \ No newline at end of file diff --git a/scripts/SkillSectorTractorBeam.cs b/scripts/SkillSectorTractorBeam.cs index 52a772b..7e749dd 100644 --- a/scripts/SkillSectorTractorBeam.cs +++ b/scripts/SkillSectorTractorBeam.cs @@ -17,7 +17,7 @@ datablock ForceFieldBareData(TractorBeamFF) // texture[3] = "skins/forcef4"; // texture[4] = "skins/forcef5"; - framesPerSec = 5; + framesPerSec = 10; numFrames = 5; scrollSpeed = 15; umapping = 1.0; diff --git a/scripts/SkillSectorWaypointWrangler.cs b/scripts/SkillSectorWaypointWrangler.cs new file mode 100644 index 0000000..e746caf --- /dev/null +++ b/scripts/SkillSectorWaypointWrangler.cs @@ -0,0 +1,141 @@ +// I guess there's two kinds of waypoints that I want to wrangle. +// 1. Zone based waypoints +// 2. Point to point waypoints + +// Zone based waypoints are perfect for rooms full of teleporters / switches / etc. +// Zone based waypoint SimGroup should have a 'zone' waypoint that is only shown when the player is outside of the zone, allowing zones to be discovered. + +// Point to point waypoints are perfect for races and leading someone from one end of the map to another. I dunno, like a tutorial. + +// After a lot of reading scripts, engine source code and Ghidra decompiling, I've ascertained that... we're stuck with a bit of an odd structure. +// While it's true that you can allocate 512 TargetManager targets, HUDTargetList is limited to 32 targets exactly. +// Those 32 targets are split across three categories. +// 1 - ClientTarget::AssignedTask +// 15 - ClientTarget::PotentialTask +// 16 - ClientTarget::Waypoint + +// Waypoints can't be removed per-client without extensive modifications, so they're still permament. +// While it's possible to swap the clients team to show them different team waypoints, it doesn't seem worth the hassle. + +// What does that mean for my original intent with this script? Well, it's still achievable... but only by spamming the client. +// PotentialTasks are shown for 2 seconds after they're received. +// The player can show those tasks again by pressing n to summon the task list. +// Instead of trying to train players to press `n` when they want directions/more information... I'll spam them. +// Sending the task every 1900ms means it will arrive well before the last task expires. +// Players will always see a task when they're in the zone, and when they leave the zone, they will expire quickly. +// The oldest task is overwritten, so if someone starts using the chat menu or command circuit to create more tasks, that will still work. + +datablock TriggerData(WaypointWranglerZone) { + tickPeriodMS = 1500; +}; + +function WaypointWranglerZone__onAdd(%this, %obj) { + // New zone added for waypoint wrangling. + echo("Obj: " @ %obj); + echo("New group: " @ %this.getGroup()); +} + +function scanGroupForWWZ(%group) { + if (%group.getName() $= "MissionCleanup") { + // Ignoring a busy group that probably doesn't have WaypointWrangler triggers + return; + } + for (%i = 0; %i < %group.getCount(); %i++) { + %obj = %group.getObject(%i); + if (%obj.getClassName() $= "SimGroup") { + echo("Group detected: " @ %obj.getName()); + scanGroupForWWZ(%obj); + } else if (%obj.getClassName() $= "Trigger" && %obj.getDatablock().getName() $= "WaypointWranglerZone") { + echo("Waypoint detected: " @ %obj.getName()); + $WPZones[$WPZNextFree] = %obj; + $WPZNextFree++; + } + } +} + +function WaypointWranglerInit() { + // Reset WPZone system + $WPZNextFree = 0; + $WPZones[0] = 0; + // Iterate over every group and find relevant triggers + scanGroupForWWZ(MissionGroup); + // Iterate over + // Use zone.getGroup to get their containing group + // Iterate over all the objects in the containing group that have a WPN (waypoint name), put them into a SimSet or array with a name relating to the containing group + // Whenever a player enters the Trigger zone, hide the pimary waypoint associated with the zone and show the other waypoints + // Might make sense to make a flag for 'hide all other primary waypoints inside zone' (useful for point to point races and very busy zones like the Bank) + // This flag might get set automatically if there are too many waypoints in a zone (>10?) + + // This system should prevent players for placing waypoints if they exceed the maximum waypoint count. I don't know how that works so I probably won't do it yet. +} + +// MaxTargets = 512 +// HUDTargetList = 32 + +//%target = createTarget(%flag.waypoint, CTFGame::getTeamName( CTFGame, %flag.team), "", "", 'Base', %flag.team, 0); + +function showWaypoint(%client, %wp) { + echo(%wp.getName()); + echo(%wp.getPosition()); + %client.setTargetId(%wp.target); + commandToClient(%client, 'TaskInfo', %client, -1, false, %wp.getName()); + commandToClient(%client, 'PotentialTask', %client.name, "wub wub", "target name"); + %client.sendTargetTo(%client, false); + // %clRabbit.player.scopeToClient(%cl); + // %visMask = getSensorGroupAlwaysVisMask(%clRabbit.getSensorGroup()); + // %visMask |= (1 << %cl.getSensorGroup()); + // setSensorGroupAlwaysVisMask(%clRabbit.getSensorGroup(), %visMask); + // %cl.setTargetId(%clRabbit.target); + // commandToClient(%cl, 'TaskInfo', %cl, -1, false, "Kill the Rabbit!"); + // commandToClient(%targetClient, 'PotentialTask', %client.name, %client.currentTaskDescription, %targetName); + // %client.sendTargetTo(%targetClient, false); + // %cl.sendTargetTo(%cl, true); +} + +function hideWaypoint() { + +// function clientCmdAcceptedTask(%description) { +// addMessageHudLine("\c3Your current task is:\cr " @ %description); +// } + +// commandToClient(%client, 'TaskInfo', %issueClient, -1, %issueClient.name, %description); +// commandToClient(%client, 'AcceptedTask', %description); + +// %client.sendTargetTo(%client, true); +} + +function debugDispatch() { + %count = ClientGroup.getCount(); + + for (%i = 0; %i < %count; %i++) { + %client = ClientGroup.getObject(%i); + echo("Client: " @ %client); + WWDispatchWaypoints(%client); + } +} + +function WWDispatchWaypoints(%client) { + for (%i = 0; %i < $WPZNextFree; %i++) { + %wp = $WPZones[%i]; + showWaypoint(%client, %wp); + //allocTarget, createTarget + // allocClientTarget is only relevant to other players, it's for creating targets that represent client connections + // Con::addCommand("ClientTarget", "sendToServer", cTargetSendToServer, "target.sendToServer()", 2, 2); + // Con::addCommand("ClientTarget", "createWaypoint", cCreateWaypoint, "target.createWaypoint(text)", 3, 3); + // Con::addCommand("ClientTarget", "addPotentialTask", cAddPotentialTask, "target.addPotentialTask()", 2, 2); + // Con::addCommand("ClientTarget", "setText", cSetText, "target.setText(text)", 3, 3); + // Con::addCommand("ClientTarget", "getTargetId", cGetTargetId, "target.getTargetId()", 2, 2); + // Con::addCommand("createClientTarget", cCreateClientTarget, "createClientTarget(targetId, )", 2, 3); + // Con::addCommand("removeClientTargetType", cRemoveClientTargetType, "removeClientTargetType(client, type)", 3, 3); + // Con::addVariable("clientTargetTimeout", TypeS32, &HUDTargetList::smTargetTimeout); + } +} + + + + + +// Revisiting this concept by looking through the code for dlgDrawText\(.* to find all locations where text is rendered +// Hopefully I can find a more suitable way to render text for these items, but I'm not overly optimistic +// guiShapeNameHud seems relevant to 'directly looking at an object and seeing some text' but that's not quite what I want +// shapeNameHud seems similar \ No newline at end of file