Skip to content
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

Created vehicle tuning GUI using new .addonpart mod type #3096

Merged
merged 55 commits into from
Feb 4, 2024

Conversation

ohlidalp
Copy link
Member

@ohlidalp ohlidalp commented Oct 18, 2023

UPDATE 01/2024: For most up-to-date info, please see the Wrapping Up post below.

The master branch has almost everything you need to create a truck editor script. Almost. This PR will fill the blanks. EDIT: After Discord debate, I steered this PR towards a vehicle configuration/tuning system.

So far I've done the most important bit: I've made GenericDocument editable, as originally promised. The GenericDocReaderClass was renamed to GenericDocContextClass and there are new functions:

    bool insertToken(int offset = 0); //!< Inserts `TokenType::NONE`; @return false if offset is beyond EOF
    bool eraseToken(int offset = 0); //!< @return false if offset is beyond EOF

    bool setTokString(int offset, const string&in str);
    bool setTokFloat(int offset, float val);
    bool setTokBool(int offset, bool val);
    bool setTokKeyword(int offset, const string&in str);
    bool setTokComment(int offset, const string&in str);
    bool setTokLineBreak(int offset);

To showcase it, I created an example script - you can run it by opening ingame console and typing loadscript example_GenericDoc_editor.as. It doesn't edit yet, just lets you select tokens with mouse and prints details. Green text is hovered, red text has focus.
obrazek

@CuriousMike56
Copy link
Collaborator

Nice! Hopefully we'll be able to make temporary edits and apply them to the vehicle. Would be fun to mess with, say, engine tunes in real time.

@ohlidalp
Copy link
Member Author

ohlidalp commented Oct 18, 2023

@CuriousMike56 💌 I'd like that too, here's facts:

  • Ideally game would spawn actors directly from a GenericDocument, technically it makes sense but it absolutely requires Parser corrections (nodes2, forset, sectionconfig) #2922 (the parser revert) to be completed first. So not doable now.
  • I could do the same I did with the script editor - add a buffer param to ActorSpawnRequest, making game spawn from memory string rather than file on disk. However, spawning is firmly tied with modcache which makes sense because you want to also load the zip/directory where the file lives. I don't want to hack this, I'll instead explore ad-hoc updating modcache.
  • Right now you must be in menu to update modcache, and it's synchronous (loading dialog). The single (stupid!) reason for this is that CacheEntry-ies are kept in a plan std::vector<CacheEntry> and actors have raw pointers to them (updating std::vector breaks raw pointers). If a cache entry was a RefCountingObject<>, we could simply flag them 'deleted' and insert new ones on-the-go, even in simulation. RepoUI could be used anytime. Minimum dev work, fantastic implications. I'll go this route. EDIT: Done! 🎉
  • Saving the modified actor would best be done directly to 'mods/' directory, possibly to some 'mods/actor_projects' subdir. I'm not going to give users the raw CreateDirectory() function, instead I'd do something like MSG_EDI_CREATE_PROJECT_REQUESTED which creates a subdir and possibly pre-populates it with files from a ZIP. And inserts it to modcache while at that. PS: maybe I'll add a whole new 'Rigs of Rods\projects' dir while at it, since async modcache can easily handle it. EDIT2: Also done 🥳
  • Engine tuning of live actors is a different story, but there is already some code for it: Angelscript vehicle engine bindings #3048 - I may incorporate it here.

@ohlidalp
Copy link
Member Author

ohlidalp commented Oct 19, 2023

You can now do this in AngelScript:

       // Fetch the current actor cache entry
         CacheEntryClass@ src_entry = cache.findEntryByFilename(LOADER_TYPE_ALLBEAM, /*partial:*/false, actor.getTruckFileName());

       // request project to be created from that cache entry
       string proj_name = "project1";
       game.pushMessage(MSG_EDI_CREATE_PROJECT_REQUESTED, {
           {'name', proj_name},
           {'source_entry', src_entry}
       });

