Skip to content

Commit 2e1f63d

Browse files
committed
Tuning: added exhausts removal (_unwanted or UI)
To understand code changes, find previous commit which adds flares to the tuning system - it provides detailed checklist for making such change.
1 parent 96f55dd commit 2e1f63d

File tree

10 files changed

+127
-19
lines changed

10 files changed

+127
-19
lines changed

source/main/ForwardDeclarations.h

+3
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ namespace RoR
6464
typedef int FlareID_t; //!< Index into `Actor::ar_flares`, use `RoR::FLAREID_INVALID` as empty value
6565
static const FlareID_t FLAREID_INVALID = -1;
6666

67+
typedef int ExhaustID_t; //!< Index into `Actor::exhausts`, use `RoR::EXHAUSTID_INVALID` as empty value
68+
static const ExhaustID_t EXHAUSTID_INVALID = -1;
69+
6770
class Actor;
6871
class ActorManager;
6972
class ActorSpawner;

source/main/gui/panels/GUI_TopMenubar.cpp

+31
Original file line numberDiff line numberDiff line change
@@ -1908,6 +1908,37 @@ void TopMenubar::Draw(float dt)
19081908
ImGui::PopID(); // flareid
19091909
}
19101910
}
1911+
1912+
// Draw exhausts
1913+
size_t total_exhausts = tuning_actor->exhausts.size();
1914+
std::string exhausts_title = fmt::format(_LC("Tuning", "Exhausts ({})"), total_exhausts);
1915+
if (ImGui::CollapsingHeader(exhausts_title.c_str()))
1916+
{
1917+
// Draw all exhausts (those removed by addonparts are also present as placeholders)
1918+
for (ExhaustID_t exhaustid = 0; exhaustid < (int)tuning_actor->exhausts.size(); exhaustid++)
1919+
{
1920+
ImGui::PushID(exhaustid);
1921+
ImGui::AlignTextToFramePadding();
1922+
1923+
this->DrawTuningBoxedSubjectIdInline(exhaustid);
1924+
1925+
this->DrawTuningForceRemoveControls(
1926+
exhaustid,
1927+
tuning_actor->exhausts[exhaustid].particleSystemName,
1928+
tuneup_def && tuneup_def->isExhaustUnwanted(exhaustid),
1929+
tuneup_def && tuneup_def->isExhaustForceRemoved(exhaustid),
1930+
ModifyProjectRequestType::TUNEUP_FORCEREMOVE_EXHAUST_SET,
1931+
ModifyProjectRequestType::TUNEUP_FORCEREMOVE_EXHAUST_RESET);
1932+
1933+
this->DrawTuningProtectedChkRightAligned(
1934+
exhaustid,
1935+
tuneup_def && tuneup_def->isExhaustProtected(exhaustid),
1936+
ModifyProjectRequestType::TUNEUP_PROTECTED_EXHAUST_SET,
1937+
ModifyProjectRequestType::TUNEUP_PROTECTED_EXHAUST_RESET);
1938+
1939+
ImGui::PopID(); // exhaustid
1940+
}
1941+
}
19111942
}
19121943

19131944
m_open_menu_hoverbox_min = menu_pos - MENU_HOVERBOX_PADDING;

source/main/physics/ActorSpawner.cpp

+19-14
Original file line numberDiff line numberDiff line change
@@ -1282,32 +1282,37 @@ void ActorSpawner::ProcessExhaust(RigDef::Exhaust & def)
12821282
return;
12831283
}
12841284

1285+
const ExhaustID_t exhaust_id = (ExhaustID_t)m_actor->exhausts.size();
12851286
exhaust_t exhaust;
12861287
exhaust.emitterNode = this->GetNodeIndexOrThrow(def.reference_node);
12871288
exhaust.directionNode = this->GetNodeIndexOrThrow(def.direction_node);
12881289

12891290
std::string template_name = def.particle_name;
1290-
if (template_name.empty() || template_name == "default")
1291+
if (template_name == "" || template_name == "default")
12911292
{
12921293
template_name = "tracks/Smoke"; // defined in `particles/smoke.particle`
12931294
}
1295+
exhaust.particleSystemName = template_name;
12941296

