From 33d2987d547b5ae89307f14439d6f19afe41c2a4 Mon Sep 17 00:00:00 2001 From: ohlidalp Date: Wed, 4 Dec 2024 01:58:31 +0100 Subject: [PATCH] :truck: New section 'flaregroups_no_import ' Prevents actor from importing flare states when linked (locked/tied). Suggested on Discord by DarthCain: * https://discord.com/channels/136544456244461568/189904947649708032/1313301325538136147 * https://discord.com/channels/136544456244461568/189904947649708032/1313542914747662397 Syntax: ``` ;flaregroups_no_import ; ``` Testing: There are 2 RoR.log messages specifically for testers (`{}` is where values are filled) - these may be removed later: * `[RoR|RigDef::Parser] parsed FlaregroupNoImport ({} {})` * `[RoR|ActorSpawner] processing FlaregroupNoImport ({} {})` --- source/main/physics/Actor.cpp | 10 ++++++ source/main/physics/Actor.h | 2 ++ source/main/physics/ActorManager.cpp | 2 +- source/main/physics/ActorSpawner.cpp | 35 +++++++++++++++++++ source/main/physics/ActorSpawner.h | 1 + source/main/physics/ActorSpawnerFlow.cpp | 1 + .../rig_def_fileformat/RigDef_File.h | 8 +++++ .../rig_def_fileformat/RigDef_Parser.cpp | 26 ++++++++++++++ .../rig_def_fileformat/RigDef_Parser.h | 1 + .../rig_def_fileformat/RigDef_Regexes.h | 1 + 10 files changed, 86 insertions(+), 1 deletion(-) diff --git a/source/main/physics/Actor.cpp b/source/main/physics/Actor.cpp index 544b0e26eb..01e54eb29b 100644 --- a/source/main/physics/Actor.cpp +++ b/source/main/physics/Actor.cpp @@ -3176,6 +3176,16 @@ void Actor::setLightStateMask(BitMask_t lightmask) m_lightmask = lightmask; } +void Actor::importLightStateMask(BitMask_t lightmask) +{ + // Override incoming '0' bits where "no import" is set. + BITMASK_SET_1(lightmask, m_lightmask & m_flaregroups_no_import); + // Override incoming '1' bits where "no import" is set. + BITMASK_SET_0(lightmask, ~m_lightmask & m_flaregroups_no_import); + + this->setLightStateMask(lightmask); +} + void Actor::toggleCustomParticles() { if (ar_state == ActorState::DISPOSED) diff --git a/source/main/physics/Actor.h b/source/main/physics/Actor.h index e4d4583bd6..f1e811eeef 100644 --- a/source/main/physics/Actor.h +++ b/source/main/physics/Actor.h @@ -182,6 +182,7 @@ class Actor : public RefCountingObject void toggleHeadlights(); BitMask_t getLightStateMask() const { return m_lightmask; } void setLightStateMask(BitMask_t lightmask); //!< Does all the necessary toggling. + void importLightStateMask(BitMask_t lightmask); //!< Only for linked (locked/tied) actors forwarding flare states; see 'flaregroups_no_import' in .truck format. bool getSideLightsVisible() const { return m_lightmask & RoRnet::LIGHTMASK_SIDELIGHTS; } void setSideLightsVisible(bool val) { BITMASK_SET(m_lightmask, RoRnet::LIGHTMASK_SIDELIGHTS, val); } bool getHeadlightsVisible() const { return m_lightmask & RoRnet::LIGHTMASK_HEADLIGHT; } @@ -614,6 +615,7 @@ class Actor : public RefCountingObject /// @{ GfxFlaresMode m_flares_mode = GfxFlaresMode::NONE; //!< Snapshot of cvar 'gfx_flares_mode' on spawn. BitMask_t m_lightmask = 0; //!< RoRnet::Lightmask + BitMask_t m_flaregroups_no_import = 0; //!< RoRnet::Lightmask bool m_blinker_autoreset = false; //!< When true, we're steering and blinker will turn off automatically. bool m_blinker_left_lit = false; //!< Blinking state of left turn signal bool m_blinker_right_lit = false; //!< Blinking state of right turn signal diff --git a/source/main/physics/ActorManager.cpp b/source/main/physics/ActorManager.cpp index 5845f5a7db..9a3e65415a 100644 --- a/source/main/physics/ActorManager.cpp +++ b/source/main/physics/ActorManager.cpp @@ -712,7 +712,7 @@ void ActorManager::ForwardCommands(ActorPtr source_actor) } // forward lights - hook.hk_locked_actor->setLightStateMask(source_actor->getLightStateMask()); + hook.hk_locked_actor->importLightStateMask(source_actor->getLightStateMask()); } } } diff --git a/source/main/physics/ActorSpawner.cpp b/source/main/physics/ActorSpawner.cpp index d941307728..46b410b730 100644 --- a/source/main/physics/ActorSpawner.cpp +++ b/source/main/physics/ActorSpawner.cpp @@ -2358,6 +2358,41 @@ void ActorSpawner::ProcessFlare2(RigDef::Flare2 & def) m_actor->ar_flares.push_back(flare); } +void ActorSpawner::ProcessFlaregroupNoImport(RigDef::FlaregroupNoImport& def) +{ + LOG(fmt::format("[RoR|ActorSpawner] processing FlaregroupNoImport ({} {})", (char)def.type, def.control_number)); + switch (def.type) + { + case FlareType::HEADLIGHT: BITMASK_SET_1(m_actor->m_flaregroups_no_import, RoRnet::LIGHTMASK_HEADLIGHT); break; + case FlareType::HIGH_BEAM: BITMASK_SET_1(m_actor->m_flaregroups_no_import, RoRnet::LIGHTMASK_HIGHBEAMS); break; + case FlareType::FOG_LIGHT: BITMASK_SET_1(m_actor->m_flaregroups_no_import, RoRnet::LIGHTMASK_FOGLIGHTS); break; + case FlareType::SIDELIGHT: BITMASK_SET_1(m_actor->m_flaregroups_no_import, RoRnet::LIGHTMASK_SIDELIGHTS); break; + case FlareType::TAIL_LIGHT: BITMASK_SET_1(m_actor->m_flaregroups_no_import, RoRnet::LIGHTMASK_HEADLIGHT); break; + case FlareType::BRAKE_LIGHT: BITMASK_SET_1(m_actor->m_flaregroups_no_import, RoRnet::LIGHTMASK_BRAKES); break; + case FlareType::REVERSE_LIGHT: BITMASK_SET_1(m_actor->m_flaregroups_no_import, RoRnet::LIGHTMASK_REVERSE); break; + case FlareType::BLINKER_LEFT: BITMASK_SET_1(m_actor->m_flaregroups_no_import, RoRnet::LIGHTMASK_BLINK_LEFT); break; + case FlareType::BLINKER_RIGHT: BITMASK_SET_1(m_actor->m_flaregroups_no_import, RoRnet::LIGHTMASK_BLINK_RIGHT); break; + //case FlareType::DASHBOARD: ~ Not subject to syncing between linked actors. + case FlareType::USER: + switch (def.control_number - 1) + { + case 0: BITMASK_SET_1(m_actor->m_flaregroups_no_import, RoRnet::LIGHTMASK_CUSTOM1); break; + case 1: BITMASK_SET_1(m_actor->m_flaregroups_no_import, RoRnet::LIGHTMASK_CUSTOM2); break; + case 2: BITMASK_SET_1(m_actor->m_flaregroups_no_import, RoRnet::LIGHTMASK_CUSTOM3); break; + case 3: BITMASK_SET_1(m_actor->m_flaregroups_no_import, RoRnet::LIGHTMASK_CUSTOM4); break; + case 4: BITMASK_SET_1(m_actor->m_flaregroups_no_import, RoRnet::LIGHTMASK_CUSTOM5); break; + case 5: BITMASK_SET_1(m_actor->m_flaregroups_no_import, RoRnet::LIGHTMASK_CUSTOM6); break; + case 6: BITMASK_SET_1(m_actor->m_flaregroups_no_import, RoRnet::LIGHTMASK_CUSTOM7); break; + case 7: BITMASK_SET_1(m_actor->m_flaregroups_no_import, RoRnet::LIGHTMASK_CUSTOM8); break; + case 8: BITMASK_SET_1(m_actor->m_flaregroups_no_import, RoRnet::LIGHTMASK_CUSTOM9); break; + case 9: BITMASK_SET_1(m_actor->m_flaregroups_no_import, RoRnet::LIGHTMASK_CUSTOM10);break; + default: break; + } + break; + default: break; + } +} + Ogre::MaterialPtr ActorSpawner::InstantiateManagedMaterial(const Ogre::String& rg_name, Ogre::String const & source_name, Ogre::String const & clone_name) { Ogre::MaterialPtr src_mat = Ogre::MaterialManager::getSingleton().getByName(source_name, rg_name); diff --git a/source/main/physics/ActorSpawner.h b/source/main/physics/ActorSpawner.h index 15caf4e5a2..ecd9ecd2d9 100644 --- a/source/main/physics/ActorSpawner.h +++ b/source/main/physics/ActorSpawner.h @@ -173,6 +173,7 @@ class ActorSpawner void ProcessFixedNode(RigDef::Node::Ref node_ref); // 'fixes' void ProcessFlare2(RigDef::Flare2 & def); void ProcessFlare3(RigDef::Flare3 & def); + void ProcessFlaregroupNoImport(RigDef::FlaregroupNoImport & def); void ProcessFlexbody(RigDef::Flexbody& def); void ProcessFlexBodyWheel(RigDef::FlexBodyWheel & def); void ProcessFusedrag(RigDef::Fusedrag & def); diff --git a/source/main/physics/ActorSpawnerFlow.cpp b/source/main/physics/ActorSpawnerFlow.cpp index c23e4839df..121f3d9132 100644 --- a/source/main/physics/ActorSpawnerFlow.cpp +++ b/source/main/physics/ActorSpawnerFlow.cpp @@ -178,6 +178,7 @@ void ActorSpawner::ProcessNewActor(ActorPtr actor, ActorSpawnRequest rq, RigDef: PROCESS_ELEMENT(RigDef::Keyword::ANTILOCKBRAKES, antilockbrakes, ProcessAntiLockBrakes); PROCESS_ELEMENT(RigDef::Keyword::FLARES2, flares2, ProcessFlare2); PROCESS_ELEMENT(RigDef::Keyword::FLARES3, flares3, ProcessFlare3); + PROCESS_ELEMENT(RigDef::Keyword::FLAREGROUPS_NO_IMPORT, flaregroups_no_import, ProcessFlaregroupNoImport); PROCESS_ELEMENT(RigDef::Keyword::AXLES, axles, ProcessAxle); PROCESS_ELEMENT(RigDef::Keyword::TRANSFERCASE, transfercase, ProcessTransferCase); PROCESS_ELEMENT(RigDef::Keyword::INTERAXLES, interaxles, ProcessInterAxle); diff --git a/source/main/resources/rig_def_fileformat/RigDef_File.h b/source/main/resources/rig_def_fileformat/RigDef_File.h index dc2fb74c61..ebd10e4f1a 100644 --- a/source/main/resources/rig_def_fileformat/RigDef_File.h +++ b/source/main/resources/rig_def_fileformat/RigDef_File.h @@ -107,6 +107,7 @@ enum class Keyword FLARES, FLARES2, FLARES3, + FLAREGROUPS_NO_IMPORT, FLEXBODIES, FLEXBODY_CAMERA_MODE, FLEXBODYWHEELS, @@ -892,6 +893,12 @@ struct Flare3: public Flare2 std::shared_ptr inertia_defaults; }; +struct FlaregroupNoImport +{ + RoR::FlareType type = RoR::FlareType::NONE; + int control_number = -1; //!< Only 'u' type flares. +}; + struct Flexbody { Node::Ref reference_node; @@ -1510,6 +1517,7 @@ struct Document std::vector fileinfo; std::vector flares2; // 'flares' are auto-imported as 'flares2' (only 1 extra argument) std::vector flares3; + std::vector flaregroups_no_import; std::vector flexbodies; std::vector flexbodywheels; std::vector fusedrag; diff --git a/source/main/resources/rig_def_fileformat/RigDef_Parser.cpp b/source/main/resources/rig_def_fileformat/RigDef_Parser.cpp index 67e1307b5f..c322f56192 100644 --- a/source/main/resources/rig_def_fileformat/RigDef_Parser.cpp +++ b/source/main/resources/rig_def_fileformat/RigDef_Parser.cpp @@ -256,6 +256,7 @@ void Parser::ProcessCurrentLine() case Keyword::FLARES: case Keyword::FLARES2: this->ParseFlaresUnified(); return; case Keyword::FLARES3: this->ParseFlares3(); return; + case Keyword::FLAREGROUPS_NO_IMPORT:this->ParseFlaregroupsNoImport(); return; case Keyword::FLEXBODIES: this->ParseFlexbody(); return; case Keyword::FLEXBODYWHEELS: this->ParseFlexBodyWheel(); return; case Keyword::FUSEDRAG: this->ParseFusedrag(); return; @@ -2064,6 +2065,31 @@ void Parser::ParseDirectiveSetDefaultMinimass() m_set_default_minimass->min_mass_Kg = this->GetArgFloat(1); } +void Parser::ParseFlaregroupsNoImport() +{ + // ;flare_groups_no_import + // ; + if (!this->CheckNumArguments(1)) { return; } + + FlaregroupNoImport fni; + fni.type = this->GetArgFlareType(0); + if (m_num_args > 1) + { + fni.control_number = this->GetArgInt(1); + if (fni.control_number < 1) + { + this->LogMessage(Console::CONSOLE_SYSTEM_WARNING, fmt::format("flaregroup_no_import: parameter must be 1-10; got {}, clamping to 1", fni.control_number)); + } + if (fni.control_number > 10) + { + this->LogMessage(Console::CONSOLE_SYSTEM_WARNING, fmt::format("flaregroup_no_import: parameter must be 1-10; got {}, clamping to 10", fni.control_number)); + } + } + + LOG(fmt::format("[RoR|RigDef::Parser] parsed FlaregroupNoImport ({} {})", (char)fni.type, fni.control_number)); + m_current_module->flaregroups_no_import.push_back(fni); +} + void Parser::ParseDirectiveSetInertiaDefaults() { if (! this->CheckNumArguments(2)) { return; } diff --git a/source/main/resources/rig_def_fileformat/RigDef_Parser.h b/source/main/resources/rig_def_fileformat/RigDef_Parser.h index 1682411793..587cc0e9cc 100644 --- a/source/main/resources/rig_def_fileformat/RigDef_Parser.h +++ b/source/main/resources/rig_def_fileformat/RigDef_Parser.h @@ -141,6 +141,7 @@ class Parser void ParseFixes(); void ParseFlaresUnified(); void ParseFlares3(); + void ParseFlaregroupsNoImport(); void ParseFlexbody(); void ParseFlexBodyWheel(); void ParseFusedrag(); diff --git a/source/main/resources/rig_def_fileformat/RigDef_Regexes.h b/source/main/resources/rig_def_fileformat/RigDef_Regexes.h index 93fa11d023..d9c695f715 100644 --- a/source/main/resources/rig_def_fileformat/RigDef_Regexes.h +++ b/source/main/resources/rig_def_fileformat/RigDef_Regexes.h @@ -159,6 +159,7 @@ namespace Regexes E_KEYWORD_BLOCK("flares") \ E_KEYWORD_BLOCK("flares2") \ E_KEYWORD_BLOCK("flares3") \ + E_KEYWORD_BLOCK("flaregroups_no_import") \ E_KEYWORD_BLOCK("flexbodies") \ E_KEYWORD_INLINE("flexbody_camera_mode") \ E_KEYWORD_BLOCK("flexbodywheels") \