RigsofRods
Soft-body Physics Simulation
Savegame.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-2020 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 "Application.h"
23 
24 #include "AeroEngine.h"
25 #include "Application.h"
26 #include "Actor.h"
27 #include "Buoyance.h"
28 #include "CacheSystem.h"
29 #include "ContentManager.h"
30 #include "Console.h"
31 #include "EngineSim.h"
32 #include "GameContext.h"
33 #include "GUIManager.h"
34 #include "GUI_MessageBox.h"
35 #include "InputEngine.h"
36 #include "Language.h"
37 #include "PlatformUtils.h"
38 #include "ScrewProp.h"
39 #include "Skidmark.h"
40 #include "SkyManager.h"
41 #include "Terrain.h"
42 #include "TuneupFileFormat.h"
43 
44 #include <rapidjson/rapidjson.h>
45 #include <fstream>
46 
47 #define SAVEGAME_FILE_FORMAT 3
48 
49 using namespace Ogre;
50 using namespace RoR;
51 
52 // --------------------------------
53 // GameContext functions
54 
55 std::string GameContext::GetQuicksaveFilename()
56 {
57  std::string terrain_name = App::sim_terrain_name->getStr();
58  std::string mp = (App::mp_state->getEnum<MpState>() == RoR::MpState::CONNECTED) ? "_mp" : "";
59 
60  return "quicksave_" + StringUtil::replaceAll(terrain_name, ".terrn2", "") + mp + ".sav";
61 }
62 
63 void GameContext::LoadScene(std::string const& filename)
64 {
65  ROR_ASSERT(App::GetGameContext()->GetTerrain());
66  m_actor_manager.LoadScene(filename);
67 }
68 
69 void GameContext::SaveScene(std::string const& filename)
70 {
71  m_actor_manager.SaveScene(filename);
72 }
73 
74 std::string GameContext::ExtractSceneName(std::string const& filename)
75 {
76  // Read from disk
77  rapidjson::Document j_doc;
78  if (!App::GetContentManager()->LoadAndParseJson(filename, RGN_SAVEGAMES, j_doc) ||
79  !j_doc.IsObject() || !j_doc.HasMember("format_version") || !j_doc["format_version"].IsNumber() ||
80  !j_doc.HasMember("scene_name") || !j_doc["scene_name"].IsString())
81  return "";
82 
83  return j_doc["scene_name"].GetString();
84 }
85 
86 std::string GameContext::ExtractSceneTerrain(std::string const& filename)
87 {
88  // Read from disk
89  rapidjson::Document j_doc;
90  if (!App::GetContentManager()->LoadAndParseJson(filename, RGN_SAVEGAMES, j_doc) ||
91  !j_doc.IsObject() || !j_doc.HasMember("format_version") || !j_doc["format_version"].IsNumber() ||
92  !j_doc.HasMember("terrain_name") || !j_doc["terrain_name"].IsString())
93  return "";
94 
95  return j_doc["terrain_name"].GetString();
96 }
97 
98 void GameContext::HandleSavegameHotkeys()
99 {
100  // Global savegames
101  int slot = -1;
102  if (App::GetInputEngine()->getEventBoolValueBounce(EV_COMMON_QUICKLOAD_01, 1.0f))
103  {
104  slot = 1;
105  }
106  if (App::GetInputEngine()->getEventBoolValueBounce(EV_COMMON_QUICKLOAD_02, 1.0f))
107  {
108  slot = 2;
109  }
110  if (App::GetInputEngine()->getEventBoolValueBounce(EV_COMMON_QUICKLOAD_03, 1.0f))
111  {
112  slot = 3;
113  }
114  if (App::GetInputEngine()->getEventBoolValueBounce(EV_COMMON_QUICKLOAD_04, 1.0f))
115  {
116  slot = 4;
117  }
118  if (App::GetInputEngine()->getEventBoolValueBounce(EV_COMMON_QUICKLOAD_05, 1.0f))
119  {
120  slot = 5;
121  }
122  if (App::GetInputEngine()->getEventBoolValueBounce(EV_COMMON_QUICKLOAD_06, 1.0f))
123  {
124  slot = 6;
125  }
126  if (App::GetInputEngine()->getEventBoolValueBounce(EV_COMMON_QUICKLOAD_07, 1.0f))
127  {
128  slot = 7;
129  }
130  if (App::GetInputEngine()->getEventBoolValueBounce(EV_COMMON_QUICKLOAD_08, 1.0f))
131  {
132  slot = 8;
133  }
134  if (App::GetInputEngine()->getEventBoolValueBounce(EV_COMMON_QUICKLOAD_09, 1.0f))
135  {
136  slot = 9;
137  }
138  if (App::GetInputEngine()->getEventBoolValueBounce(EV_COMMON_QUICKLOAD_10, 1.0f))
139  {
140  slot = 0;
141  }
142  if (slot != -1)
143  {
144  Ogre::String filename = Ogre::StringUtil::format("quicksave-%d.sav", slot);
146  }
147 
148  if (App::sim_terrain_name->getStr() == "" || App::sim_state->getEnum<SimState>() != SimState::RUNNING)
149  return;
150 
151  slot = -1;
152  if (App::GetInputEngine()->getEventBoolValueBounce(EV_COMMON_QUICKSAVE_01, 1.0f))
153  {
154  slot = 1;
155  }
156  if (App::GetInputEngine()->getEventBoolValueBounce(EV_COMMON_QUICKSAVE_02, 1.0f))
157  {
158  slot = 2;
159  }
160  if (App::GetInputEngine()->getEventBoolValueBounce(EV_COMMON_QUICKSAVE_03, 1.0f))
161  {
162  slot = 3;
163  }
164  if (App::GetInputEngine()->getEventBoolValueBounce(EV_COMMON_QUICKSAVE_04, 1.0f))
165  {
166  slot = 4;
167  }
168  if (App::GetInputEngine()->getEventBoolValueBounce(EV_COMMON_QUICKSAVE_05, 1.0f))
169  {
170  slot = 5;
171  }
172  if (App::GetInputEngine()->getEventBoolValueBounce(EV_COMMON_QUICKSAVE_06, 1.0f))
173  {
174  slot = 6;
175  }
176  if (App::GetInputEngine()->getEventBoolValueBounce(EV_COMMON_QUICKSAVE_07, 1.0f))
177  {
178  slot = 7;
179  }
180  if (App::GetInputEngine()->getEventBoolValueBounce(EV_COMMON_QUICKSAVE_08, 1.0f))
181  {
182  slot = 8;
183  }
184  if (App::GetInputEngine()->getEventBoolValueBounce(EV_COMMON_QUICKSAVE_09, 1.0f))
185  {
186  slot = 9;
187  }
188  if (App::GetInputEngine()->getEventBoolValueBounce(EV_COMMON_QUICKSAVE_10, 1.0f))
189  {
190  slot = 0;
191  }
192  if (slot != -1)
193  {
194  Ogre::String filename = Ogre::StringUtil::format("quicksave-%d.sav", slot);
195  App::GetGameContext()->SaveScene(filename);
196  }
197 
198  // Terrain local savegames
199 
200  if (App::GetInputEngine()->getEventBoolValueBounce(EV_COMMON_QUICKLOAD, 1.0f))
201  {
202  if (App::sim_quickload_dialog->getBool())
203  {
205  dialog->mbc_title = _LC("QuickloadDialog", "Load game?");
206  dialog->mbc_text = _LC("QuickloadDialog", "You will lose all unsaved progress!");
208 
209  GUI::MessageBoxButton ok_btn;
210  ok_btn.mbb_caption = _LC("QuickloadDialog", "Load");
213  dialog->mbc_buttons.push_back(ok_btn);
214 
215  GUI::MessageBoxButton cancel_btn;
216  cancel_btn.mbb_caption = _LC("QuickloadDialog", "Cancel");
217  dialog->mbc_buttons.push_back(cancel_btn); // No action - just close the dialog.
218 
221  }
222  else
223  {
226  App::GetGameContext()->GetQuicksaveFilename()));
227  }
228  }
229 
230  if (App::GetInputEngine()->getEventBoolValueBounce(EV_COMMON_QUICKSAVE))
231  {
232  App::GetGameContext()->SaveScene(App::GetGameContext()->GetQuicksaveFilename());
233  }
234 }
235 
236 // --------------------------------
237 // ActorManager functions
238 
239 bool ActorManager::LoadScene(Ogre::String save_filename)
240 {
241  // Read from disk
242  rapidjson::Document j_doc;
243  if (!App::GetContentManager()->LoadAndParseJson(save_filename, RGN_SAVEGAMES, j_doc) ||
244  !j_doc.IsObject() || !j_doc.HasMember("format_version") || !j_doc["format_version"].IsNumber())
245  {
247  Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_ERROR, _L("Error while loading scene: File invalid or missing"));
248  return false;
249  }
250  if (j_doc["format_version"].GetInt() != SAVEGAME_FILE_FORMAT)
251  {
253  Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_ERROR, _L("Error while loading scene: File format mismatch"));
254  return false;
255  }
256 
257  // Terrain
258  String terrain_name = j_doc["terrain_name"].GetString();
259 
260  if (App::mp_state->getEnum<MpState>() == RoR::MpState::CONNECTED)
261  {
262  if (save_filename == "autosave.sav")
263  return false;
264  if (terrain_name != App::sim_terrain_name->getStr())
265  {
267  Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_ERROR, _L("Error while loading scene: Terrain mismatch"));
268  return false;
269  }
270  if (j_doc["actors"].GetArray().Size() > 3)
271  {
273  Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_ERROR, _L("Error while loading scene: Too many vehicles"));
274  return false;
275  }
276  }
277 
278  m_forced_awake = j_doc["forced_awake"].GetBool();
279 
280  App::GetGameContext()->GetActorManager()->SetSimulationPaused(j_doc["physics_paused"].GetBool());
281 
282 #ifdef USE_CAELUM
283  if (App::gfx_sky_mode->getEnum<GfxSkyMode>() == GfxSkyMode::CAELUM)
284  {
285  if (j_doc.HasMember("daytime"))
286  {
287  App::GetGameContext()->GetTerrain()->getSkyManager()->SetTime(j_doc["daytime"].GetDouble());
288  }
289  }
290 #endif // USE_CAELUM
291 
292  // Character
293  auto data = j_doc["player_position"].GetArray();
294  Vector3 position = Vector3(data[0].GetFloat(), data[1].GetFloat(), data[2].GetFloat());
296  App::GetGameContext()->GetPlayerCharacter()->setRotation(Radian(j_doc["player_rotation"].GetFloat()));
297 
298  // Actors
299  auto actors_changed = false;
300  auto player_actor = App::GetGameContext()->GetPlayerActor();
301  auto prev_player_actor = App::GetGameContext()->GetPrevPlayerActor();
302  std::vector<ActorPtr> actors;
303  std::vector<ActorPtr> x_actors = GetLocalActors();
304  for (rapidjson::Value& j_entry: j_doc["actors"].GetArray())
305  {
306  // NOTE: The filename is by default in "Bundle-qualified" format, i.e. "mybundle.zip:myactor.truck"
307  String rigdef_filename = j_entry["filename"].GetString();
308  CacheEntryPtr actor_entry = App::GetCacheSystem()->FindEntryByFilename(LT_AllBeam, /*partial:*/false, rigdef_filename);
309 
310  CacheEntryPtr skin = nullptr;
311  if (j_entry.HasMember("skin"))
312  {
313  skin = App::GetCacheSystem()->FetchSkinByName(j_entry["skin"].GetString());
314  }
315 
316  TuneupDefPtr working_tuneup = nullptr;
317  if (j_entry.HasMember("tuneup_document"))
318  {
319  const char* tuneup_str = j_entry["tuneup_document"].GetString();
320  size_t tuneup_len = j_entry["tuneup_document"].GetStringLength();
321  Ogre::DataStreamPtr datastream(new Ogre::MemoryDataStream((void*)tuneup_str, tuneup_len));
322  std::vector<TuneupDefPtr> tuneups = TuneupUtil::ParseTuneups(datastream);
323  ROR_ASSERT(tuneups.size() > 0);
324  working_tuneup = tuneups[0];
325  }
326 
327  String section_config = j_entry["section_config"].GetString();
328 
329  ActorPtr actor = nullptr;
330  int index = static_cast<int>(actors.size());
331  if (index < x_actors.size())
332  {
333  if (j_entry["filename"].GetString() != x_actors[index]->ar_filename ||
334  (skin != nullptr && skin->dname != x_actors[index]->m_used_skin_entry->dname) ||
335  section_config != x_actors[index]->getSectionConfig())
336  {
337  if (x_actors[index] == player_actor)
338  {
340  }
341  else if (x_actors[index] == prev_player_actor)
342  {
344  }
345  App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, static_cast<void*>(new ActorPtr(x_actors[index]))));
346  actors_changed = true;
347  }
348  else
349  {
350  actor = x_actors[index];
351  actor->SyncReset(false);
352  }
353  }
354 
355  if (actor == nullptr)
356  {
357  bool preloaded = j_entry["preloaded_with_terrain"].GetBool();
358 
360  rq->asr_filename = rigdef_filename;
361  rq->asr_position.x = j_entry["position"][0].GetFloat();
362  rq->asr_position.y = preloaded ? j_entry["position"][1].GetFloat() : j_entry["min_height"].GetFloat();
363  rq->asr_position.z = j_entry["position"][2].GetFloat();
364  rq->asr_rotation = Quaternion(Degree(270) - Radian(j_entry["rotation"].GetFloat()), Vector3::UNIT_Y);
365  rq->asr_skin_entry = skin;
366  rq->asr_working_tuneup = working_tuneup;
367  rq->asr_config = section_config;
368  rq->asr_origin = preloaded ? ActorSpawnRequest::Origin::TERRN_DEF : ActorSpawnRequest::Origin::SAVEGAME;
369  rq->asr_free_position = preloaded;
370  // Copy saved state
371  rq->asr_saved_state = std::shared_ptr<rapidjson::Document>(new rapidjson::Document());
372  rq->asr_saved_state->CopyFrom(j_entry, rq->asr_saved_state->GetAllocator());
373 
375  actors_changed = true;
376  // CAUTION: `actor` remains nullptr!
377  }
378 
379  actors.push_back(actor);
380  }
381  for (size_t index = actors.size(); index < x_actors.size(); index++)
382  {
383  if (x_actors[index] == player_actor)
384  {
386  }
387  else if (x_actors[index] == prev_player_actor)
388  {
390  }
391  App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, static_cast<void*>(new ActorPtr(x_actors[index]))));
392  actors_changed = true;
393  }
394 
395  const int num_actors = static_cast<int>(j_doc["actors"].Size());
396  for (int index = 0; index < num_actors; index++)
397  {
398  if (actors[index] == nullptr)
399  continue;
400 
401  ActorPtr actor = actors[index];
402  rapidjson::Value& j_entry = j_doc["actors"][index];
403 
404  this->RestoreSavedState(actor, j_entry);
405  }
406 
407  if (save_filename != "autosave.sav")
408  {
410  Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_NOTICE, _L("Scene loaded"));
411  }
412 
413  return true;
414 }
415 
416 bool ActorManager::SaveScene(Ogre::String filename)
417 {
418  std::vector<ActorPtr> x_actors = GetLocalActors();
419 
420  if (App::mp_state->getEnum<MpState>() == RoR::MpState::CONNECTED)
421  {
422  if (filename == "autosave.sav")
423  return false;
424  if (x_actors.size() > 3)
425  {
427  Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_ERROR, _L("Error while saving scene: Too many vehicles"));
428  return false;
429  }
430  }
431 
432  rapidjson::Document j_doc;
433  j_doc.SetObject();
434  j_doc.AddMember("format_version", SAVEGAME_FILE_FORMAT, j_doc.GetAllocator());
435 
436  // Pretty name
437  String pretty_name = App::GetCacheSystem()->GetPrettyName(App::sim_terrain_name->getStr());
438  String scene_name = StringUtil::format("%s [%d]", pretty_name.c_str(), x_actors.size());
439  j_doc.AddMember("scene_name", rapidjson::StringRef(scene_name.c_str()), j_doc.GetAllocator());
440 
441  // Terrain
442  j_doc.AddMember("terrain_name", rapidjson::StringRef(App::sim_terrain_name->getStr().c_str()), j_doc.GetAllocator());
443 
444 #ifdef USE_CAELUM
445  if (App::gfx_sky_mode->getEnum<GfxSkyMode>() == GfxSkyMode::CAELUM)
446  {
447  j_doc.AddMember("daytime", App::GetGameContext()->GetTerrain()->getSkyManager()->GetTime(), j_doc.GetAllocator());
448  }
449 #endif // USE_CAELUM
450 
451  j_doc.AddMember("forced_awake", m_forced_awake, j_doc.GetAllocator());
452 
453  j_doc.AddMember("physics_paused", App::GetGameContext()->GetActorManager()->IsSimulationPaused(), j_doc.GetAllocator());
454 
455  // Character
456  rapidjson::Value j_player_position(rapidjson::kArrayType);
457  j_player_position.PushBack(App::GetGameContext()->GetPlayerCharacter()->getPosition().x, j_doc.GetAllocator());
458  j_player_position.PushBack(App::GetGameContext()->GetPlayerCharacter()->getPosition().y, j_doc.GetAllocator());
459  j_player_position.PushBack(App::GetGameContext()->GetPlayerCharacter()->getPosition().z, j_doc.GetAllocator());
460  j_doc.AddMember("player_position", j_player_position, j_doc.GetAllocator());
461  j_doc.AddMember("player_rotation", App::GetGameContext()->GetPlayerCharacter()->getRotation().valueRadians(), j_doc.GetAllocator());
462 
463  std::map<int, int> vector_index_lookup;
464  for (ActorPtr& actor : m_actors)
465  {
466  vector_index_lookup[actor->ar_vector_index] = -1;
467  auto search = std::find_if(x_actors.begin(), x_actors.end(), [actor](ActorPtr b)
468  { return actor->ar_instance_id == b->ar_instance_id; });
469  if (search != x_actors.end())
470  {
471  vector_index_lookup[actor->ar_vector_index] = std::distance(x_actors.begin(), search);
472  }
473  }
474 
475  // Actors
476  rapidjson::Value j_actors(rapidjson::kArrayType);
477  for (ActorPtr actor : x_actors)
478  {
479  rapidjson::Value j_entry(rapidjson::kObjectType);
480 
481  // Save the filename in "Bundle-qualified" format, i.e. "mybundle.zip:myactor.truck"
482  std::string bname;
483  std::string bpath;
484  Ogre::StringUtil::splitFilename(actor->getUsedActorEntry()->resource_bundle_path, bname, bpath);
485  std::string bq_filename = fmt::format("{}:{}", bname, actor->ar_filename);
486  rapidjson::Value j_bq_filename(bq_filename.c_str(), j_doc.GetAllocator());
487  j_entry.AddMember("filename", j_bq_filename, j_doc.GetAllocator());
488 
489  rapidjson::Value j_actor_position(rapidjson::kArrayType);
490  j_actor_position.PushBack(actor->ar_nodes[0].AbsPosition.x, j_doc.GetAllocator());
491  j_actor_position.PushBack(actor->ar_nodes[0].AbsPosition.y, j_doc.GetAllocator());
492  j_actor_position.PushBack(actor->ar_nodes[0].AbsPosition.z, j_doc.GetAllocator());
493  j_entry.AddMember("position", j_actor_position, j_doc.GetAllocator());
494  j_entry.AddMember("rotation", actor->getRotation(), j_doc.GetAllocator());
495  j_entry.AddMember("min_height", actor->getMinHeight(), j_doc.GetAllocator());
496  j_entry.AddMember("spawn_rotation", actor->m_spawn_rotation, j_doc.GetAllocator());
497  j_entry.AddMember("preloaded_with_terrain", actor->isPreloadedWithTerrain(), j_doc.GetAllocator());
498  j_entry.AddMember("sim_state", static_cast<int>(actor->ar_state), j_doc.GetAllocator());
499  j_entry.AddMember("physics_paused", actor->ar_physics_paused, j_doc.GetAllocator());
500  j_entry.AddMember("player_actor", actor==App::GetGameContext()->GetPlayerActor(), j_doc.GetAllocator());
501  j_entry.AddMember("prev_player_actor", actor==App::GetGameContext()->GetPrevPlayerActor(), j_doc.GetAllocator());
502 
503  if (actor->m_used_skin_entry)
504  {
505  j_entry.AddMember("skin", rapidjson::StringRef(actor->m_used_skin_entry->dname.c_str()), j_doc.GetAllocator());
506  }
507 
508  if (actor->getWorkingTuneupDef())
509  {
510  // Include the entire .tuneup file in the savegame.
511  rapidjson::Value j_tuneup_document(rapidjson::kStringType);
512  Str<TUNEUP_BUF_SIZE> tuneup_buf; // `Ogre::MemoryDataStream` doesn't zero-out the buffer it creates; we must supply our own zeroed memory.
513  Ogre::DataStreamPtr datastream(new Ogre::MemoryDataStream(tuneup_buf.GetBuffer(), tuneup_buf.GetCapacity()));
514  TuneupUtil::ExportTuneup(datastream, actor->getWorkingTuneupDef());
515  j_tuneup_document.SetString(datastream->getAsString().c_str(), j_doc.GetAllocator());
516  j_entry.AddMember("tuneup_document", j_tuneup_document, j_doc.GetAllocator());
517  }
518 
519  j_entry.AddMember("section_config", rapidjson::StringRef(actor->m_section_config.c_str()), j_doc.GetAllocator());
520 
521  // Engine, anti-lock brake, traction control
522  if (actor->ar_engine)
523  {
524  j_entry.AddMember("engine_gear", actor->ar_engine->GetGear(), j_doc.GetAllocator());
525  j_entry.AddMember("engine_rpm", actor->ar_engine->GetEngineRpm(), j_doc.GetAllocator());
526  j_entry.AddMember("engine_auto_mode", actor->ar_engine->GetAutoMode(), j_doc.GetAllocator());
527  j_entry.AddMember("engine_auto_select", actor->ar_engine->getAutoShift(), j_doc.GetAllocator());
528  j_entry.AddMember("engine_is_running", actor->ar_engine->isRunning(), j_doc.GetAllocator());
529  j_entry.AddMember("engine_has_contact", actor->ar_engine->hasContact(), j_doc.GetAllocator());
530  j_entry.AddMember("engine_wheel_spin", actor->ar_wheel_spin, j_doc.GetAllocator());
531  j_entry.AddMember("alb_mode", actor->alb_mode, j_doc.GetAllocator());
532  j_entry.AddMember("tc_mode", actor->tc_mode, j_doc.GetAllocator());
533  j_entry.AddMember("cc_mode", actor->cc_mode, j_doc.GetAllocator());
534  j_entry.AddMember("cc_target_rpm", actor->cc_target_rpm, j_doc.GetAllocator());
535  j_entry.AddMember("cc_target_speed", actor->cc_target_speed, j_doc.GetAllocator());
536  }
537 
538  j_entry.AddMember("hydro_dir_state", actor->ar_hydro_dir_state, j_doc.GetAllocator());
539  j_entry.AddMember("hydro_aileron_state", actor->ar_hydro_aileron_state, j_doc.GetAllocator());
540  j_entry.AddMember("hydro_rudder_state", actor->ar_hydro_rudder_state, j_doc.GetAllocator());
541  j_entry.AddMember("hydro_elevator_state", actor->ar_hydro_elevator_state, j_doc.GetAllocator());
542  j_entry.AddMember("parking_brake", actor->ar_parking_brake, j_doc.GetAllocator());
543  j_entry.AddMember("trailer_parking_brake", actor->ar_trailer_parking_brake, j_doc.GetAllocator());
544  j_entry.AddMember("avg_wheel_speed", actor->ar_avg_wheel_speed, j_doc.GetAllocator());
545  j_entry.AddMember("wheel_speed", actor->ar_wheel_speed, j_doc.GetAllocator());
546  j_entry.AddMember("wheel_spin", actor->ar_wheel_spin, j_doc.GetAllocator());
547 
548  j_entry.AddMember("custom_particles", actor->m_custom_particles_enabled, j_doc.GetAllocator());
549 
550  // Flares
551  j_entry.AddMember("lights", (int)actor->getHeadlightsVisible(), j_doc.GetAllocator());
552  j_entry.AddMember("blink_type", (int)actor->getBlinkType(), j_doc.GetAllocator());
553  // "beacon_light" was "pp_beacon_light" since release 2021.02 (savegame file format 2).
554  // It was caused by find-&-replace derp in commit 5a159ad9c0d0ffb1fa3e6f4f9c4577fab3910e3e.
555  j_entry.AddMember("beacon_light", actor->getBeaconMode(), j_doc.GetAllocator());
556  j_entry.AddMember("high_beams_on", actor->getHighBeamsVisible(), j_doc.GetAllocator());
557  j_entry.AddMember("fog_lights_on", actor->getFogLightsVisible(), j_doc.GetAllocator());
558 
559  // User-defined flares
560  rapidjson::Value j_custom_lights(rapidjson::kArrayType);
561  for (int i = 0; i < MAX_CLIGHTS; i++)
562  {
563  j_custom_lights.PushBack(actor->getCustomLightVisible(i), j_doc.GetAllocator());
564  }
565  j_entry.AddMember("custom_lights", j_custom_lights, j_doc.GetAllocator());
566 
567  // Buoyance
568  if (actor->m_buoyance)
569  {
570  j_entry.AddMember("buoyance_sink", actor->m_buoyance->sink, j_doc.GetAllocator());
571  }
572 
573  // Turboprops / Turbojets
574  rapidjson::Value j_aeroengines(rapidjson::kArrayType);
575  for (int i = 0; i < actor->ar_num_aeroengines; i++)
576  {
577  rapidjson::Value j_aeroengine(rapidjson::kObjectType);
578  j_aeroengine.AddMember("rpm", actor->ar_aeroengines[i]->getRPM(), j_doc.GetAllocator());
579  j_aeroengine.AddMember("reverse", actor->ar_aeroengines[i]->getReverse(), j_doc.GetAllocator());
580  j_aeroengine.AddMember("ignition", actor->ar_aeroengines[i]->getIgnition(), j_doc.GetAllocator());
581  j_aeroengine.AddMember("throttle", actor->ar_aeroengines[i]->getThrottle(), j_doc.GetAllocator());
582  j_aeroengines.PushBack(j_aeroengine, j_doc.GetAllocator());
583  }
584  j_entry.AddMember("aeroengines", j_aeroengines, j_doc.GetAllocator());
585 
586  // Screwprops
587  rapidjson::Value j_screwprops(rapidjson::kArrayType);
588  for (int i = 0; i < actor->ar_num_screwprops; i++)
589  {
590  rapidjson::Value j_screwprop(rapidjson::kObjectType);
591  j_screwprop.AddMember("rudder", actor->ar_screwprops[i]->getRudder(), j_doc.GetAllocator());
592  j_screwprop.AddMember("throttle", actor->ar_screwprops[i]->getThrottle(), j_doc.GetAllocator());
593  j_screwprops.PushBack(j_screwprop, j_doc.GetAllocator());
594  }
595  j_entry.AddMember("screwprops", j_screwprops, j_doc.GetAllocator());
596 
597  // Rotators
598  rapidjson::Value j_rotators(rapidjson::kArrayType);
599  for (int i = 0; i < actor->ar_num_rotators; i++)
600  {
601  j_rotators.PushBack(actor->ar_rotators[i].angle, j_doc.GetAllocator());
602  }
603  j_entry.AddMember("rotators", j_rotators, j_doc.GetAllocator());
604 
605  // Wheels
606  rapidjson::Value j_wheels(rapidjson::kArrayType);
607  for (int i = 0; i < actor->ar_num_wheels; i++)
608  {
609  j_wheels.PushBack(actor->ar_wheels[i].wh_is_detached, j_doc.GetAllocator());
610  }
611  j_entry.AddMember("wheels", j_wheels, j_doc.GetAllocator());
612 
613  // Wheel differentials
614  rapidjson::Value j_wheel_diffs(rapidjson::kArrayType);
615  for (int i = 0; i < actor->m_num_wheel_diffs; i++)
616  {
617  j_wheel_diffs.PushBack(actor->m_wheel_diffs[i]->GetActiveDiffType(), j_doc.GetAllocator());
618  }
619  j_entry.AddMember("wheel_diffs", j_wheel_diffs, j_doc.GetAllocator());
620 
621  // Axle differentials
622  rapidjson::Value j_axle_diffs(rapidjson::kArrayType);
623  for (int i = 0; i < actor->m_num_axle_diffs; i++)
624  {
625  j_axle_diffs.PushBack(actor->m_axle_diffs[i]->GetActiveDiffType(), j_doc.GetAllocator());
626  }
627  j_entry.AddMember("axle_diffs", j_axle_diffs, j_doc.GetAllocator());
628 
629  // Transfercase
630  if (actor->m_transfer_case)
631  {
632  rapidjson::Value j_transfer_case(rapidjson::kObjectType);
633  j_transfer_case.AddMember("4WD", actor->m_transfer_case->tr_4wd_mode, j_doc.GetAllocator());
634  j_transfer_case.AddMember("GearRatio", actor->m_transfer_case->tr_gear_ratios[0], j_doc.GetAllocator());
635  j_entry.AddMember("transfercase", j_transfer_case, j_doc.GetAllocator());
636  }
637 
638  // Commands
639  rapidjson::Value j_commands(rapidjson::kArrayType);
640  for (int i = 0; i < MAX_COMMANDS; i++) // BEWARE: commandkeys are indexed 1-MAX_COMMANDS! - but to preserve compatibility we omit the last commandkey in savegames.
641  {
642  rapidjson::Value j_command(rapidjson::kArrayType);
643  j_command.PushBack(actor->ar_command_key[i].commandValue, j_doc.GetAllocator());
644  j_command.PushBack(actor->ar_command_key[i].triggerInputValue, j_doc.GetAllocator());
645 
646  rapidjson::Value j_command_beams(rapidjson::kArrayType);
647  for (int j = 0; j < (int)actor->ar_command_key[i].beams.size(); j++)
648  {
649  rapidjson::Value j_cmb(rapidjson::kArrayType);
650  auto& beam = actor->ar_command_key[i].beams[j];
651  j_cmb.PushBack(beam.cmb_state->auto_moving_mode, j_doc.GetAllocator());
652  j_cmb.PushBack(beam.cmb_state->pressed_center_mode, j_doc.GetAllocator());
653  j_command_beams.PushBack(j_cmb, j_doc.GetAllocator());
654  }
655  j_command.PushBack(j_command_beams, j_doc.GetAllocator());
656 
657  j_commands.PushBack(j_command, j_doc.GetAllocator());
658  }
659  j_entry.AddMember("commands", j_commands, j_doc.GetAllocator());
660 
661  // Hooks
662  rapidjson::Value j_hooks(rapidjson::kArrayType);
663  for (const auto& h : actor->ar_hooks)
664  {
665  rapidjson::Value j_hook(rapidjson::kObjectType);
666  int lock_node = h.hk_lock_node ? h.hk_lock_node->pos : -1;
667  int locked_actor = h.hk_locked_actor ? vector_index_lookup[h.hk_locked_actor->ar_vector_index] : -1;
668  j_hook.AddMember("locked", h.hk_locked, j_doc.GetAllocator());
669  j_hook.AddMember("lock_node", lock_node, j_doc.GetAllocator());
670  j_hook.AddMember("locked_actor", locked_actor, j_doc.GetAllocator());
671  j_hooks.PushBack(j_hook, j_doc.GetAllocator());
672  }
673  j_entry.AddMember("hooks", j_hooks, j_doc.GetAllocator());
674 
675  // Ropes
676  rapidjson::Value j_ropes(rapidjson::kArrayType);
677  for (const auto& r : actor->ar_ropes)
678  {
679  rapidjson::Value j_rope(rapidjson::kObjectType);
680  int locked_ropable = r.rp_locked_ropable ? r.rp_locked_ropable->pos : -1;
681  int locked_actor = r.rp_locked_actor ? vector_index_lookup[r.rp_locked_actor->ar_vector_index] : -1;
682  j_rope.AddMember("locked", r.rp_locked, j_doc.GetAllocator());
683  j_rope.AddMember("locked_ropable", locked_ropable, j_doc.GetAllocator());
684  j_rope.AddMember("locked_actor", locked_actor, j_doc.GetAllocator());
685  j_ropes.PushBack(j_rope, j_doc.GetAllocator());
686  }
687  j_entry.AddMember("ropes", j_ropes, j_doc.GetAllocator());
688 
689  // Ties
690  rapidjson::Value j_ties(rapidjson::kArrayType);
691  for (const auto& t : actor->ar_ties)
692  {
693  rapidjson::Value j_tie(rapidjson::kObjectType);
694  int locked_ropable = t.ti_locked_ropable ? t.ti_locked_ropable->pos : -1;
695  int locked_actor = t.ti_locked_actor ? vector_index_lookup[t.ti_locked_actor->ar_vector_index] : -1;
696  j_tie.AddMember("tied", t.ti_tied, j_doc.GetAllocator());
697  j_tie.AddMember("tying", t.ti_tying, j_doc.GetAllocator());
698  j_tie.AddMember("locked_ropable", locked_ropable, j_doc.GetAllocator());
699  j_tie.AddMember("locked_actor", locked_actor, j_doc.GetAllocator());
700  j_ties.PushBack(j_tie, j_doc.GetAllocator());
701  }
702  j_entry.AddMember("ties", j_ties, j_doc.GetAllocator());
703 
704  // Ropables
705  rapidjson::Value j_ropables(rapidjson::kArrayType);
706  for (const auto& r : actor->ar_ropables)
707  {
708  rapidjson::Value j_ropable(rapidjson::kObjectType);
709  j_ropable.AddMember("attached_ties", r.attached_ties, j_doc.GetAllocator());
710  j_ropable.AddMember("attached_ropes", r.attached_ropes, j_doc.GetAllocator());
711  j_ropables.PushBack(j_ropable, j_doc.GetAllocator());
712  }
713  j_entry.AddMember("ropables", j_ropables, j_doc.GetAllocator());
714 
715  j_entry.AddMember("slidenodes_locked", actor->m_slidenodes_locked, j_doc.GetAllocator());
716 
717  // Nodes
718  rapidjson::Value j_nodes(rapidjson::kArrayType);
719  for (int i = 0; i < actor->ar_num_nodes; i++)
720  {
721  rapidjson::Value j_node(rapidjson::kArrayType);
722 
723  // Position
724  j_node.PushBack(actor->ar_nodes[i].AbsPosition.x, j_doc.GetAllocator());
725  j_node.PushBack(actor->ar_nodes[i].AbsPosition.y, j_doc.GetAllocator());
726  j_node.PushBack(actor->ar_nodes[i].AbsPosition.z, j_doc.GetAllocator());
727 
728  // Velocity
729  j_node.PushBack(actor->ar_nodes[i].Velocity.x, j_doc.GetAllocator());
730  j_node.PushBack(actor->ar_nodes[i].Velocity.y, j_doc.GetAllocator());
731  j_node.PushBack(actor->ar_nodes[i].Velocity.z, j_doc.GetAllocator());
732 
733  // Initial Position
734  j_node.PushBack(actor->ar_initial_node_positions[i].x, j_doc.GetAllocator());
735  j_node.PushBack(actor->ar_initial_node_positions[i].y, j_doc.GetAllocator());
736  j_node.PushBack(actor->ar_initial_node_positions[i].z, j_doc.GetAllocator());
737 
738  j_nodes.PushBack(j_node, j_doc.GetAllocator());
739  }
740  j_entry.AddMember("nodes", j_nodes, j_doc.GetAllocator());
741 
742  // Beams
743  rapidjson::Value j_beams(rapidjson::kArrayType);
744  for (int i = 0; i < actor->ar_num_beams; i++)
745  {
746  rapidjson::Value j_beam(rapidjson::kArrayType);
747 
748  j_beam.PushBack(actor->ar_beams[i].maxposstress, j_doc.GetAllocator());
749  j_beam.PushBack(actor->ar_beams[i].maxnegstress, j_doc.GetAllocator());
750  j_beam.PushBack(actor->ar_beams[i].minmaxposnegstress, j_doc.GetAllocator());
751  j_beam.PushBack(actor->ar_beams[i].strength, j_doc.GetAllocator());
752  j_beam.PushBack(actor->ar_beams[i].L, j_doc.GetAllocator());
753  j_beam.PushBack(actor->ar_beams[i].bm_broken, j_doc.GetAllocator());
754  j_beam.PushBack(actor->ar_beams[i].bm_disabled, j_doc.GetAllocator());
755  j_beam.PushBack(actor->ar_beams[i].bm_inter_actor, j_doc.GetAllocator());
756  ActorPtr locked_actor = actor->ar_beams[i].bm_locked_actor;
757  j_beam.PushBack(locked_actor ? vector_index_lookup[locked_actor->ar_vector_index] : -1, j_doc.GetAllocator());
758 
759  j_beams.PushBack(j_beam, j_doc.GetAllocator());
760  }
761  j_entry.AddMember("beams", j_beams, j_doc.GetAllocator());
762 
763  j_actors.PushBack(j_entry, j_doc.GetAllocator());
764  }
765  j_doc.AddMember("actors", j_actors, j_doc.GetAllocator());
766 
767  // Write to disk
768  if (!App::GetContentManager()->SerializeAndWriteJson(filename, RGN_SAVEGAMES, j_doc))
769  {
770  // Error already logged
772  Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_ERROR, _L("Error while saving scene"));
773  return false;
774  }
775 
776  if (filename != "autosave.sav")
777  {
779  Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_NOTICE, _L("Scene saved"));
780  }
781 
782  return true;
783 }
784 
785 void ActorManager::RestoreSavedState(ActorPtr actor, rapidjson::Value const& j_entry)
786 {
787  actor->m_spawn_rotation = j_entry["spawn_rotation"].GetFloat();
788  actor->ar_state = static_cast<ActorState>(j_entry["sim_state"].GetInt());
789  actor->ar_physics_paused = j_entry["physics_paused"].GetBool();
790 
791  if (j_entry["player_actor"].GetBool())
792  {
794  }
795  else if (j_entry["prev_player_actor"].GetBool())
796  {
798  }
799 
800  if (actor->ar_engine)
801  {
802  int gear = j_entry["engine_gear"].GetInt();
803  float rpm = j_entry["engine_rpm"].GetFloat();
804  int automode = j_entry["engine_auto_mode"].GetInt();
805  int autoselect = j_entry["engine_auto_select"].GetInt();
806  bool running = j_entry["engine_is_running"].GetBool();
807  bool contact = j_entry["engine_has_contact"].GetBool();
808  if (running != actor->ar_engine->isRunning())
809  {
810  if (running)
811  actor->ar_engine->StartEngine();
812  else
813  actor->ar_engine->StopEngine();
814  }
815  actor->ar_engine->PushNetworkState(rpm, 0.0f, 0.0f, gear, running, contact, automode, autoselect);
816  actor->ar_engine->SetWheelSpin(j_entry["wheel_spin"].GetFloat() * RAD_PER_SEC_TO_RPM);
817  actor->alb_mode = j_entry["alb_mode"].GetBool();
818  actor->tc_mode = j_entry["tc_mode"].GetBool();
819  actor->cc_mode = j_entry["cc_mode"].GetBool();
820  actor->cc_target_rpm = j_entry["cc_target_rpm"].GetFloat();
821  actor->cc_target_speed = j_entry["cc_target_speed"].GetFloat();
822  }
823 
824  actor->ar_hydro_dir_state = j_entry["hydro_dir_state"].GetFloat();
825  actor->ar_hydro_aileron_state = j_entry["hydro_aileron_state"].GetFloat();
826  actor->ar_hydro_rudder_state = j_entry["hydro_rudder_state"].GetFloat();
827  actor->ar_hydro_elevator_state = j_entry["hydro_elevator_state"].GetFloat();
828  actor->ar_parking_brake = j_entry["parking_brake"].GetBool();
829  actor->ar_trailer_parking_brake = j_entry["trailer_parking_brake"].GetBool();
830  actor->ar_avg_wheel_speed = j_entry["avg_wheel_speed"].GetFloat();
831  actor->ar_wheel_speed = j_entry["wheel_speed"].GetFloat();
832  actor->ar_wheel_spin = j_entry["wheel_spin"].GetFloat();
833 
834  if (actor->m_custom_particles_enabled != j_entry["custom_particles"].GetBool())
835  {
836  actor->toggleCustomParticles();
837  }
838 
839  // Flares
840  actor->setHeadlightsVisible((bool)j_entry["lights"].GetInt()); // legacy name
841  actor->setBlinkType(BlinkType(j_entry["blink_type"].GetInt()));
842  // "beacon_light" was "pp_beacon_light" since release 2021.02 (savegame file format 2).
843  // It was caused by find-&-replace derp in commit 5a159ad9c0d0ffb1fa3e6f4f9c4577fab3910e3e.
844  actor->setBeaconMode(j_entry.HasMember("beacon_light") ? j_entry["beacon_light"].GetBool() : j_entry["pp_beacon_light"].GetBool());
845  actor->setHighBeamsVisible(j_entry.HasMember("high_beams_on") ? j_entry["high_beams_on"].GetBool() : false); // (added to savegame file format 3)
846  actor->setFogLightsVisible(j_entry.HasMember("fog_lights_on") ? j_entry["fog_lights_on"].GetBool() : false); // (added to savegame file format 3)
847 
848  // User-defined flares
849  if (j_entry.HasMember("custom_lights"))
850  {
851  auto flares = j_entry["custom_lights"].GetArray();
852  for (int i = 0; i < MAX_CLIGHTS; i++)
853  {
854  actor->setCustomLightVisible(i, flares[i].GetBool());
855  }
856  }
857 
858  if (actor->m_buoyance)
859  {
860  actor->m_buoyance->sink = j_entry["buoyance_sink"].GetBool();
861  }
862 
863  auto aeroengines = j_entry["aeroengines"].GetArray();
864  for (int i = 0; i < actor->ar_num_aeroengines; i++)
865  {
866  actor->ar_aeroengines[i]->setRPM(aeroengines[i]["rpm"].GetFloat());
867  actor->ar_aeroengines[i]->setReverse(aeroengines[i]["reverse"].GetBool());
868  actor->ar_aeroengines[i]->setIgnition(aeroengines[i]["ignition"].GetBool());
869  actor->ar_aeroengines[i]->setThrottle(aeroengines[i]["throttle"].GetFloat());
870  }
871 
872  auto screwprops = j_entry["screwprops"].GetArray();
873  for (int i = 0; i < actor->ar_num_screwprops; i++)
874  {
875  actor->ar_screwprops[i]->setRudder(screwprops[i]["rudder"].GetFloat());
876  actor->ar_screwprops[i]->setThrottle(screwprops[i]["throttle"].GetFloat());
877  }
878 
879  for (int i = 0; i < actor->ar_num_rotators; i++)
880  {
881  actor->ar_rotators[i].angle = j_entry["rotators"][i].GetFloat();
882  }
883 
884  for (int i = 0; i < actor->ar_num_wheels; i++)
885  {
886  if (actor->m_skid_trails[i])
887  {
888  actor->m_skid_trails[i]->reset();
889  }
890  actor->ar_wheels[i].wh_is_detached = j_entry["wheels"][i].GetBool();
891  }
892 
893  for (int i = 0; i < actor->m_num_wheel_diffs; i++)
894  {
895  for (int k = 0; k < actor->m_wheel_diffs[i]->GetNumDiffTypes(); k++)
896  {
897  if (actor->m_wheel_diffs[i]->GetActiveDiffType() != j_entry["wheel_diffs"][i].GetInt())
899  }
900  }
901 
902  for (int i = 0; i < actor->m_num_axle_diffs; i++)
903  {
904  for (int k = 0; k < actor->m_axle_diffs[i]->GetNumDiffTypes(); k++)
905  {
906  if (actor->m_axle_diffs[i]->GetActiveDiffType() != j_entry["axle_diffs"][i].GetInt())
908  }
909  }
910 
911  if (actor->m_transfer_case)
912  {
913  actor->m_transfer_case->tr_4wd_mode = j_entry["transfercase"]["4WD"].GetBool();
914  for (int k = 0; k < actor->m_transfer_case->tr_gear_ratios.size(); k++)
915  {
916  if (actor->m_transfer_case->tr_gear_ratios[0] != j_entry["transfercase"]["GearRatio"].GetFloat())
918  }
919  }
920 
921  auto commands = j_entry["commands"].GetArray();
922  for (int i = 0; i < MAX_COMMANDS; i++) // BEWARE: commandkeys are indexed 1-MAX_COMMANDS! - but to preserve compatibility we omit the last commandkey in savegames.
923  {
924  auto& command_key = actor->ar_command_key[i];
925  command_key.commandValue = commands[i][0].GetFloat();
926  command_key.triggerInputValue = commands[i][1].GetFloat();
927  auto command_beams = commands[i][2].GetArray();
928  for (int j = 0; j < (int)command_key.beams.size(); j++)
929  {
930  command_key.beams[j].cmb_state->auto_moving_mode = command_beams[j][0].GetInt();
931  command_key.beams[j].cmb_state->pressed_center_mode = command_beams[j][1].GetBool();
932  }
933  }
934 
935  auto nodes = j_entry["nodes"].GetArray();
936  for (rapidjson::SizeType i = 0; i < nodes.Size(); i++)
937  {
938  auto data = nodes[i].GetArray();
939  actor->ar_nodes[i].AbsPosition = Vector3(data[0].GetFloat(), data[1].GetFloat(), data[2].GetFloat());
940  actor->ar_nodes[i].RelPosition = actor->ar_nodes[i].AbsPosition - actor->ar_origin;
941  actor->ar_nodes[i].Velocity = Vector3(data[3].GetFloat(), data[4].GetFloat(), data[5].GetFloat());
942  actor->ar_initial_node_positions[i] = Vector3(data[6].GetFloat(), data[7].GetFloat(), data[8].GetFloat());
943  }
944 
945  std::vector<ActorPtr> actors = this->GetLocalActors();
946 
947  auto beams = j_entry["beams"].GetArray();
948  for (rapidjson::SizeType i = 0; i < beams.Size(); i++)
949  {
950  auto data = beams[i].GetArray();
951  actor->ar_beams[i].maxposstress = data[0].GetFloat();
952  actor->ar_beams[i].maxnegstress = data[1].GetFloat();
953  actor->ar_beams[i].minmaxposnegstress = data[2].GetFloat();
954  actor->ar_beams[i].strength = data[3].GetFloat();
955  actor->ar_beams[i].L = data[4].GetFloat();
956  actor->ar_beams[i].bm_broken = data[5].GetBool();
957  actor->ar_beams[i].bm_disabled = data[6].GetBool();
958  actor->ar_beams[i].bm_inter_actor = data[7].GetBool();
959  int locked_actor = data[8].GetInt();
960  if (locked_actor != -1 &&
961  locked_actor < (int)actors.size() &&
962  actors[locked_actor] != nullptr)
963  {
964  actor->AddInterActorBeam(&actor->ar_beams[i], actors[locked_actor], ActorLinkingRequestType::LOAD_SAVEGAME); // OK to be invoked here - RestoreSavedState() - processing MSG_SIM_MODIFY_ACTOR_REQUESTED
965  }
966  }
967 
968  auto hooks = j_entry["hooks"].GetArray();
969  for (int i = 0; i < actor->ar_hooks.size(); i++)
970  {
971  int lock_node = hooks[i]["lock_node"].GetInt();
972  int locked_actor = hooks[i]["locked_actor"].GetInt();
973  if (lock_node != -1 &&
974  locked_actor != -1 &&
975  locked_actor < (int)actors.size() &&
976  actors[locked_actor] != nullptr)
977  {
978  actor->ar_hooks[i].hk_locked = HookState(hooks[i]["locked"].GetInt());
979  actor->ar_hooks[i].hk_locked_actor = actors[locked_actor];
980  actor->ar_hooks[i].hk_lock_node = &actors[locked_actor]->ar_nodes[lock_node];
981  if (actor->ar_hooks[i].hk_beam->bm_inter_actor)
982  {
983  actor->ar_hooks[i].hk_beam->p2 = actor->ar_hooks[i].hk_lock_node;
984  }
985  }
986  }
987 
988  auto ropes = j_entry["ropes"].GetArray();
989  for (int i = 0; i < actor->ar_ropes.size(); i++)
990  {
991  int ropable = ropes[i]["locked_ropable"].GetInt();
992  int locked_actor = ropes[i]["locked_actor"].GetInt();
993  if (ropable != -1 &&
994  locked_actor != -1 &&
995  locked_actor < (int)actors.size() &&
996  actors[locked_actor] != nullptr)
997  {
998  actor->ar_ropes[i].rp_locked = ropes[i]["locked"].GetInt();
999  actor->ar_ropes[i].rp_locked_actor = actors[locked_actor];
1000  actor->ar_ropes[i].rp_locked_ropable = &actors[locked_actor]->ar_ropables[ropable];
1001  }
1002  }
1003 
1004  auto ties = j_entry["ties"].GetArray();
1005  for (int i = 0; i < actor->ar_ties.size(); i++)
1006  {
1007  int ropable = ties[i]["locked_ropable"].GetInt();
1008  int locked_actor = ties[i]["locked_actor"].GetInt();
1009  if (ropable != -1 &&
1010  locked_actor != -1 &&
1011  locked_actor < (int)actors.size() &&
1012  actors[locked_actor] != nullptr)
1013  {
1014  actor->ar_ties[i].ti_tied = ties[i]["tied"].GetBool();
1015  actor->ar_ties[i].ti_tying = ties[i]["tying"].GetBool();
1016  actor->ar_ties[i].ti_locked_actor = actors[locked_actor];
1017  actor->ar_ties[i].ti_locked_ropable = &actors[locked_actor]->ar_ropables[ropable];
1018  if (actor->ar_ties[i].ti_beam->bm_inter_actor)
1019  {
1020  actor->ar_ties[i].ti_beam->p2 = actor->ar_ties[i].ti_locked_ropable->node;
1021  }
1022  }
1023  }
1024 
1025  auto ropables = j_entry["ropables"].GetArray();
1026  for (int i = 0; i < actor->ar_ropables.size(); i++)
1027  {
1028  actor->ar_ropables[i].attached_ties = ropables[i]["attached_ties"].GetInt();
1029  actor->ar_ropables[i].attached_ropes = ropables[i]["attached_ropes"].GetInt();
1030  }
1031 
1032  actor->resetSlideNodes();
1033  if (actor->m_slidenodes_locked != j_entry["slidenodes_locked"].GetBool())
1034  {
1035  actor->toggleSlideNodeLock(); // OK to be invoked here - RestoreSavedState() - processing MSG_SIM_MODIFY_ACTOR_REQUESTED
1036  }
1037 
1038  actor->UpdateBoundingBoxes();
1039  actor->calculateAveragePosition();
1041 }
RoR::GUI::MessageBoxConfig::mbc_buttons
std::vector< MessageBoxButton > mbc_buttons
Definition: GUI_MessageBox.h:59
RoR::Actor::setHighBeamsVisible
void setHighBeamsVisible(bool val)
Definition: Actor.h:190
ROR_ASSERT
#define ROR_ASSERT(_EXPR)
Definition: Application.h:40
GameContext.h
Game state manager and message-queue provider.
RoR::Actor::ar_avg_wheel_speed
float ar_avg_wheel_speed
Physics state; avg wheel speed in m/s.
Definition: Actor.h:402
MAX_COMMANDS
static const int MAX_COMMANDS
maximum number of commands per actor
Definition: SimConstants.h:28
SAVEGAME_FILE_FORMAT
#define SAVEGAME_FILE_FORMAT
Definition: Savegame.cpp:47
RoR::App::sim_quickload_dialog
CVar * sim_quickload_dialog
Definition: Application.cpp:110
RoR::Actor::cc_mode
bool cc_mode
Cruise Control.
Definition: Actor.h:364
RoR::Character::setPosition
void setPosition(Ogre::Vector3 position)
Definition: Character.cpp:85
RoR::App::GetContentManager
ContentManager * GetContentManager()
Definition: Application.cpp:267
RoR::MSG_GUI_SHOW_MESSAGE_BOX_REQUESTED
@ MSG_GUI_SHOW_MESSAGE_BOX_REQUESTED
Payload = MessageBoxConfig* (owner)
Definition: Application.h:138
RoR::CacheEntry::dname
Ogre::String dname
name parsed from the file
Definition: CacheSystem.h:70
RoR::ActorSpawnRequest::asr_free_position
bool asr_free_position
Disables the automatic spawn position adjustment.
Definition: SimData.h:863
RoR::EngineSim::PushNetworkState
void PushNetworkState(float engine_rpm, float acc, float clutch, int gear, bool running, bool contact, char auto_mode, char auto_select=-1)
Sets current engine state;.
Definition: EngineSim.cpp:885
RoR::node_t::Velocity
Ogre::Vector3 Velocity
Definition: SimData.h:295
y
float y
Definition: (ValueTypes) quaternion.h:6
RoR::EngineSim::isRunning
bool isRunning() const
Definition: EngineSim.h:93
RoR::EV_COMMON_QUICKLOAD_10
@ EV_COMMON_QUICKLOAD_10
Definition: InputEngine.h:392
RoR::Actor::ar_hydro_dir_state
float ar_hydro_dir_state
Definition: Actor.h:404
RoR::Actor::ar_physics_paused
bool ar_physics_paused
Sim state.
Definition: Actor.h:484
RoR::MpState::CONNECTED
@ CONNECTED
RoR::Str::GetBuffer
char * GetBuffer()
Definition: Str.h:48
MAX_CLIGHTS
static const int MAX_CLIGHTS
See RoRnet::Lightmask and enum events in InputEngine.h.
Definition: SimConstants.h:35
RoR::Actor::setHeadlightsVisible
void setHeadlightsVisible(bool val)
Definition: Actor.h:188
RoR::Actor::m_num_wheel_diffs
int m_num_wheel_diffs
Physics attr.
Definition: Actor.h:572
RoR::ActorSpawnRequest::asr_origin
Origin asr_origin
Definition: SimData.h:857
RoR::Actor::ar_vector_index
unsigned int ar_vector_index
Sim attr; actor element index in std::vector<m_actors>
Definition: Actor.h:377
RoR::node_t::AbsPosition
Ogre::Vector3 AbsPosition
absolute position in the world (shaky)
Definition: SimData.h:294
GUI_MessageBox.h
Generic UI dialog (not modal). Invocable from scripting. Any number of buttons. Configurable to fire ...
RoR::Actor::ar_parking_brake
bool ar_parking_brake
Definition: Actor.h:414
RoR::Differential::GetActiveDiffType
DiffType GetActiveDiffType() const
Definition: Differentials.h:79
z
float z
Definition: (ValueTypes) quaternion.h:7
RoR::Actor::cc_target_rpm
float cc_target_rpm
Cruise Control.
Definition: Actor.h:366
SkyManager.h
ContentManager.h
RoR::Actor::m_num_axle_diffs
int m_num_axle_diffs
Physics attr.
Definition: Actor.h:570
RoR::Actor::m_wheel_diffs
Differential * m_wheel_diffs[MAX_WHEELS/2]
Physics.
Definition: Actor.h:571
format
Truck file format(technical spec)
RoR::Terrain::getSkyManager
SkyManager * getSkyManager()
Definition: Terrain.cpp:513
RoR::GameContext::GetPlayerCharacter
Character * GetPlayerCharacter()
Definition: GameContext.cpp:872
RoR::Str::GetCapacity
size_t GetCapacity() const
Definition: Str.h:49
RoR::Actor::ar_engine
EngineSim * ar_engine
Definition: Actor.h:379
RoR::EV_COMMON_QUICKLOAD_01
@ EV_COMMON_QUICKLOAD_01
Definition: InputEngine.h:383
RoR::MpState
MpState
Definition: Application.h:169
RoR::beam_t::strength
float strength
Definition: SimData.h:343
RoR::Actor::toggleCustomParticles
void toggleCustomParticles()
Definition: Actor.cpp:3179
RoR::Actor::ar_num_rotators
int ar_num_rotators
Definition: Actor.h:294
RoR::EV_COMMON_QUICKSAVE_07
@ EV_COMMON_QUICKSAVE_07
Definition: InputEngine.h:378
Console.h
RoR::beam_t::bm_locked_actor
ActorPtr bm_locked_actor
in case p2 is on another actor
Definition: SimData.h:350
RoR::Console::putMessage
void putMessage(MessageArea area, MessageType type, std::string const &msg, std::string icon="")
Definition: Console.cpp:97
RoR::Actor::ar_hooks
std::vector< hook_t > ar_hooks
Definition: Actor.h:302
RoR::Actor::ar_trailer_parking_brake
bool ar_trailer_parking_brake
Definition: Actor.h:415
RoR::TransferCase::tr_4wd_mode
bool tr_4wd_mode
Enables 4WD mode.
Definition: Differentials.h:53
RoR::Actor::ar_ties
std::vector< tie_t > ar_ties
Definition: Actor.h:301
RoR::GUI::MessageBoxButton::mbb_caption
std::string mbb_caption
Definition: GUI_MessageBox.h:43
RoR::ActorSpawnRequest::asr_working_tuneup
TuneupDefPtr asr_working_tuneup
Only filled when editing tuneup via Tuning menu.
Definition: SimData.h:856
TuneupFileFormat.h
The vehicle tuning system; applies addonparts and user overrides to vehicles.
RoR::Actor::m_avg_node_position_prev
Ogre::Vector3 m_avg_node_position_prev
Definition: Actor.h:553
RoR::AeroEngine::setReverse
virtual void setReverse(bool val)=0
RoR::EngineSim::SetWheelSpin
void SetWheelSpin(float rpm)
Set current wheel spinning speed.
Definition: EngineSim.cpp:933
RoR::TransferCase::tr_gear_ratios
std::vector< float > tr_gear_ratios
Gear reduction ratios.
Definition: Differentials.h:54
RoR::Screwprop::setRudder
void setRudder(float val)
Definition: ScrewProp.cpp:89
RoR::App::sim_state
CVar * sim_state
Definition: Application.cpp:96
RoR::EV_COMMON_QUICKSAVE_06
@ EV_COMMON_QUICKSAVE_06
Definition: InputEngine.h:377
RoR::Actor::ar_hydro_rudder_state
float ar_hydro_rudder_state
Definition: Actor.h:409
RoR::ActorSpawnRequest::asr_filename
std::string asr_filename
Can be in "Bundle-qualified" format, i.e. "mybundle.zip:myactor.truck".
Definition: SimData.h:849
RoR::node_t::RelPosition
Ogre::Vector3 RelPosition
relative to the local physics origin (one origin per actor) (shaky)
Definition: SimData.h:293
Language.h
RoR::EV_COMMON_QUICKLOAD_09
@ EV_COMMON_QUICKLOAD_09
Definition: InputEngine.h:391
RoR::Actor::m_skid_trails
Skidmark * m_skid_trails[MAX_WHEELS *2]
Definition: Actor.h:591
RefCountingObjectPtr< CacheEntry >
GUIManager.h
Actor.h
RoR::Actor::setBlinkType
void setBlinkType(BlinkType blink)
Definition: Actor.cpp:3093
RoR::ActorSpawnRequest
Definition: SimData.h:832
EngineSim.h
RoR::Actor::ar_wheel_speed
float ar_wheel_speed
Physics state; wheel speed in m/s.
Definition: Actor.h:400
RoR::App::mp_state
CVar * mp_state
Definition: Application.cpp:115
RoR::EV_COMMON_QUICKSAVE
@ EV_COMMON_QUICKSAVE
quicksave scene to the disk
Definition: InputEngine.h:248
RoR::EV_COMMON_QUICKSAVE_09
@ EV_COMMON_QUICKSAVE_09
Definition: InputEngine.h:380
RoR::ActorSpawnRequest::asr_config
Ogre::String asr_config
Definition: SimData.h:850
RoR::Actor::ar_aeroengines
AeroEngine * ar_aeroengines[MAX_AEROENGINES]
Definition: Actor.h:329
ScrewProp.h
RoR::Actor::ar_screwprops
Screwprop * ar_screwprops[MAX_SCREWPROPS]
Definition: Actor.h:331
RoR::Actor::ar_beams
beam_t * ar_beams
Definition: Actor.h:287
RoR::Actor::ar_num_aeroengines
int ar_num_aeroengines
Definition: Actor.h:330
RoR::CVar::getStr
std::string const & getStr() const
Definition: CVar.h:95
RoR::Actor::ar_rotators
rotator_t * ar_rotators
Definition: Actor.h:293
RoR::Str
Wrapper for classic c-string (local buffer) Refresher: strlen() excludes '\0' terminator; strncat() A...
Definition: Str.h:35
RoR::CacheSystem::FindEntryByFilename
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,...
Definition: CacheSystem.cpp:184
RoR::Actor::m_transfer_case
TransferCase * m_transfer_case
Physics.
Definition: Actor.h:573
RoR::EV_COMMON_QUICKLOAD_06
@ EV_COMMON_QUICKLOAD_06
Definition: InputEngine.h:388
RAD_PER_SEC_TO_RPM
static const float RAD_PER_SEC_TO_RPM
Convert radian/second to RPM (60/2*PI)
Definition: SimConstants.h:37
RoR::Actor::m_slidenodes_locked
bool m_slidenodes_locked
Physics state; Are SlideNodes locked?
Definition: Actor.h:623
RoR::MSG_SIM_SEAT_PLAYER_REQUESTED
@ MSG_SIM_SEAT_PLAYER_REQUESTED
Payload = RoR::ActorPtr (owner) | nullptr.
Definition: Application.h:122
RoR::GUI::MessageBoxButton
Definition: GUI_MessageBox.h:41
RoR::Actor::AddInterActorBeam
void AddInterActorBeam(beam_t *beam, ActorPtr other, ActorLinkingRequestType type)
Do not call directly - use MSG_SIM_ACTOR_LINKING_REQUESTED
Definition: Actor.cpp:3322
CacheSystem.h
A database of user-installed content alias 'mods' (vehicles, terrains...)
RoR::Actor::cc_target_speed
float cc_target_speed
Cruise Control.
Definition: Actor.h:367
RoR::EV_COMMON_QUICKLOAD_02
@ EV_COMMON_QUICKLOAD_02
Definition: InputEngine.h:384
RoR::EV_COMMON_QUICKLOAD_07
@ EV_COMMON_QUICKLOAD_07
Definition: InputEngine.h:389
RoR::GameContext::PushMessage
void PushMessage(Message m)
Doesn't guarantee order! Use ChainMessage() if order matters.
Definition: GameContext.cpp:65
RoR::EV_COMMON_QUICKLOAD_05
@ EV_COMMON_QUICKLOAD_05
Definition: InputEngine.h:387
RoR::GUI::MessageBoxConfig::mbc_title
std::string mbc_title
Definition: GUI_MessageBox.h:52
RoR::Actor::ar_origin
Ogre::Vector3 ar_origin
Physics state; base position for softbody nodes.
Definition: Actor.h:385
RoR::App::sim_terrain_name
CVar * sim_terrain_name
Definition: Application.cpp:97
RoR::EV_COMMON_QUICKSAVE_02
@ EV_COMMON_QUICKSAVE_02
Definition: InputEngine.h:373
RoR::Actor::setFogLightsVisible
void setFogLightsVisible(bool val)
Definition: Actor.h:192
RoR::Actor::SyncReset
void SyncReset(bool reset_position)
this one should be called only synchronously (without physics running in background)
Definition: Actor.cpp:1597
RoR::Actor::ar_command_key
CmdKeyArray ar_command_key
BEWARE: commandkeys are indexed 1-MAX_COMMANDS!
Definition: Actor.h:305
RoR::AeroEngine::setRPM
virtual void setRPM(float _rpm)=0
RoR::CacheSystem::GetPrettyName
Ogre::String GetPrettyName(Ogre::String fname)
Definition: CacheSystem.cpp:556
RoR::EV_COMMON_QUICKLOAD
@ EV_COMMON_QUICKLOAD
quickload scene from the disk
Definition: InputEngine.h:247
PlatformUtils.h
Platform-specific utilities. We use narrow UTF-8 encoded strings as paths. Inspired by http://utf8eve...
RoR::GameContext::SetPrevPlayerActor
void SetPrevPlayerActor(ActorPtr actor)
Definition: GameContext.cpp:814
RoR::HookState
HookState
Definition: SimData.h:81
RoR::Actor::ar_hydro_aileron_state
float ar_hydro_aileron_state
Definition: Actor.h:407
RoR::Screwprop::setThrottle
void setThrottle(float val)
Definition: ScrewProp.cpp:76
RoR::Differential::GetNumDiffTypes
int GetNumDiffTypes()
Definition: Differentials.h:80
Application.h
Central state/object manager and communications hub.
RoR::App::GetConsole
Console * GetConsole()
Definition: Application.cpp:270
RoR::EV_COMMON_QUICKSAVE_08
@ EV_COMMON_QUICKSAVE_08
Definition: InputEngine.h:379
RoR::GameContext::GetPrevPlayerActor
const ActorPtr & GetPrevPlayerActor()
Definition: GameContext.h:135
RoR::App::GetGameContext
GameContext * GetGameContext()
Definition: Application.cpp:280
RoR::CVar::getEnum
T getEnum() const
Definition: CVar.h:99
RoR::GUI::MessageBoxConfig::mbc_text
std::string mbc_text
Definition: GUI_MessageBox.h:53
RoR::Actor::m_spawn_rotation
float m_spawn_rotation
Definition: Actor.h:561
RoR::Actor::ar_num_screwprops
int ar_num_screwprops
Definition: Actor.h:332
RoR::BlinkType
BlinkType
< Turn signal
Definition: SimData.h:121
RoR::GameContext::GetQuicksaveFilename
std::string GetQuicksaveFilename()
For currently loaded terrain (cvar 'sim_terrain_name')
Definition: Savegame.cpp:55
RoR::ActorSpawnRequest::asr_skin_entry
CacheEntryPtr asr_skin_entry
Definition: SimData.h:854
RoR::Actor::ar_wheel_spin
float ar_wheel_spin
Physics state; wheel speed in radians/s.
Definition: Actor.h:401
RoR::Differential::ToggleDifferentialMode
void ToggleDifferentialMode()
Definition: Differentials.cpp:27
RoR::App::gfx_sky_mode
CVar * gfx_sky_mode
Definition: Application.cpp:219
RoR::ActorState
ActorState
Definition: SimData.h:265
RoR::Actor::toggleSlideNodeLock
void toggleSlideNodeLock()
Definition: ActorSlideNode.cpp:34
_LC
#define _LC(ctx, str)
Definition: Language.h:42
RoR::Actor::tc_mode
bool tc_mode
Traction control state; Enabled? {1/0}.
Definition: Actor.h:357
RoR::Actor::ar_hydro_elevator_state
float ar_hydro_elevator_state
Definition: Actor.h:411
RoR::EV_COMMON_QUICKSAVE_04
@ EV_COMMON_QUICKSAVE_04
Definition: InputEngine.h:375
RoR::GUI::MessageBoxButton::mbb_mq_message
MsgType mbb_mq_message
Message to queue on click.
Definition: GUI_MessageBox.h:44
RoR::AeroEngine::setIgnition
virtual void setIgnition(bool val)=0
Skidmark.h
RoR::GUI::MessageBoxConfig::mbc_always_ask_conf
CVar * mbc_always_ask_conf
If set, displays classic checkbox "[x] Always ask".
Definition: GUI_MessageBox.h:54
RoR::Actor::alb_mode
bool alb_mode
Anti-lock brake state; Enabled? {1/0}.
Definition: Actor.h:350
RoR::Actor::setBeaconMode
void setBeaconMode(bool val)
Definition: Actor.h:193
RoR::beam_t::bm_inter_actor
bool bm_inter_actor
in case p2 is on another actor
Definition: SimData.h:349
RoR::Actor::ar_initial_node_positions
std::vector< Ogre::Vector3 > ar_initial_node_positions
Definition: Actor.h:311
RoR::App::GetCacheSystem
CacheSystem * GetCacheSystem()
Definition: Application.cpp:272
RoR::EngineSim::StopEngine
void StopEngine()
stall engine
Definition: EngineSim.cpp:1062
RoR::CacheSystem::FetchSkinByName
CacheEntryPtr FetchSkinByName(std::string const &skin_name)
Definition: CacheSystem.cpp:1560
RoR::Actor::ar_nodes
node_t * ar_nodes
Definition: Actor.h:279
RoR::wheel_t::wh_is_detached
bool wh_is_detached
Definition: SimData.h:454
RoR::GUI::MessageBoxConfig
Definition: GUI_MessageBox.h:50
Buoyance.h
RoR::Message
Unified game event system - all requests and state changes are reported using a message.
Definition: GameContext.h:51
_L
#define _L
Definition: ErrorUtils.cpp:34
RoR::Actor::m_axle_diffs
Differential * m_axle_diffs[1+MAX_WHEELS/2]
Physics.
Definition: Actor.h:569
RoR::Actor::ar_ropes
std::vector< rope_t > ar_ropes
Definition: Actor.h:299
RoR::Actor::resetSlideNodes
void resetSlideNodes()
Reset all the SlideNodes.
Definition: ActorSlideNode.cpp:122
RoR::EV_COMMON_QUICKSAVE_10
@ EV_COMMON_QUICKSAVE_10
Definition: InputEngine.h:381
RoR::EngineSim::StartEngine
void StartEngine()
Quick engine start. Plays sounds.
Definition: EngineSim.cpp:998
RoR::beam_t::maxnegstress
float maxnegstress
Definition: SimData.h:342
nodes
or anywhere else will not be considered a but parsed as regular data ! Each line is treated as values separated by separators Possible i e animators Multiline description Single does not affect it Directive usualy set global attributes or change behavior of the parsing Directive may appear in any block section Modularity The elements can be grouped into modules Each module must belong to one or more configurations Directives sectionconfig specify truck configurations the user can choose from Exactly one must be selected If the first defined is used lettercase matches original docs(parsing is insensitive). NAME TYPE NOTES advdrag BLOCK add_animation DIRECTIVE Special syntax airbrakes BLOCK animators BLOCK Special syntax IF(values[0]=="") bad trailing chars are silently ignored no space at the end Items delimited On each side of there is max item Empty invalid string parses as node num items Acceptable item the node is the others When a node range has more than nodes
Definition: ReadMe.txt:302
RoR::beam_t::minmaxposnegstress
float minmaxposnegstress
Definition: SimData.h:340
RoR::Actor::toggleTransferCaseGearRatio
void toggleTransferCaseGearRatio()
Definition: Actor.cpp:1462
RoR::MSG_SIM_SPAWN_ACTOR_REQUESTED
@ MSG_SIM_SPAWN_ACTOR_REQUESTED
Payload = RoR::ActorSpawnRequest* (owner)
Definition: Application.h:119
RoR::Actor::ar_num_wheels
int ar_num_wheels
Definition: Actor.h:324
RoR::App::GetInputEngine
InputEngine * GetInputEngine()
Definition: Application.cpp:271
RoR::Actor::m_avg_node_position
Ogre::Vector3 m_avg_node_position
average node position
Definition: Actor.h:551
RoR::ActorPtr
RefCountingObjectPtr< Actor > ActorPtr
Definition: ForwardDeclarations.h:194
RoR::MSG_SIM_DELETE_ACTOR_REQUESTED
@ MSG_SIM_DELETE_ACTOR_REQUESTED
Payload = RoR::ActorPtr* (owner)
Definition: Application.h:121
RoR::LT_AllBeam
@ LT_AllBeam
Definition: Application.h:303
RoR::Actor::setCustomLightVisible
void setCustomLightVisible(int number, bool visible)
Definition: Actor.cpp:4500
RoR::ActorManager::SetSimulationPaused
void SetSimulationPaused(bool v)
Definition: ActorManager.h:95
RoR::AeroEngine::setThrottle
virtual void setThrottle(float val)=0
RoR::rotator_t::angle
float angle
Definition: SimData.h:606
Terrain.h
AeroEngine.h
InputEngine.h
Handles controller inputs from player. Defines input events and binding mechanism,...
RGN_SAVEGAMES
#define RGN_SAVEGAMES
Definition: Application.h:50
RoR::GameContext::SaveScene
void SaveScene(std::string const &filename)
Definition: Savegame.cpp:69
Ogre
Definition: ExtinguishableFireAffector.cpp:35
RoR::Actor::calculateAveragePosition
void calculateAveragePosition()
Definition: Actor.cpp:1130
RoR::EV_COMMON_QUICKLOAD_04
@ EV_COMMON_QUICKLOAD_04
Definition: InputEngine.h:386
RoR::ActorSpawnRequest::asr_position
Ogre::Vector3 asr_position
Definition: SimData.h:851
RoR::Actor::ar_wheels
wheel_t ar_wheels[MAX_WHEELS]
Definition: Actor.h:323
RoR::Actor::m_custom_particles_enabled
bool m_custom_particles_enabled
Gfx state.
Definition: Actor.h:628
RoR::Actor::ar_ropables
std::vector< ropable_t > ar_ropables
Definition: Actor.h:300
RoR::EV_COMMON_QUICKSAVE_03
@ EV_COMMON_QUICKSAVE_03
Definition: InputEngine.h:374
RoR::Actor::ar_state
ActorState ar_state
Definition: Actor.h:446
RoR::GameContext::GetPlayerActor
const ActorPtr & GetPlayerActor()
Definition: GameContext.h:134
RoR::MSG_SIM_LOAD_SAVEGAME_REQUESTED
@ MSG_SIM_LOAD_SAVEGAME_REQUESTED
Definition: Application.h:117
RoR::ActorSpawnRequest::asr_rotation
Ogre::Quaternion asr_rotation
Definition: SimData.h:852
RoR::Actor::UpdateBoundingBoxes
void UpdateBoundingBoxes()
Definition: Actor.cpp:1165
RoR
Definition: AppContext.h:36
RoR::EV_COMMON_QUICKSAVE_05
@ EV_COMMON_QUICKSAVE_05
Definition: InputEngine.h:376
x
float x
Definition: (ValueTypes) quaternion.h:5
RoR::GameContext::GetActorManager
ActorManager * GetActorManager()
Definition: GameContext.h:127
RoR::GUI::MessageBoxButton::mbb_mq_description
std::string mbb_mq_description
Message argument to queue on click.
Definition: GUI_MessageBox.h:45
RoR::EV_COMMON_QUICKLOAD_08
@ EV_COMMON_QUICKLOAD_08
Definition: InputEngine.h:390
RoR::beam_t::bm_disabled
bool bm_disabled
Definition: SimData.h:351
RoR::Skidmark::reset
void reset()
Definition: Skidmark.cpp:312
RoR::Character::setRotation
void setRotation(Ogre::Radian rotation)
Definition: Character.cpp:98
RoR::Actor::m_buoyance
std::unique_ptr< Buoyance > m_buoyance
Physics.
Definition: Actor.h:587
RoR::beam_t::L
float L
length
Definition: SimData.h:339
RoR::beam_t::bm_broken
bool bm_broken
Definition: SimData.h:352
RoR::EV_COMMON_QUICKLOAD_03
@ EV_COMMON_QUICKLOAD_03
Definition: InputEngine.h:385
RoR::ActorSpawnRequest::asr_saved_state
std::shared_ptr< rapidjson::Document > asr_saved_state
Pushes msg MODIFY_ACTOR (type RESTORE_SAVED) after spawn.
Definition: SimData.h:867
RoR::GameContext::GetTerrain
const TerrainPtr & GetTerrain()
Definition: GameContext.h:117
RoR::beam_t::maxposstress
float maxposstress
Definition: SimData.h:341
RoR::EV_COMMON_QUICKSAVE_01
@ EV_COMMON_QUICKSAVE_01
Definition: InputEngine.h:372