1295-
std::string name = this->ComposeName(template_name.c_str(), (int)m_actor->exhausts.size());
1296-
exhaust.smoker = this->CreateParticleSystem(name, template_name);
1297-
if (exhaust.smoker == nullptr)
1297+
if (!TuneupUtil::isExhaustAnyhowRemoved(m_actor->getWorkingTuneupDef(), exhaust_id))
12981298
{
1299-
std::stringstream msg;
1300-
msg << "Failed to create particle system '" << name << "' (template: '" << template_name <<"')";
1301-
AddMessage(Message::TYPE_ERROR, msg.str());
1302-
return;
1303-
}
1299+
std::string name = this->ComposeName(template_name.c_str(), (int)m_actor->exhausts.size());
1300+
exhaust.smoker = this->CreateParticleSystem(name, template_name);
1301+
if (exhaust.smoker == nullptr)
1302+
{
1303+
std::stringstream msg;
1304+
msg << "Failed to create particle system '" << name << "' (template: '" << template_name <<"')";
1305+
AddMessage(Message::TYPE_ERROR, msg.str());
1306+
return;
1307+
}
13041308

1305-
exhaust.smokeNode = m_particles_parent_scenenode->createChildSceneNode(this->ComposeName("exhaust", (int)m_actor->exhausts.size()));
1306-
exhaust.smokeNode->attachObject(exhaust.smoker);
1307-
exhaust.smokeNode->setPosition(m_actor->ar_nodes[exhaust.emitterNode].AbsPosition);
1309+
exhaust.smokeNode = m_particles_parent_scenenode->createChildSceneNode(this->ComposeName("exhaust", (int)m_actor->exhausts.size()));
1310+
exhaust.smokeNode->attachObject(exhaust.smoker);
1311+
exhaust.smokeNode->setPosition(m_actor->ar_nodes[exhaust.emitterNode].AbsPosition);
13081312

1309-
m_actor->m_gfx_actor->SetNodeHot(exhaust.emitterNode, true);
1310-
m_actor->m_gfx_actor->SetNodeHot(exhaust.directionNode, true);
1313+
m_actor->m_gfx_actor->SetNodeHot(exhaust.emitterNode, true);
1314+
m_actor->m_gfx_actor->SetNodeHot(exhaust.directionNode, true);
1315+
}
13111316

13121317
m_actor->exhausts.push_back(exhaust);
13131318
}

source/main/physics/SimData.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -650,8 +650,9 @@ struct exhaust_t
650650
{
651651
NodeNum_t emitterNode = NODENUM_INVALID;
652652
NodeNum_t directionNode = NODENUM_INVALID;
653-
Ogre::SceneNode *smokeNode;
654-
Ogre::ParticleSystem* smoker;
653+
Ogre::SceneNode *smokeNode = nullptr;
654+
Ogre::ParticleSystem* smoker = nullptr; //!< This remains `nullptr` if removed via `addonpart_unwanted_exhaust` or Tuning UI.
655+
std::string particleSystemName; //!< Name in .particle file ~ for display in Tuning UI.
655656
};
656657

657658

source/main/resources/CacheSystem.cpp

+20
Original file line numberDiff line numberDiff line change
@@ -1827,6 +1827,16 @@ void CacheSystem::ModifyProject(ModifyProjectRequest* request)
18271827
request->mpr_target_actor->getWorkingTuneupDef()->force_wheel_sides.erase(request->mpr_subject_id);
18281828
break;
18291829

1830+
case ModifyProjectRequestType::TUNEUP_FORCEREMOVE_EXHAUST_SET:
1831+
request->mpr_target_actor->ensureWorkingTuneupDef();
1832+
request->mpr_target_actor->getWorkingTuneupDef()->force_remove_exhausts.insert(request->mpr_subject_id);
1833+
break;
1834+
1835+
case ModifyProjectRequestType::TUNEUP_FORCEREMOVE_EXHAUST_RESET:
1836+
request->mpr_target_actor->ensureWorkingTuneupDef();
1837+
request->mpr_target_actor->getWorkingTuneupDef()->force_remove_exhausts.erase(request->mpr_subject_id);
1838+
break;
1839+
18301840
case ModifyProjectRequestType::TUNEUP_PROTECTED_PROP_SET:
18311841
request->mpr_target_actor->ensureWorkingTuneupDef();
18321842
request->mpr_target_actor->getWorkingTuneupDef()->protected_props.insert(request->mpr_subject_id);
@@ -1867,6 +1877,16 @@ void CacheSystem::ModifyProject(ModifyProjectRequest* request)
18671877
request->mpr_target_actor->getWorkingTuneupDef()->protected_flares.erase(request->mpr_subject_id);
18681878
break;
18691879