The game will create a subdirectory in 'My Games\Rigs of Rods\project' and copy all files from the existing mod ZIP. It will also rename the truck file for you and publish it in modcache. You can look it up under new category "Projects" (catetgory ID 8990). As you can see on the screenshot, the material is glitched but otherwise the project spawns as fully functional actor.
obrazek

The example script does all this. I guess I'm done with this branch for now, if anybody is interested in expanding this, everything can be deduced from docs, demo_script.as or builtin examples.

What doesn't work yet: the cachefile is not updated and modcache regen doesn't yet pick up the new projects directory. Also the new MSG_ and the new modcache objects weren't added to docs yet. Contributions are most welcome.

@ohlidalp
Copy link
Member Author

ohlidalp commented Oct 23, 2023

This is why I started this branch in the first place... While working on the script editor, I prototyped a GridViewer component (#include gridviewer_utils.as) which draws a scrolling/zooming window and lets you draw stuff to it, automatically calculating the zoomed/scrolled positions. It was just collecting dust on my harddisk, and now it's finally at work, with 3 instances and a tokenized document view on the left. Inspired by good ol' Editorizer.. As you can see, axes are off and views are rotated/upside down, but with a hint it's recognizable as DAF semitruck.

obrazek

@ohlidalp ohlidalp force-pushed the MrMayhem_TruckEditorScript branch 8 times, most recently from f4464f3 to 48e5551 Compare October 24, 2023 11:44
@ohlidalp
Copy link
Member Author

ohlidalp commented Oct 24, 2023

Some interesting thoughts from Discord (UPDATE: added "-->" closures):

@ohlidalp
Copy link
Member Author

ohlidalp commented Oct 29, 2023

After Discord debate, I steered this PR towards a vehicle configuration/tuning system.

STATUS: ALPHA! Glitchy, only adding a part works, the remove-button is dummy.
addonpartsPrototype

This adds a new mod type "addonpart" (file pattern *.addonpart) which works as a partial truck file - when selected, it adds additional elements to it. Currently supported features are: managedmaterials, props, flexbodies. The point is to automate what users had to do manually before: https://docs.rigsofrods.org/tools-tutorials/addons/

The addon parts receive all usual treatment from modcache: they can have preview images, name + description are always displayed, they can be searched for, the MainSelectorUI can be opened in mode 'LT_AddonPart' to show only addon parts. In addition, the search can be filtered by a vehicle GUID, much like with SkinZips. This is an example addonpart (port of https://forum.rigsofrods.org/resources/heavy-bumper-for-the-chevy-k3500.461/):

addonpart_name "Heavy Bumper for the Chevy K3500 (Prop, Black)"
addonpart_description "For use with GMT400 88-98 Chevy Truck Pack"

;addonpart_guid <guid>  ~ multiple GUIDs can be specified
addonpart_guid 057b21c8-cb54-496d-88ce-4855a8d6d43d
; * 1990 Chevy 454ss,  * 1990 Chevy k3500    * 1990 Chevy K3500HD
addonpart_guid 6a53ad83-255d-4d5e-bf14-ca0714e5228d
; * 1990 Chevy k2500 Blazer, -SAS, -Suburban

managedmaterials
    CHeavyBumper		mesh_standard		HeavyBumper.dds		HeavyBumper_s.dds

props
    39, 62, 34,    0.50,    0.32,     -0.5,   0,    180,    180, CHeavyBumper.mesh

There's a new menu in TopMenubarUI: "Tuning". It lists already installed addonparts and contains [add parts] button which opens MainSelectorUI in 'LT_AddonPart' mode, with GUID filtering for the current vehicle.

To remember what addonparts user selected, an additional mod type was added: "tuneup" (file pattern *.tuneup) - this works like ".skin for addonparts" and has intentionally similar syntax. There are 2 power tools:

  • "use_addonpart " to install an addonpart on the vehicle (multiple can be used!)
  • "remove_prop " to strip an existing prop from the vehicle.

Note: An option to replace prop was intentionally not implemented because that would be a duplicate feature with addonparts. It's up to user to remove props if and only if they don't want them together with new parts.

When user uses addonpart with a vehicle for the first time, the game creates a .tuneup file for it in {Documents\My Games\Rigs of Rods\projects}. When spawning the vehicle next time, the .tuneup is loaded automatically. In the future the menu will be able to save custom tuneups. Here's an example:

Tuned 1990 Chevy 454ss
{
      use_addonpart = CHeavyBumperBlackProp.addonpart
	preview =
	description =
	author_name = ohlidalp
	author_id = -1
	category_id = 8100
	guid = 057b21c8-cb54-496d-88ce-4855a8d6d43d
}

Under the hood, applying the addonparts to the vehicle works entirely in system memory, no truck files are modified or written.

  • "use_addonpart" works by literally introducing a fake 'section/end_section' to the truck file parsed in memory - see class RigDef::File::Module and function ActorSpawner::ConfigureAddonParts() for details.
  • "remove_prop" works as last-minute check in ActorSpawner::ProcessProp(), skipping props which are blacklisted.

@ohlidalp
Copy link
Member Author

I added GUI for 'remove_prop' directives in .tuneup:
obrazek

The '.tuneup' on display:

// This is a '.tuneup' mod - it's similar to '.skin' mod but deals with '.addonpart' mods.
// See https://github.com/RigsOfRods/rigs-of-rods/pull/3096#issuecomment-1783976601

Tuned 1990 Chevy 454ss
{
	preview = ABCD
	description = EFGT
	author_name = 
	author_id = -1
	category_id = 8100
	guid = 057b21c8-cb54-496d-88ce-4855a8d6d43d

	remove_prop = 454ss_Mirrors.mesh
	remove_prop = Kodiak_Windows.mesh
}

@ohlidalp
Copy link
Member Author

ohlidalp commented Oct 31, 2023

I made the rusted bumper work, which means texture lookup works for .addonpart mods.

Prop-addons are now fully functional; Flexbody addons report "node not found" for all nodes at the moment.

See bottom posts for updated downloads.

obrazek

@ohlidalp
Copy link
Member Author

ohlidalp commented Nov 2, 2023

Saving '.tuneup' presets now works. And I think the UI is not an embarrasement.
I figured a nice confirmation mechanic - just hold the button for 1.5 sec and watch the countdown progressbar.

obrazek

@ohlidalp
Copy link
Member Author

ohlidalp commented Nov 3, 2023

I added the concept of 'unwanted props/flexbodies' to addons and 'protected props/flexbodies' to tuneups.

The .addonpart file can now specify "unwanted" props or flexbodies, to simulate swapping of parts. Under the hood, this works by adding the mesh names to "remove" lists, same as if user disabled them from top menu. Example addonpart:

  ; Add the stock bumpers to 'tuneup.removed_flexbodies' unless user added it to 'tuneup.protected_flexbodies' first.
  addonpart_unwanted_flexbody "K3500_FBump.mesh"
  addonpart_unwanted_flexbody "454ss_FBump.mesh"

The .tuneup file now contains lists of "protected" props and flexbodies which cannot be removed by the addonpart and remain "removed" or not as the user wishes. This lets user force default meshes to be kept or addonpart meshes to not be added (may be useful if the addonpart specifies multiple meshes). Example of protected entry in .tuneup file:

	protected_flexbody = 454ss_FBump.mesh
	protected_flexbody = K3500_FBump.mesh

See bottom posts for updated downloads.

Meshes can be marked 'protected' via new widget in top menubar:
obrazek

@ohlidalp
Copy link
Member Author

ohlidalp commented Nov 6, 2023

By popular demand, I added 'tweaks' in the addonpart system. These directives let you modify existing elements.

There are 2 new directives in the addonpart format:

  • addonpart_tweak_node <nodenum> <posX> <posY> <posZ>
  • addonpart_tweak_wheel <wheel ID> <rim mesh> <tire radius> <rim radius>

See bottom posts for updated downloads.

image

@ohlidalp ohlidalp changed the title Scripting support for truck file editing Created vehicle tuning GUI using new .addonpart mod type Nov 13, 2023
@ohlidalp ohlidalp marked this pull request as ready for review November 13, 2023 19:06
@ohlidalp
Copy link
Member Author

ohlidalp commented Nov 13, 2023

I fixed the last big glitch and renamed the PR to advertise the new main feature. Originally the goal was an example truck editing script, which is present, but the main focus became an addon part system with UI, which doesn't use scripting.

new features so far

  • New directory under 'Documents\My Games\Rigs of Rods': 'projects'. It's processed by modcache (like 'mods' dir), so putting ZIPs here will work, but it's intended to host directories with unpacked WIP mods.
  • New mod type ".addonpart" with syntax similar to .truck. It's processed by modcache like other mods, including mini-image. It can be placed in any ZIP. See above posts for examples.
  • New mod type ".tuneup" with syntax intentionally similar to .skin and very similar functionality. It allows you to remove and tweak certain elements. The main purpose is to let player save their tuned configurations, and also remember the last working state after game exits. Again, see above for examples.
  • New menu in TopMenubar UI, 'Tuning', which automatically displays the available addon parts and existing props/flexbodies, with checkboxes allowing player to apply/remove them. The game remembers the changes user made across sessions (as a 'working tuneup'), to reset it, press and hold the big 'Reset' button. When loading a previously saved tuneup, it overwrites the working one, so further changes to it do not modify the saved tuneup - the player must save again.

scripting extensions so far:

  • GenericDocument is now editable via GenericDocContext (renamed GenericDocReader) - see example script 'example_GenericDoc_editor.as'.
  • New ✉️ MSG_EDI_CREATE_PROJECT_REQUESTED which takes an existing mod as parameter. It automatically unpacks it's files to new directory under 'projects', renames the mod file and sets it's category ID to 'Projects' so that it doesn't show among other mods in the selector - the player must select "Projects" category.
  • New include script 'gridviewer_utils.as' (_utils is my convention for include scripts) - it's a generic zooming/scrolling 2D viewer which lets you draw anything into it using DearIMGUI's ImDrawList API.
  • New script 'example_RigEditor.as' which showcases the GridViewer component and makes use of the new CREATE_PROJECT message to edit existing mods.
  • New ✉️ MSG_EDI_MODIFY_PROJECT_REQUESTED which is internally used by the TopMenubar 'Tuning' menu to make changes to the working .tuneup file, which is itself placed in the projects dir.
  • ModCache is now accessible from AngelScript as new global variable modcache - see documentation of CacheSystemClass.
  • New ✉️ MSG_EDI_LOAD_BUNDLE_REQUESTED
  • New ✉️ MSG_EDI_UNLOAD_BUNDLE_REQUESTED
  • added script event SE_GENERIC_MODCACHE_ACTIVITY
  • added enum modCacheActivityType with fields _ADDED, _DELETED, _LOADED, _RELOADED, _UNLOADED
  • added function modcache.getEntryByNumber(int)
  • added function modcache.query() which takes a dictionary resembling RoR::CacheQuery and returns a dictionary with results. Query dictionary params:
    • "search_expr" - searchstring, recognizes all advanced modes from MainSelectorUI like "author"
    • "filter_guid" - filter by exact match on GUID, used for skins/missions(WIP)/addonparts(WIP)
    • "filter_category_id" - filter by category. Special category Projects is 8990.
      Result dictionary params:
    • "count" (int64)
    • "entries" (array<CacheEntry@>)
    • "scores" (array)

@CuriousMike56
Copy link
Collaborator

In addition to the above, I've realized it is technically possible to create wheel addons that can be applied to almost any vehicle. Only real problem is the wheel side flag, as the direction the wheel mesh faces depends on the vehicle. Would be awesome if the wheel direction could be changed on-the-fly through the tuning menu.

@ohlidalp
Copy link
Member Author

ohlidalp commented Nov 16, 2023

The design agreed on Discord https://discord.com/channels/136544456244461568/189904947649708032/1174499523901534218

  1. player spawns a clean car. UI shows each wheel with small "L/R" radio button and an "protected" checkbox on the right, like other things. The radiobutton is set to whatever's in the truckfile.
  2. player installs an addonpart with the generic wheels. tweak_wheel records are inserted to the .tuneup file. Radiobutton updates to whatever the addonpart did.
  3. player sees the rims are wrong and adjusts the radiobuttons. Internally this means updating the tweak_wheel entries that came from addonpart, which is possible as long as the "protected" flag is set for the wheels. This however also means that when user uninstalls the addonpart, the wheels will stay on. Alternatively I can add ui_fixups_* concept to the .tuneup format and scrap the whole "protected" flag system... I'll give it some more thought.

Ditto: https://discord.com/channels/136544456244461568/189904947649708032/1174464748461506634

addonpart_tweak_prop <prop ID> <offsetX> <offsetY> <offsetZ> <rotX> <rotY> <rotZ> <meshName>

  • Offset and rotation is OK to consider tweak.
  • Changing nodes would be messy, let's keep that as remove-recreate.
  • Changing the mesh also feels dirty but super convenient, so I'd put it in.
    This needs a special "no change here" value as the traditional "-1" could be a legit offset/rotation. How about null? So if you wanted to just move the meshes a little on one axis, you could do: addonpart_tweak_prop 4 null null -0.05

@ohlidalp ohlidalp marked this pull request as draft November 19, 2023 16:59
@ohlidalp
Copy link
Member Author

ohlidalp commented Nov 27, 2023

Tuneup format + UI change

All vehicle elements in the Tuning menu now show with numbers. They represent the order of definition in the truckfile, starting with 0. The removed_/protected_ arrays in the .tuneup file now use these numbers (instead of mesh names), to cover cases where the same mesh is used multiple times.

New .addonpart features:

; PROP TWEAKS
; Media1 = prop mesh; Media2: Steering wheel mesh or beacon flare material.
addonpart_tweak_prop <prop ID> <offsetX> <offsetY> <offsetZ> <rotX> <rotY> <rotZ> <media1> <media2>

; FLEXBODY TWEAKS
addonpart_tweak_flexbody <flexbody ID> <offsetX> <offsetY> <offsetZ> <rotX> <rotY> <rotZ> <meshName>

This is an example flexbody tweak. Note that presently you must fill in all the parameters. In the future I'll add a null token to the GenericDocument so the params can be left undefined.

; 'addonpart_tweak_flexbody <flexbody ID> <offsetX> <offsetY> <offsetZ> <rotX> <rotY> <rotZ> <media1> <media2(optional)>'
addonpart_tweak_flexbody    0,             39, 62, 34,                  0.50,    0.32,  -0.5,          CHeavyBumper.mesh

For updated downloads, see bottom posts.

obrazek

@ohlidalp ohlidalp force-pushed the MrMayhem_TruckEditorScript branch 2 times, most recently from 5de8d7a to c221bf8 Compare December 2, 2023 02:51
Reported by CuriousMike: "load map, spawn any vehicle, go back to main menu, click settings -> general -> update cache".

Fixed by introducing a rule "we just always load subdirs as 'writable', even during modcache update."
an older bug that Mike reported and I didn't note down: "if the last character in .addonpart file isn't a whitespace (space, tab or linebreak), the last token is skipped. For example, if last line is `addonpart_tweak_wheel 3 "myfacemat" "" n 0.2`, the custom facemat applies but the radius '0.2' doesn't."
I fixed the 'addonpart_tweak_wheel tire radius won't apply if rim radius value is missing' bug
@ohlidalp
Copy link
Member Author

ohlidalp commented Jan 8, 2024

Wrapping up

Almost all bugs are fixed, only minor glitches may be left.
Technical overview with AngelScript docs: #3096 (comment).
List of bugs to fix / features to leave for later: #3096 (comment)

Below is a draft documentation.

The .addonpart mod type

There's a new mod type "Addon part" (file extension .addonpart) which automates the process of customizing a vehicle, previously requiring to manually edit files as you can read in https://docs.rigsofrods.org/tools-tutorials/addons/. The addonpart file format is similar to truck file format with added addonpart_* directives. In game, player can install addonparts using new menu "Tuning" in top menu bar.

Organizational info

  • addonpart_name - display name, shown in "Tuning" menu.
  • addonpart_description - text displayed in SelectorUI - presently the Tuning menu doesn't let you invoke Selector for addonparts, but it's still possible via scripting and will likely be used in the future.
  • addonpart_guid - GUID of the target vehicle family, see https://docs.rigsofrods.org/vehicle-creation/fileformat-truck/#guid - this GUID is usually not unique to one vehicle but groups structurally similar vehicles which use the same skins.

Note: Preview images for selector UI (aka mini-images) are also supported.

Tweaking existing elements

'Tweaking' is the process of modifying existing elements. You use a directive addonpart_tweak_ABC followed by the target element's position in the truck file, numbered from 0. This is akin to how materialflarebindings work.

Parameters in [ ] are optional, leaving them out results in keeping original values. To omit an argument in between, use "" for string args or -1 for numeric args. This doesn't apply to positions and offsets, those are always required.

The 'media' can be meshes/materials (more types may come) depending on what the targeted element accepts.

  • addonpart_tweak_node <nodenum> <posX> <posY> <posZ> - tweaks nodes, all params are required.
  • addonpart_tweak_wheel <wheel ID> <media1> [<media2> <side flag> <tire radius> <rim radius>] - tweaks wheels, wheels2, meshwheels, meshwheels2, flexbodywheels. Media1+2 is face+band material in wheels[2] and rim mesh+tire material otherwise.
  • addonpart_tweak_prop <prop ID> <offsetX> <offsetY> <offsetZ> <rotX> <rotY> <rotZ> <media1> <media2> Tweaks props, Media1 = prop mesh; Media2: Steering wheel mesh or beacon flare material.
  • addonpart_tweak_flexbody <flexbody ID> <offsetX> <offsetY> <offsetZ> <rotX> <rotY> <rotZ> <meshName> - Tweaks flexbodies, but does NOT support the forset line. If you need to change the node set, you need to completely replace the flexbody, see below.

Internally, the edits are applied in memory at last moment during spawn, files in mod cache are not affected.

Adding new elements

Just use the same syntax as in truck file, anywhere in the .addonpart file. Currently supported elements are props, flexbodies, managedmaterials.

Note that forset line MUST be in quotes, otherwise the parser will not read it whole. For example:

flexbodies
10,11,26,0.5,-1.17,-0.27,-90,180,0,Roll-Cage_MV4.mesh
"forset 0-110,141-177,238-239"

Supressing existing elements

These accept a single parameter - the target element's position in the truck file, numbered from 0.

  • addonpart_unwanted_prop <prop ID>
  • addonpart_unwanted_flexbody <flexbody ID>

The .tuneup mod type

This one is intentionally similar to .skin; it has the same structure and serves very similar purpose - applying addonparts and other user changes to a vehicle on spawn. The internal processing is also very similar. The game creates and edits these files automatically as the player uses the Tuning menu. Files are saved to Documents\My Games\Rigs of Rods\projects directory which is a newly introduced directory monitored by modcache (like 'mods') but intended for modding and tuning.

UPDATE: Only the user-saved tuneups are now stored to modcache (category ID 8001), the working tuneup instances are just in memory and individual to every spawned actor.

The tuning menu

obrazek

There's a new menu "Tuning" in the top menubar UI, which allows user to pick addonparts. Following paragraphs are a description of the UI, in top down order:

"Enable tuning" checkbox

Toggles cvar sim_tuning_enabled (persisted in RoR.cfg)

List of saved tuneups

Saved tuneups for current vehicle. Only created or modified on user request. When saving, the 'auto' (working) tuneup gets copied to the save; when loading, the 'auto' (working) tuneup gets overwritten by the save. Each line has [Delete] button in purplish color, indicating it's a "hold to confirm" type button.

The Save/Reset buttons

[Save] button shows a save box with text field to enter name.

[Delete] button has purplish color, indicating it's a "hold to confirm" type button.

List of installed addonparts

Each comes with a [Reload] button to reload the file from disk if you're modding it.

User overrides: props/flexbodies/wheels

Number: All vehicle elements in the Tuning menu now show with numbers. They represent the order of definition in the truckfile, starting with 0. The removed_/protected_ arrays in the .tuneup file use these numbers (instead of mesh names), to cover cases where the same mesh is used multiple times.

Override checkbox: All the UI overrides (removed flexbodies/flipped wheel rims) are separate from any addonpart changes (tweaks or unwanted_*). When you make an UI override, the respective widget will be outlined orange and a 'reset' button will be drawn.

The 'protected' checkbox: (on the right) - Just blocks addonpart changes, doesn't affect the UI overrides in any way. Translates to protected_* directives in the .tuneup file.

In the .tuneup file, the UI overrides are called "force_something", while parts removed via addonparts are called 'unwanted_something'.

Updated addonparts to test

Mostly by @CuriousMike56

Problem: if addonpart defines new prop or flexbody, the meshes are still searched in the mod's resource group. This is because the new elements are added as extra 'section' (Module) to the RigDef::Document so they're treated as any other.

Solution: add a `_mesh_rg_override` string field to RigDef::Prop/Flexbody (in RigDef_File.h) and make ActorSpawner respect it.
`Parser::ProcessForsetLine()` puts the node ranges to `node_list_to_import`. Normally `SequentialImporter::ResolveFlexbodyForset()` handles the resolution but that only works when parsing the actual truckfile, not when programmatically injecting further elements.
This required an internal overhaul as the 'working tuneup' is no longer a CacheEntry (common to all instances of the given mod), but an individual TuneupDef instance (specific to each spawned actor).

SIGNIFFICANT CODE CHANGES:
* Actor.h - Replaced `CacheEntryPtr     m_used_tuneup_entry;` with `TuneupDefPtr      m_working_tuneup_def;`
* TuneupFileFormat: added `isFooTweaked()` helpers (where Foo is Prop/Wheel etc...) used by all specific `getTweaked*()` helpers.
* Savegame.cpp - Added a "tuneup_document" field to actor entries, carrying the entire .tuneup file content.
* CacheSystem: only user-saved tuneups are now placed to modcache, the working tuneups are just in memory.
Problem1 = .tuneup with empty name-line breaks parsing. Fixed in Actor.cpp
Problem2 = the addonpart bundles didn't get always loaded. Fixed in ActorSpawner.cpp
Added tracking of active button ID - that way multiple buttons on same window don't interfere by resetting it's timer.
When disabled, the Tuning menu in TopMenubar UI doesn't appear at all and any attempt to use a tuneup (via scripting or in savegame) will be ignored.
@CuriousMike56
Copy link
Collaborator

✅ ✅

Caused by a copypaste derp.
Problem: Initially the TuneupDef object was always present, but in recent commits it's just created when actually applying some tuning. The saving logic was not updated, though, so saving early caused crash.

Fix: The UI was updated to only show the [SaveAs...] button when the TuneupDef already exists.
UI improvement: the [Reset] button now removes the TuneupDef object instead of just resetting it, so the UI returns to initial state, clearly indicating there are no changes to be saved anymore.
@ohlidalp ohlidalp merged commit cbf670c into RigsOfRods:master Feb 4, 2024
2 checks passed
@ohlidalp ohlidalp deleted the MrMayhem_TruckEditorScript branch February 4, 2024 11:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants