Rigs of Rods 2023.09
Soft-body Physics Simulation
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Loading...
Searching...
No Matches
TuneupFileFormat.cpp
Go to the documentation of this file.
1/*
2 This source file is part of Rigs of Rods
3 Copyright 2005-2012 Pierre-Michel Ricordel
4 Copyright 2007-2012 Thomas Fischer
5 Copyright 2013-2024 Petr Ohlidal
6
7 For more information, see http://www.rigsofrods.org/
8
9 Rigs of Rods is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License version 3, as
11 published by the Free Software Foundation.
12
13 Rigs of Rods is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with Rigs of Rods. If not, see <http://www.gnu.org/licenses/>.
20*/
21
22#include "TuneupFileFormat.h"
23
24#include "Actor.h"
25#include "Application.h"
26#include "CacheSystem.h"
27#include "Console.h"
28#include "Utils.h"
29
30#include <OgreEntity.h>
31#include <OgreMaterialManager.h>
32#include <OgrePass.h>
33#include <OgreSubEntity.h>
34#include <OgreTechnique.h>
35
36using namespace RoR;
37
39{
40 TuneupDefPtr ret = new TuneupDef();
41
42 // General info
43 ret->name = this->name ; //std::string
44 ret->guid = this->guid ; //std::string
45 ret->thumbnail = this->thumbnail ; //std::string
46 ret->description = this->description ; //std::string
47 ret->author_name = this->author_name ; //std::string
48 ret->author_id = this->author_id ; //int
49 ret->category_id = this->category_id ; //CacheCategoryId
50 ret->filename = this->filename ; //std::string
51
52 // addonparts
53 ret->use_addonparts = this->use_addonparts ;
54
55 // props
57 ret->unwanted_props = this->unwanted_props;
59 ret->prop_tweaks = this->prop_tweaks;
60
61 // flexbodies
66
67 // wheels
70 ret->wheel_tweaks = this->wheel_tweaks;
71
72 // nodes
74 ret->node_tweaks = this->node_tweaks;
75
76 // video cameras
78
79 // flares
81
82 // exhausts
84
85 // managed materials
87
88 return ret;
89}
90
92{
93 auto itor = force_wheel_sides.find(wheelid);
94 if (itor != force_wheel_sides.end())
95 {
96 out_val = itor->second;
97 return true;
98 }
99 else
100 {
101 return false;
102 }
103}
104
106{
107 auto itor = force_video_cam_roles.find(camera_id);
108 if (itor != force_video_cam_roles.end())
109 {
110 out_val = itor->second;
111 return true;
112 }
113 else
114 {
115 return false;
116 }
117}
118
119 // Tweaking helpers
120
121float RoR::TuneupUtil::getTweakedWheelTireRadius(TuneupDefPtr& tuneup_def, WheelID_t wheel_id, float orig_val)
122{
123 TuneupWheelTweak* tweak = nullptr;
124 if (TuneupUtil::isWheelTweaked(tuneup_def, wheel_id, /*out:*/ tweak))
125 {
126 ROR_ASSERT(tweak);
127 return (tweak->twt_tire_radius > 0) ? tweak->twt_tire_radius : orig_val;
128 }
129 else
130 {
131 return orig_val;
132 }
133}
134
135float RoR::TuneupUtil::getTweakedWheelRimRadius(TuneupDefPtr& tuneup_def, WheelID_t wheel_id, float orig_val)
136{
137 TuneupWheelTweak* tweak = nullptr;
138 if (TuneupUtil::isWheelTweaked(tuneup_def, wheel_id, tweak))
139 {
140 ROR_ASSERT(tweak);
141 return (tweak->twt_rim_radius > 0) ? tweak->twt_rim_radius : orig_val;
142 }
143 else
144 {
145 return orig_val;
146 }
147}
148
149std::string RoR::TuneupUtil::getTweakedWheelMedia(TuneupDefPtr& tuneup_def, WheelID_t wheel_id, int media_idx, const std::string& orig_val)
150{
151 TuneupWheelTweak* tweak = nullptr;
152 if (TuneupUtil::isWheelTweaked(tuneup_def, wheel_id, tweak))
153 {
154 ROR_ASSERT(tweak);
155 ROR_ASSERT(tweak->twt_media.size() > media_idx);
156 return (tweak->twt_media[media_idx] != "") ? tweak->twt_media[media_idx] : orig_val;
157 }
158 else
159 {
160 return orig_val;
161 }
162}
163
164std::string RoR::TuneupUtil::getTweakedWheelMediaRG(TuneupDefPtr& tuneup_def, WheelID_t wheel_id, int media_idx, const std::string& orig_val)
165{
166 TuneupWheelTweak* tweak = nullptr;
167 if (TuneupUtil::isWheelTweaked(tuneup_def, wheel_id, tweak))
168 {
169 ROR_ASSERT(tweak);
170 ROR_ASSERT(tweak->twt_media.size() > media_idx);
171 if (tweak->twt_media[media_idx] != "")
172 {
173 // Find the tweak addonpart
174 CacheEntryPtr addonpart_entry = App::GetCacheSystem()->FindEntryByFilename(LT_AddonPart, /*'partial':*/false, tweak->twt_origin);
175 if (addonpart_entry)
176 {
177 return addonpart_entry->resource_group;
178 }
179 else
180 {
181 LOG(fmt::format("[RoR|Tuneup] WARN Addonpart '{}' not found in modcache!", tweak->twt_origin));
182 return orig_val;
183 }
184 }
185 }
186
187 return orig_val;
188
189}
190
192{
193
194
195 if (tuneup_def)
196 {
197 WheelSide forced_side = WheelSide::INVALID;
198 if (tuneup_def->isWheelSideForced(wheel_id, forced_side))
199 {
200 return forced_side;
201 }
202
203 TuneupWheelTweak* tweak = nullptr;
204 if (TuneupUtil::isWheelTweaked(tuneup_def, wheel_id, tweak))
205 {
206 ROR_ASSERT(tweak);
207 if (tweak->twt_side != WheelSide::INVALID)
208 {
209 return tweak->twt_side;
210 }
211 }
212 }
213
214 return orig_val;
215}
216
218{
219 if (tuneup_def)
220 {
221 VideoCamRole forced_role = VCAM_ROLE_INVALID;
222 if (tuneup_def->isVideoCameraRoleForced(camera_id, forced_role))
223 {
224 return forced_role;
225 }
226
227 // STUB: actual tweaking isn't implemented yet
228 }
229
230 return orig_val;
231}
232
234{
235
236
237 if (tuneup_def)
238 {
239 auto itor = tuneup_def->wheel_tweaks.find(wheel_id);
240 if (itor != tuneup_def->wheel_tweaks.end())
241 {
242 out_tweak = &itor->second;
243 return true;
244 }
245 }
246
247 return false;
248}
249
250Ogre::Vector3 RoR::TuneupUtil::getTweakedNodePosition(TuneupDefPtr& tuneup_def, NodeNum_t nodenum, Ogre::Vector3 orig_val)
251{
252 TuneupNodeTweak* tweak = nullptr;
253 if (TuneupUtil::isNodeTweaked(tuneup_def, nodenum, tweak))
254 {
255 ROR_ASSERT(tweak);
256 return tweak->tnt_pos;
257 }
258 else
259 {
260 return orig_val;
261 }
262}
263
264Ogre::Vector3 RoR::TuneupUtil::getTweakedCineCameraPosition(TuneupDefPtr& tuneup_def, CineCameraID_t cinecamid, Ogre::Vector3 orig_val)
265{
266 TuneupCineCameraTweak* tweak = nullptr;
267 if (TuneupUtil::isCineCameraTweaked(tuneup_def, cinecamid, tweak))
268 {
269 ROR_ASSERT(tweak);
270 return tweak->tct_pos;
271 }
272 else
273 {
274 return orig_val;
275 }
276}
277
279{
280 if (tuneup_def)
281 {
282 auto itor = tuneup_def->node_tweaks.find(nodenum);
283 if (itor != tuneup_def->node_tweaks.end())
284 {
285 out_tweak = &itor->second;
286 return true;
287 }
288 }
289
290 return false;
291}
292
294{
295 if (tuneup_def)
296 {
297 auto itor = tuneup_def->cinecam_tweaks.find(cinecamid);
298 if (itor != tuneup_def->cinecam_tweaks.end())
299 {
300 out_tweak = &itor->second;
301 return true;
302 }
303 }
304
305 return false;
306}
307
308
309// > prop
311{
312 return tuneup_def
313 && (tuneup_def->isPropUnwanted(prop_id) || tuneup_def->isPropForceRemoved(prop_id));
314}
315
316Ogre::Vector3 RoR::TuneupUtil::getTweakedPropOffset(TuneupDefPtr& tuneup_def, PropID_t prop_id, Ogre::Vector3 orig_val)
317{
318 TuneupPropTweak* tweak = nullptr;
319 if (TuneupUtil::isPropTweaked(tuneup_def, prop_id, tweak))
320 {
321 ROR_ASSERT(tweak);
322 return tweak->tpt_offset;
323 }
324 else
325 {
326 return orig_val;
327 }
328}
329
330Ogre::Vector3 RoR::TuneupUtil::getTweakedPropRotation(TuneupDefPtr& tuneup_def, PropID_t prop_id, Ogre::Vector3 orig_val)
331{
332 TuneupPropTweak* tweak = nullptr;
333 if (TuneupUtil::isPropTweaked(tuneup_def, prop_id, tweak))
334 {
335 ROR_ASSERT(tweak);
336 return tweak->tpt_rotation;
337 }
338 else
339 {
340 return orig_val;
341 }
342}
343
344std::string RoR::TuneupUtil::getTweakedPropMedia(TuneupDefPtr& tuneup_def, PropID_t prop_id, int media_idx, const std::string& orig_val)
345{
346 TuneupPropTweak* tweak = nullptr;
347 if (TuneupUtil::isPropTweaked(tuneup_def, prop_id, tweak))
348 {
349 ROR_ASSERT(tweak);
350 ROR_ASSERT(tweak->tpt_media.size() > media_idx);
351 return (tweak->tpt_media[media_idx] != "") ? tweak->tpt_media[media_idx] : orig_val;
352 }
353 else
354 {
355 return orig_val;
356 }
357}
358
359std::string RoR::TuneupUtil::getTweakedPropMediaRG(TuneupDefPtr& tuneup_def, PropID_t prop_id, int media_idx, const std::string& orig_val)
360{
361 TuneupPropTweak* tweak = nullptr;
362 if (TuneupUtil::isPropTweaked(tuneup_def, prop_id, tweak))
363 {
364 ROR_ASSERT(tweak);
365 ROR_ASSERT(tweak->tpt_media.size() > media_idx);
366 if (tweak->tpt_media[media_idx] != "")
367 {
368 // Find the tweak addonpart
369 CacheEntryPtr addonpart_entry = App::GetCacheSystem()->FindEntryByFilename(LT_AddonPart, /*partial:*/false, tweak->tpt_origin);
370 if (addonpart_entry)
371 {
372 return addonpart_entry->resource_group;
373 }
374 else
375 {
376 LOG(fmt::format("[RoR|Tuneup] WARN Addonpart '{}' not found in modcache!", tweak->tpt_origin));
377 }
378 }
379 }
380
381 return orig_val;
382}
383
385{
386
387
388 if (tuneup_def)
389 {
390 auto itor = tuneup_def->prop_tweaks.find(prop_id);
391 if (itor != tuneup_def->prop_tweaks.end())
392 {
393 out_tweak = &itor->second;
394 return true;
395 }
396 }
397
398 return false;
399}
400
401// > flexbody
403{
404 return tuneup_def &&
405 (tuneup_def->isFlexbodyUnwanted(flexbody_id) || tuneup_def->isFlexbodyForceRemoved(flexbody_id));
406}
407
408Ogre::Vector3 RoR::TuneupUtil::getTweakedFlexbodyOffset(TuneupDefPtr& tuneup_def, FlexbodyID_t flexbody_id, Ogre::Vector3 orig_val)
409{
410 TuneupFlexbodyTweak* tweak = nullptr;
411 if (TuneupUtil::isFlexbodyTweaked(tuneup_def, flexbody_id, tweak))
412 {
413 ROR_ASSERT(tweak);
414 return tweak->tft_offset;
415 }
416 else
417 {
418 return orig_val;
419 }
420}
421
422Ogre::Vector3 RoR::TuneupUtil::getTweakedFlexbodyRotation(TuneupDefPtr& tuneup_def, FlexbodyID_t flexbody_id, Ogre::Vector3 orig_val)
423{
424 TuneupFlexbodyTweak* tweak = nullptr;
425 if (TuneupUtil::isFlexbodyTweaked(tuneup_def, flexbody_id, tweak))
426 {
427 ROR_ASSERT(tweak);
428 return tweak->tft_rotation;
429 }
430 else
431 {
432 return orig_val;
433 }
434}
435
436std::string RoR::TuneupUtil::getTweakedFlexbodyMedia(TuneupDefPtr& tuneup_def, FlexbodyID_t flexbody_id, int media_idx, const std::string& orig_val)
437{
438 TuneupFlexbodyTweak* tweak = nullptr;
439 if (TuneupUtil::isFlexbodyTweaked(tuneup_def, flexbody_id, tweak))
440 {
441 ROR_ASSERT(tweak);
442 return (tweak->tft_media != "") ? tweak->tft_media : orig_val;
443 }
444 else
445 {
446 return orig_val;
447 }
448}
449
450std::string RoR::TuneupUtil::getTweakedFlexbodyMediaRG(TuneupDefPtr& tuneup_def, FlexbodyID_t flexbody_id, int media_idx, const std::string& orig_val)
451{
452 TuneupFlexbodyTweak* tweak = nullptr;
453 if (TuneupUtil::isFlexbodyTweaked(tuneup_def, flexbody_id, tweak))
454 {
455 ROR_ASSERT(tweak);
456 if (tweak->tft_media != "")
457 {
458 // Find the tweak addonpart
459 CacheEntryPtr addonpart_entry = App::GetCacheSystem()->FindEntryByFilename(LT_AddonPart, /*partial:*/false, tweak->tft_origin);
460 if (addonpart_entry)
461 {
462 return addonpart_entry->resource_group;
463 }
464 else
465 {
466 LOG(fmt::format("[RoR|Tuneup] WARN Addonpart '{}' not found in modcache!", tweak->tft_origin));
467 return orig_val;
468 }
469 }
470 }
471
472 return orig_val;
473}
474
476{
477
478
479 if (tuneup_def)
480 {
481 auto itor = tuneup_def->flexbody_tweaks.find(flexbody_id);
482 if (itor != tuneup_def->flexbody_tweaks.end())
483 {
484 out_tweak = &itor->second;
485 return true;
486 }
487 }
488
489 return false;
490}
491
492// > flare
494{
495 return tuneup_def
496 && (tuneup_def->isFlareUnwanted(flare_id) || tuneup_def->isFlareForceRemoved(flare_id));
497}
498
499// > exhaust
501{
502 return tuneup_def
503 && (tuneup_def->isExhaustUnwanted(exhaust_id) || tuneup_def->isExhaustForceRemoved(exhaust_id));
504}
505
506// > managedmaterials
507bool RoR::TuneupUtil::isManagedMatAnyhowRemoved(TuneupDefPtr& tuneup_def, const std::string& material_name)
508{
509 return tuneup_def
510 && (tuneup_def->isManagedMatUnwanted(material_name) || tuneup_def->isManagedMatForceRemoved(material_name));
511}
512
513bool RoR::TuneupUtil::isManagedMatTweaked(TuneupDefPtr& tuneup_def, const std::string& material_name, TuneupManagedMatTweak*& out_tweak)
514{
515 if (tuneup_def)
516 {
517 auto itor = tuneup_def->managedmat_tweaks.find(material_name);
518 if (itor != tuneup_def->managedmat_tweaks.end())
519 {
520 out_tweak = &itor->second;
521 return true;
522 }
523 }
524
525 return false;
526}
527
528std::string RoR::TuneupUtil::getTweakedManagedMatType(TuneupDefPtr& tuneup_def, const std::string& material_name, const std::string& orig_val)
529{
530 TuneupManagedMatTweak* tweak = nullptr;
531 if (TuneupUtil::isManagedMatTweaked(tuneup_def, material_name, tweak))
532 {
533 ROR_ASSERT(tweak);
534 return (tweak->tmt_type != "") ? tweak->tmt_type : orig_val;
535 }
536 else
537 {
538 return orig_val;
539 }
540}
541
542std::string RoR::TuneupUtil::getTweakedManagedMatMedia(TuneupDefPtr& tuneup_def, const std::string& material_name, int media_idx, const std::string& orig_val)
543{
544 TuneupManagedMatTweak* tweak = nullptr;
545 if (TuneupUtil::isManagedMatTweaked(tuneup_def, material_name, tweak))
546 {
547 ROR_ASSERT(tweak);
548 ROR_ASSERT(tweak->tmt_media.size() > media_idx);
549 return (tweak->tmt_media[media_idx] != "") ? tweak->tmt_media[media_idx] : orig_val;
550 }
551 else
552 {
553 return orig_val;
554 }
555}
556
557std::string RoR::TuneupUtil::getTweakedManagedMatMediaRG(TuneupDefPtr& tuneup_def, const std::string& material_name, int media_idx, const std::string& orig_val)
558{
559 TuneupManagedMatTweak* tweak = nullptr;
560 if (TuneupUtil::isManagedMatTweaked(tuneup_def, material_name, tweak))
561 {
562 ROR_ASSERT(tweak);
563 ROR_ASSERT(tweak->tmt_media.size() > media_idx);
564 if (tweak->tmt_media[media_idx] != "")
565 {
566 // Find the tweak addonpart
567 CacheEntryPtr addonpart_entry = App::GetCacheSystem()->FindEntryByFilename(LT_AddonPart, /*partial:*/false, tweak->tmt_origin);
568 if (addonpart_entry)
569 {
570 return addonpart_entry->resource_group;
571 }
572 else
573 {
574 LOG(fmt::format("[RoR|Tuneup] WARN managedmaterial '{}': Addonpart '{}' not found in modcache!", material_name, tweak->tmt_origin));
575 return orig_val;
576 }
577 }
578 }
579
580 return orig_val;
581}
582
583bool RoR::TuneupUtil::isAddonPartUsed(TuneupDefPtr& tuneup_entry, const std::string& filename)
584{
585 return tuneup_entry
586 && tuneup_entry->use_addonparts.find(filename) != tuneup_entry->use_addonparts.end();
587}
588
589std::vector<TuneupDefPtr> RoR::TuneupUtil::ParseTuneups(Ogre::DataStreamPtr& stream)
590{
591 std::vector<TuneupDefPtr> result;
592 TuneupDefPtr curr_tuneup;
593 try
594 {
595 while(!stream->eof())
596 {
597 std::string line = SanitizeUtf8String(stream->getLine());
598
599 // Ignore blanks & comments
600 if (!line.length() || line.substr(0, 2) == "//")
601 {
602 continue;
603 }
604
605 if (!curr_tuneup)
606 {
607 // No current tuneup -- So first valid data should be tuneup name
608 Ogre::StringUtil::trim(line);
609 curr_tuneup = new TuneupDef();
610 curr_tuneup->name = line;
611 stream->skipLine("{");
612 }
613 else
614 {
615 // Already in tuneup
616 if (line == "}")
617 {
618 result.push_back(curr_tuneup); // Finished
619 curr_tuneup = nullptr;
620 }
621 else
622 {
623 RoR::TuneupUtil::ParseTuneupAttribute(line, curr_tuneup);
624 }
625 }
626 }
627
628 if (curr_tuneup)
629 {
632 fmt::format("Tuneup '{}' in file '{}' not properly closed with '}}'",
633 curr_tuneup->name, stream->getName()));
634 result.push_back(curr_tuneup); // Submit anyway
635 curr_tuneup = nullptr;
636 }
637 }
638 catch (Ogre::Exception& e)
639 {
642 fmt::format("Error parsing tuneup file '{}', message: {}",
643 stream->getName(), e.getFullDescription()));
644 }
645 return result;
646}
647
648void RoR::TuneupUtil::ParseTuneupAttribute(const std::string& line, TuneupDefPtr& tuneup_def) // static
649{
650 Ogre::StringVector params = Ogre::StringUtil::split(line, "\t=,;\n");
651 for (unsigned int i=0; i < params.size(); i++)
652 {
653 Ogre::StringUtil::trim(params[i]);
654 }
655 Ogre::String& attrib = params[0];
656 Ogre::StringUtil::toLowerCase(attrib);
657
658 // General info
659 if (attrib == "preview" && params.size() >= 2) { tuneup_def->thumbnail = params[1]; return; }
660 if (attrib == "description" && params.size() >= 2) { tuneup_def->description = params[1]; return; }
661 if (attrib == "author_name" && params.size() >= 2) { tuneup_def->author_name = params[1]; return; }
662 if (attrib == "author_id" && params.size() == 2) { tuneup_def->author_id = PARSEINT(params[1]); return; }
663 if (attrib == "category_id" && params.size() == 2) { tuneup_def->category_id = (CacheCategoryId)PARSEINT(params[1]); return; }
664 if (attrib == "guid" && params.size() >= 2) { tuneup_def->guid = params[1]; Ogre::StringUtil::trim(tuneup_def->guid); Ogre::StringUtil::toLowerCase(tuneup_def->guid); return; }
665 if (attrib == "name" && params.size() >= 2) { tuneup_def->name = params[1]; Ogre::StringUtil::trim(tuneup_def->name); return; }
666 if (attrib == "filename" && params.size() >= 2) { tuneup_def->filename = params[1]; Ogre::StringUtil::trim(tuneup_def->filename); return; }
667
668 // Addonparts and extracted data
669 if (attrib == "use_addonpart" && params.size() == 2) { tuneup_def->use_addonparts.insert(params[1]); return; }
670 if (attrib == "unwanted_prop" && params.size() == 2) { tuneup_def->unwanted_props.insert(PARSEINT(params[1])); return; }
671 if (attrib == "unwanted_flexbody" && params.size() == 2) { tuneup_def->unwanted_flexbodies.insert(PARSEINT(params[1])); return; }
672 if (attrib == "protected_prop" && params.size() == 2) { tuneup_def->protected_props.insert(PARSEINT(params[1])); return; }
673 if (attrib == "protected_flexbody" && params.size() == 2) { tuneup_def->protected_flexbodies.insert(PARSEINT(params[1])); return; }
674
675 // UI overrides
676 if (attrib == "forced_wheel_side" && params.size() == 3) { tuneup_def->force_wheel_sides[PARSEINT(params[1])] = (WheelSide)PARSEINT(params[2]); return; }
677 if (attrib == "force_remove_prop" && params.size() == 2) { tuneup_def->force_remove_props.insert(PARSEINT(params[1])); return; }
678 if (attrib == "force_remove_flexbody" && params.size() == 2) { tuneup_def->force_remove_flexbodies.insert(PARSEINT(params[1])); return; }
679}
680
681void RoR::TuneupUtil::ExportTuneup(Ogre::DataStreamPtr& stream, TuneupDefPtr& tuneup)
682{
684 buf << tuneup->name << "\n";
685 buf << "{\n";
686
687 // General info:
688 buf << "\tpreview = " << tuneup->thumbnail << "\n";
689 buf << "\tdescription = " << tuneup->description << "\n";
690 buf << "\tauthor_name = " << tuneup->author_name << "\n";
691 buf << "\tauthor_id = " << tuneup->author_id << "\n";
692 buf << "\tcategory_id = " << (int)tuneup->category_id << "\n";
693 buf << "\tguid = " << tuneup->guid << "\n";
694 buf << "\tfilename = " << tuneup->filename << "\n";
695 buf << "\n";
696
697 // Addonparts and extracted data:
698 for (const std::string& addonpart: tuneup->use_addonparts)
699 {
700 buf << "\tuse_addonpart = " << addonpart << "\n";
701 }
702 for (PropID_t unwanted_prop: tuneup->unwanted_props)
703 {
704 buf << "\tunwanted_prop = " << (int)unwanted_prop << "\n";
705 }
706 for (FlexbodyID_t unwanted_flexbody: tuneup->unwanted_flexbodies)
707 {
708 buf << "\tunwanted_flexbody = " << (int)unwanted_flexbody << "\n";
709 }
710 for (PropID_t protected_prop: tuneup->protected_props)
711 {
712 buf << "\tprotected_prop = " << (int)protected_prop << "\n";
713 }
714 for (FlexbodyID_t protected_flexbody: tuneup->protected_flexbodies)
715 {
716 buf << "\tprotected_flexbody = " << (int)protected_flexbody << "\n";
717 }
718
719 // UI overrides:
720 for (PropID_t prop: tuneup->force_remove_props)
721 {
722 buf << "\tforce_remove_prop = " << (int)prop << "\n";
723 }
724 for (FlexbodyID_t flexbody: tuneup->force_remove_flexbodies)
725 {
726 buf << "\tforce_remove_flexbody = " << (int)flexbody << "\n";
727 }
728 for (auto& pair: tuneup->force_wheel_sides)
729 {
730 buf << "\tforced_wheel_side = " << pair.first << ", " << (int)pair.second << "\n";
731 }
732 buf << "}\n\n";
733
734 size_t written = stream->write(buf.GetBuffer(), buf.GetLength());
735 if (written < buf.GetLength())
736 {
738 fmt::format("Error writing file '{}': only written {}/{} bytes", stream->getName(), written, buf.GetLength()));
739 }
740}
741
Central state/object manager and communications hub.
#define ROR_ASSERT(_EXPR)
Definition Application.h:40
#define PARSEINT(x)
Definition Application.h:58
void LOG(const char *msg)
Legacy alias - formerly a macro.
A database of user-installed content alias 'mods' (vehicles, terrains...)
The vehicle tuning system; applies addonparts and user overrides to vehicles.
Ogre::String resource_group
Resource group of the loaded bundle. Empty if not loaded yet.
Definition CacheSystem.h:89
CacheEntryPtr FindEntryByFilename(RoR::LoaderType type, bool partial, const std::string &_filename_maybe_bundlequalified)
Returns NULL if none found; "Bundle-qualified" format also specifies the ZIP/directory in modcache,...
@ CONSOLE_MSGTYPE_ACTOR
Parsing/spawn/simulation messages for actors.
Definition Console.h:63
@ CONSOLE_MSGTYPE_INFO
Generic message.
Definition Console.h:60
void putMessage(MessageArea area, MessageType type, std::string const &msg, std::string icon="")
Definition Console.cpp:103
@ CONSOLE_SYSTEM_WARNING
Definition Console.h:53
Wrapper for classic c-string (local buffer) Refresher: strlen() excludes '\0' terminator; strncat() A...
Definition Str.h:36
char * GetBuffer()
Definition Str.h:48
size_t GetLength() const
Definition Str.h:51
static bool isAddonPartUsed(TuneupDefPtr &tuneup_entry, const std::string &filename)
static Ogre::Vector3 getTweakedPropRotation(TuneupDefPtr &tuneup_entry, PropID_t prop_id, Ogre::Vector3 orig_val)
static VideoCamRole getTweakedVideoCameraRole(TuneupDefPtr &tuneup_def, VideoCameraID_t camera_id, VideoCamRole orig_val)
static std::string getTweakedPropMedia(TuneupDefPtr &tuneup_entry, PropID_t prop_id, int media_idx, const std::string &orig_val)
static bool isManagedMatTweaked(TuneupDefPtr &tuneup_def, const std::string &matname, TuneupManagedMatTweak *&out_tweak)
static std::string getTweakedPropMediaRG(TuneupDefPtr &tuneup_def, PropID_t prop_id, int media_idx, const std::string &orig_val)
static void ParseTuneupAttribute(const std::string &line, TuneupDefPtr &tuneup_def)
static void ExportTuneup(Ogre::DataStreamPtr &stream, TuneupDefPtr &tuneup)
static bool isPropAnyhowRemoved(TuneupDefPtr &tuneup_def, PropID_t prop_id)
static bool isWheelTweaked(TuneupDefPtr &tuneup_entry, WheelID_t wheel_id, TuneupWheelTweak *&out_tweak)
static Ogre::Vector3 getTweakedCineCameraPosition(TuneupDefPtr &tuneup_entry, CineCameraID_t cinecamid, Ogre::Vector3 orig_val)
static Ogre::Vector3 getTweakedPropOffset(TuneupDefPtr &tuneup_entry, PropID_t prop_id, Ogre::Vector3 orig_val)
static bool isFlareAnyhowRemoved(TuneupDefPtr &tuneup_def, FlareID_t flare_id)
static std::string getTweakedFlexbodyMediaRG(TuneupDefPtr &tuneup_def, FlexbodyID_t flexbody_id, int media_idx, const std::string &orig_val)
static float getTweakedWheelTireRadius(TuneupDefPtr &tuneup_entry, WheelID_t wheel_id, float orig_val)
static std::string getTweakedFlexbodyMedia(TuneupDefPtr &tuneup_entry, FlexbodyID_t flexbody_id, int media_idx, const std::string &orig_val)
static bool isManagedMatAnyhowRemoved(TuneupDefPtr &tuneup_def, const std::string &matname)
static bool isNodeTweaked(TuneupDefPtr &tuneup_entry, NodeNum_t nodenum, TuneupNodeTweak *&out_tweak)
static Ogre::Vector3 getTweakedFlexbodyOffset(TuneupDefPtr &tuneup_entry, FlexbodyID_t flexbody_id, Ogre::Vector3 orig_val)
static float getTweakedWheelRimRadius(TuneupDefPtr &tuneup_entry, WheelID_t wheel_id, float orig_val)
static std::string getTweakedManagedMatMediaRG(TuneupDefPtr &tuneup_def, const std::string &matname, int media_idx, const std::string &orig_val)
static bool isFlexbodyTweaked(TuneupDefPtr &tuneup_entry, FlexbodyID_t flexbody_id, TuneupFlexbodyTweak *&out_tweak)
static bool isCineCameraTweaked(TuneupDefPtr &tuneup_entry, CineCameraID_t cinecamid, TuneupCineCameraTweak *&out_tweak)
static std::vector< TuneupDefPtr > ParseTuneups(Ogre::DataStreamPtr &stream)
static std::string getTweakedManagedMatMedia(TuneupDefPtr &tuneup_def, const std::string &matname, int media_idx, const std::string &orig_val)
static bool isPropTweaked(TuneupDefPtr &tuneup_entry, PropID_t flexbody_id, TuneupPropTweak *&out_tweak)
static Ogre::Vector3 getTweakedNodePosition(TuneupDefPtr &tuneup_entry, NodeNum_t nodenum, Ogre::Vector3 orig_val)
static Ogre::Vector3 getTweakedFlexbodyRotation(TuneupDefPtr &tuneup_entry, FlexbodyID_t flexbody_id, Ogre::Vector3 orig_val)
static bool isFlexbodyAnyhowRemoved(TuneupDefPtr &tuneup_def, FlexbodyID_t flexbody_id)
static std::string getTweakedManagedMatType(TuneupDefPtr &tuneup_def, const std::string &matname, const std::string &orig_val)
static WheelSide getTweakedWheelSide(TuneupDefPtr &tuneup_entry, WheelID_t wheel_id, WheelSide orig_val)
static bool isExhaustAnyhowRemoved(TuneupDefPtr &tuneup_def, ExhaustID_t exhaust_id)
static std::string getTweakedWheelMediaRG(TuneupDefPtr &tuneup_def, WheelID_t wheel_id, int media_idx, const std::string &orig_val)
static std::string getTweakedWheelMedia(TuneupDefPtr &tuneup_entry, WheelID_t wheel_id, int media_idx, const std::string &orig_val)
Console * GetConsole()
CacheSystem * GetCacheSystem()
@ LT_AddonPart
int CineCameraID_t
Index into Actor::ar_cinecam_node and Actor::ar_camera_node_* arrays; use RoR::CINECAMERAID_INVALID a...
WheelSide
Used by rig-def/addonpart/tuneup formats to specify wheel rim mesh orientation.
VideoCamRole
@ VCAM_ROLE_INVALID
int WheelID_t
Index to Actor::ar_wheels, use RoR::WHEELID_INVALID as empty value.
int VideoCameraID_t
Index into GfxActor::m_videocameras, use RoR::VIDEOCAMERAID_INVALID as empty value.
int PropID_t
Index to GfxActor::m_props, use RoR::PROPID_INVALID as empty value.
int FlareID_t
Index into Actor::ar_flares, use RoR::FLAREID_INVALID as empty value.
int ExhaustID_t
Index into GfxActor::m_exhausts, use RoR::EXHAUSTID_INVALID as empty value.
std::string SanitizeUtf8String(std::string const &str_in)
Definition Utils.cpp:120
int FlexbodyID_t
Index to GfxActor::m_flexbodies, use RoR::FLEXBODYID_INVALID as empty value.
CacheCategoryId
uint16_t NodeNum_t
Node position within Actor::ar_nodes; use RoR::NODENUM_INVALID as empty value.
< Data of 'addonpart_tweak_cinecam <cinecam ID> <posX> <posY> <posZ>'
Ogre::Vector3 tct_pos
Args#234, required.
Dual purpose:
std::string description
std::string filename
target vehicle filename
bool isFlexbodyUnwanted(FlexbodyID_t flexbodyid)
bool isManagedMatUnwanted(const std::string &matname)
std::set< WheelID_t > protected_wheels
Wheels that cannot be altered via 'addonpart_tweak_wheel'.
bool isVideoCameraRoleForced(VideoCameraID_t camera_id, VideoCamRole &out_val) const
std::string thumbnail
std::set< FlareID_t > protected_flares
Flares which cannot be altered via 'addonpart_unwanted_flare' directive.
std::map< WheelID_t, TuneupWheelTweak > wheel_tweaks
Mesh name and radius overrides via 'addonpart_tweak_wheel'.
std::set< std::string > protected_managedmats
Managed materials which cannot be altered via 'addonpart_tweak_managedmaterial' directive.
bool isFlareUnwanted(FlareID_t flareid)
std::set< ExhaustID_t > protected_exhausts
Exhausts which cannot be altered via 'addonpart_unwanted_exhaust' directive.
std::set< NodeNum_t > protected_nodes
Nodes that cannot be altered via 'addonpart_tweak_node'.
std::set< PropID_t > unwanted_props
'addonpart_unwanted_prop' directives.
bool isPropForceRemoved(PropID_t propid)
std::set< FlexbodyID_t > unwanted_flexbodies
'addonpart_unwanted_flexbody' directives.
std::map< VideoCameraID_t, VideoCamRole > force_video_cam_roles
UI overrides.
std::set< FlexbodyID_t > protected_flexbodies
Flexbodies which cannot be altered via 'addonpart_tweak_flexbody' or 'addonpart_unwanted_flexbody' di...
std::map< PropID_t, TuneupPropTweak > prop_tweaks
Mesh name(s), offset and rotation overrides via 'addonpart_tweak_prop'.
TuneupDefPtr clone()
bool isPropUnwanted(PropID_t propid)
bool isWheelSideForced(WheelID_t wheelid, WheelSide &out_val) const
std::map< NodeNum_t, TuneupNodeTweak > node_tweaks
Node position overrides via 'addonpart_tweak_node'.
std::set< std::string > use_addonparts
Addonpart filenames.
bool isFlexbodyForceRemoved(FlexbodyID_t flexbodyid)
bool isFlareForceRemoved(FlareID_t flareid)
bool isManagedMatForceRemoved(const std::string &matname)
std::map< FlexbodyID_t, TuneupFlexbodyTweak > flexbody_tweaks
Mesh name, offset and rotation overrides via 'addonpart_tweak_flexbody'.
CacheCategoryId category_id
std::set< PropID_t > force_remove_props
UI overrides.
bool isExhaustUnwanted(ExhaustID_t exhaustid)
std::map< CineCameraID_t, TuneupCineCameraTweak > cinecam_tweaks
Cinecam position overrides via 'addonpart_tweak_cinecam'.
bool isExhaustForceRemoved(ExhaustID_t exhaustid)
std::map< std::string, TuneupManagedMatTweak > managedmat_tweaks
Managed material overrides via 'addonpart_tweak_managedmaterial'.
std::set< PropID_t > protected_props
Props which cannot be altered via 'addonpart_tweak_prop' or 'addonpart_unwanted_prop' directive.
std::string guid
target vehicle GUID
std::set< FlexbodyID_t > force_remove_flexbodies
UI overrides.
std::string author_name
std::map< WheelID_t, WheelSide > force_wheel_sides
UI overrides.
< Data of 'addonpart_tweak_flexbody <flexbody ID> <offsetX> <offsetY> <offsetZ> <rotX> <rotY> <rotZ> ...
std::string tft_origin
Addonpart filename.
< Data of 'addonpart_tweak_managedmaterial <name> <type> <media1> <media2> [<media3>]'
std::string tmt_type
Arg#2, required.
std::string tmt_origin
Addonpart filename.
std::array< std::string, 3 > tmt_media
Arg#3, required, Arg#4, optional, Arg#5, optional.
< Data of 'addonpart_tweak_node <nodenum> <posX> <posY> <posZ>'
Ogre::Vector3 tnt_pos
Args#234, required.
< Data of 'addonpart_tweak_prop <prop ID> <offsetX> <offsetY> <offsetZ> <rotX> <rotY> <rotZ> <media1>...
std::string tpt_origin
Addonpart filename.
Ogre::Vector3 tpt_rotation
std::array< std::string, 2 > tpt_media
Media1 = prop mesh; Media2: Steering wheel mesh or beacon flare material.
< Data of 'addonpart_tweak_wheel <wheel ID> <media1> <media2> <side flag> <tire radius> <rim radius>'
WheelSide twt_side
Arg#4, optional, default LEFT (Only applicable to mesh/flexbody wheels)
float twt_tire_radius
Arg#5, optional.
std::array< std::string, 2 > twt_media
twt_media[0] Arg#2, required ('wheels[2]': face material, 'meshwheels[2]/flexbodywheels': rim mesh) t...
std::string twt_origin
Addonpart filename.
float twt_rim_radius
Arg#6, optional, only applies to some wheel types.