1880+
case ModifyProjectRequestType::TUNEUP_PROTECTED_EXHAUST_SET:
1881+
request->mpr_target_actor->ensureWorkingTuneupDef();
1882+
request->mpr_target_actor->getWorkingTuneupDef()->protected_exhausts.insert(request->mpr_subject_id);
1883+
break;
1884+
1885+
case ModifyProjectRequestType::TUNEUP_PROTECTED_EXHAUST_RESET:
1886+
request->mpr_target_actor->ensureWorkingTuneupDef();
1887+
request->mpr_target_actor->getWorkingTuneupDef()->protected_exhausts.erase(request->mpr_subject_id);
1888+
break;
1889+
18701890
case ModifyProjectRequestType::PROJECT_LOAD_TUNEUP:
18711891
{
18721892
// Instead of loading with the saved tuneup directly, keep the autogenerated and sync it with the save.

source/main/resources/CacheSystem.h

+6-2
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,10 @@ enum class ModifyProjectRequestType
237237
TUNEUP_FORCEREMOVE_FLEXBODY_RESET, //!< 'subject_id' is flexbody ID.
238238
TUNEUP_FORCED_WHEEL_SIDE_SET, //!< 'subject_id' is wheel ID, 'value_int' is RoR::WheelSide
239239
TUNEUP_FORCED_WHEEL_SIDE_RESET, //!< 'subject_id' is wheel ID.
240-
TUNEUP_FORCEREMOVE_FLARE_SET, //!< 'subject_id' is flare ID.
241-
TUNEUP_FORCEREMOVE_FLARE_RESET, //!< 'subject_id' is flare ID.
240+
TUNEUP_FORCEREMOVE_FLARE_SET, //!< 'subject_id' is flare ID.
241+
TUNEUP_FORCEREMOVE_FLARE_RESET, //!< 'subject_id' is flare ID.
242+
TUNEUP_FORCEREMOVE_EXHAUST_SET, //!< 'subject_id' is exhaust ID.
243+
TUNEUP_FORCEREMOVE_EXHAUST_RESET, //!< 'subject_id' is exhaust ID.
242244
TUNEUP_PROTECTED_PROP_SET, //!< 'subject_id' is prop ID.
243245
TUNEUP_PROTECTED_PROP_RESET, //!< 'subject_id' is prop ID.
244246
TUNEUP_PROTECTED_FLEXBODY_SET, //!< 'subject_id' is flexbody ID.
@@ -247,6 +249,8 @@ enum class ModifyProjectRequestType
247249
TUNEUP_PROTECTED_WHEEL_RESET, //!< 'subject_id' is wheel ID.
248250
TUNEUP_PROTECTED_FLARE_SET, //!< 'subject_id' is flare ID.
249251
TUNEUP_PROTECTED_FLARE_RESET, //!< 'subject_id' is flare ID.
252+
TUNEUP_PROTECTED_EXHAUST_SET, //!< 'subject_id' is exhaust ID.
253+
TUNEUP_PROTECTED_EXHAUST_RESET, //!< 'subject_id' is exhaust ID.
250254
PROJECT_LOAD_TUNEUP, //!< 'subject' is tuneup filename. This overwrites the auto-generated tuneup with the save.
251255
PROJECT_RESET_TUNEUP, //!< 'subject' is empty. This resets the auto-generated tuneup to orig. values.
252256
};

source/main/resources/addonpart_fileformat/AddonPartFileFormat.cpp

+26
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,8 @@ void AddonPartUtility::ResolveUnwantedAndTweakedElements(TuneupDefPtr& tuneup, C
153153
this->ProcessUnwantedFlexbody();
154154
else if (m_context->getTokKeyword() == "addonpart_unwanted_flare" )
155155
this->ProcessUnwantedFlare();
156+
else if (m_context->getTokKeyword() == "addonpart_unwanted_exhaust" )
157+
this->ProcessUnwantedExhaust();
156158
else if (m_context->getTokKeyword() == "addonpart_tweak_wheel")
157159
this->ProcessTweakWheel();
158160
else if (m_context->getTokKeyword() == "addonpart_tweak_node")
@@ -470,6 +472,30 @@ void AddonPartUtility::ProcessUnwantedFlare()
470472
}
471473
}
472474

