Rigs of Rods 2023.09
Soft-body Physics Simulation
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Loading...
Searching...
No Matches
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#include "ScriptUtils.h"
24
25#ifdef USE_CURL
26# include <curl/curl.h>
27# include <curl/easy.h>
28#endif //USE_CURL
29
30// AS addons start
31#include "scriptany/scriptany.h"
32#include "scriptarray/scriptarray.h"
33#include "scripthelper/scripthelper.h"
34#include "scriptmath/scriptmath.h"
35#include "scriptstdstring/scriptstdstring.h"
36// AS addons end
37
38#include "AppContext.h"
39#include "Actor.h"
40#include "ActorManager.h"
41#include "CacheSystem.h"
42#include "Character.h"
43#include "ChatSystem.h"
44#include "Collisions.h"
45#include "Console.h"
46#include "CurlHelpers.h"
47#include "Engine.h"
48#include "GameContext.h"
49#include "GfxScene.h"
50#include "GUIManager.h"
51#include "GUI_TopMenubar.h"
52#include "Language.h"
53#include "PlatformUtils.h"
54#include "Network.h"
55#include "RoRVersion.h"
56#include "ScriptEngine.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
1024 return -11;
1025}
1026
1027AngelScript::CScriptArray* GameScript::getRunningScripts()
1028{
1029 std::vector<ScriptUnitID_t> ids;
1030 for (auto& pair: App::GetScriptEngine()->getScriptUnits())
1031 ids.push_back(pair.first);
1032
1033 return VectorToScriptArray(ids, "int");
1034}
1035
1036
1037AngelScript::CScriptDictionary* GameScript::getScriptDetails(ScriptUnitID_t nid)
1038{
1039 if (!App::GetScriptEngine()->scriptUnitExists(nid))
1040 return nullptr;
1041
1043 AngelScript::CScriptDictionary* dict = AngelScript::CScriptDictionary::Create(App::GetScriptEngine()->getEngine());
1044 int stringTypeid = App::GetScriptEngine()->getEngine()->GetTypeIdByDecl("string");
1045 int scriptCategoryTypeid = App::GetScriptEngine()->getEngine()->GetTypeIdByDecl("ScriptCategory");
1046
1047 dict->Set("uniqueId", (asINT64)info.uniqueId);
1048 dict->Set("scriptName", new std::string(info.scriptName), stringTypeid);
1049 dict->Set("scriptCategory", &info.scriptCategory, scriptCategoryTypeid);
1050 dict->Set("eventMask", (asINT64)info.eventMask);
1051 dict->Set("scriptBuffer", new std::string(info.scriptBuffer), stringTypeid);
1052
1053 // TBD Some other time...
1054 //AngelScript::asIScriptModule* scriptModule = nullptr;
1055 //AngelScript::asIScriptFunction* frameStepFunctionPtr = nullptr; //!< script function pointer to the frameStep function
1056 //AngelScript::asIScriptFunction* eventCallbackFunctionPtr = nullptr; //!< script function pointer to the event callback function
1057 //AngelScript::asIScriptFunction* eventCallbackExFunctionPtr = nullptr; //!< script function pointer to the event callback function
1058 //AngelScript::asIScriptFunction* defaultEventCallbackFunctionPtr = nullptr; //!< script function pointer for spawner events
1059 //ActorPtr associatedActor; //!< For ScriptCategory::ACTOR
1060 //Ogre::String scriptHash;
1061
1062 return dict;
1063}
1064
1066{
1067 VehicleAIPtr result = nullptr;
1068 if (App::GetGameContext()->GetPlayerActor())
1069 {
1071 }
1072 return result;
1073}
1074
1076{
1077 VehicleAIPtr result = nullptr;
1079 if (actor != nullptr)
1080 {
1081 result = actor->ar_vehicle_ai;
1082 }
1083 return result;
1084}
1085
1086ActorPtr GameScript::spawnTruck(Ogre::String& truckName, Ogre::Vector3& pos, Ogre::Vector3& rot)
1087{
1089 rq.asr_position = pos;
1090 rq.asr_rotation = Quaternion(Degree(rot.x), Vector3::UNIT_X) * Quaternion(Degree(rot.y), Vector3::UNIT_Y) * Quaternion(Degree(rot.z), Vector3::UNIT_Z);
1091 rq.asr_filename = truckName;
1092 return App::GetGameContext()->SpawnActor(rq);
1093}
1094
1095ActorPtr GameScript::spawnTruckAI(Ogre::String& truckName, Ogre::Vector3& pos, Ogre::String& truckSectionConfig, std::string& truckSkin, int x)
1096{
1097 try
1098 {
1100 rq.asr_position = pos;
1101
1102 // Set rotation based on first two waypoints
1103 std::vector<Ogre::Vector3> waypoints;
1104 for (int i = 0; i < App::GetGuiManager()->TopMenubar.ai_waypoints.size(); i++)
1105 {
1106 waypoints.push_back(App::GetGuiManager()->TopMenubar.ai_waypoints[i].position);
1107 }
1108 if (App::GetGuiManager()->TopMenubar.ai_mode == 3 && x == 1) // Crash driving mode
1109 {
1110 std::reverse(waypoints.begin(), waypoints.end());
1111 }
1112
1113 // Check if we have enough waypoints
1114 Ogre::Vector3 dir = Ogre::Vector3::ZERO;
1115 if (waypoints.size() >= 2)
1116 dir = waypoints[0] - waypoints[1];
1117 else if (waypoints.size() >= 1)
1118 dir = waypoints[0];
1119 dir.y = 0;
1120 rq.asr_rotation = Ogre::Vector3::UNIT_X.getRotationTo(dir, Ogre::Vector3::UNIT_Y);
1121
1122 rq.asr_filename = truckName;
1123 rq.asr_config = truckSectionConfig;
1126 return App::GetGameContext()->SpawnActor(rq);
1127 }
1128 catch (...)
1129 {
1130 App::GetScriptEngine()->forwardExceptionAsScriptEvent("GameScript::setMaterialTextureScale()");
1131 return ActorPtr();
1132 }
1133}
1134
1135AngelScript::CScriptArray* GameScript::getWaypoints(int x)
1136{
1137 std::vector<Ogre::Vector3> vec;
1138 for (int i = 0; i < App::GetGuiManager()->TopMenubar.ai_waypoints.size(); i++)
1139 {
1140 vec.push_back(App::GetGuiManager()->TopMenubar.ai_waypoints[i].position);
1141 }
1142 if (App::GetGuiManager()->TopMenubar.ai_mode == 3 && x == 1) // Crash driving mode
1143 {
1144 std::reverse(vec.begin(), vec.end());
1145 }
1146
1147 AngelScript::CScriptArray* arr = AngelScript::CScriptArray::Create(AngelScript::asGetActiveContext()->GetEngine()->GetTypeInfoByDecl("array<vector3>"), vec.size());
1148
1149 for(AngelScript::asUINT i = 0; i < arr->GetSize(); i++)
1150 {
1151 // Set the value of each element
1152 arr->SetValue(i, &vec[i]);
1153 }
1154
1155 return arr;
1156}
1157
1158AngelScript::CScriptArray* GameScript::getAllTrucks()
1159{
1161 AngelScript::CScriptArray* arr = AngelScript::CScriptArray::Create(AngelScript::asGetActiveContext()->GetEngine()->GetTypeInfoByDecl("array<BeamClass@>"), actors.size());
1162
1163 for (AngelScript::asUINT i = 0; i < arr->GetSize(); i++)
1164 {
1165 // Set the value of each element
1166 arr->SetValue(i, &actors[i]);
1167 }
1168
1169 return arr;
1170}
1171
1172void GameScript::addWaypoint(const Ogre::Vector3& pos)
1173{
1174 std::vector<Ogre::Vector3> waypoints;
1175 for (int i = 0; i < App::GetGuiManager()->TopMenubar.ai_waypoints.size(); i++)
1176 {
1177 waypoints.push_back(App::GetGuiManager()->TopMenubar.ai_waypoints[i].position);
1178 }
1179}
1180
1181AngelScript::CScriptArray* GameScript::getWaypointsSpeed()
1182{
1183 std::vector<int> vec;
1184 for (int i = 0; i < App::GetGuiManager()->TopMenubar.ai_waypoints.size(); i++)
1185 {
1186 vec.push_back(App::GetGuiManager()->TopMenubar.ai_waypoints[i].speed);
1187 }
1188
1189 AngelScript::CScriptArray* arr = AngelScript::CScriptArray::Create(AngelScript::asGetActiveContext()->GetEngine()->GetTypeInfoByDecl("array<int>"), vec.size());
1190
1191 for(AngelScript::asUINT i = 0; i < arr->GetSize(); i++)
1192 {
1193 // Set the value of each element
1194 arr->SetValue(i, &vec[i]);
1195 }
1196
1197 return arr;
1198}
1199
1201{
1203 return num;
1204}
1205
1207{
1209 return dist;
1210}
1211
1213{
1215 return scheme;
1216}
1217
1219{
1220 int speed = App::GetGuiManager()->TopMenubar.ai_speed;
1221 return speed;
1222}
1223
1225{
1226 if ((App::GetGuiManager()->TopMenubar.ai_mode == 2 || App::GetGuiManager()->TopMenubar.ai_mode == 3) && x == 1) // Drag Race or Crash driving mode
1227 {
1228 Ogre::String name = App::GetGuiManager()->TopMenubar.ai_fname2;
1229 return name;
1230 }
1231 else
1232 {
1233 Ogre::String name = App::GetGuiManager()->TopMenubar.ai_fname;
1234 return name;
1235 }
1236}
1237
1239{
1240 if ((App::GetGuiManager()->TopMenubar.ai_mode == 2 || App::GetGuiManager()->TopMenubar.ai_mode == 3) && x == 1) // Drag Race or Crash driving mode
1241 {
1242 Ogre::String config = App::GetGuiManager()->TopMenubar.ai_sectionconfig2;
1243 return config;
1244 }
1245 else
1246 {
1247 Ogre::String config = App::GetGuiManager()->TopMenubar.ai_sectionconfig;
1248 return config;
1249 }
1250}
1251
1253{
1254 if ((App::GetGuiManager()->TopMenubar.ai_mode == 2 || App::GetGuiManager()->TopMenubar.ai_mode == 3) && x == 1) // Drag Race or Crash driving mode
1255 {
1256 std::string skin = App::GetGuiManager()->TopMenubar.ai_skin2;
1257 return skin;
1258 }
1259 else
1260 {
1261 std::string skin = App::GetGuiManager()->TopMenubar.ai_skin;
1262 return skin;
1263 }
1264}
1265
1267{
1268 int times = App::GetGuiManager()->TopMenubar.ai_times;
1269 return times;
1270}
1271
1273{
1275 return mode;
1276}
1277
1278// AI: set
1279
1284
1289
1294
1296{
1298}
1299
1300void GameScript::setAIVehicleName(int x, std::string name)
1301{
1302 if ((App::GetGuiManager()->TopMenubar.ai_mode == 2 || App::GetGuiManager()->TopMenubar.ai_mode == 3) && x == 1) // Drag Race or Crash driving mode
1303 {
1305 }
1306 else
1307 {
1309 }
1310}
1311
1312void GameScript::setAIVehicleSectionConfig(int x, std::string config)
1313{
1314 switch (x)
1315 {
1316 case 0:
1318 break;
1319 case 1:
1321 break;
1322 default:
1323 this->log(fmt::format("setAIVehicleSectionConfig: ERROR, valid 'x' is 0 or 1, got {}", x));
1324 break;
1325 }
1326}
1327
1328void GameScript::setAIVehicleSkin(int x, std::string skin)
1329{
1330 switch (x)
1331 {
1332 case 0:
1334 break;
1335 case 1:
1337 break;
1338 default:
1339 this->log(fmt::format("setAIVehicleSkin: ERROR, valid 'x' is 0 or 1, got {}", x));
1340 break;
1341 }
1342}
1343
1345{
1347}
1348
1350{
1352}
1353
1354void 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)
1355{
1356 // Sanitize inputs
1357 const char* btn1_cstr = nullptr; // = Button disabled
1358 const char* btn2_cstr = nullptr;
1359
1360 if (use_btn1)
1361 {
1362 btn1_cstr = (btn1_text.empty() ? "~1~" : btn1_text.c_str());
1363 }
1364 if (use_btn2)
1365 {
1366 btn2_cstr = (btn2_text.empty() ? "~2~" : btn2_text.c_str());
1367 }
1368
1369 RoR::App::GetGuiManager()->ShowMessageBox(title.c_str(), text.c_str(), allow_close, btn1_cstr, btn2_cstr);
1370}
1371
1377
1382
1384{
1385 return App::GetAppContext()->GetRenderWindow()->getStatistics().lastFPS;
1386}
1387
1389{
1390 return App::GetAppContext()->GetRenderWindow()->getStatistics().avgFPS;
1391}
1392
1393bool GameScript::getMousePositionOnTerrain(Ogre::Vector3& out_pos)
1394{
1395 if (!HaveSimTerrain(__FUNCTION__))
1396 return false;
1397
1398 Ogre::Vector2 mouse_npos = App::GetInputEngine()->getMouseNormalizedScreenPos();
1399 Ogre::Ray ray = App::GetCameraManager()->GetCamera()->getCameraToViewportRay(mouse_npos.x, mouse_npos.y);
1400 Ogre::TerrainGroup::RayResult ray_result = App::GetGameContext()->GetTerrain()->getGeometryManager()->getTerrainGroup()->rayIntersects(ray);
1401 if (ray_result.hit)
1402 {
1403 out_pos = ray_result.position;
1404 }
1405 return ray_result.hit;
1406}
1407
1408class ScriptRayQueryListener : public Ogre::RaySceneQueryListener
1409{
1410public:
1411 Ogre::Ray ray;
1412 std::vector<Ogre::MovableObject*> results_array;
1413
1414 bool queryResult(MovableObject* obj, Real distance) override
1415 {
1416 results_array.push_back(obj);
1417 return true; // Continue query
1418 }
1419
1420 bool queryResult(SceneQuery::WorldFragment* fragment, Real distance) override
1421 {
1422 return true; // Continue query
1423 }
1424};
1425
1427{
1428 if (!HaveSimTerrain(__FUNCTION__))
1429 return nullptr;
1430
1431 Ogre::Vector2 mouse_npos = App::GetInputEngine()->getMouseNormalizedScreenPos();
1432 Ogre::Ray ray = App::GetCameraManager()->GetCamera()->getCameraToViewportRay(mouse_npos.x, mouse_npos.y);
1433 Ogre::DefaultRaySceneQuery query(App::GetGfxScene()->GetSceneManager());
1434 query.setRay(ray);
1435 query.setSortByDistance(true);
1437 qlis.ray = ray;
1438 query.execute(&qlis);
1439 return VectorToScriptArray(qlis.results_array, "Ogre::MovableObject@");
1440}
1441
1442Ogre::SceneManager* GameScript::getSceneManager()
1443{
1445}
1446
1447bool GameScript::pushMessage(MsgType type, AngelScript::CScriptDictionary* dict)
1448{
1449 Message m(type);
1450 std::string log_msg = fmt::format("`pushMessage({})`", MsgTypeToString(type));
1451
1452 switch (type)
1453 {
1454 // -- NOT ALLOWED --
1455
1456 // Application
1458 // Networking
1465 case MSG_NET_RECV_ERROR:
1476 // GUI
1479 // Editing
1481 this->log(fmt::format("{} is not allowed.", log_msg));
1482 return false;
1483
1484
1485 // -- SOME ASSEMBLY REQUIRED --
1486
1487 // Application
1489 {
1491 bool has_filename = GetValueFromScriptDict(log_msg, dict, /*required:*/false, "filename", "string", rq->lsr_filename);
1492 bool has_buffer = GetValueFromScriptDict(log_msg, dict, /*required:*/false, "buffer", "string", rq->lsr_buffer);
1493 if (!has_filename && !has_buffer)
1494 {
1495 this->log(fmt::format("{}: ERROR, either 'filename' or 'buffer' must be set!", log_msg));
1496 delete rq;
1497 return false;
1498 }
1499 GetValueFromScriptDict(log_msg, dict, /*required:*/false, "category", "ScriptCategory", rq->lsr_category);
1501 {
1502 int64_t instance_id; // AngelScript's `Dictionary` converts all ints int `int64`
1503 if (!GetValueFromScriptDict(log_msg, dict, /*required:*/true, "associated_actor", "int64", instance_id))
1504 {
1505 this->log(fmt::format("{}: WARNING, category 'ACTOR' specified but 'associated_actor' not given.", log_msg, rq->lsr_filename));
1506 delete rq;
1507 return false;
1508 }
1509 }
1510 m.payload = rq;
1511 break;
1512 }
1513
1515 {
1516 int64_t id; // AngelScript's `Dictionary` converts all ints int `int64`
1517 if (!GetValueFromScriptDict(log_msg, dict, /*required:*/true, "id", "int64", id))
1518 {
1519 return false;
1520 }
1521 m.payload = new ScriptUnitID_t(static_cast<ScriptUnitID_t>(id));
1522 break;
1523 }
1524
1525 // Simulation
1527 if (!GetValueFromScriptDict(log_msg, dict, /*required:*/true, "filename", "string", m.description))
1528 {
1529 return false;
1530 }
1531 break;
1532
1534 if (!GetValueFromScriptDict(log_msg, dict, /*required:*/true, "filename", "string", m.description))
1535 {
1536 return false;
1537 }
1538 break;
1539
1541 {
1543
1544 // Get required params
1545 if (GetValueFromScriptDict(log_msg, dict, /*required:*/true, "filename", "string", rq->asr_filename) &&
1546 GetValueFromScriptDict(log_msg, dict, /*required:*/true, "position", "vector3", rq->asr_position) &&
1547 GetValueFromScriptDict(log_msg, dict, /*required:*/true, "rotation", "quaternion", rq->asr_rotation))
1548 {
1550 if (!rq->asr_cache_entry)
1551 {
1552 this->log(fmt::format("{}: WARNING, vehicle '{}' is not installed.", log_msg, rq->asr_filename));
1553 delete rq;
1554 return false;
1555 }
1556
1557 // Set instance ID if specified
1558 GetValueFromScriptDict(log_msg, dict, /*required:*/false, "instance_id", "int", rq->asr_instance_id);
1559
1560 // Set sectionconfig
1561 GetValueFromScriptDict(log_msg, dict, /*required:*/false, "config", "string", rq->asr_config);
1562 // Make sure config exists
1563 if (rq->asr_config != "")
1564 {
1565 auto result = std::find(rq->asr_cache_entry->sectionconfigs.begin(), rq->asr_cache_entry->sectionconfigs.end(), rq->asr_config);
1566 if (result == rq->asr_cache_entry->sectionconfigs.end())
1567 {
1568 this->log(fmt::format("{}: WARNING, configuration '{}' does not exist in '{}'.", log_msg, rq->asr_config, rq->asr_filename));
1569 rq->asr_config = "";
1570 }
1571 }
1572 // If no config given (or was invalid), use the first available (classic behavior).
1573 if (rq->asr_config == "" && rq->asr_cache_entry->sectionconfigs.size() > 0)
1574 {
1576 }
1577
1578 // Enter or not?
1579 GetValueFromScriptDict(log_msg, dict, /*required:*/false, "enter", "bool", rq->asr_enter);
1580
1581 // Get skin
1582 std::string skin_name;
1583 if (GetValueFromScriptDict(log_msg, dict, /*required:*/false, "skin", "string", skin_name))
1584 {
1586 if (!rq->asr_skin_entry)
1587 this->log(fmt::format("{}: WARNING, skin '{}' is not installed.", log_msg, skin_name));
1588 }
1589
1590 m.payload = rq;
1591 }
1592 else
1593 {
1594 delete rq;
1595 return false;
1596 }
1597 break;
1598 }
1599
1601 {
1602 ActorModifyRequest::Type modify_type;
1603 // `dictionary` converts all primitives to `double` or `int64`, see 'scriptdictionary.cpp', function `Set()`
1604 int64_t instance_id = -1;
1605 if (GetValueFromScriptDict(log_msg, dict, /*required:*/true, "type", "ActorModifyRequestType", modify_type) &&
1606 GetValueFromScriptDict(log_msg, dict, /*required:*/true, "instance_id", "int64", instance_id))
1607 {
1609 rq->amr_type = modify_type;
1610 rq->amr_actor = static_cast<ActorInstanceID_t>(instance_id);
1611 m.payload = rq;
1612 }
1613 else
1614 {
1615 return false;
1616 }
1617 break;
1618 }
1619
1623 {
1624 // `dictionary` converts all primitives to `double` or `int64`, see 'scriptdictionary.cpp', function `Set()`
1625 int64_t instance_id = -1;
1626 if (GetValueFromScriptDict(log_msg, dict, /*required:*/true, "instance_id", "int64", instance_id))
1627 {
1628 ActorPtr actor = App::GetGameContext()->GetActorManager()->GetActorById(instance_id);
1629 if (actor)
1630 {
1631 m.payload = new ActorPtr(actor);
1632 }
1633 else
1634 {
1635 this->log(fmt::format("{}: Actor with instance ID '{}' not found!", log_msg, instance_id));
1636 return false;
1637 }
1638 }
1639 else
1640 {
1641 return false;
1642 }
1643 break;
1644 }
1645
1647 {
1648 // `dictionary` converts all primitives to `double` or `int64`, see 'scriptdictionary.cpp', function `Set()`
1649 int64_t instance_id = -1;
1650 ActorPtr actor;
1651 if (GetValueFromScriptDict(log_msg, dict, /*required:*/true, "instance_id", "int64", instance_id)
1652 && instance_id > -1)
1653 {
1654 actor = App::GetGameContext()->GetActorManager()->GetActorById(instance_id);
1655 }
1656 m.payload = new ActorPtr(actor);
1657 break;
1658 }
1659
1661 {
1662 Ogre::Vector3 position;
1663 if (GetValueFromScriptDict(log_msg, dict, /*required:*/true, "position", "vector3", position))
1664 {
1665 m.payload = new Ogre::Vector3(position);
1666 }
1667 else
1668 {
1669 return false;
1670 }
1671 break;
1672 }
1673
1676 {
1677 // `dictionary` converts all primitives to `double` or `int64`, see 'scriptdictionary.cpp', function `Set()`
1679 if (GetValueFromScriptDict(log_msg, dict, /*required:*/true, "id", "int64", rq->ffr_id) &&
1680 GetValueFromScriptDict(log_msg, dict, /*required:*/true, "type", "FreeForceType", rq->ffr_type) &&
1681 GetValueFromScriptDict(log_msg, dict, /*required:*/true, "force_magnitude", "double", rq->ffr_force_magnitude) &&
1682 GetValueFromScriptDict(log_msg, dict, /*required:*/true, "base_actor", "int64", rq->ffr_base_actor) &&
1683 GetValueFromScriptDict(log_msg, dict, /*required:*/true, "base_node", "int64", rq->ffr_base_node))
1684 {
1685 switch (rq->ffr_type)
1686 {
1687 case (int64_t)FreeForceType::CONSTANT:
1688 if (GetValueFromScriptDict(log_msg, dict, /*required:*/true, "force_const_direction", "vector3", rq->ffr_force_const_direction))
1689 {
1690 m.payload = rq;
1691 }
1692 else
1693 {
1694 delete rq;
1695 return false;
1696 }
1697 break;
1698
1699 case (int64_t)FreeForceType::TOWARDS_COORDS:
1700 if (GetValueFromScriptDict(log_msg, dict, /*required:*/true, "target_coords", "vector3", rq->ffr_target_coords))
1701 {
1702 m.payload = rq;
1703 }
1704 else
1705 {
1706 delete rq;
1707 return false;
1708 }
1709 break;
1710
1711 case (int64_t)FreeForceType::TOWARDS_NODE:
1712 if (GetValueFromScriptDict(log_msg, dict, /*required:*/true, "target_actor", "int64", rq->ffr_target_actor) &&
1713 GetValueFromScriptDict(log_msg, dict, /*required:*/true, "target_node", "int64", rq->ffr_target_node))
1714 {
1715 m.payload = rq;
1716 }
1717 else
1718 {
1719 delete rq;
1720 return false;
1721 }
1722 break;
1723
1724 case (int64_t)FreeForceType::HALFBEAM_GENERIC:
1725 case (int64_t)FreeForceType::HALFBEAM_ROPE:
1726 if (GetValueFromScriptDict(log_msg, dict, /*required:*/true, "target_actor", "int64", rq->ffr_target_actor) &&
1727 GetValueFromScriptDict(log_msg, dict, /*required:*/true, "target_node", "int64", rq->ffr_target_node))
1728 {
1729 GetValueFromScriptDict(log_msg, dict, /*required:*/false, "halfb_spring", "double", rq->ffr_halfb_spring);
1730 GetValueFromScriptDict(log_msg, dict, /*required:*/false, "halfb_damp", "double", rq->ffr_halfb_damp);
1731 GetValueFromScriptDict(log_msg, dict, /*required:*/false, "halfb_deform", "double", rq->ffr_halfb_deform);
1732 GetValueFromScriptDict(log_msg, dict, /*required:*/false, "halfb_strength", "double", rq->ffr_halfb_strength);
1733 GetValueFromScriptDict(log_msg, dict, /*required:*/false, "halfb_diameter", "double", rq->ffr_halfb_diameter);
1734 m.payload = rq;
1735 }
1736 else
1737 {
1738 delete rq;
1739 return false;
1740 }
1741 break;
1742
1743 default:
1744 this->log(fmt::format("{}: ERROR, invalid 'free force type' value '{}'", log_msg, rq->ffr_type));
1745 delete rq;
1746 return false;
1747 }
1748 m.payload = rq;
1749 }
1750 else
1751 {
1752 delete rq;
1753 return false;
1754 }
1755 break;
1756 }
1757
1759 {
1760 // `dictionary` converts all primitives to `double` or `int64`, see 'scriptdictionary.cpp', function `Set()`
1761 int64_t id = -1;
1762 if (GetValueFromScriptDict(log_msg, dict, /*required:*/true, "id", "int64", id))
1763 {
1764 m.payload = new FreeForceID_t(id);
1765 }
1766 else
1767 {
1768 return false;
1769 }
1770 break;
1771 }
1772
1776 {
1777 CacheEntryPtr entry;
1778 if (GetValueFromScriptDict(log_msg, dict, /*required*/true, "cache_entry", "CacheEntryClass@", entry))
1779 {
1780 m.payload = new CacheEntryPtr(entry);
1781 }
1782 else
1783 {
1784 return false;
1785 }
1786 break;
1787 }
1788
1790 {
1792 if (GetValueFromScriptDict(log_msg, dict, /*required:*/true, "name", "string", request->cpr_name) &&
1793 GetValueFromScriptDict(log_msg, dict, /*required:*/true, "source_entry", "CacheEntryClass@", request->cpr_source_entry))
1794 {
1795 m.payload = request;
1796 }
1797 else
1798 {
1799 delete request;
1800 return false;
1801 }
1802 break;
1803 }
1804
1805 // Payload = RoR::FreeBeamGfxRequest* (owner)
1808 {
1809 // `dictionary` converts all primitives to `double` or `int64`, see 'scriptdictionary.cpp', function `Set()`
1811 if (GetValueFromScriptDict(log_msg, dict, /*required:*/true, "id", "int64", rq->fbr_id) &&
1812 GetValueFromScriptDict(log_msg, dict, /*required:*/true, "freeforce_primary", "int64", rq->fbr_freeforce_primary))
1813 {
1814 // Beams fixed to ground don't need a secondary free force
1815 GetValueFromScriptDict(log_msg, dict, /*required:*/false, "freeforce_secondary", "int64", rq->fbr_freeforce_secondary);
1816 GetValueFromScriptDict(log_msg, dict, /*required:*/false, "mesh_name", "string", rq->fbr_mesh_name);
1817 GetValueFromScriptDict(log_msg, dict, /*required:*/false, "material_name", "string", rq->fbr_material_name);
1818 GetValueFromScriptDict(log_msg, dict, /*required:*/false, "diameter", "double", rq->fbr_diameter);
1819 m.payload = rq;
1820 }
1821 else
1822 {
1823 delete rq;
1824 return false;
1825 }
1826 break;
1827 }
1828
1830 {
1831 // `dictionary` converts all primitives to `double` or `int64`, see 'scriptdictionary.cpp', function `Set()`
1832 int64_t id = -1;
1833 if (GetValueFromScriptDict(log_msg, dict, /*required:*/true, "id", "int64", id))
1834 {
1835 m.payload = new FreeBeamGfxID_t(id);
1836 }
1837 else
1838 {
1839 return false;
1840 }
1841 break;
1842 }
1843
1845 {
1846 // `dictionary` converts all primitives to `double` or `int64`, see 'scriptdictionary.cpp', function `Set()`
1847 int64_t repo_resource_id = -1;
1848 int64_t repo_file_id = -1;
1849 std::string repo_filename;
1850 if (GetValueFromScriptDict(log_msg, dict, /*required:*/true, "resource_id", "int64", repo_resource_id) &&
1851 GetValueFromScriptDict(log_msg, dict, /*required:*/true, "file_id", "int64", repo_file_id) &&
1852 GetValueFromScriptDict(log_msg, dict, /*required:*/true, "filename", "string", repo_filename))
1853 {
1855 rq->rfir_resource_id = repo_resource_id;
1856 rq->rfir_repofile_id = repo_file_id;
1857 rq->rfir_filename = repo_filename;
1858 m.payload = rq;
1859 }
1860 else
1861 {
1862 return false;
1863 }
1864 }
1865
1866 default:;
1867 }
1868
1870 return true;
1871}
1872
1877
1882
1887
1888// --------------------------------
1889// Audio
1890
1892{
1893 return MapToScriptArray(App::GetSoundScriptManager()->getAllTemplates(), "SoundScriptTemplateClass@");
1894}
1895
1900
1901AngelScript::CScriptArray* GameScript::getAllSoundScriptInstances()
1902{
1903 return VectorToScriptArray(App::GetSoundScriptManager()->getAllInstances(), "SoundScriptInstanceClass@");
1904}
1905
1906SoundPtr GameScript::createSoundFromResource(const std::string& filename, const std::string& resource_group_name)
1907{
1908 return App::GetSoundScriptManager()->getSoundManager()->createSound(filename, resource_group_name);
1909}
1910
1912{
1913 return App::GetSoundScriptManager()->createInstance(template_name, actor_instance_id);
1914}
1915
1916bool GameScript::checkResourceExists(const std::string& filename, const std::string& resource_group)
1917{
1918 try
1919 {
1920 std::string resource_name = this->CheckFileAccess("checkResourceExists()", filename, resource_group);
1921 if (resource_name == "")
1922 return false; // Access denied - error already logged
1923
1924 // Actually check for the resource
1925 return Ogre::ResourceGroupManager::getSingleton().resourceExists(resource_group, resource_name);
1926 }
1927 catch (...)
1928 {
1929 App::GetScriptEngine()->forwardExceptionAsScriptEvent("GameScript::checkResourceExists()");
1930 return false;
1931 }
1932}
1933
1934bool GameScript::deleteResource(const std::string& filename, const std::string& resource_group)
1935{
1936 try
1937 {
1938 std::string resource_name = this->CheckFileAccess("deleteResource()", filename, resource_group);
1939 if (resource_name == "")
1940 return false; // Access denied - error already logged
1941
1942 // Actually delete the resource
1943 Ogre::ResourceGroupManager::getSingleton().deleteResource(resource_name, resource_group);
1944 return true;
1945 }
1946 catch (...)
1947 {
1948 App::GetScriptEngine()->forwardExceptionAsScriptEvent("GameScript::deleteResource()");
1949 return false;
1950 }
1951}
1952
1953std::string GameScript::loadTextResourceAsString(const std::string& filename, const std::string& resource_group)
1954{
1955 try
1956 {
1957 std::string resource_name = this->CheckFileAccess("loadTextResourceAsString()", filename, resource_group);
1958 if (resource_name == "")
1959 return ""; // Access denied - error already logged
1960
1961 Ogre::DataStreamPtr stream = Ogre::ResourceGroupManager::getSingleton().openResource(resource_name, resource_group);
1962
1963 if (!stream || !stream->isReadable())
1964 {
1966 fmt::format("loadTextResourceAsString() could not read resource '{}' in group '{}'",
1967 resource_name, resource_group));
1968 return "";
1969 }
1970
1971#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
1972 // WORKAROUND: apparently `getAsString()` has some Linux-x64 issues (`eof()` triggers SIGINT):
1973 // https://discord.com/channels/136544456244461568/189904947649708032/1155952230130778262
1974 // Observed with OGRE 1.11.6
1975 std::string str;
1976 const size_t BUF_LEN = 4000;
1977 char buf[BUF_LEN] = {};
1978 bool eof = false;
1979 while (!eof)
1980 {
1981 size_t read_len = stream->read(buf, BUF_LEN);
1982 if (read_len < BUF_LEN)
1983 {
1984 buf[read_len] = 0;
1985 eof = true;
1986 }
1987 str.append(buf, read_len);
1988 }
1989 return str;
1990#else
1991 return stream->getAsString();
1992#endif
1993 }
1994 catch (...)
1995 {
1996 App::GetScriptEngine()->forwardExceptionAsScriptEvent("GameScript::loadTextResourceAsString()");
1997 return "";
1998 }
1999}
2000
2001bool GameScript::createTextResourceFromString(const std::string& data, const std::string& filename, const std::string& resource_group, bool overwrite/*=false*/)
2002{
2003 try
2004 {
2005 std::string resource_name = this->CheckFileAccess("createTextResourceFromString()", filename, resource_group);
2006 if (resource_name == "")
2007 return false; // Access denied - error already logged
2008
2009 Ogre::DataStreamPtr stream = Ogre::ResourceGroupManager::getSingleton().createResource(resource_name, resource_group, overwrite);
2010
2011 if (!stream || !stream->isWriteable())
2012 {
2014 fmt::format("createTextResourceFromString() could not create resource '{}' in group '{}'",
2015 resource_name, resource_group));
2016 return false;
2017 }
2018
2019 stream->write(data.data(), data.size());
2020 return true;
2021 }
2022 catch (...)
2023 {
2024 App::GetScriptEngine()->forwardExceptionAsScriptEvent("GameScript::createTextResourceFromString()");
2025 return false;
2026 }
2027}
2028
2029AngelScript::CScriptArray* GameScript::findResourceFileInfo(const std::string& resource_group, const std::string& pattern, bool dirs /*= false*/)
2030{
2031 try
2032 {
2033 // Search the file system
2034 Ogre::FileInfoListPtr fileInfoList
2035 = Ogre::ResourceGroupManager::getSingleton().findResourceFileInfo(resource_group, pattern, dirs);
2036
2037 // Put results to array
2038 AngelScript::asITypeInfo* typeinfo = App::GetScriptEngine()->getEngine()->GetTypeInfoByDecl("array<dictionary>");
2039 AngelScript::CScriptArray* arr = AngelScript::CScriptArray::Create(typeinfo);
2040 int stringTypeid = App::GetScriptEngine()->getEngine()->GetTypeIdByDecl("string");
2041 for (const Ogre::FileInfo& fileinfo: *fileInfoList)
2042 {
2043 AngelScript::CScriptDictionary* dict = AngelScript::CScriptDictionary::Create(App::GetScriptEngine()->getEngine());
2044 dict->Set("filename", new std::string(fileinfo.filename), stringTypeid);
2045 dict->Set("basename", new std::string(fileinfo.basename), stringTypeid);
2046 dict->Set("compressedSize", (asINT64)fileinfo.compressedSize);
2047 dict->Set("uncompressedSize", (asINT64)fileinfo.uncompressedSize);
2048
2049 arr->InsertLast(dict);
2050 }
2051 return arr;
2052 }
2053 catch (...)
2054 {
2055 App::GetScriptEngine()->forwardExceptionAsScriptEvent("GameScript::findResourceFileInfo()");
2056 return nullptr;
2057 }
2058}
2059
2060Ogre::Image GameScript::loadImageResource(const std::string& filename, const std::string& resource_group)
2061{
2062 try
2063 {
2064 std::string resource_name = this->CheckFileAccess("loadImageResource()", filename, resource_group);
2065 if (resource_name == "")
2066 return Ogre::Image(); // Access denied - error already logged
2067
2068 Ogre::Image img;
2069 return img.load(resource_name, resource_group);
2070 }
2071 catch (...)
2072 {
2073 App::GetScriptEngine()->forwardExceptionAsScriptEvent("GameScript::loadImageResource()");
2074 return Ogre::Image();
2075 }
2076}
2077
2078bool GameScript::serializeMeshResource(const std::string& filename, const std::string& resource_group, const Ogre::MeshPtr& mesh)
2079{
2080 try
2081 {
2082 std::string resource_name = this->CheckFileAccess("serializeMeshResource()", filename, resource_group);
2083 if (resource_name == "")
2084 return false; // Access denied - error already logged
2085
2086 Ogre::MeshSerializer ser;
2087 Ogre::DataStreamPtr stream = Ogre::ResourceGroupManager::getSingleton().createResource(resource_name, resource_group);
2088 ser.exportMesh(mesh.get(), stream);
2089 return true;
2090 }
2091 catch (...)
2092 {
2093 App::GetScriptEngine()->forwardExceptionAsScriptEvent("GameScript::serializeMeshResource()");
2094 return false;
2095 }
2096}
2097
2098// ------------------------
2099// Helpers:
2100
2101bool GameScript::HaveSimTerrain(const char* func_name)
2102{
2103 if (App::GetGameContext()->GetTerrain() == nullptr)
2104 {
2105 this->logFormat("Cannot execute '%s', terrain not ready", func_name);
2106 return false;
2107 }
2108 return true;
2109}
2110
2111bool GameScript::HavePlayerAvatar(const char* func_name)
2112{
2113 if (App::GetGameContext()->GetPlayerCharacter() == nullptr)
2114 {
2115 this->logFormat("Cannot execute '%s', player avatar not ready", func_name);
2116 return false;
2117 }
2118 return true;
2119}
2120
2121bool GameScript::HaveMainCamera(const char* func_name)
2122{
2123 if (App::GetCameraManager()->GetCamera() == nullptr)
2124 {
2125 this->logFormat("Cannot execute '%s', main camera not ready", func_name);
2126 return false;
2127 }
2128 return true;
2129}
2130
2131std::string GameScript::CheckFileAccess(const char* func_name, const std::string& filename, const std::string& resource_group)
2132{
2133 // Extract filename and extension from the input, because OGRE allows absolute paths in resource system.
2134 // -----------------------------------------------------------------------------------------------------
2135
2136 std::string basename, extension, path;
2137 Ogre::StringUtil::splitFullFilename(filename, basename, extension, path);
2138 if (path != "")
2139 {
2141 fmt::format("{}: access denied to '{}' with group '{}' - file paths are not allowed",
2142 func_name, filename, resource_group));
2143 return "";
2144 }
2145 else
2146 {
2147 return basename + "." + extension;
2148 }
2149}
System integration layer; inspired by OgreBites::ApplicationContext.
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.
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:432
std::string ar_filehash
Attribute; filled at spawn.
Definition Actor.h:477
Ogre::String ar_design_name
Name of the vehicle/machine/object this actor represents.
Definition Actor.h:406
ActorInstanceID_t ar_instance_id
Static attr; session-unique ID.
Definition Actor.h:429
ActorPtrVec ar_linked_actors
BEWARE: Includes indirect links, see DetermineLinkedActors(); Other actors linked using 'hooks/ties/r...
Definition Actor.h:519
std::string ar_filename
Attribute; filled at spawn.
Definition Actor.h:476
VehicleAIPtr ar_vehicle_ai
Definition Actor.h:450
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:67
std::string const & getStr() const
Definition CVar.h:95
std::vector< Ogre::String > sectionconfigs
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:94
void setRPM(float rpm)
Definition Engine.cpp:918
Ogre::String ai_sectionconfig
Ogre::String ai_sectionconfig2
std::vector< ai_events > ai_waypoints
GUI::TopMenubar TopMenubar
Definition GUIManager.h:133
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)
void AddPacket(int streamid, int type, int len, const char *content)
Definition Network.cpp:616
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)
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:490
TerrainObjectManager * getObjectManager()
Definition Terrain.h:80
SkyManager * getSkyManager()
Definition Terrain.cpp:522
TerrainGeometryManager * getGeometryManager()
Definition Terrain.h:79
std::string getTerrainName() const
Definition Terrain.cpp:586
float getHeightAt(float x, float z)
Definition Terrain.cpp:512
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)
const char * MsgTypeToString(MsgType type)
MsgType
Global gameplay message loop, see struct Message in GameContext.h.
Definition Application.h:76
@ MSG_GUI_OPEN_MENU_REQUESTED
@ MSG_APP_MODCACHE_LOAD_REQUESTED
Definition Application.h:90
@ MSG_SIM_TELEPORT_PLAYER_REQUESTED
Payload = Ogre::Vector3* (owner)
@ MSG_NET_CONNECT_STARTED
Definition Application.h:99
@ 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:94
@ 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:93
@ 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:86
@ 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:95
@ 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:43
AngelScript::CScriptArray * MapToScriptArray(std::map< T, U > &map, const std::string &decl)
Definition ScriptUtils.h:60
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)
@ ACTOR
Defined in truck file under 'scripts', contains global variable BeamClass@ thisActor.
CVar * mp_player_name
CVar * mp_api_url
AppContext * GetAppContext()
InputEngine * GetInputEngine()
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
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
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:292
std::string fbr_material_name
Definition GfxData.h:301
double fbr_diameter
meters
Definition GfxData.h:302
int64_t fbr_freeforce_primary
Required.
Definition GfxData.h:297
int64_t fbr_id
ID of the freebeam gfx, use GfxScene::GetFreeBeamGfxNextId()
Definition GfxData.h:295
int64_t fbr_freeforce_secondary
Not required for fixed-end beams.
Definition GfxData.h:298
std::string fbr_mesh_name
Definition GfxData.h:300
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.
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