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