475+
void AddonPartUtility::ProcessUnwantedExhaust()
476+
{
477+
ROR_ASSERT(m_context->getTokKeyword() == "addonpart_unwanted_exhaust"); // also asserts !EOF and TokenType::KEYWORD
478+
479+
if (m_context->isTokFloat(1))
480+
{
481+
if (!m_tuneup->isExhaustProtected((ExhaustID_t)m_context->getTokFloat(1)))
482+
{
483+
m_tuneup->unwanted_exhausts.insert((ExhaustID_t)m_context->getTokFloat(1));
484+
this->Log(fmt::format("[RoR|Addonpart] INFO: file '{}', directive '{}': marking exhaust '{}' as UNWANTED",
485+
m_addonpart_entry->fname, m_context->getTokKeyword(), (int)m_context->getTokFloat(1)));
486+
}
487+
else
488+
{
489+
this->Log(fmt::format("[RoR|Addonpart] INFO: file '{}', directive '{}': skipping exhaust '{}' because it's marked PROTECTED",
490+
m_addonpart_entry->fname, m_context->getTokKeyword(), m_context->getTokString(1)));
491+
}
492+
}
493+
else
494+
{
495+
this->Log(fmt::format("[RoR|Addonpart] WARNING: file '{}', directive '{}': bad arguments", m_addonpart_entry->fname, m_context->getTokKeyword()));
496+
}
497+
}
498+
473499
void AddonPartUtility::ProcessTweakWheel()
474500
{
475501
ROR_ASSERT(m_context->getTokKeyword() == "addonpart_tweak_wheel"); // also asserts !EOF and TokenType::KEYWORD

source/main/resources/addonpart_fileformat/AddonPartFileFormat.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ class AddonPartUtility
7474
void ProcessFlexbody();
7575
void ProcessFlare();
7676
void ProcessFlare2();
77-
void ProcessFlare3();
7877
void ProcessTweakWheel();
7978
void ProcessTweakNode();
8079
void ProcessTweakFlexbody();
@@ -84,6 +83,7 @@ class AddonPartUtility
8483
void ProcessUnwantedProp();
8584
void ProcessUnwantedFlexbody();
8685
void ProcessUnwantedFlare();
86+
void ProcessUnwantedExhaust();
8787

8888
void Log(const std::string& text);
8989

source/main/resources/tuneup_fileformat/TuneupFileFormat.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,13 @@ bool RoR::TuneupUtil::isFlareAnyhowRemoved(TuneupDefPtr& tuneup_def, FlareID_t f
452452
&& (tuneup_def->isFlareUnwanted(flare_id) || tuneup_def->isFlareForceRemoved(flare_id));
453453
}
454454

455+
// > exhaust
456+
bool RoR::TuneupUtil::isExhaustAnyhowRemoved(TuneupDefPtr& tuneup_def, ExhaustID_t exhaust_id)
457+
{
458+
return tuneup_def
459+
&& (tuneup_def->isExhaustUnwanted(exhaust_id) || tuneup_def->isExhaustForceRemoved(exhaust_id));
460+
}
461+
455462
bool RoR::TuneupUtil::isAddonPartUsed(TuneupDefPtr& tuneup_entry, const std::string& filename)
456463
{
457464
return tuneup_entry

source/main/resources/tuneup_fileformat/TuneupFileFormat.h

+11
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ struct TuneupDef: public RefCountingObject<TuneupDef>
106106
std::set<PropID_t> unwanted_props; //!< 'addonpart_unwanted_prop' directives.
107107
std::set<FlexbodyID_t> unwanted_flexbodies; //!< 'addonpart_unwanted_flexbody' directives.
108108
std::set<FlareID_t> unwanted_flares; //!< 'addonpart_unwanted_flare' directives.
109+
std::set<ExhaustID_t> unwanted_exhausts; //!< 'addonpart_unwanted_exhaust' directives.
109110
/// @}
110111

111112
/// @name UI-controlled forced changes (override addonparts)
@@ -114,6 +115,7 @@ struct TuneupDef: public RefCountingObject<TuneupDef>
114115
std::set<FlexbodyID_t> force_remove_flexbodies; //!< UI overrides
115116
std::map<WheelID_t, WheelSide> force_wheel_sides; //!< UI overrides
116117
std::set<FlareID_t> force_remove_flares; //!< User unticked an UI checkbox in Tuning menu, section Flares.
118+
std::set<ExhaustID_t> force_remove_exhausts; //!< User unticked an UI checkbox in Tuning menu, section Exhausts.
117119
/// @}
118120

119121
/// @name UI-controlled protection from addonpart tweaks
@@ -123,6 +125,7 @@ struct TuneupDef: public RefCountingObject<TuneupDef>
123125
std::set<PropID_t> protected_props; //!< Props which cannot be altered via 'addonpart_tweak_prop' or 'addonpart_unwanted_prop' directive.
124126
std::set<FlexbodyID_t> protected_flexbodies; //!< Flexbodies which cannot be altered via 'addonpart_tweak_flexbody' or 'addonpart_unwanted_flexbody' directive.
125127
std::set<FlareID_t> protected_flares; //!< Flares which cannot be altered via 'addonpart_unwanted_flare' directive.
128+
std::set<ExhaustID_t> protected_exhausts; //!< Exhausts which cannot be altered via 'addonpart_unwanted_exhaust' directive.
126129
/// @}
127130

128131
TuneupDefPtr clone();
@@ -135,13 +138,15 @@ struct TuneupDef: public RefCountingObject<TuneupDef>
135138
bool isWheelProtected(WheelID_t wheelid) const { return protected_wheels.find(wheelid) != protected_wheels.end(); }
136139
bool isNodeProtected(NodeNum_t nodenum) const { return protected_nodes.find(nodenum) != protected_nodes.end(); }
137140
bool isFlareProtected(FlareID_t flareid) const { return protected_flares.find(flareid) != protected_flares.end(); }
141+
bool isExhaustProtected(ExhaustID_t exhaustid) const { return protected_exhausts.find(exhaustid) != protected_exhausts.end(); }
138142
/// @}
139143

140144
/// @name Unwanted-state helpers
141145
/// @{
142146
bool isPropUnwanted(PropID_t propid) { return unwanted_props.find(propid) != unwanted_props.end(); }
143147
bool isFlexbodyUnwanted(FlexbodyID_t flexbodyid) { return unwanted_flexbodies.find(flexbodyid) != unwanted_flexbodies.end(); }
144148
bool isFlareUnwanted(FlareID_t flareid) { return unwanted_flares.find(flareid) != unwanted_flares.end(); }
149+
bool isExhaustUnwanted(ExhaustID_t exhaustid) { return unwanted_exhausts.find(exhaustid) != unwanted_exhausts.end(); }
145150
/// @}
146151

147152
/// @name Forced-state helpers
@@ -150,6 +155,7 @@ struct TuneupDef: public RefCountingObject<TuneupDef>
150155
bool isFlexbodyForceRemoved(FlexbodyID_t flexbodyid) { return force_remove_flexbodies.find(flexbodyid) != force_remove_flexbodies.end(); }
151156
bool isWheelSideForced(WheelID_t wheelid, WheelSide& out_val) const;
152157
bool isFlareForceRemoved(FlareID_t flareid) { return force_remove_flares.find(flareid) != force_remove_flares.end(); }
158+
bool isExhaustForceRemoved(ExhaustID_t exhaustid) { return force_remove_exhausts.find(exhaustid) != force_remove_exhausts.end(); }
153159
/// @}
154160
};
155161

@@ -206,6 +212,11 @@ class TuneupUtil
206212
static bool isFlareAnyhowRemoved(TuneupDefPtr& tuneup_def, FlareID_t flare_id);
207213
/// @}
208214

215+
/// @name Exhaust helpers
216+
/// @{
217+
static bool isExhaustAnyhowRemoved(TuneupDefPtr& tuneup_def, ExhaustID_t exhaust_id);
218+
/// @}
219+
209220
private:
210221

211222
static void ParseTuneupAttribute(const std::string& line, TuneupDefPtr& tuneup_def);

0 commit comments

Comments
 (0)