Rigs of Rods 2026.01
Soft-body Physics Simulation
Loading...
Searching...
No Matches
GameScript.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 "GameScript.h"
23
24#ifdef USE_CURL
25# include <curl/curl.h>
26# include <curl/easy.h>
27#endif //USE_CURL
28
29// AS addons start
30#include "scriptany/scriptany.h"
31#include "scriptarray/scriptarray.h"
32#include "scripthelper/scripthelper.h"
33#include "scriptmath/scriptmath.h"
34#include "scriptstdstring/scriptstdstring.h"
35// AS addons end
36
37#include "AppContext.h"
38#include "Actor.h"
39#include "ActorManager.h"
40#include "CacheSystem.h"
41#include "Character.h"
42#include "ChatSystem.h"
43#include "Collisions.h"
44#include "Console.h"
45#include "CurlHelpers.h"
46#include "Engine.h"
47#include "GameContext.h"
48#include "GfxScene.h"
49#include "GUIManager.h"
50#include "GUI_TopMenubar.h"
51#include "Language.h"
52#include "PlatformUtils.h"
53#include "Network.h"
54#include "RoRVersion.h"
55#include "ScriptEngine.h"
56#include "ServerScriptEngine.h"
57#include "ScriptUtils.h"
58#include "SkyManager.h"
59#include "SoundScriptManager.h"
60#include "Terrain.h"
63#include "Utils.h"
64#include "VehicleAI.h"
65#include "GfxWater.h"
66
67#include <rapidjson/document.h>
68#include <rapidjson/writer.h>
69
70using namespace Ogre;
71using namespace RoR;
72using namespace AngelScript;
73
74// GUIDELINE: Make functions safe from invoking in wrong circumstances,
75// i.e. when server script calls function using SimController while in main menu.
76// --> Getter functions should silently return zero/empty value.
77// --> Functions performing simulation changes should log warning and do nothing.
78
79
80
81void GameScript::log(const String& msg)
82{
84}
85
86void GameScript::logFormat(const char* format, ...)
87{
88 char buffer[4000] = {};
89 sprintf(buffer, "[RoR|Script] "); // Length: 13 characters
90 char* buffer_pos = buffer + 13;
91
92 va_list args;
93 va_start(args, format);
94 vsprintf(buffer_pos, format, args);
95 va_end(args);
96
97 App::GetScriptEngine()->SLOG(buffer);
98}
99
104
106{
108}
109
114
115void GameScript::setPersonPosition(const Vector3& vec)
116{
117 if (!this->HavePlayerAvatar(__FUNCTION__))
118 return;
119
121}
122
123void GameScript::loadTerrain(const String& terrain)
124{
126}
127
129{
130 Vector3 result(Vector3::ZERO);
131 if (App::GetGameContext()->GetPlayerCharacter())
133 return result;
134}
135
136void GameScript::movePerson(const Vector3& vec)
137{
138 if (!this->HavePlayerAvatar(__FUNCTION__))
139 return;
140
142}
143
144void GameScript::setPersonRotation(const Radian& rot)
145{
146 if (!this->HavePlayerAvatar(__FUNCTION__))
147 return;
148
150}
151
153{
154 Radian result(0);
155 if (App::GetGameContext()->GetPlayerCharacter())
157 return result;
158}
159
161{
162 String result = "";
163#ifdef USE_CAELUM
164 if (App::GetGameContext()->GetTerrain())
165 {
166 result = App::GetGameContext()->GetTerrain()->getSkyManager()->GetPrettyTime();
167 }
168#endif // USE_CAELUM
169 return result;
170}
171
173{
174#ifdef USE_CAELUM
175 if (!this->HaveSimTerrain(__FUNCTION__))
176 return;
177
178 App::GetGameContext()->GetTerrain()->getSkyManager()->SetSkyTimeFactor(value);
179#endif // USE_CAELUM
180}
181
183{
184 bool result = false;
185#ifdef USE_CAELUM
186 if (App::GetGameContext()->GetTerrain())
187 result = App::GetGameContext()->GetTerrain()->getSkyManager() != 0;
188#endif // USE_CAELUM
189 return result;
190}
191
196
201
206
211
213{
214 if (!this->HaveSimTerrain(__FUNCTION__))
215 return;
216
217 if (App::GetGameContext()->GetTerrain()->getWater())
218 {
219 auto water = App::GetGameContext()->GetTerrain()->getWater();
220 water->SetStaticWaterHeight(value);
221 }
222}
223
225{
226 float result = -1.0f;
227 if (App::GetGameContext()->GetTerrain())
228 result = App::GetGameContext()->GetTerrain()->getHeightAt(v.x, v.z);
229 return result;
230}
231
233{
234 float result = 0.0f;
235 if (App::GetGameContext()->GetTerrain() && App::GetGameContext()->GetTerrain()->getWater())
237 return result;
238}
239
244
246{
247 float result = 0.f;
248 if (App::GetGameContext()->GetTerrain())
249 {
251 }
252 return result;
253}
254
255void GameScript::setGravity(float value)
256{
257 if (!this->HaveSimTerrain(__FUNCTION__))
258 return;
259
261}
262
267
269{
270 int result = 0;
272 {
273 if (!flag || static_cast<int>(actor->ar_state) == flag)
274 result++;
275 }
276 return result;
277}
278
280{
282 return (actor != nullptr) ? actor->ar_instance_id : -1;
283}
284
290
292{
294 {
296 if (unit_id != SCRIPTUNITID_INVALID)
297 {
298 App::GetScriptEngine()->getScriptUnit(unit_id).eventMask |= eventValue;
299 }
300 }
301}
302
303void GameScript::unRegisterEvent(int eventValue)
304{
306 {
308 if (unit_id != SCRIPTUNITID_INVALID)
309 {
310 App::GetScriptEngine()->getScriptUnit(unit_id).eventMask &= ~eventValue;
311 }
312 }
313}
314
316{
317 if (App::GetScriptEngine()->scriptUnitExists(nid))
319 else
320 return BitMask_t(0);
321}
322
324{
325 if (App::GetScriptEngine()->scriptUnitExists(nid))
326 App::GetScriptEngine()->getScriptUnit(nid).eventMask = eventMask;
327}
328
329void GameScript::flashMessage(String& txt, float time, float charHeight)
330{
332}
333
338
339void GameScript::updateDirectionArrow(String& text, Vector3& vec)
340{
341 App::GetGameContext()->GetRaceSystem().UpdateDirectionArrow(const_cast<char*>(text.c_str()), Vector3(vec.x, vec.y, vec.z));
342}
343
345{
346 return 0; //NETCHAT.getFontSize();
347}
348
350{
351 //NETCHAT.setFontSize(size);
352}
353
354void GameScript::showChooser(const String& type, const String& instance, const String& box)
355{
356 LoaderType ntype = LT_None;
357
358 if (type == "airplane")
359 ntype = LT_Airplane;
360 if (type == "all")
361 ntype = LT_AllBeam;
362 if (type == "boat")
363 ntype = LT_Boat;
364 if (type == "car")
365 ntype = LT_Car;
366 if (type == "extension")
367 ntype = LT_Extension;
368 if (type == "heli")
369 ntype = LT_Airplane;
370 if (type == "load")
371 ntype = LT_Load;
372 if (type == "trailer")
373 ntype = LT_Trailer;
374 if (type == "train")
375 ntype = LT_Train;
376 if (type == "truck")
377 ntype = LT_Truck;
378 if (type == "vehicle")
379 ntype = LT_Vehicle;
380
381 if (ntype != LT_None)
382 {
383 App::GetGameContext()->ShowLoaderGUI(ntype, instance, box);
384 }
385
386}
387
388void GameScript::repairVehicle(const String& instance, const String& box, bool keepPosition)
389{
390 App::GetGameContext()->GetActorManager()->RepairActor(App::GetGameContext()->GetTerrain()->GetCollisions(), instance, box, keepPosition);
391}
392
393void GameScript::removeVehicle(const String& event_source_instance_name, const String& event_source_box_name)
394{
395 ActorPtr actor = App::GetGameContext()->FindActorByCollisionBox(event_source_instance_name, event_source_box_name);
396 if (actor)
397 {
399 }
400}
401
402AngelScript::CScriptArray* GameScript::getEditorObjects()
403{
404 if (!this->HaveSimTerrain(__FUNCTION__))
405 return nullptr;
406
407 if (!App::GetGameContext()->GetTerrain()->getObjectManager())
408 return nullptr;
409
410 // Adopted from `VectorToScriptArray()` in file 'ScriptUtils.h'
411 std::string arraydecl = fmt::format("array<{}>", "TerrainEditorObjectClass@");
412 AngelScript::asITypeInfo* typeinfo = App::GetScriptEngine()->getEngine()->GetTypeInfoByDecl(arraydecl.c_str());
413 TerrainEditorObjectPtrVec& vec = App::GetGameContext()->GetTerrain()->getObjectManager()->GetEditorObjects(); AngelScript::CScriptArray* arr = AngelScript::CScriptArray::Create(typeinfo, vec.size());
414
415 for (AngelScript::asUINT i = 0; i < arr->GetSize(); i++)
416 {
417 // Set the value of each element
418 TerrainEditorObject* ref = vec[i].GetRef();
419 arr->SetValue(i, &ref);
420 }
421
422 return arr;
423
424}
425
426void GameScript::destroyObject(const String& instanceName)
427{
428 if (!this->HaveSimTerrain(__FUNCTION__))
429 return;
430
431 if (App::GetGameContext()->GetTerrain()->getObjectManager())
432 {
434 }
435}
436
437void GameScript::moveObjectVisuals(const String& instanceName, const Vector3& pos)
438{
439 if (!this->HaveSimTerrain(__FUNCTION__))
440 return;
441
442 if (App::GetGameContext()->GetTerrain()->getObjectManager())
443 {
445 }
446}
447
448void GameScript::spawnObject(const String& objectName, const String& instanceName, const Vector3& pos, const Vector3& rot, const String& eventhandler, bool uniquifyMaterials)
449{
450 if (!this->HaveSimTerrain(__FUNCTION__))
451 return;
452
453 if ((App::GetGameContext()->GetTerrain()->getObjectManager() == nullptr))
454 {
455 this->logFormat("spawnObject(): Cannot spawn object, no terrain loaded!");
456 return;
457 }
458
459 if (App::GetScriptEngine()->getTerrainScriptUnit() == -1)
460 {
461 this->logFormat("spawnObject(): Cannot spawn object, no terrain script loaded!");
462 return;
463 }
464
465 try
466 {
467 AngelScript::asIScriptModule* module = App::GetScriptEngine()->getScriptUnit(App::GetScriptEngine()->getTerrainScriptUnit()).scriptModule;
468 if (module == nullptr)
469 {
470 this->logFormat("spawnObject(): Failed to fetch/create script module");
471 return;
472 }
473
474 int handler_func_id = -1; // no function
475 if (!eventhandler.empty())
476 {
477 // Let script author know (via Angelscript.log) there's a better alternative.
480 "spawnObject(): Specifying event handler function in `game.spawnObject()` (or .TOBJ file) is obsolete and only works with terrain scripts;"
481 " Use `eventCallbackEx()` with event `SE_EVENTBOX_ENTER` instead, it does the same job and works with any script."
482 " Just pass an empty string to the `game.spawnObject()` parameter.");
484
485 // Look up the function and log if not found or found with bad arguments (probably a typo).
486 AngelScript::asIScriptFunction* handler_func = App::GetScriptEngine()->getFunctionByDeclAndLogCandidates(
487 App::GetScriptEngine()->getTerrainScriptUnit(), GETFUNCFLAG_REQUIRED,
489 if (handler_func != nullptr)
490 {
491 handler_func_id = handler_func->GetId();
492 }
493 }
494
495 const String type = "";
496 App::GetGameContext()->GetTerrain()->getObjectManager()->LoadTerrainObject(objectName, pos, rot, instanceName, type, /*rendering_distance=*/0, true, handler_func_id, uniquifyMaterials);
497 }
498 catch (...)
499 {
500 App::GetScriptEngine()->forwardExceptionAsScriptEvent("GameScript::spawnObject()");
501 return;
502 }
503}
504
509
510bool GameScript::getScreenPosFromWorldPos(Ogre::Vector3 const& world_pos, Ogre::Vector2& out_screen)
511{
512 ImVec2 screen_size = ImGui::GetIO().DisplaySize;
513 World2ScreenConverter world2screen(
514 App::GetCameraManager()->GetCamera()->getViewMatrix(true), App::GetCameraManager()->GetCamera()->getProjectionMatrix(), Ogre::Vector2(screen_size.x, screen_size.y));
515 Ogre::Vector3 pos_xyz = world2screen.Convert(world_pos);
516 if (pos_xyz.z < 0.f)
517 {
518 out_screen.x = pos_xyz.x;
519 out_screen.y = pos_xyz.y;
520 return true;
521 }
522 return false;
523}
524
526{
527 ImVec2 size = ImGui::GetIO().DisplaySize;
528 return Vector2(size.x, size.y);
529}
530
532{
533 ImVec2 pos = ImGui::GetIO().MousePos;
534 return Vector2(pos.x, pos.y);
535}
536
537int GameScript::setMaterialAmbient(const String& materialName, float red, float green, float blue)
538{
539 try
540 {
541 MaterialPtr m = MaterialManager::getSingleton().getByName(materialName);
542 if (!m)
543 return 0;
544 m->setAmbient(red, green, blue);
545 }
546 catch (...)
547 {
548 App::GetScriptEngine()->forwardExceptionAsScriptEvent("GameScript::setMaterialAmbient()");
549 return 0;
550 }
551 return 1;
552}
553
554int GameScript::setMaterialDiffuse(const String& materialName, float red, float green, float blue, float alpha)
555{
556 try
557 {
558 MaterialPtr m = MaterialManager::getSingleton().getByName(materialName);
559 if (!m)
560 return 0;
561 m->setDiffuse(red, green, blue, alpha);
562 }
563 catch (...)
564 {
565 App::GetScriptEngine()->forwardExceptionAsScriptEvent("GameScript::setMaterialDiffuse()");
566 return 0;
567 }
568 return 1;
569}
570
571int GameScript::setMaterialSpecular(const String& materialName, float red, float green, float blue, float alpha)
572{
573 try
574 {
575 MaterialPtr m = MaterialManager::getSingleton().getByName(materialName);
576 if (!m)
577 return 0;
578 m->setSpecular(red, green, blue, alpha);
579 }
580 catch (...)
581 {
582 App::GetScriptEngine()->forwardExceptionAsScriptEvent("GameScript::setMaterialSpecular()");
583 return 0;
584 }
585 return 1;
586}
587
588int GameScript::setMaterialEmissive(const String& materialName, float red, float green, float blue)
589{
590 try
591 {
592 MaterialPtr m = MaterialManager::getSingleton().getByName(materialName);
593 if (!m)
594 return 0;
595 m->setSelfIllumination(red, green, blue);
596 }
597 catch (...)
598 {
599 App::GetScriptEngine()->forwardExceptionAsScriptEvent("GameScript::setMaterialEmissive()");
600 return 0;
601 }
602 return 1;
603}
604
605int GameScript::getTextureUnitState(TextureUnitState** tu, const String materialName, int techniqueNum, int passNum, int textureUnitNum)
606{
607 // Internal helper - propagate exceptions outside so that correct function names appear in exception-events
608 // ========================================================================================================
609
610 MaterialPtr m = MaterialManager::getSingleton().getByName(materialName);
611 if (!m)
612 return 1;
613
614 // verify technique
615 if (techniqueNum < 0 || techniqueNum > m->getNumTechniques())
616 return 2;
617 Technique* t = m->getTechnique(techniqueNum);
618 if (!t)
619 return 2;
620
621 //verify pass
622 if (passNum < 0 || passNum > t->getNumPasses())
623 return 3;
624 Pass* p = t->getPass(passNum);
625 if (!p)
626 return 3;
627
628 //verify texture unit
629 if (textureUnitNum < 0 || textureUnitNum > p->getNumTextureUnitStates())
630 return 4;
631 TextureUnitState* tut = p->getTextureUnitState(textureUnitNum);
632 if (!tut)
633 return 4;
634
635 *tu = tut;
636 return 0;
637}
638
639int GameScript::setMaterialTextureName(const String& materialName, int techniqueNum, int passNum, int textureUnitNum, const String& textureName)
640{
641 try
642 {
643 TextureUnitState* tu = 0;
644 int res = getTextureUnitState(&tu, materialName, techniqueNum, passNum, textureUnitNum);
645 if (res == 0 && tu != 0)
646 {
647 // finally, set it
648 tu->setTextureName(textureName);
649 }
650 return res;
651 }
652 catch (...)
653 {
654 App::GetScriptEngine()->forwardExceptionAsScriptEvent("GameScript::setMaterialTextureName()");
655 return 0;
656 }
657}
658
659int GameScript::setMaterialTextureRotate(const String& materialName, int techniqueNum, int passNum, int textureUnitNum, float rotation)
660{
661 try
662 {
663 TextureUnitState* tu = 0;
664 int res = getTextureUnitState(&tu, materialName, techniqueNum, passNum, textureUnitNum);
665 if (res == 0 && tu != 0)
666 {
667 tu->setTextureRotate(Degree(rotation));
668 }
669 return res;
670 }
671 catch (...)
672 {
673 App::GetScriptEngine()->forwardExceptionAsScriptEvent("GameScript::setMaterialTextureRotate()");
674 return 0;
675 }
676}
677
678int GameScript::setMaterialTextureScroll(const String& materialName, int techniqueNum, int passNum, int textureUnitNum, float sx, float sy)
679{
680 try
681 {
682 TextureUnitState* tu = 0;
683 int res = getTextureUnitState(&tu, materialName, techniqueNum, passNum, textureUnitNum);
684 if (res == 0 && tu != 0)
685 {
686 tu->setTextureScroll(sx, sy);
687 }
688 return res;
689 }
690 catch (...)
691 {
692 App::GetScriptEngine()->forwardExceptionAsScriptEvent("GameScript::setMaterialTextureScroll()");
693 return 0;
694 }
695}
696
697int GameScript::setMaterialTextureScale(const String& materialName, int techniqueNum, int passNum, int textureUnitNum, float u, float v)
698{
699 try
700 {
701 TextureUnitState* tu = 0;
702 int res = getTextureUnitState(&tu, materialName, techniqueNum, passNum, textureUnitNum);
703 if (res == 0 && tu != 0)
704 {
705 tu->setTextureScale(u, v);
706 }
707 return res;
708 }
709 catch (...)
710 {
711 App::GetScriptEngine()->forwardExceptionAsScriptEvent("GameScript::setMaterialTextureScale()");
712 return 0;
713 }
714}
715
716float GameScript::rangeRandom(float from, float to)
717{
718 return Math::RangeRandom(from, to);
719}
720
722{
723 String terrainName = "";
724
725 if (App::GetGameContext()->GetTerrain())
726 {
727 terrainName = App::GetGameContext()->GetTerrain()->getTerrainName();
728 result = terrainName;
729 }
730
731 return !terrainName.empty();
732}
733
738
740{
741 if (!this->HaveSimTerrain(__FUNCTION__))
742 return;
743
744 if (App::GetGameContext()->GetTerrain()->GetCollisions() == nullptr)
745 {
746 this->logFormat("Cannot execute '%s', collisions not ready", __FUNCTION__);
747 return;
748 }
749
751}
752
753void GameScript::setCameraPosition(const Vector3& pos)
754{
755 if (!this->HaveMainCamera(__FUNCTION__))
756 return;
757
758 App::GetCameraManager()->GetCameraNode()->setPosition(Vector3(pos.x, pos.y, pos.z));
759}
760
761void GameScript::setCameraDirection(const Vector3& rot)
762{
763 if (!this->HaveMainCamera(__FUNCTION__))
764 return;
765
766 App::GetCameraManager()->GetCameraNode()->setDirection(Vector3(rot.x, rot.y, rot.z), Ogre::Node::TS_WORLD);
767}
768
769void GameScript::setCameraOrientation(const Quaternion& q)
770{
771 if (!this->HaveMainCamera(__FUNCTION__))
772 return;
773
774 App::GetCameraManager()->GetCameraNode()->setOrientation(Quaternion(q.w, q.x, q.y, q.z));
775}
776
778{
779 if (!this->HaveMainCamera(__FUNCTION__))
780 return;
781
782 App::GetCameraManager()->GetCameraNode()->yaw(Degree(rotX), Ogre::Node::TS_WORLD);
783}
784
786{
787 if (!this->HaveMainCamera(__FUNCTION__))
788 return;
789
790 App::GetCameraManager()->GetCameraNode()->pitch(Degree(rotY));
791}
792
794{
795 if (!this->HaveMainCamera(__FUNCTION__))
796 return;
797
798 App::GetCameraManager()->GetCameraNode()->roll(Degree(rotZ));
799}
800
802{
803 Vector3 result(Vector3::ZERO);
804 if (App::GetCameraManager()->GetCameraNode())
805 result = App::GetCameraManager()->GetCameraNode()->getPosition();
806 return result;
807}
808
810{
811 Vector3 result(Vector3::ZERO);
812 if (App::GetCameraManager()->GetCameraNode())
813 {
814 // Direction points down -Z by default (adapted from Ogre::Camera)
815 result = App::GetCameraManager()->GetCameraNode()->getOrientation() * -Ogre::Vector3::UNIT_Z;
816 }
817 return result;
818}
819
821{
822 Quaternion result(Quaternion::ZERO);
823 if (App::GetCameraManager()->GetCameraNode())
824 result = App::GetCameraManager()->GetCameraNode()->getOrientation();
825 return result;
826}
827
828void GameScript::cameraLookAt(const Vector3& pos)
829{
830 if (!this->HaveMainCamera(__FUNCTION__))
831 return;
832
833 App::GetCameraManager()->GetCameraNode()->lookAt(Vector3(pos.x, pos.y, pos.z), Ogre::Node::TS_WORLD);
834}
835
836int GameScript::useOnlineAPI(const String& apiquery, const AngelScript::CScriptDictionary& dict, String& result)
837{
838 if (App::app_disable_online_api->getBool())
839 return 0;
840
842 if (unit_id == SCRIPTUNITID_INVALID)
843 return 2;
844
845 ActorPtr player_actor = App::GetGameContext()->GetPlayerActor();
846
847 if (player_actor == nullptr)
848 return 1;
849
850 std::string hashtok = Sha1Hash(App::mp_player_name->getStr());
851 std::string url = App::mp_api_url->getStr() + apiquery;
852 std::string user = std::string("RoR-Api-User: ") + App::mp_player_name->getStr();
853 std::string token = std::string("RoR-Api-User-Token: ") + hashtok;
854
855 std::string terrain_name = App::GetGameContext()->GetTerrain()->getTerrainName();
856
857 std::string script_name = App::GetScriptEngine()->getScriptUnit(unit_id).scriptName;
858 std::string script_hash = App::GetScriptEngine()->getScriptUnit(unit_id).scriptHash;
859
860 rapidjson::Document j_doc;
861 j_doc.SetObject();
862
863 j_doc.AddMember("user-name", rapidjson::StringRef(App::mp_player_name->getStr().c_str()), j_doc.GetAllocator());
864 j_doc.AddMember("user-country", rapidjson::StringRef(App::app_country->getStr().c_str()), j_doc.GetAllocator());
865 j_doc.AddMember("user-token", rapidjson::StringRef(hashtok.c_str()), j_doc.GetAllocator());
866
867 j_doc.AddMember("terrain-name", rapidjson::StringRef(terrain_name.c_str()), j_doc.GetAllocator());
868 j_doc.AddMember("terrain-filename", rapidjson::StringRef(App::sim_terrain_name->getStr().c_str()), j_doc.GetAllocator());
869
870 j_doc.AddMember("script-name", rapidjson::StringRef(script_name.c_str()), j_doc.GetAllocator());
871 j_doc.AddMember("script-hash", rapidjson::StringRef(script_hash.c_str()), j_doc.GetAllocator());
872
873 j_doc.AddMember("actor-name", rapidjson::StringRef(player_actor->ar_design_name.c_str()), j_doc.GetAllocator());
874 j_doc.AddMember("actor-filename", rapidjson::StringRef(player_actor->ar_filename.c_str()), j_doc.GetAllocator());
875 j_doc.AddMember("actor-hash", rapidjson::StringRef(player_actor->ar_filehash.c_str()), j_doc.GetAllocator());
876
877 rapidjson::Value j_linked_actors(rapidjson::kArrayType);
878 for (ActorPtr& actor : player_actor->ar_linked_actors)
879 {
880 rapidjson::Value j_actor(rapidjson::kObjectType);
881 j_actor.AddMember("actor-name", rapidjson::StringRef(actor->ar_design_name.c_str()), j_doc.GetAllocator());
882 j_actor.AddMember("actor-filename", rapidjson::StringRef(actor->ar_filename.c_str()), j_doc.GetAllocator());
883 j_actor.AddMember("actor-hash", rapidjson::StringRef(actor->ar_filehash.c_str()), j_doc.GetAllocator());
884 j_linked_actors.PushBack(j_actor, j_doc.GetAllocator());
885 }
886 j_doc.AddMember("linked-actors", j_linked_actors, j_doc.GetAllocator());
887
888 j_doc.AddMember("avg-fps", getAvgFPS(), j_doc.GetAllocator());
889 j_doc.AddMember("ror-version", rapidjson::StringRef(ROR_VERSION_STRING), j_doc.GetAllocator());
890
891 for (auto item : dict)
892 {
893 const std::string& key = item.GetKey();
894 const std::string* value = (std::string *)item.GetAddressOfValue();
895 j_doc.AddMember(rapidjson::StringRef(key.c_str()), rapidjson::StringRef(value->c_str()), j_doc.GetAllocator());
896 }
897
898 rapidjson::StringBuffer buffer;
899 rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
900 j_doc.Accept(writer);
901 std::string json = buffer.GetString();
902
903#if USE_CURL
905 _L("using Online API..."), "information.png");
906
907 LOG("[RoR|GameScript] Submitting race results to '" + url + "'");
908
909 std::thread([url, user, token, json]()
910 {
911 long response_code = 0;
912
913 struct curl_slist *slist = NULL;
914 slist = curl_slist_append(slist, "Accept: application/json");
915 slist = curl_slist_append(slist, "Content-Type: application/json");
916 slist = curl_slist_append(slist, user.c_str());
917 slist = curl_slist_append(slist, token.c_str());
918
919 CURL *curl = curl_easy_init();
920 curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
921 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
922 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json.c_str());
923
924 CURLcode curl_result = curl_easy_perform(curl);
925 curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
926
927 if (curl_result != CURLE_OK || response_code != 200)
928 {
929 Ogre::LogManager::getSingleton().stream()
930 << "[RoR|GameScript] `useOnlineAPI()` failed to submit data;"
931 << " Error: '" << curl_easy_strerror(curl_result) << "'; HTTP status code: " << response_code;
932 }
933
934 curl_easy_cleanup(curl);
935 curl = nullptr;
936 curl_slist_free_all(slist);
937 slist = NULL;
938 }).detach();
939#else // USE_CURL
941 _L("Cannot use Online API in this build (CURL not available)"));
942#endif // USE_CURL
943
944 return 0;
945}
946
947void GameScript::openUrlInDefaultBrowser(const std::string& url)
948{
949 RoR::OpenUrlInDefaultBrowser(url); // PlatformUtils.h
950}
951
952void GameScript::fetchUrlAsStringAsync(const std::string& url, const std::string& display_filename)
953{
954#if defined(USE_CURL)
955 CurlTaskContext task;
956 task.ctc_url = url;
957 task.ctc_displayname = display_filename;
958 // Messages to post // See `RoR::angelScriptThreadStatus`
959 task.ctc_msg_progress = MSG_APP_SCRIPT_THREAD_STATUS; // `RoR::ASTHREADSTATUS_CURLSTRING_PROGRESS`
960 task.ctc_msg_success = MSG_APP_SCRIPT_THREAD_STATUS; // `RoR::ASTHREADSTATUS_CURLSTRING_SUCCESS`
961 task.ctc_msg_failure = MSG_APP_SCRIPT_THREAD_STATUS; // `RoR::ASTHREADSTATUS_CURLSTRING_FAILURE`
962
963 std::packaged_task<void(CurlTaskContext)> pktask(GetUrlAsStringMQ);
964 std::thread(std::move(pktask), task).detach();
965#endif // defined(USE_CURL)
966}
967
969{
971 if (actor && actor->ar_engine)
972 {
973 float rpm = actor->ar_engine->getRPM();
974 rpm += 2000.0f * factor;
975 actor->ar_engine->setRPM(rpm);
976 }
977}
978
980{
981 return App::GetScriptEngine()->addFunction(arg, nid);
982}
983
985{
986 return App::GetScriptEngine()->functionExists(arg, nid);
987}
988
990{
991 return App::GetScriptEngine()->deleteFunction(arg, nid);
992}
993
995{
996 return App::GetScriptEngine()->addVariable(arg, nid);
997}
998
1000{
1001 return App::GetScriptEngine()->variableExists(arg, nid);
1002}
1003
1005{
1006 return App::GetScriptEngine()->deleteVariable(arg, nid);
1007}
1008
1009int GameScript::getScriptVariable(const Ogre::String& varName, void *ref, int refTypeId, ScriptUnitID_t nid)
1010{
1011 return App::GetScriptEngine()->getVariable(varName, ref, refTypeId, nid);
1012}
1013
1014int GameScript::sendGameCmd(const String& message)
1015{
1016#ifdef USE_SOCKETW
1017 if (RoR::App::mp_state->getEnum<MpState>() == RoR::MpState::CONNECTED)
1018 {
1019 App::GetNetwork()->AddPacket(0, RoRnet::MSG2_GAME_CMD, (int)message.size(), const_cast<char*>(message.c_str()));
1020 return 0;
1021 }
1022#endif // USE_SOCKETW
1023 if (RoR::App::mp_state->getEnum<MpState>() == RoR::MpState::LOCAL_SCRIPT)
1024 {
1026 return 0;
1027 }
1028
1029 return -11;
1030}
1031
1032AngelScript::CScriptArray* GameScript::getRunningScripts()
1033{
1034 std::vector<ScriptUnitID_t> ids;
1035 for (auto& pair: App::GetScriptEngine()->getScriptUnits())
1036 ids.push_back(pair.first);
1037
1038 return VectorToScriptArray(ids, "int");
1039}
1040
1041
1042AngelScript::CScriptDictionary* GameScript::getScriptDetails(ScriptUnitID_t nid)
1043{
1044 if (!App::GetScriptEngine()->scriptUnitExists(nid))
1045 return nullptr;
1046
1048 AngelScript::CScriptDictionary* dict = AngelScript::CScriptDictionary::Create(App::GetScriptEngine()->getEngine());
1049 int stringTypeid = App::GetScriptEngine()->getEngine()->GetTypeIdByDecl("string");
1050 int scriptCategoryTypeid = App::GetScriptEngine()->getEngine()->GetTypeIdByDecl("ScriptCategory");
1051
1052 dict->Set("uniqueId", (asINT64)info.uniqueId);
1053 dict->Set("scriptName", new std::string(info.scriptName), stringTypeid);
1054 dict->Set("scriptCategory", &info.scriptCategory, scriptCategoryTypeid);
1055 dict->Set("eventMask", (asINT64)info.eventMask);
1056 dict->Set("scriptBuffer", new std::string(info.scriptBuffer), stringTypeid);
1057
1058 // TBD Some other time...
1059 //AngelScript::asIScriptModule* scriptModule = nullptr;
1060 //AngelScript::asIScriptFunction* frameStepFunctionPtr = nullptr; //!< script function pointer to the frameStep function
1061 //AngelScript::asIScriptFunction* eventCallbackFunctionPtr = nullptr; //!< script function pointer to the event callback function
1062 //AngelScript::asIScriptFunction* eventCallbackExFunctionPtr = nullptr; //!< script function pointer to the event callback function
1063 //AngelScript::asIScriptFunction* defaultEventCallbackFunctionPtr = nullptr; //!< script function pointer for spawner events
1064 //ActorPtr associatedActor; //!< For ScriptCategory::ACTOR
1065 //Ogre::String scriptHash;
1066
1067 return dict;
1068}
1069
1071{
1072 VehicleAIPtr result = nullptr;
1073 if (App::GetGameContext()->GetPlayerActor())
1074 {
1076 }
1077 return result;
1078}
1079
1081{
1082 VehicleAIPtr result = nullptr;
1084 if (actor != nullptr)
1085 {
1086 result = actor->ar_vehicle_ai;
1087 }
1088 return result;
1089}
1090
1091ActorPtr GameScript::spawnTruck(Ogre::String& truckName, Ogre::Vector3& pos, Ogre::Vector3& rot)
1092{
1094 rq.asr_position = pos;
1095 rq.asr_rotation = Quaternion(Degree(rot.x), Vector3::UNIT_X) * Quaternion(Degree(rot.y), Vector3::UNIT_Y) * Quaternion(Degree(rot.z), Vector3::UNIT_Z);
1096 rq.asr_filename = truckName;
1097 return App::GetGameContext()->SpawnActor(rq);
1098}
1099
1101{
1102 // Fill network info to the spawn request ~ this will not trigger networking because 'origin' remains 'AI'.
1103 ROR_ASSERT(unit.associatedNetUid != -1);
1105 RoRnet::UserInfo user_info;
1106 if (App::GetNetwork()->GetAnyUserInfo(unit.associatedNetUid, user_info))
1107 {
1108 rq.asr_net_color = user_info.colournum;
1109 rq.asr_net_username = user_info.username;
1111 }
1112
1113 // Fabricate rornet message and send to serverscript
1116 strcpy(reg.name, rq.asr_filename.c_str());
1117 strcpy(reg.sectionconfig, rq.asr_config.c_str());
1118 if (rq.asr_skin_entry)
1119 {
1120 strcpy(reg.skin, rq.asr_skin_entry->dname.c_str());
1121 }
1123}
1124
1125ActorPtr GameScript::spawnTruckAI(Ogre::String& truckName, Ogre::Vector3& pos, Ogre::String& truckSectionConfig, std::string& truckSkin, int x)
1126{
1127 try
1128 {
1130 rq.asr_position = pos;
1131
1132 // Set rotation based on first two waypoints
1133 std::vector<Ogre::Vector3> waypoints;
1134 for (int i = 0; i < App::GetGuiManager()->TopMenubar.ai_waypoints.size(); i++)
1135 {
1136 waypoints.push_back(App::GetGuiManager()->TopMenubar.ai_waypoints[i].position);
1137 }
1138 if (App::GetGuiManager()->TopMenubar.ai_mode == 3 && x == 1) // Crash driving mode
1139 {
1140 std::reverse(waypoints.begin(), waypoints.end());
1141 }
1142
1143 // Check if we have enough waypoints
1144 Ogre::Vector3 dir = Ogre::Vector3::ZERO;
1145 if (waypoints.size() >= 2)
1146 dir = waypoints[0] - waypoints[1];
1147 else if (waypoints.size() >= 1)
1148 dir = waypoints[0];
1149 dir.y = 0;
1150 rq.asr_rotation = Ogre::Vector3::UNIT_X.getRotationTo(dir, Ogre::Vector3::UNIT_Y);
1151
1152 rq.asr_filename = truckName;
1153 rq.asr_config = truckSectionConfig;
1156
1157 // Check if spawned by AI_BOT
1162 {
1163 spawnTruckAiBotHelper(rq, unit);
1164 }
1165
1166 return App::GetGameContext()->SpawnActor(rq);
1167 }
1168 catch (...)
1169 {
1170 App::GetScriptEngine()->forwardExceptionAsScriptEvent("GameScript::spawnTruckAI()");
1171 return ActorPtr();
1172 }
1173}
1174
1175AngelScript::CScriptArray* GameScript::getWaypoints(int x)
1176{
1177 std::vector<Ogre::Vector3> vec;
1178 for (int i = 0; i < App::GetGuiManager()->TopMenubar.ai_waypoints.size(); i++)
1179 {
1180 vec.push_back(App::GetGuiManager()->TopMenubar.ai_waypoints[i].position);
1181 }
1182 if (App::GetGuiManager()->TopMenubar.ai_mode == 3 && x == 1) // Crash driving mode
1183 {
1184 std::reverse(vec.begin(), vec.end());
1185 }
1186
1187 AngelScript::CScriptArray* arr = AngelScript::CScriptArray::Create(AngelScript::asGetActiveContext()->GetEngine()->GetTypeInfoByDecl("array<vector3>"), vec.size());
1188
1189 for(AngelScript::asUINT i = 0; i < arr->GetSize(); i++)
1190 {
1191 // Set the value of each element
1192 arr->SetValue(i, &vec[i]);
1193 }
1194
1195 return arr;
1196}
1197
1198AngelScript::CScriptArray* GameScript::getAllTrucks()
1199{
1201 AngelScript::CScriptArray* arr = AngelScript::CScriptArray::Create(AngelScript::asGetActiveContext()->GetEngine()->GetTypeInfoByDecl("array<BeamClass@>"), actors.size());
1202
1203 for (AngelScript::asUINT i = 0; i < arr->GetSize(); i++)
1204 {
1205 // Set the value of each element
1206 arr->SetValue(i, &actors[i]);
1207 }
1208
1209 return arr;
1210}
1211
1212void GameScript::addWaypoint(const Ogre::Vector3& pos)
1213{
1214 ai_events wp_data;
1215 wp_data.position = pos;
1216 App::GetGuiManager()->TopMenubar.ai_waypoints.push_back(wp_data);
1217}
1218
1223
1224AngelScript::CScriptArray* GameScript::getWaypointsSpeed()
1225{
1226 std::vector<int> vec;
1227 for (int i = 0; i < App::GetGuiManager()->TopMenubar.ai_waypoints.size(); i++)
1228 {
1229 vec.push_back(App::GetGuiManager()->TopMenubar.ai_waypoints[i].speed);
1230 }
1231
1232 AngelScript::CScriptArray* arr = AngelScript::CScriptArray::Create(AngelScript::asGetActiveContext()->GetEngine()->GetTypeInfoByDecl("array<int>"), vec.size());
1233
1234 for(AngelScript::asUINT i = 0; i < arr->GetSize(); i++)
1235 {
1236 // Set the value of each element
1237 arr->SetValue(i, &vec[i]);
1238 }
1239
1240 return arr;
1241}
1242
1244{
1246 return num;
1247}
1248
1250{
1252 return dist;
1253}
1254
1256{
1258 return scheme;
1259}
1260
1262{
1263 int speed = App::GetGuiManager()->TopMenubar.ai_speed;
1264 return speed;
1265}
1266
1268{
1269 if ((App::GetGuiManager()->TopMenubar.ai_mode == 2 || App::GetGuiManager()->TopMenubar.ai_mode == 3) && x == 1) // Drag Race or Crash driving mode
1270 {
1271 Ogre::String name = App::GetGuiManager()->TopMenubar.ai_fname2;
1272 return name;
1273 }
1274 else
1275 {
1276 Ogre::String name = App::GetGuiManager()->TopMenubar.ai_fname;
1277 return name;
1278 }
1279}
1280
1282{
1283 if ((App::GetGuiManager()->TopMenubar.ai_mode == 2 || App::GetGuiManager()->TopMenubar.ai_mode == 3) && x == 1) // Drag Race or Crash driving mode
1284 {
1285 Ogre::String config = App::GetGuiManager()->TopMenubar.ai_sectionconfig2;
1286 return config;
1287 }
1288 else
1289 {
1290 Ogre::String config = App::GetGuiManager()->TopMenubar.ai_sectionconfig;
1291 return config;
1292 }
1293}
1294
1296{
1297 if ((App::GetGuiManager()->TopMenubar.ai_mode == 2 || App::GetGuiManager()->TopMenubar.ai_mode == 3) && x == 1) // Drag Race or Crash driving mode
1298 {
1299 std::string skin = App::GetGuiManager()->TopMenubar.ai_skin2;
1300 return skin;
1301 }
1302 else
1303 {
1304 std::string skin = App::GetGuiManager()->TopMenubar.ai_skin;
1305 return skin;
1306 }
1307}
1308
1310{
1311 int times = App::GetGuiManager()->TopMenubar.ai_times;
1312 return times;
1313}
1314
1316{
1318 return mode;
1319}
1320
1321// AI: set
1322
1327
1332
1337
1339{
1341}
1342
1343void GameScript::setAIVehicleName(int x, std::string name)
1344{
1345 if ((App::GetGuiManager()->TopMenubar.ai_mode == 2 || App::GetGuiManager()->TopMenubar.ai_mode == 3) && x == 1) // Drag Race or Crash driving mode
1346 {
1348 }
1349 else
1350 {
1352 }
1353}
1354
1355void GameScript::setAIVehicleSectionConfig(int x, std::string config)
1356{
1357 switch (x)
1358 {
1359 case 0:
1361 break;
1362 case 1:
1364 break;
1365 default:
1366 this->log(fmt::format("setAIVehicleSectionConfig: ERROR, valid 'x' is 0 or 1, got {}", x));
1367 break;
1368 }
1369}
1370
1371void GameScript::setAIVehicleSkin(int x, std::string skin)
1372{
1373 switch (x)
1374 {
1375 case 0:
1377 break;
1378 case 1:
1380 break;
1381 default:
1382 this->log(fmt::format("setAIVehicleSkin: ERROR, valid 'x' is 0 or 1, got {}", x));
1383 break;
1384 }
1385}
1386
1388{
1390}
1391
1393{
1395}
1396
1397void GameScript::showMessageBox(Ogre::String& title, Ogre::String& text, bool use_btn1, Ogre::String& btn1_text, bool allow_close, bool use_btn2, Ogre::String& btn2_text)
1398{
1399 // Sanitize inputs
1400 const char* btn1_cstr = nullptr; // = Button disabled
1401 const char* btn2_cstr = nullptr;
1402
1403 if (use_btn1)
1404 {
1405 btn1_cstr = (btn1_text.empty() ? "~1~" : btn1_text.c_str());
1406 }
1407 if (use_btn2)
1408 {
1409 btn2_cstr = (btn2_text.empty() ? "~2~" : btn2_text.c_str());
1410 }
1411
1412 RoR::App::GetGuiManager()->ShowMessageBox(title.c_str(), text.c_str(), allow_close, btn1_cstr, btn2_cstr);
1413}
1414
1420
1425
1427{
1428 return App::GetAppContext()->GetRenderWindow()->getStatistics().lastFPS;
1429}
1430
1432{
1433 return App::GetAppContext()->GetRenderWindow()->getStatistics().avgFPS;
1434}
1435
1436bool GameScript::getMousePositionOnTerrain(Ogre::Vector3& out_pos)
1437{
1438 if (!HaveSimTerrain(__FUNCTION__))
1439 return false;
1440
1441 Ogre::Vector2 mouse_npos = App::GetInputEngine()->getMouseNormalizedScreenPos();
1442 Ogre::Ray ray = App::GetCameraManager()->GetCamera()->getCameraToViewportRay(mouse_npos.x, mouse_npos.y);
1443 Ogre::TerrainGroup::RayResult ray_result = App::GetGameContext()->GetTerrain()->getGeometryManager()->getTerrainGroup()->rayIntersects(ray);
1444 if (ray_result.hit)
1445 {
1446 out_pos = ray_result.position;
1447 }
1448 return ray_result.hit;
1449}
1450
1451class ScriptRayQueryListener : public Ogre::RaySceneQueryListener
1452{
1453public:
1454 Ogre::Ray ray;
1455 std::vector<Ogre::MovableObject*> results_array;
1456
1457 bool queryResult(MovableObject* obj, Real distance) override
1458 {
1459 results_array.push_back(obj);
1460 return true; // Continue query
1461 }
1462
1463 bool queryResult(SceneQuery::WorldFragment* fragment, Real distance) override
1464 {
1465 return true; // Continue query
1466 }
1467};
1468
1470{
1471 if (!HaveSimTerrain(__FUNCTION__))
1472 return nullptr;
1473
1474 Ogre::Vector2 mouse_npos = App::GetInputEngine()->getMouseNormalizedScreenPos();
1475 Ogre::Ray ray = App::GetCameraManager()->GetCamera()->getCameraToViewportRay(mouse_npos.x, mouse_npos.y);
1476 Ogre::DefaultRaySceneQuery query(App::GetGfxScene()->GetSceneManager());
1477 query.setRay(ray);
1478 query.setSortByDistance(true);
1480 qlis.ray = ray;
1481 query.execute(&qlis);
1482 return VectorToScriptArray(qlis.results_array, "Ogre::MovableObject@");
1483}
1484
1485Ogre::SceneManager* GameScript::getSceneManager()
1486{
1488}
1489
1490bool GameScript::pushMessage(MsgType type, AngelScript::CScriptDictionary* dict)
1491{
1492 Message m(type);
1493 std::string log_msg = fmt::format("`pushMessage({})`", MsgTypeToString(type));
1494
1495 switch (type)
1496 {
1497 // -- NOT ALLOWED --
1498
1499 // Application
1501 // Networking
1508 case MSG_NET_RECV_ERROR:
1519 // GUI
1522 // Editing
1524 this->log(fmt::format("{} is not allowed.", log_msg));
1525 return false;
1526
1527
1528 // -- SOME ASSEMBLY REQUIRED --
1529
1530 // Application
1532 {
1534 bool has_filename = GetValueFromScriptDict(log_msg, dict, /*required:*/false, "filename", "string", rq->lsr_filename);
1535 bool has_buffer = GetValueFromScriptDict(log_msg, dict, /*required:*/false, "buffer", "string", rq->lsr_buffer);
1536 if (!has_filename && !has_buffer)
1537 {
1538 this->log(fmt::format("{}: ERROR, either 'filename' or 'buffer' must be set!", log_msg));
1539 delete rq;
1540 return false;
1541 }
1542 GetValueFromScriptDict(log_msg, dict, /*required:*/false, "category", "ScriptCategory", rq->lsr_category);
1544 {
1545 int64_t instance_id; // AngelScript's `Dictionary` converts all ints int `int64`
1546 if (!GetValueFromScriptDict(log_msg, dict, /*required:*/true, "associated_actor", "int64", instance_id))
1547 {
1548 this->log(fmt::format("{}: WARNING, category 'ACTOR' specified but 'associated_actor' not given.", log_msg, rq->lsr_filename));
1549 delete rq;
1550 return false;
1551 }
1552 }
1553 m.payload = rq;
1554 break;
1555 }
1556
1558 {
1559 int64_t id; // AngelScript's `Dictionary` converts all ints int `int64`
1560 if (!GetValueFromScriptDict(log_msg, dict, /*required:*/true, "id", "int64", id))
1561 {
1562 return false;
1563 }
1564 m.payload = new ScriptUnitID_t(static_cast<ScriptUnitID_t>(id));
1565 break;
1566 }
1567
1568 // Simulation
1570 if (!GetValueFromScriptDict(log_msg, dict, /*required:*/true, "filename", "string", m.description))
1571 {
1572 return false;
1573 }
1574 break;
1575
1577 if (!GetValueFromScriptDict(log_msg, dict, /*required:*/true, "filename", "string", m.description))
1578 {
1579 return false;
1580 }
1581 break;
1582
1584 {
1586
1587 // Get required params
1588 if (GetValueFromScriptDict(log_msg, dict, /*required:*/true, "filename", "string", rq->asr_filename) &&
1589 GetValueFromScriptDict(log_msg, dict, /*required:*/true, "position", "vector3", rq->asr_position) &&
1590 GetValueFromScriptDict(log_msg, dict, /*required:*/true, "rotation", "quaternion", rq->asr_rotation))
1591 {
1593 if (!rq->asr_cache_entry)
1594 {
1595 this->log(fmt::format("{}: WARNING, vehicle '{}' is not installed.", log_msg, rq->asr_filename));
1596 delete rq;
1597 return false;
1598 }
1599
1600 // Set instance ID if specified
1601 GetValueFromScriptDict(log_msg, dict, /*required:*/false, "instance_id", "int", rq->asr_instance_id);
1602
1603 // Set sectionconfig
1604 GetValueFromScriptDict(log_msg, dict, /*required:*/false, "config", "string", rq->asr_config);
1605 // Make sure config exists
1606 if (rq->asr_config != "")
1607 {
1608 auto result = std::find(rq->asr_cache_entry->sectionconfigs.begin(), rq->asr_cache_entry->sectionconfigs.end(), rq->asr_config);
1609 if (result == rq->asr_cache_entry->sectionconfigs.end())
1610 {
1611 this->log(fmt::format("{}: WARNING, configuration '{}' does not exist in '{}'.", log_msg, rq->asr_config, rq->asr_filename));
1612 rq->asr_config = "";
1613 }
1614 }
1615 // If no config given (or was invalid), use the first available (classic behavior).
1616 if (rq->asr_config == "" && rq->asr_cache_entry->sectionconfigs.size() > 0)
1617 {
1619 }
1620
1621 // Enter or not?
1622 GetValueFromScriptDict(log_msg, dict, /*required:*/false, "enter", "bool", rq->asr_enter);
1623
1624 // Get skin
1625 std::string skin_name;
1626 if (GetValueFromScriptDict(log_msg, dict, /*required:*/false, "skin", "string", skin_name))
1627 {
1629 if (!rq->asr_skin_entry)
1630 this->log(fmt::format("{}: WARNING, skin '{}' is not installed.", log_msg, skin_name));
1631 }
1632
1633 m.payload = rq;
1634 }
1635 else
1636 {
1637 delete rq;
1638 return false;
1639 }
1640 break;
1641 }
1642
1644 {
1645 ActorModifyRequest::Type modify_type;
1646 // `dictionary` converts all primitives to `double` or `int64`, see 'scriptdictionary.cpp', function `Set()`
1647 int64_t instance_id = -1;
1648 if (GetValueFromScriptDict(log_msg, dict, /*required:*/true, "type", "ActorModifyRequestType", modify_type) &&
1649 GetValueFromScriptDict(log_msg, dict, /*required:*/true, "instance_id", "int64", instance_id))
1650 {
1652 rq->amr_type = modify_type;
1653 rq->amr_actor = static_cast<ActorInstanceID_t>(instance_id);
1654 m.payload = rq;
1655 }
1656 else
1657 {
1658 return false;
1659 }
1660 break;
1661 }
1662
1666 {
1667 // `dictionary` converts all primitives to `double` or `int64`, see 'scriptdictionary.cpp', function `Set()`
1668 int64_t instance_id = -1;
1669 if (GetValueFromScriptDict(log_msg, dict, /*required:*/true, "instance_id", "int64", instance_id))
1670 {
1671 ActorPtr actor = App::GetGameContext()->GetActorManager()->GetActorById(instance_id);
1672 if (actor)
1673 {
1674 m.payload = new ActorPtr(actor);
1675 }
1676 else
1677 {
1678 this->log(fmt::format("{}: Actor with instance ID '{}' not found!", log_msg, instance_id));
1679 return false;
1680 }
1681 }
1682 else
1683 {
1684 return false;
1685 }
1686 break;
1687 }
1688
1690 {
1691 // `dictionary` converts all primitives to `double` or `int64`, see 'scriptdictionary.cpp', function `Set()`
1692 int64_t instance_id = -1;
1693 ActorPtr actor;
1694 if (GetValueFromScriptDict(log_msg, dict, /*required:*/true, "instance_id", "int64", instance_id)
1695 && instance_id > -1)
1696 {
1697 actor = App::GetGameContext()->GetActorManager()->GetActorById(instance_id);
1698 }
1699 m.payload = new ActorPtr(actor);
1700 break;
1701 }
1702
1704 {
1705 Ogre::Vector3 position;
1706 if (GetValueFromScriptDict(log_msg, dict, /*required:*/true, "position", "vector3", position))
1707 {
1708 m.payload = new Ogre::Vector3(position);
1709 }
1710 else
1711 {
1712 return false;
1713 }
1714 break;
1715 }
1716
1719 {
1720 // `dictionary` converts all primitives to `double` or `int64`, see 'scriptdictionary.cpp', function `Set()`
1722 if (GetValueFromScriptDict(log_msg, dict, /*required:*/true, "id", "int64", rq->ffr_id) &&
1723 GetValueFromScriptDict(log_msg, dict, /*required:*/true, "type", "FreeForceType", rq->ffr_type) &&
1724 GetValueFromScriptDict(log_msg, dict, /*required:*/true, "force_magnitude", "double", rq->ffr_force_magnitude) &&
1725 GetValueFromScriptDict(log_msg, dict, /*required:*/true, "base_actor", "int64", rq->ffr_base_actor) &&
1726 GetValueFromScriptDict(log_msg, dict, /*required:*/true, "base_node", "int64", rq->ffr_base_node))
1727 {
1728 switch (rq->ffr_type)
1729 {
1730 case (int64_t)FreeForceType::CONSTANT:
1731 if (GetValueFromScriptDict(log_msg, dict, /*required:*/true, "force_const_direction", "vector3", rq->ffr_force_const_direction))
1732 {
1733 m.payload = rq;
1734 }
1735 else
1736 {
1737 delete rq;
1738 return false;
1739 }
1740 break;
1741
1742 case (int64_t)FreeForceType::TOWARDS_COORDS:
1743 if (GetValueFromScriptDict(log_msg, dict, /*required:*/true, "target_coords", "vector3", rq->ffr_target_coords))
1744 {
1745 m.payload = rq;
1746 }
1747 else
1748 {
1749 delete rq;
1750 return false;
1751 }
1752 break;
1753
1754 case (int64_t)FreeForceType::TOWARDS_NODE:
1755 if (GetValueFromScriptDict(log_msg, dict, /*required:*/true, "target_actor", "int64", rq->ffr_target_actor) &&
1756 GetValueFromScriptDict(log_msg, dict, /*required:*/true, "target_node", "int64", rq->ffr_target_node))
1757 {
1758 m.payload = rq;
1759 }
1760 else
1761 {
1762 delete rq;
1763 return false;
1764 }
1765 break;
1766
1767 case (int64_t)FreeForceType::HALFBEAM_GENERIC:
1768 case (int64_t)FreeForceType::HALFBEAM_ROPE:
1769 if (GetValueFromScriptDict(log_msg, dict, /*required:*/true, "target_actor", "int64", rq->ffr_target_actor) &&
1770 GetValueFromScriptDict(log_msg, dict, /*required:*/true, "target_node", "int64", rq->ffr_target_node))
1771 {
1772 GetValueFromScriptDict(log_msg, dict, /*required:*/false, "halfb_spring", "double", rq->ffr_halfb_spring);
1773 GetValueFromScriptDict(log_msg, dict, /*required:*/false, "halfb_damp", "double", rq->ffr_halfb_damp);
1774 GetValueFromScriptDict(log_msg, dict, /*required:*/false, "halfb_deform", "double", rq->ffr_halfb_deform);
1775 GetValueFromScriptDict(log_msg, dict, /*required:*/false, "halfb_strength", "double", rq->ffr_halfb_strength);
1776 GetValueFromScriptDict(log_msg, dict, /*required:*/false, "halfb_diameter", "double", rq->ffr_halfb_diameter);
1777 m.payload = rq;
1778 }
1779 else
1780 {
1781 delete rq;
1782 return false;
1783 }
1784 break;
1785
1786 default:
1787 this->log(fmt::format("{}: ERROR, invalid 'free force type' value '{}'", log_msg, rq->ffr_type));
1788 delete rq;
1789 return false;
1790 }
1791 m.payload = rq;
1792 }
1793 else
1794 {
1795 delete rq;
1796 return false;
1797 }
1798 break;
1799 }
1800
1802 {
1803 // `dictionary` converts all primitives to `double` or `int64`, see 'scriptdictionary.cpp', function `Set()`
1804 int64_t id = -1;
1805 if (GetValueFromScriptDict(log_msg, dict, /*required:*/true, "id", "int64", id))
1806 {
1807 m.payload = new FreeForceID_t(id);
1808 }
1809 else
1810 {
1811 return false;
1812 }
1813 break;
1814 }
1815
1819 {
1820 CacheEntryPtr entry;
1821 if (GetValueFromScriptDict(log_msg, dict, /*required*/true, "cache_entry", "CacheEntryClass@", entry))
1822 {
1823 m.payload = new CacheEntryPtr(entry);
1824 }
1825 else
1826 {
1827 return false;
1828 }
1829 break;
1830 }
1831
1833 {
1835 if (GetValueFromScriptDict(log_msg, dict, /*required:*/true, "name", "string", request->cpr_name) &&
1836 GetValueFromScriptDict(log_msg, dict, /*required:*/true, "source_entry", "CacheEntryClass@", request->cpr_source_entry))
1837 {
1838 m.payload = request;
1839 }
1840 else
1841 {
1842 delete request;
1843 return false;
1844 }
1845 break;
1846 }
1847
1848 // Payload = RoR::FreeBeamGfxRequest* (owner)
1851 {
1852 // `dictionary` converts all primitives to `double` or `int64`, see 'scriptdictionary.cpp', function `Set()`
1854 if (GetValueFromScriptDict(log_msg, dict, /*required:*/true, "id", "int64", rq->fbr_id) &&
1855 GetValueFromScriptDict(log_msg, dict, /*required:*/true, "freeforce_primary", "int64", rq->fbr_freeforce_primary))
1856 {
1857 // Beams fixed to ground don't need a secondary free force
1858 GetValueFromScriptDict(log_msg, dict, /*required:*/false, "freeforce_secondary", "int64", rq->fbr_freeforce_secondary);
1859 GetValueFromScriptDict(log_msg, dict, /*required:*/false, "mesh_name", "string", rq->fbr_mesh_name);
1860 GetValueFromScriptDict(log_msg, dict, /*required:*/false, "material_name", "string", rq->fbr_material_name);
1861 GetValueFromScriptDict(log_msg, dict, /*required:*/false, "diameter", "double", rq->fbr_diameter);
1862 m.payload = rq;
1863 }
1864 else
1865 {
1866 delete rq;
1867 return false;
1868 }
1869 break;
1870 }
1871
1873 {
1874 // `dictionary` converts all primitives to `double` or `int64`, see 'scriptdictionary.cpp', function `Set()`
1875 int64_t id = -1;
1876 if (GetValueFromScriptDict(log_msg, dict, /*required:*/true, "id", "int64", id))
1877 {
1878 m.payload = new FreeBeamGfxID_t(id);
1879 }
1880 else
1881 {
1882 return false;
1883 }
1884 break;
1885 }
1886
1888 {
1889 // `dictionary` converts all primitives to `double` or `int64`, see 'scriptdictionary.cpp', function `Set()`
1890 int64_t repo_resource_id = -1;
1891 int64_t repo_file_id = -1;
1892 std::string repo_filename;
1893 if (GetValueFromScriptDict(log_msg, dict, /*required:*/true, "resource_id", "int64", repo_resource_id) &&
1894 GetValueFromScriptDict(log_msg, dict, /*required:*/true, "file_id", "int64", repo_file_id) &&
1895 GetValueFromScriptDict(log_msg, dict, /*required:*/true, "filename", "string", repo_filename))
1896 {
1898 rq->rfir_resource_id = repo_resource_id;
1899 rq->rfir_repofile_id = repo_file_id;
1900 rq->rfir_filename = repo_filename;
1901 m.payload = rq;
1902 }
1903 else
1904 {
1905 return false;
1906 }
1907 }
1908
1909 default:;
1910 }
1911
1913 return true;
1914}
1915
1920
1925
1930
1931// --------------------------------
1932// Audio
1933
1935{
1936 return MapToScriptArray(App::GetSoundScriptManager()->getAllTemplates(), "SoundScriptTemplateClass@");
1937}
1938
1943
1944AngelScript::CScriptArray* GameScript::getAllSoundScriptInstances()
1945{
1946 return VectorToScriptArray(App::GetSoundScriptManager()->getAllInstances(), "SoundScriptInstanceClass@");
1947}
1948
1949SoundPtr GameScript::createSoundFromResource(const std::string& filename, const std::string& resource_group_name)
1950{
1951 return App::GetSoundScriptManager()->getSoundManager()->createSound(filename, resource_group_name);
1952}
1953
1955{
1956 return App::GetSoundScriptManager()->createInstance(template_name, actor_instance_id);
1957}
1958
1959bool GameScript::checkResourceExists(const std::string& filename, const std::string& resource_group)
1960{
1961 try
1962 {
1963 std::string resource_name = this->CheckFileAccess("checkResourceExists()", filename, resource_group);
1964 if (resource_name == "")
1965 return false; // Access denied - error already logged
1966
1967 // Actually check for the resource
1968 return Ogre::ResourceGroupManager::getSingleton().resourceExists(resource_group, resource_name);
1969 }
1970 catch (...)
1971 {
1972 App::GetScriptEngine()->forwardExceptionAsScriptEvent("GameScript::checkResourceExists()");
1973 return false;
1974 }
1975}
1976
1977bool GameScript::deleteResource(const std::string& filename, const std::string& resource_group)
1978{
1979 try
1980 {
1981 std::string resource_name = this->CheckFileAccess("deleteResource()", filename, resource_group);
1982 if (resource_name == "")
1983 return false; // Access denied - error already logged
1984
1985 // Actually delete the resource
1986 Ogre::ResourceGroupManager::getSingleton().deleteResource(resource_name, resource_group);
1987 return true;
1988 }
1989 catch (...)
1990 {
1991 App::GetScriptEngine()->forwardExceptionAsScriptEvent("GameScript::deleteResource()");
1992 return false;
1993 }
1994}
1995
1996std::string GameScript::loadTextResourceAsString(const std::string& filename, const std::string& resource_group)
1997{
1998 try
1999 {
2000 std::string resource_name = this->CheckFileAccess("loadTextResourceAsString()", filename, resource_group);
2001 if (resource_name == "")
2002 return ""; // Access denied - error already logged
2003
2004 Ogre::DataStreamPtr stream = Ogre::ResourceGroupManager::getSingleton().openResource(resource_name, resource_group);
2005
2006 if (!stream || !stream->isReadable())
2007 {
2009 fmt::format("loadTextResourceAsString() could not read resource '{}' in group '{}'",
2010 resource_name, resource_group));
2011 return "";
2012 }
2013
2014#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
2015 // WORKAROUND: apparently `getAsString()` has some Linux-x64 issues (`eof()` triggers SIGINT):
2016 // https://discord.com/channels/136544456244461568/189904947649708032/1155952230130778262
2017 // Observed with OGRE 1.11.6
2018 std::string str;
2019 const size_t BUF_LEN = 4000;
2020 char buf[BUF_LEN] = {};
2021 bool eof = false;
2022 while (!eof)
2023 {
2024 size_t read_len = stream->read(buf, BUF_LEN);
2025 if (read_len < BUF_LEN)
2026 {
2027 buf[read_len] = 0;
2028 eof = true;
2029 }
2030 str.append(buf, read_len);
2031 }
2032 return str;
2033#else
2034 return stream->getAsString();
2035#endif
2036 }
2037 catch (...)
2038 {
2039 App::GetScriptEngine()->forwardExceptionAsScriptEvent("GameScript::loadTextResourceAsString()");
2040 return "";
2041 }
2042}
2043
2044bool GameScript::createTextResourceFromString(const std::string& data, const std::string& filename, const std::string& resource_group, bool overwrite/*=false*/)
2045{
2046 try
2047 {
2048 std::string resource_name = this->CheckFileAccess("createTextResourceFromString()", filename, resource_group);
2049 if (resource_name == "")
2050 return false; // Access denied - error already logged
2051
2052 Ogre::DataStreamPtr stream = Ogre::ResourceGroupManager::getSingleton().createResource(resource_name, resource_group, overwrite);
2053
2054 if (!stream || !stream->isWriteable())
2055 {
2057 fmt::format("createTextResourceFromString() could not create resource '{}' in group '{}'",
2058 resource_name, resource_group));
2059 return false;
2060 }
2061
2062 stream->write(data.data(), data.size());
2063 return true;
2064 }
2065 catch (...)
2066 {
2067 App::GetScriptEngine()->forwardExceptionAsScriptEvent("GameScript::createTextResourceFromString()");
2068 return false;
2069 }
2070}
2071
2072AngelScript::CScriptArray* GameScript::findResourceFileInfo(const std::string& resource_group, const std::string& pattern, bool dirs /*= false*/)
2073{
2074 try
2075 {
2076 // Search the file system
2077 Ogre::FileInfoListPtr fileInfoList
2078 = Ogre::ResourceGroupManager::getSingleton().findResourceFileInfo(resource_group, pattern, dirs);
2079
2080 // Put results to array
2081 AngelScript::asITypeInfo* typeinfo = App::GetScriptEngine()->getEngine()->GetTypeInfoByDecl("array<dictionary>");
2082 AngelScript::CScriptArray* arr = AngelScript::CScriptArray::Create(typeinfo);
2083 int stringTypeid = App::GetScriptEngine()->getEngine()->GetTypeIdByDecl("string");
2084 for (const Ogre::FileInfo& fileinfo: *fileInfoList)
2085 {
2086 AngelScript::CScriptDictionary* dict = AngelScript::CScriptDictionary::Create(App::GetScriptEngine()->getEngine());
2087 dict->Set("filename", new std::string(fileinfo.filename), stringTypeid);
2088 dict->Set("basename", new std::string(fileinfo.basename), stringTypeid);
2089 dict->Set("compressedSize", (asINT64)fileinfo.compressedSize);
2090 dict->Set("uncompressedSize", (asINT64)fileinfo.uncompressedSize);
2091
2092 arr->InsertLast(dict);
2093 }
2094 return arr;
2095 }
2096 catch (...)
2097 {
2098 App::GetScriptEngine()->forwardExceptionAsScriptEvent("GameScript::findResourceFileInfo()");
2099 return nullptr;
2100 }
2101}
2102
2103Ogre::Image GameScript::loadImageResource(const std::string& filename, const std::string& resource_group)
2104{
2105 try
2106 {
2107 std::string resource_name = this->CheckFileAccess("loadImageResource()", filename, resource_group);
2108 if (resource_name == "")
2109 return Ogre::Image(); // Access denied - error already logged
2110
2111 Ogre::Image img;
2112 return img.load(resource_name, resource_group);
2113 }
2114 catch (...)
2115 {
2116 App::GetScriptEngine()->forwardExceptionAsScriptEvent("GameScript::loadImageResource()");
2117 return Ogre::Image();
2118 }
2119}
2120
2121bool GameScript::serializeMeshResource(const std::string& filename, const std::string& resource_group, const Ogre::MeshPtr& mesh)
2122{
2123 try
2124 {
2125 std::string resource_name = this->CheckFileAccess("serializeMeshResource()", filename, resource_group);
2126 if (resource_name == "")
2127 return false; // Access denied - error already logged
2128
2129 Ogre::MeshSerializer ser;
2130 Ogre::DataStreamPtr stream = Ogre::ResourceGroupManager::getSingleton().createResource(resource_name, resource_group);
2131 ser.exportMesh(mesh.get(), stream);
2132 return true;
2133 }
2134 catch (...)
2135 {
2136 App::GetScriptEngine()->forwardExceptionAsScriptEvent("GameScript::serializeMeshResource()");
2137 return false;
2138 }
2139}
2140
2141// ------------------------
2142// Helpers:
2143
2144bool GameScript::HaveSimTerrain(const char* func_name)
2145{
2146 if (App::GetGameContext()->GetTerrain() == nullptr)
2147 {
2148 this->logFormat("Cannot execute '%s', terrain not ready", func_name);
2149 return false;
2150 }
2151 return true;
2152}
2153
2154bool GameScript::HavePlayerAvatar(const char* func_name)
2155{
2156 if (App::GetGameContext()->GetPlayerCharacter() == nullptr)
2157 {
2158 this->logFormat("Cannot execute '%s', player avatar not ready", func_name);
2159 return false;
2160 }
2161 return true;
2162}
2163
2164bool GameScript::HaveMainCamera(const char* func_name)
2165{
2166 if (App::GetCameraManager()->GetCamera() == nullptr)
2167 {
2168 this->logFormat("Cannot execute '%s', main camera not ready", func_name);
2169 return false;
2170 }
2171 return true;
2172}
2173
2174std::string GameScript::CheckFileAccess(const char* func_name, const std::string& filename, const std::string& resource_group)
2175{
2176 // Extract filename and extension from the input, because OGRE allows absolute paths in resource system.
2177 // -----------------------------------------------------------------------------------------------------
2178
2179 std::string basename, extension, path;
2180 Ogre::StringUtil::splitFullFilename(filename, basename, extension, path);
2181 if (path != "")
2182 {
2184 fmt::format("{}: access denied to '{}' with group '{}' - file paths are not allowed",
2185 func_name, filename, resource_group));
2186 return "";
2187 }
2188 else
2189 {
2190 return basename + "." + extension;
2191 }
2192}
System integration layer; inspired by OgreBites::ApplicationContext.
#define ROR_ASSERT(_EXPR)
Definition Application.h:40
void LOG(const char *msg)
Legacy alias - formerly a macro.
uint32_t BitMask_t
Definition BitFlags.h:7
A database of user-installed content alias 'mods' (vehicles, terrains...)
#define _L
Game state manager and message-queue provider.
void spawnTruckAiBotHelper(ActorSpawnRequest &rq, const ScriptUnit &unit)
Platform-specific utilities. We use narrow UTF-8 encoded strings as paths. Inspired by http://utf8eve...
const char *const ROR_VERSION_STRING
Simple waypoint AI.
EnginePtr ar_engine
Definition Actor.h:467
std::string ar_filehash
Attribute; filled at spawn.
Definition Actor.h:519
Ogre::String ar_design_name
Name of the vehicle/machine/object this actor represents.
Definition Actor.h:441
ActorInstanceID_t ar_instance_id
Static attr; session-unique ID.
Definition Actor.h:464
ActorPtrVec ar_linked_actors
BEWARE: Includes indirect links, see DetermineLinkedActors(); Other actors linked using 'hooks/ties/r...
Definition Actor.h:568
std::string ar_filename
Attribute; filled at spawn.
Definition Actor.h:518
VehicleAIPtr ar_vehicle_ai
Definition Actor.h:485
ActorPtrVec & GetActors()
FreeForceID_t GetFreeForceNextId()
Script proxy: game.getFreeForceNextId()
void SetTrucksForcedAwake(bool forced)
float GetTotalTime() const
const ActorPtr & GetActorById(ActorInstanceID_t actor_id)
ActorInstanceID_t GetActorNextInstanceId()
Script proxy: game.getActorNextInstanceId()
void RepairActor(Collisions *collisions, const Ogre::String &inst, const Ogre::String &box, bool keepPosition=false)
Ogre::RenderWindow * GetRenderWindow()
Definition AppContext.h:70
std::string const & getStr() const
Definition CVar.h:95
std::vector< Ogre::String > sectionconfigs
Ogre::String dname
name parsed from the file
Definition CacheSystem.h:70
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,...
CacheEntryPtr FetchSkinByName(std::string const &skin_name)
Ogre::SceneNode * GetCameraNode()
Ogre::Camera * GetCamera()
void setPosition(Ogre::Vector3 position)
Definition Character.cpp:85
Ogre::Vector3 getPosition()
Definition Character.cpp:92
void setRotation(Ogre::Radian rotation)
Definition Character.cpp:98
void move(Ogre::Vector3 offset)
Ogre::Radian getRotation() const
Definition Character.h:53
void clearEventCache()
Definition Collisions.h:209
@ CONSOLE_MSGTYPE_SCRIPT
Messages sent from scripts.
Definition Console.h:62
@ CONSOLE_MSGTYPE_INFO
Generic message.
Definition Console.h:60
void putMessage(MessageArea area, MessageType type, std::string const &msg, std::string icon="")
Definition Console.cpp:103
@ CONSOLE_SYSTEM_ERROR
Definition Console.h:52
@ CONSOLE_SYSTEM_NOTICE
Definition Console.h:51
@ CONSOLE_SYSTEM_WARNING
Definition Console.h:53
float getRPM()
Definition Engine.h:95
void setRPM(float rpm)
Definition Engine.cpp:928
Ogre::String ai_sectionconfig
Ogre::String ai_sectionconfig2
std::vector< ai_events > ai_waypoints
GUI::TopMenubar TopMenubar
Definition GUIManager.h:134
void ShowMessageBox(const char *title, const char *text, bool allow_close=true, const char *btn1_text="OK", const char *btn2_text=nullptr)
ActorPtr SpawnActor(ActorSpawnRequest &rq)
ActorPtr FindActorByCollisionBox(std::string const &ev_src_instance_name, std::string const &box_name)
Character * GetPlayerCharacter()
const ActorPtr & GetPlayerActor()
const TerrainPtr & GetTerrain()
void ShowLoaderGUI(int type, const Ogre::String &instance, const Ogre::String &box)
void PushMessage(Message m)
Doesn't guarantee order! Use ChainMessage() if order matters.
const ActorPtr & GetActorRemotelyReceivingCommands()
ActorManager * GetActorManager()
RaceSystem & GetRaceSystem()
FreeBeamGfxID_t getFreeBeamGfxNextId()
Returns an unused (not reused) ID to use with MSG_SIM_ADD_FREEBEAMGFX_REQUESTED; see game....
AngelScript::CScriptArray * getRunningScripts()
Returns array<int> with active ScriptUnitIDs; check agains global var thisScript or use getScriptDeta...
Ogre::String getAIVehicleSectionConfig(int x)
bool checkResourceExists(const std::string &filename, const std::string &resource_group)
Checks if the resource file exists in the given group.
void showMessageBox(Ogre::String &title, Ogre::String &text, bool use_btn1, Ogre::String &btn1_text, bool allow_close, bool use_btn2, Ogre::String &btn2_text)
void registerForEvent(int eventValue)
registers for a new event to be received by the scripting system
int setMaterialTextureScroll(const Ogre::String &materialName, int techniqueNum, int passNum, int textureUnitNum, float sx, float sy)
int setMaterialTextureRotate(const Ogre::String &materialName, int techniqueNum, int passNum, int textureUnitNum, float rotation)
void movePerson(const Ogre::Vector3 &vec)
moves the person relative
void logFormat(const char *fmt,...)
writes a message to the games log (RoR.log)
void setAIVehicleCount(int count)
void log(const Ogre::String &msg)
writes a message to the games log (RoR.log)
void fetchUrlAsStringAsync(const std::string &url, const std::string &display_filename)
Invokes a background thread to fetch data using CURL; when finished, sends MSG_APP_SCRIPT_THREAD_STAT...
void setGravity(float value)
sets the gravity terrain wide.
float getGroundHeight(Ogre::Vector3 &v)
Gets terrain height at given coordinates.
void cameraLookAt(const Ogre::Vector3 &targetPoint)
Points the camera at a location in worldspace.
std::string CheckFileAccess(const char *func_name, const std::string &filename, const std::string &resource_group)
Extract filename and extension from the input, because OGRE allows absolute paths in resource system.
bool getCaelumAvailable()
ScriptRetCode_t getScriptVariable(const Ogre::String &varName, void *ref, int refTypeId, ScriptUnitID_t nid)
Retrieves a memory address of a global variable in any script.
AngelScript::CScriptArray * getAllTrucks()
returns an array of all currently existing actors.
AngelScript::CScriptArray * getMousePointedMovableObjects()
Returns array<Ogre::MovableObjects@> in no particular order.
void setTimeDiff(float diff)
int getChatFontSize()
OBSOLETE, returns 0;.
int sendGameCmd(const Ogre::String &message)
Multiplayer only: sends AngelScript snippet to all players.
int getLoadedTerrain(Ogre::String &result)
gets the name of current terrain.
bool getScreenPosFromWorldPos(Ogre::Vector3 const &world_pos, Ogre::Vector2 &out_screen_pos)
Ogre::String getCaelumTime()
gets the time of the day in seconds
bool HaveSimTerrain(const char *func_name)
Helper; Check if SimController instance exists, log warning if not.
Ogre::String getAIVehicleName(int x)
void setAIVehicleSpeed(int speed)
int getCurrentTruckNumber()
returns the current truck number.
void setAIVehicleSectionConfig(int x, std::string config)
AngelScript::CScriptArray * getEditorObjects()
Returns array<TerrainEditorObjectClassPtr@> with all static objects on map (from any source).
ActorPtr spawnTruck(Ogre::String &truckName, Ogre::Vector3 &pos, Ogre::Vector3 &rot)
void setCaelumTime(float value)
sets the time of the day in seconds
void activateAllVehicles()
std::string getAIVehicleSkin(int x)
void unRegisterEvent(int eventValue)
unregisters from receiving event.
AngelScript::CScriptArray * getWaypoints(int x)
void setBestLapTime(float time)
void setChatFontSize(int size)
OBSOLETE, does nothing.
int useOnlineAPI(const Ogre::String &apiquery, const AngelScript::CScriptDictionary &dict, Ogre::String &result)
Ogre::Vector3 getPersonPosition()
ActorPtr getCurrentTruck()
returns the current selected truck, 0 if in person mode
AngelScript::CScriptDictionary * getScriptDetails(ScriptUnitID_t nid)
Returns all info about running script; obtain the NID from getRunningScripts(), global var thisScript...
bool serializeMeshResource(const std::string &filename, const std::string &resource_group, const Ogre::MeshPtr &mesh)
Uses Ogre::MeshSerializer to save binary .mesh file (latest format, native endianness).
SoundPtr createSoundFromResource(const std::string &filename, const std::string &resource_group_name)
int getAIVehiclePositionScheme()
void setPersonPosition(const Ogre::Vector3 &vec)
sets the character position
ScriptRetCode_t deleteScriptVariable(const Ogre::String &arg, ScriptUnitID_t nid)
Deletes a global variable from the script (Wrapper for ScriptEngine::deleteVariable)
ScriptRetCode_t deleteScriptFunction(const Ogre::String &arg, ScriptUnitID_t nid)
Deletes a global function from the script (Wrapper for ScriptEngine::deleteFunction)
Ogre::Vector2 getMouseScreenPosition()
Gets mouse position in pixels.
void setWaterHeight(float value)
sets the base water height
Ogre::Quaternion getCameraOrientation()
Gets the camera's orientation.
int setMaterialAmbient(const Ogre::String &materialName, float red, float green, float blue)
bool getMousePositionOnTerrain(Ogre::Vector3 &out_pos)
Calculates mouse cursor position on terrain.
void setCameraOrientation(const Ogre::Quaternion &q)
Sets the camera's orientation.
void setCameraRoll(float angle)
Rolls the camera anticlockwise, around its local z axis.
float getTime()
returns the time in seconds since the game was started
int setMaterialDiffuse(const Ogre::String &materialName, float red, float green, float blue, float alpha)
AngelScript::CScriptArray * getAllSoundScriptTemplates()
Ogre::Vector3 getCameraDirection()
Gets the camera's direction.
void flashMessage(Ogre::String &txt, float time, float charHeight)
DEPRECATED: use message() shows a message to the user.
ScriptRetCode_t scriptFunctionExists(const Ogre::String &arg, ScriptUnitID_t nid)
Checks if a global function exists in the script (Wrapper for ScriptEngine::functionExists)
void setAIVehicleSkin(int x, std::string skin)
void updateDirectionArrow(Ogre::String &text, Ogre::Vector3 &vec)
set direction arrow
void setAIVehiclePositionScheme(int scheme)
ActorInstanceID_t getActorNextInstanceId()
Returns an unused (not reused) ID to use with MSG_SIM_SPAWN_ACTOR_REQUESTED; see game....
bool pushMessage(MsgType type, AngelScript::CScriptDictionary *dict)
Pushes a message to internal message queue.
Ogre::Vector2 getDisplaySize()
Gets screen size in pixels.
void moveObjectVisuals(const Ogre::String &instanceName, const Ogre::Vector3 &pos)
This moves an object to a new position.
Ogre::SceneManager * getSceneManager()
AngelScript::CScriptArray * getAllSoundScriptInstances()
TerrainPtr getTerrain()
void setCameraPosition(const Ogre::Vector3 &pos)
Sets the camera's position.
Ogre::Vector3 getCameraPosition()
Retrieves the camera's position.
bool createTextResourceFromString(const std::string &data, const std::string &filename, const std::string &resource_group, bool overwrite=false)
Saves a string as a text file resource.
FreeForceID_t getFreeForceNextId()
Returns an unused (not reused) ID to use with MSG_SIM_ADD_FREEFORCE_REQUESTED; see game....
void removeVehicle(const Ogre::String &instance, const Ogre::String &box)
int getNumTrucksByFlag(int flag)
Ogre::Image loadImageResource(const std::string &filename, const std::string &resource_group)
Loads an image in any format recognized by OGRE.
void hideDirectionArrow()
void setAIVehicleName(int x, std::string name)
VehicleAIPtr getCurrentTruckAI()
void setPersonRotation(const Ogre::Radian &rot)
sets the character rotation
float getWaterHeight()
returns the current base water level (without waves)
void showChooser(const Ogre::String &type, const Ogre::String &instance, const Ogre::String &box)
void setCameraDirection(const Ogre::Vector3 &vec)
Sets the camera's direction vector.
int getTextureUnitState(Ogre::TextureUnitState **tu, const Ogre::String materialName, int techniqueNum, int passNum, int textureUnitNum)
int setMaterialEmissive(const Ogre::String &materialName, float red, float green, float blue)
ActorPtr getTruckByNum(int num)
returns a truck by index, get max index by calling getNumTrucks
void message(Ogre::String &txt, Ogre::String &icon)
shows a message to the user over the console system
ActorPtr getTruckRemotelyReceivingCommands()
Actors with 'importcommands' flag will remotely respond to command keys when the player is close enou...
ScriptRetCode_t scriptVariableExists(const Ogre::String &arg, ScriptUnitID_t nid)
Adds a global variable to the script (Wrapper for ScriptEngine::variableExists)
void loadTerrain(const Ogre::String &terrain)
std::string loadTextResourceAsString(const std::string &filename, const std::string &resource_group)
Loads a text file resource as string.
Ogre::Radian getPersonRotation()
gets the character rotation
void setAIVehicleDistance(int dist)
ScriptRetCode_t addScriptFunction(const Ogre::String &arg, ScriptUnitID_t nid)
Adds a global function to the script (Wrapper for ScriptEngine::addFunction)
BitMask_t getRegisteredEventsMask(ScriptUnitID_t nid)
Gets event mask for a specific running script.
ScriptRetCode_t addScriptVariable(const Ogre::String &arg, ScriptUnitID_t nid)
Adds a global variable to the script (Wrapper for ScriptEngine::addVariable)
AngelScript::CScriptArray * getWaypointsSpeed()
void openUrlInDefaultBrowser(const std::string &url)
Opens URL (must start with 'http://' or 'https://') in system's default web browser.
void destroyObject(const Ogre::String &instanceName)
This destroys an object.
void startTimer(int id)
void setRegisteredEventsMask(ScriptUnitID_t nid, BitMask_t eventMask)
Overwrites event mask for a specific running script.
int setMaterialTextureName(const Ogre::String &materialName, int techniqueNum, int passNum, int textureUnitNum, const Ogre::String &textureName)
SoundScriptTemplatePtr getSoundScriptTemplate(const std::string &name)
void setCameraYaw(float angle)
Rotates the camera anticlockwise around it's local y axis.
void setAIRepeatTimes(int times)
bool HavePlayerAvatar(const char *func_name)
Helper; Check if local Character instance exists, log warning if not.
float rangeRandom(float from, float to)
void spawnObject(const Ogre::String &objectName, const Ogre::String &instanceName, const Ogre::Vector3 &pos, const Ogre::Vector3 &rot, const Ogre::String &eventhandler, bool uniquifyMaterials)
This spawns a static terrain object (.ODEF file)
bool HaveMainCamera(const char *func_name)
Helper; Check if main camera exists, log warning if not.
void boostCurrentTruck(float factor)
void repairVehicle(const Ogre::String &instance, const Ogre::String &box, bool keepPosition)
int setMaterialSpecular(const Ogre::String &materialName, float red, float green, float blue, float alpha)
SoundScriptInstancePtr createSoundScriptInstance(const std::string &template_name, int actor_instance_id)
bool deleteResource(const std::string &filename, const std::string &resource_group)
Deletes a resource from the given group.
void addWaypoint(const Ogre::Vector3 &pos)
VehicleAIPtr getTruckAIByNum(int num)
void setCameraPitch(float angle)
Pitches the camera up/down anticlockwise around it's local z axis.
float getGravity()
returns the currently set upo gravity
void setAIMode(int mode)
int setMaterialTextureScale(const Ogre::String &materialName, int techniqueNum, int passNum, int textureUnitNum, float u, float v)
ActorPtr spawnTruckAI(Ogre::String &truckName, Ogre::Vector3 &pos, Ogre::String &truckSectionConfig, std::string &truckSkin, int x)
void setTrucksForcedAwake(bool forceActive)
AngelScript::CScriptArray * findResourceFileInfo(const std::string &resource_group, const std::string &pattern, bool dirs=false)
Proxy to Ogre::ResourceGroupManager::findResourceFileInfo(), see https://ogrecave....
FreeBeamGfxID_t GetFreeBeamGfxNextId()
Definition GfxScene.h:65
Ogre::SceneManager * GetSceneManager()
Definition GfxScene.h:83
Ogre::Vector2 getMouseNormalizedScreenPos()
Returns XY position in range from 0 (top/left) to 1 (bottom/right)
bool GetUserPeerOpts(int uid, BitMask_t &result)
Definition Network.cpp:740
void AddPacket(int streamid, int type, int len, const char *content)
Definition Network.cpp:617
void UpdateDirectionArrow(char *text, Ogre::Vector3 position)
void SetRaceBestTime(float time)
Definition RaceSystem.h:44
void StartRaceTimer(int id)
void SetRaceTimeDiff(float diff)
Definition RaceSystem.h:41
ScriptUnit & getScriptUnit(ScriptUnitID_t unique_id)
ScriptRetCode_t variableExists(const Ogre::String &arg, const ScriptUnitID_t nid=SCRIPTUNITID_DEFAULT)
Adds a global variable to the script.
ScriptRetCode_t deleteVariable(const Ogre::String &arg, const ScriptUnitID_t nid=SCRIPTUNITID_DEFAULT)
Deletes a global variable from the script.
void forwardExceptionAsScriptEvent(const std::string &from)
Forwards useful info from C++ try{}catch{} exceptions to script in the form of game event.
ScriptRetCode_t addVariable(const Ogre::String &arg, const ScriptUnitID_t nid=SCRIPTUNITID_DEFAULT)
Adds a global variable to the script.
ScriptRetCode_t deleteFunction(const Ogre::String &arg, const ScriptUnitID_t nid=SCRIPTUNITID_DEFAULT)
Deletes a global function from the script.
ScriptUnitMap const & getScriptUnits() const
void SLOG(const char *msg)
Replacement of macro.
ScriptRetCode_t getVariable(const Ogre::String &varName, void *ref, int typeID, ScriptUnitID_t nid=SCRIPTUNITID_DEFAULT)
Retrieves a global variable from any running script.
ScriptRetCode_t addFunction(const Ogre::String &arg, const ScriptUnitID_t nid=SCRIPTUNITID_DEFAULT)
Adds a global function to the script.
ScriptUnitID_t getCurrentlyExecutingScriptUnit() const
AngelScript::asIScriptFunction * getFunctionByDeclAndLogCandidates(ScriptUnitID_t nid, GetFuncFlags_t flags, const std::string &funcName, const std::string &fmtFuncDecl)
Finds a function by full declaration, and if not found, finds candidates by name and logs them to Ang...
ScriptRetCode_t functionExists(const Ogre::String &arg, const ScriptUnitID_t nid=SCRIPTUNITID_DEFAULT)
Checks if a global function exists.
AngelScript::asIScriptEngine * getEngine()
void setForwardScriptLogToConsole(bool doForward)
void queueMessageGameCmd(int uid, const std::string &data)
void queueMessageStreamRegister(int uid, RoRnet::StreamRegister *reg)
SoundPtr createSound(Ogre::String filename, Ogre::String resource_group_name="")
static const int ACTOR_ID_UNKNOWN
SoundScriptTemplatePtr & getTemplate(Ogre::String name)
SoundManager * getSoundManager()
SoundScriptInstancePtr createInstance(Ogre::String templatename, int actor_id, int soundLinkType=SL_DEFAULT, int soundLinkItemId=-1)
Represents an instance of static terrain object (.ODEF file format)
Ogre::TerrainGroup * getTerrainGroup()
void setGravity(float value)
Definition Terrain.cpp:489
TerrainObjectManager * getObjectManager()
Definition Terrain.h:80
SkyManager * getSkyManager()
Definition Terrain.cpp:521
TerrainGeometryManager * getGeometryManager()
Definition Terrain.h:79
std::string getTerrainName() const
Definition Terrain.cpp:585
float getHeightAt(float x, float z)
Definition Terrain.cpp:511
Collisions * GetCollisions()
Definition Terrain.h:86
Wavefield * getWater()
Definition Terrain.h:87
float getGravity() const
Definition Terrain.h:101
bool LoadTerrainObject(const Ogre::String &name, const Ogre::Vector3 &pos, const Ogre::Vector3 &rot, const Ogre::String &instancename, const Ogre::String &type, float rendering_distance=0, bool enable_collisions=true, int scripthandler=-1, bool uniquifyMaterial=false)
TerrainEditorObjectPtrVec & GetEditorObjects()
void moveObjectVisuals(const Ogre::String &instancename, const Ogre::Vector3 &pos)
void destroyObject(const Ogre::String &instancename)
void SetStaticWaterHeight(float value)
Definition Wavefield.cpp:80
float GetStaticWaterHeight()
Returns static water level configured in 'terrn2'.
Definition Wavefield.cpp:75
< Keeps data close for faster access.
Definition Utils.h:83
Ogre::Vector3 Convert(Ogre::Vector3 world_pos)
Definition Utils.h:90
bool queryResult(SceneQuery::WorldFragment *fragment, Real distance) override
std::vector< Ogre::MovableObject * > results_array
bool queryResult(MovableObject *obj, Real distance) override
void OpenUrlInDefaultBrowser(std::string const &url)
@ LOCAL_SCRIPT
Not actually connected to network, but running server script locally.
const char * MsgTypeToString(MsgType type)
MsgType
Global gameplay message loop, see struct Message in GameContext.h.
Definition Application.h:77
@ MSG_GUI_OPEN_MENU_REQUESTED
@ MSG_APP_MODCACHE_LOAD_REQUESTED
Definition Application.h:91
@ MSG_SIM_TELEPORT_PLAYER_REQUESTED
Payload = Ogre::Vector3* (owner)
@ MSG_NET_CONNECT_STARTED
@ MSG_NET_FETCH_AI_PRESETS_SUCCESS
Description = JSON string.
@ MSG_NET_DOWNLOAD_REPOFILE_REQUESTED
Payload = RoR::RepoFileInstallRequest* (owner)
@ MSG_NET_RECV_ERROR
@ MSG_EDI_ADD_FREEBEAMGFX_REQUESTED
Payload = RoR::FreeBeamGfxRequest* (owner)
@ MSG_NET_DOWNLOAD_REPOFILE_SUCCESS
Payload = RoR::RepoFileInstallRequest* (owner)
@ MSG_SIM_UNHIDE_NET_ACTOR_REQUESTED
Payload = ActorPtr* (owner)
@ MSG_SIM_HIDE_NET_ACTOR_REQUESTED
Payload = ActorPtr* (owner)
@ MSG_SIM_UNLOAD_TERRN_REQUESTED
@ MSG_EDI_UNLOAD_BUNDLE_REQUESTED
Payload = RoR::CacheEntryPtr* (owner)
@ MSG_NET_CONNECT_FAILURE
@ MSG_NET_FETCH_AI_PRESETS_FAILURE
Description = message.
@ MSG_SIM_SPAWN_ACTOR_REQUESTED
Payload = RoR::ActorSpawnRequest* (owner)
@ MSG_SIM_REMOVE_FREEFORCE_REQUESTED
Payload = RoR::FreeForceID_t* (owner)
@ MSG_GUI_OPEN_SELECTOR_REQUESTED
Payload = LoaderType* (owner), Description = GUID | empty.
@ MSG_APP_UNLOAD_SCRIPT_REQUESTED
Payload = RoR::ScriptUnitId_t* (owner)
Definition Application.h:95
@ MSG_SIM_SEAT_PLAYER_REQUESTED
Payload = RoR::ActorPtr (owner) | nullptr.
@ MSG_NET_CONNECT_PROGRESS
@ MSG_EDI_LOAD_BUNDLE_REQUESTED
Payload = RoR::CacheEntryPtr* (owner)
@ MSG_APP_LOAD_SCRIPT_REQUESTED
Payload = RoR::LoadScriptRequest* (owner)
Definition Application.h:94
@ MSG_SIM_LOAD_SAVEGAME_REQUESTED
@ MSG_NET_CONNECT_SUCCESS
@ MSG_NET_USER_DISCONNECT
@ MSG_SIM_ADD_FREEFORCE_REQUESTED
Payload = RoR::FreeForceRequest* (owner)
@ MSG_NET_OPEN_RESOURCE_SUCCESS
Payload = GUI::ResourcesCollection* (owner)
@ MSG_APP_SHUTDOWN_REQUESTED
Definition Application.h:87
@ MSG_EDI_MODIFY_FREEBEAMGFX_REQUESTED
Payload = RoR::FreeBeamGfxRequest* (owner)
@ MSG_EDI_MODIFY_GROUNDMODEL_REQUESTED
Payload = RoR::ground_model_t* (weak)
@ MSG_EDI_DELETE_FREEBEAMGFX_REQUESTED
Payload = RoR::FreeBeamGfxID_t* (owner)
@ MSG_NET_DOWNLOAD_REPOFILE_PROGRESS
Payload = int* (owner)
@ MSG_GUI_SHOW_MESSAGE_BOX_REQUESTED
Payload = MessageBoxConfig* (owner)
@ MSG_SIM_MODIFY_FREEFORCE_REQUESTED
Payload = RoR::FreeForceRequest* (owner)
@ MSG_NET_REFRESH_SERVERLIST_FAILURE
Payload = RoR::CurlFailInfo* (owner)
@ MSG_NET_REFRESH_REPOLIST_FAILURE
Payload = RoR::CurlFailInfo* (owner)
@ MSG_EDI_CREATE_PROJECT_REQUESTED
Payload = RoR::CreateProjectRequest* (owner)
@ MSG_APP_SCRIPT_THREAD_STATUS
Payload = RoR::ScriptEventArgs* (owner)
Definition Application.h:96
@ MSG_SIM_LOAD_TERRN_REQUESTED
@ MSG_NET_REFRESH_REPOLIST_SUCCESS
Payload = GUI::ResourcesCollection* (owner)
@ MSG_NET_DOWNLOAD_REPOFILE_FAILURE
Payload = RoR::RepoFileInstallRequest* (owner)
@ MSG_SIM_DELETE_ACTOR_REQUESTED
Payload = RoR::ActorPtr* (owner)
@ MSG_NET_REFRESH_SERVERLIST_SUCCESS
Payload = GUI::MpServerInfoVec* (owner)
@ MSG_SIM_MODIFY_ACTOR_REQUESTED
Payload = RoR::ActorModifyRequest* (owner)
@ MSG_NET_SERVER_KICK
@ MSG_EDI_RELOAD_BUNDLE_REQUESTED
Payload = RoR::CacheEntryPtr* (owner)
@ TOWARDS_COORDS
Constant force directed towards ffc_target_coords
@ HALFBEAM_ROPE
Like TOWARDS_NODE, but parametrized like a rope-beam in truck fileformat.
@ CONSTANT
Constant force given by direction and magnitude.
@ HALFBEAM_GENERIC
Like TOWARDS_NODE, but parametrized like a beam in truck fileformat.
@ TOWARDS_NODE
Constant force directed towards ffc_target_node
AngelScript::CScriptArray * VectorToScriptArray(const std::vector< T > &vec, const std::string &decl)
Definition ScriptUtils.h:44
AngelScript::CScriptArray * MapToScriptArray(std::map< T, U > &map, const std::string &decl)
Definition ScriptUtils.h:61
const std::string GETFUNC_DEFAULTEVENTCALLBACK_SIGFMT
const GetFuncFlags_t GETFUNCFLAG_REQUIRED
Always logs warning that function was not found.
bool GetValueFromScriptDict(const std::string &log_msg, AngelScript::CScriptDictionary *dict, bool required, std::string const &key, const char *decl, T &out_value)
@ AI_BOT
Only valid under MpState::LOCAL_SCRIPT; registers as RoRnet user in the server script (i....
@ ACTOR
Defined in truck file under 'scripts', contains global variable BeamClass@ thisActor.
CVar * mp_player_name
CVar * mp_api_url
AppContext * GetAppContext()
InputEngine * GetInputEngine()
ServerScriptSequencer * GetServerScript()
CVar * sim_terrain_name
CameraManager * GetCameraManager()
CVar * app_country
SoundScriptManager * GetSoundScriptManager()
GUIManager * GetGuiManager()
GameContext * GetGameContext()
GfxScene * GetGfxScene()
CVar * mp_state
CVar * app_disable_online_api
Console * GetConsole()
ScriptEngine * GetScriptEngine()
CacheSystem * GetCacheSystem()
Network * GetNetwork()
std::vector< ActorPtr > ActorPtrVec
bool GetUrlAsStringMQ(CurlTaskContext task)
LoaderType
< Search mode for ModCache::Query() & Operation mode for GUI::MainSelector
@ LT_Airplane
@ LT_Boat
@ LT_Train
@ LT_Truck
@ LT_Car
@ LT_Load
@ LT_Trailer
@ LT_Vehicle
@ LT_None
@ LT_Extension
@ LT_AllBeam
int ActorInstanceID_t
Unique sequentially generated ID of an actor in session. Use ActorManager::GetActorById()
int FreeForceID_t
Unique sequentially generated ID of FreeForce; use ActorManager::GetFreeForceNextId().
int ScriptUnitID_t
Unique sequentially generated ID of a loaded and running scriptin session. Use ScriptEngine::getScrip...
RefCountingObjectPtr< Actor > ActorPtr
static const ScriptUnitID_t SCRIPTUNITID_INVALID
std::string Sha1Hash(std::string const &data)
Definition Utils.cpp:141
std::vector< TerrainEditorObjectPtr > TerrainEditorObjectPtrVec
RefCountingObjectPtr< CacheEntry > CacheEntryPtr
int FreeBeamGfxID_t
Index into GfxScene::m_gfx_freebeams, use RoR::FREEBEAMGFXID_INVALID as empty value.
@ MSG2_GAME_CMD
Script message. Can be sent in both directions.
Definition RoRnet.h:56
ActorInstanceID_t amr_actor
Definition SimData.h:875
std::string asr_net_username
Definition SimData.h:845
Ogre::String asr_config
Definition SimData.h:836
CacheEntryPtr asr_cache_entry
Optional, overrides 'asr_filename' and 'asr_cache_entry_num'.
Definition SimData.h:834
Ogre::Vector3 asr_position
Definition SimData.h:837
CacheEntryPtr asr_skin_entry
Definition SimData.h:840
ActorInstanceID_t asr_instance_id
Optional; see ActorManager::GetActorNextInstanceID();.
Definition SimData.h:833
std::string asr_filename
Can be in "Bundle-qualified" format, i.e. "mybundle.zip:myactor.truck".
Definition SimData.h:835
Ogre::Quaternion asr_rotation
Definition SimData.h:838
BitMask_t asr_net_peeropts
RoRnet::PeerOptions to be applied after spawn.
Definition SimData.h:847
Creates subdirectory in 'My Games\Rigs of Rods\projects', pre-populates it with files and adds modcac...
CacheEntryPtr cpr_source_entry
The original mod to copy files from.
std::string cpr_name
Directory and also the mod file (without extension).
std::string ctc_displayname
Definition CurlHelpers.h:36
std::string ctc_url
Definition CurlHelpers.h:37
MsgType ctc_msg_failure
Sent on failure; Payload: RoR::ScriptEventArgs (see 'gameplay/ScriptEvents.h') with args for RoR::SE_...
Definition CurlHelpers.h:41
Used by MSG_EDI_[ADD/MODIFY]_FREEBEAMGFX_REQUESTED; tailored for use with AngelScript thru GameScript...
Definition GfxData.h:293
std::string fbr_material_name
Definition GfxData.h:302
double fbr_diameter
meters
Definition GfxData.h:303
int64_t fbr_freeforce_primary
Required.
Definition GfxData.h:298
int64_t fbr_id
ID of the freebeam gfx, use GfxScene::GetFreeBeamGfxNextId()
Definition GfxData.h:296
int64_t fbr_freeforce_secondary
Not required for fixed-end beams.
Definition GfxData.h:299
std::string fbr_mesh_name
Definition GfxData.h:301
Common for ADD and MODIFY requests; tailored for use with AngelScript thru GameScript::pushMessage().
Definition SimData.h:784
double ffr_force_magnitude
Definition SimData.h:790
double ffr_halfb_strength
Definition SimData.h:802
int64_t ffr_target_actor
Definition SimData.h:796
Ogre::Vector3 ffr_target_coords
Definition SimData.h:795
int64_t ffr_target_node
Definition SimData.h:797
double ffr_halfb_diameter
Definition SimData.h:803
Ogre::Vector3 ffr_force_const_direction
Definition SimData.h:794
std::string lsr_filename
Load from resource ('.as' file or '.gadget' file); If buffer is supplied, use this as display name on...
ScriptCategory lsr_category
std::string lsr_buffer
Load from memory buffer.
Unified game event system - all requests and state changes are reported using a message.
Definition GameContext.h:52
std::string description
Definition GameContext.h:58
void * payload
Definition GameContext.h:59
Payload for MSG_NET_INSTALL_REPOFILE_REQUEST message - also used for update (overwrites existing)
Represents a loaded script and all associated resources/handles.
int32_t associatedNetUid
For ScriptCategory::AI_BOT ~ used to identify the bot in the server script.
ScriptCategory scriptCategory
unsigned int eventMask
filter mask for script events
Ogre::String scriptHash
Ogre::String scriptBuffer
Ogre::String scriptName
Name of the '.as' file exclusively.
ScriptUnitID_t uniqueId
< Must preserve mem. layout of RoRnet::StreamRegister
Definition RoRnet.h:170
char sectionconfig[60]
section configuration
Definition RoRnet.h:181
char name[128]
truck file name
Definition RoRnet.h:176
int32_t origin_sourceid
origin sourceid
Definition RoRnet.h:174
< Sent from the client to server and vice versa, to broadcast a new stream
Definition RoRnet.h:160
char username[RORNET_MAX_USERNAME_LEN]
the nickname of the user (UTF-8)
Definition RoRnet.h:196
int32_t colournum
colour set by server
Definition RoRnet.h:194
Ogre::Vector3 position