-
Notifications
You must be signed in to change notification settings - Fork 178
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mission system (.missionzip) #3018
Conversation
@CuriousMike56 suggested creating multiplayer challenges using this system: https://forum.rigsofrods.org/threads/mission-system-prototype.3846/#post-19130 |
I added a new mission type: 'stunt'. It uses 2 eventboxes and measures various parameters while travelling between them. This is a demo mission 'Simple Test Ramp' - the start eventbox is at the ramp, the finish eventbox is on the landing ground. |
TODO:
|
hey, It's theJesser from discord :) . We definitely need the ability to add icons onto the overview map for missions as suggested by mike on discord https://discord.com/channels/136544456244461568/189904947649708032/1089317783164166266 |
|
5a32a82
to
3073cb0
Compare
3073cb0
to
38bd008
Compare
Info: https://forum.rigsofrods.org/threads/mission-system-prototype.3846/ Features: * A new mod type is recognized: *.mission - can add terrain objects, procedural roads and races to existing terrain. * A new archive type is recognized: *.missionzip * Mission types: only "race", more to come. * To load a mission, open in-game console and say 'loadmission <filename>' * Unloading missions is not implemented yet, use "top menubar / simulation / reload current terrain" to remove mission. New scripts: * missions.as - like races.as but for missions. An include file. See comments on the top of the file. * mission_default.as - like terrain_default.as but for missions. Does the basic handling of .mission files. * road_utils.as - an include file, does parsing procedural roads using GenericDocument tokenizer. Code changes: * Application.h - new LoaderType value 'LT_Mission' * CacheSystem - added new mod+archive types, added mission details to CacheEntry * GameContext - new function LoadMission() * ConsoleCmd - new object LoadmissionCmd * ScriptEngine - new category MISSION, new callbacks `un/loadMission()`, extended `addFunction()` to work with non-terrain scripts, new constant DEFAULT_MISSION_SCRIPT, updated constant DEFAULT_TERRAIN_SCRIPT * GameScript - extended `spawnObject()` to work with non-terrain scripts. FIXUP: ModCache::FillMissionDetailInfo() - use NAKED_STRINGS flag. FIXUP: Improved error message of `ScriptEngine::invokeLoadMission()`
Codechanges: * TopMenubar - new tab 'Missions', new button "Load a mission" in 'Simulation' tab. * Application - new messages MSG_SIM_UN/LOAD_MISSION_REQUESTED * main.cpp - processing new messages * GameContext - changed LoadMission() to use CacheEntry* * ConsoleCmd - call LoadMission() with CacheEntry* rather than filename. * Terrain.cpp - dispose() - unload mission scripts * ScriptEngine - added `missionEntry` to ScriptUnit, implemented `invokeUnloadMission()` * ModCache - fixed bug in previous commit - misison details not filled. * missions.as - implemented unloading. * mission_default.as - actually try to unload. FIXUP mission unloading - procedural roads not deleting.
The problem was removing collision boxes+tris from collision system was never implemented - the elements were only disabled and hiden, not removed. Changes: * New scripting API: `game.pruneCollisionElements()` - deletes boxes+tris marked for deletion. * missions.as: invoke `game.pruneCollisionElements()` after unloading mission. * CollisionsDebugUI: added button "prune collision elements" which forces the pruning. * ProceduralRoad: fixed missing cleanup of collision mesh. * Utils.h: `std::erase_if()` hack for Microsoft Visual Studio. FIXUP: Collisions Debug UI: fixed typo in "Num collision meshes" FIXUP: Portable `erase_if<>()`
The mission-specific callbacks `loadMission(filename, rg)` and `unloadMission()` were decomissioned; instead the name and RG of the .mission file gets delivered via SE_ANGELSCRIPT_MANIPULATIONS+ASMANIP_SCRIPT_LOADED, (params #6 and #7) and unloading is triggered by SE_ANGELSCRIPT_MANIPULATIONS+ASMANIP_SCRIPT_UNLOADING. This archives the same result with less copypasted callback-invocation code. Minor changes: MANIP_ enum fields got renamed to ASMANIP_ to match C++ with AngelScript. Doxygen docs were added.
I've set out to thoroughly study the race system script by Neorej16. I would like to create an editor for it and make it multiplayer. Then I'd like to extend it with other game modes. First thing I noticed is that there's an extensible callback mechanism - modder can call `races.setCallback()` with callback type and function satisfying `funcdef void RACE_EVENT_CALLBACK(dictionary@);`. When invoked, the function gets all params as dictionary. The available callback types are nicely documented directly in the raceManager setup: ``` // we initialize the callbacks dictionary this.callbacks.set("RaceFinish", null); // when a race was finished this.callbacks.set("RaceCancel", null); // when a race was canceled by any means (race_abort box or forbidden user action) this.callbacks.set("RaceStart", null); // when a race starts this.callbacks.set("AdvanceLap", null); // when a lap is done, but not when the race is done this.callbacks.set("Checkpoint", null); // when a checkpoint is taken (excluding start and finish) this.callbacks.set("NewBestLap", null); // When a new best lap time is set this.callbacks.set("NewBestRace", null);// When a new best race time is set this.callbacks.set("LockedRace", null); // When the user passes the start line of a locked race this.callbacks.set("RaceEvent", null); // When the user passes the start line of a locked race this.callbacks.set("PenaltyEvent", null); // When the user gets in a race_penalty box, handled by the raceEvent method this.callbacks.set("AbortEvent", null); // When the user gets in a race_abort box, handled by the raceEvent method ``` As you can see, there can be only one common callback of every type, and the entry in `this.callbacks` is "type name => function pointer". That's enough though, as each checkpoint has instance name of scheme "checkpoint|$raceID|$sequenceNumber|$splitTrailNumber" (yes, the race system supports tracks with multi-checkpoint split sections!) and this went as parameter to the callback every time. However, there was one callback type other than the rest - cancel point callback. The entry in `this.callback` was "instance name => dictionary", where dictionary held all the info normally embedded in the instance name, and also field named "callback" with the actual function pointer. Apparently the programmer intended to support multiple cancel points, each with it's own callback. I don't understand why, as following the checkpoint mechanic would archieve the same, only instead of 2 functions you'd have one that decides what to do based on the arguments dictionary. Either way, there was a bug in the code: the `cancelPointCount` was never updated, so there could effectively be just one common callback, and it was still broken because as I already wrote it didn't encode info to instance name but kept it inside the `this.callbacks` dictionary. While deciding how to fix it, I noticed there are in total 3 (!) callbacks for race cancelling - the broken cancel points, "AbortEvent" and "RaceCancel". Apparently "RaceCancel" was invoked each time race was aborted for any reason. "AbortEvent", though, would only be invoked when driving through an event box called "race_abort". I fulltext-searched our resources if we have any .ODEF with such eventbox, and no we don't. So either map creators knew, or it went unused. Either way, "AbortEvent" was basically the same thing as the broken cancel points, except that it kept data in instance names like checkpoints do. So I ended up fixing the cancel points by actually redirecting them to "AbortEvent", only ignoring the box name. I'd hate to break Neorej16's code so I tested using modified Auriga Proving Grounds terrain (which uses one cancel point). I added a secondary cancel point and tested they're indeed broken as I thought. Then I tested again with my fix.
Closing this as stale and mostly obsolete:
|
Info:
https://forum.rigsofrods.org/threads/mission-system-prototype.3846/
Features:
New scripts:
New script API:
array<BeamClass@> game.getAllTrucks()
float game.getElapsedTime()
array<BeamClass@> BeamClass.getAllLinkedTrucks()
int BeamClass.getInstanceId()
eventCallbackEx()
- same aseventCallback()
but with extra parameters.SE_EVENTBOX_ENTER
andSE_EVENTBOX_EXIT
terrain.addSurveyMapEntity()
,terrain.delSurveyMapEntities()
Example:
Download the attached file and place it to your 'mods' directory. Note GitHub doesn't allow '.missionzip' extension, so I just used '.zip' - it works the same.
simple2circuit.zip
To test, load the "Simple Test Terrain" (simple2.terrn2), open in-game console and say 'loadmission simple2circuit.mission'.