Skip to content

Commit b97e60d

Browse files
committed
Character (RoRbot) is now a mod type (select in Settings UI).
The usage is equivalent to other mods: a ZIP/directory under 'ROR_HOMEDIR/mods' containing a '*.character' file. To select character, open Settings UI, go to Gameplay tab, scroll to "Player character:" at the bottom and press "Select" button - the standard Selector UI will appear. Character is always loaded with terrain. If the character fails to load, a "Cannot load terrain" messagebox appears and user remains in main menu. The classic character resources were deleted from /resources and will be added to /content (a Git submodule).
1 parent 6314ad0 commit b97e60d

16 files changed

Lines changed: 165 additions & 104 deletions

resources/materials/character.material

Lines changed: 0 additions & 30 deletions
This file was deleted.

resources/meshes/character.material

Lines changed: 0 additions & 23 deletions
This file was deleted.

resources/meshes/character.mesh

-462 KB
Binary file not shown.
-344 KB
Binary file not shown.

source/main/Application.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ CVar* sim_no_self_collisions;
104104
CVar* sim_gearbox_mode;
105105
CVar* sim_soft_reset_mode;
106106
CVar* sim_quickload_dialog;
107+
CVar* sim_player_character;
107108

108109
// Multiplayer
109110
CVar* mp_state;

source/main/Application.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ enum VisibilityMasks
243243
enum LoaderType //!< Operation mode for GUI::MainSelector
244244
{
245245
LT_None,
246+
LT_Character, // No script alias, invoked from Settings UI.
246247
LT_Terrain, // Invocable from GUI; No script alias, used in main menu
247248
LT_Vehicle, // Script "vehicle", ext: truck car
248249
LT_Truck, // Script "truck", ext: truck car
@@ -294,6 +295,7 @@ extern CVar* sim_no_self_collisions;
294295
extern CVar* sim_gearbox_mode;
295296
extern CVar* sim_soft_reset_mode;
296297
extern CVar* sim_quickload_dialog;
298+
extern CVar* sim_player_character;
297299

298300
// Multiplayer
299301
extern CVar* mp_state;

source/main/GameContext.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -693,10 +693,17 @@ void GameContext::OnLoaderGuiApply(LoaderType type, CacheEntry* entry, std::stri
693693
// --------------------------------
694694
// Characters
695695

696-
void GameContext::CreatePlayerCharacter()
696+
bool GameContext::CreatePlayerCharacter()
697697
{
698698
m_character_factory.CreateLocalCharacter();
699699

700+
if (!this->GetPlayerCharacter())
701+
{
702+
App::GetGuiManager()->ShowMessageBox(_L("Terrain loading error"),
703+
"Failed to create player character, see console or 'RoR.log' for more info.");
704+
return false;
705+
}
706+
700707
// Adjust character position
701708
Ogre::Vector3 spawn_pos = App::GetSimTerrain()->getSpawnPos();
702709
float spawn_rot = 0.0f;
@@ -744,6 +751,8 @@ void GameContext::CreatePlayerCharacter()
744751
{
745752
App::GetCameraManager()->UpdateInputEvents(0.02f);
746753
}
754+
755+
return true;
747756
}
748757

749758
Character* GameContext::GetPlayerCharacter() // Convenience ~ counterpart of `GetPlayerActor()`

source/main/GameContext.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ class GameContext
139139
/// @name Characters
140140
/// @{
141141

142-
void CreatePlayerCharacter(); //!< Terrain must be loaded
142+
bool CreatePlayerCharacter(); //!< Terrain must be loaded
143143
Character* GetPlayerCharacter();
144144
CharacterFactory* GetCharacterFactory() { return &m_character_factory; }
145145

source/main/gameplay/CharacterFactory.cpp

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@
2222
#include "CharacterFactory.h"
2323

2424
#include "Application.h"
25+
#include "CacheSystem.h"
2526
#include "Character.h"
27+
#include "Console.h"
2628
#include "GfxScene.h"
2729
#include "Utils.h"
2830

@@ -32,6 +34,26 @@ CharacterFactory::CharacterFactory()
3234
{
3335
}
3436

37+
CharacterDocumentPtr CharacterFactory::FetchCharacterDef(CacheEntry* cache_entry)
38+
{
39+
if (!cache_entry->character_def)
40+
{
41+
try
42+
{
43+
Ogre::DataStreamPtr datastream = Ogre::ResourceGroupManager::getSingleton().openResource(cache_entry->fname, cache_entry->resource_group);
44+
CharacterParser character_parser;
45+
cache_entry->character_def = character_parser.ProcessOgreStream(datastream);
46+
}
47+
catch (Ogre::Exception& eeh)
48+
{
49+
App::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_ERROR,
50+
fmt::format("Could not load character, message: {}", eeh.getFullDescription()));
51+
}
52+
}
53+
54+
return cache_entry->character_def;
55+
}
56+
3557
Character* CharacterFactory::CreateLocalCharacter()
3658
{
3759
int colourNum = -1;
@@ -46,7 +68,21 @@ Character* CharacterFactory::CreateLocalCharacter()
4668
}
4769
#endif // USE_SOCKETW
4870

49-
m_local_character = std::unique_ptr<Character>(new Character(m_character_defs[0], -1, 0, playerName, colourNum, false));
71+
CacheEntry* cache_entry = App::GetCacheSystem()->FindEntryByFilename(LT_Character, /*partial:*/false, App::sim_player_character->getStr());
72+
if (!cache_entry)
73+
{
74+
App::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_ERROR,
75+
fmt::format("Could not find character '{}' in mod cache.", App::sim_player_character->getStr()));
76+
return nullptr;
77+
}
78+
79+
CharacterDocumentPtr document = this->FetchCharacterDef(cache_entry);
80+
if (!document)
81+
{
82+
return nullptr; // Error already reported
83+
}
84+
85+
m_local_character = std::unique_ptr<Character>(new Character(document, -1, 0, playerName, colourNum, false));
5086
App::GetGfxScene()->RegisterGfxCharacter(m_local_character.get());
5187
return m_local_character.get();
5288
}
@@ -59,9 +95,29 @@ void CharacterFactory::createRemoteInstance(int sourceid, int streamid)
5995
int colour = info.colournum;
6096
Ogre::UTFString name = tryConvertUTF(info.username);
6197

62-
LOG(" new character for " + TOSTRING(sourceid) + ":" + TOSTRING(streamid) + ", colour: " + TOSTRING(colour));
98+
std::string info_str = fmt::format("player '{}' ({}:{}), colour: {}", info.clientname, sourceid, streamid, colour);
99+
100+
LOG(" new character for " + info_str);
101+
102+
std::string filename = App::sim_player_character->getStr(); // TBD: transmit and use the actual character used by the player
103+
104+
CacheEntry* cache_entry = App::GetCacheSystem()->FindEntryByFilename(LT_Character, /*partial:*/false, filename);
105+
if (!cache_entry)
106+
{
107+
App::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_ERROR,
108+
fmt::format("Could not create character for {} - character '{}' not found in mod cache.", info_str, filename));
109+
return;
110+
}
111+
112+
CharacterDocumentPtr document = this->FetchCharacterDef(cache_entry);
113+
if (!document)
114+
{
115+
App::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_ERROR,
116+
fmt::format("Could not create character for {} - cannot load file '{}'.", info_str, cache_entry->fname));
117+
return;
118+
}
63119

64-
Character* ch = new Character(m_character_defs[0], sourceid, streamid, name, colour, true);
120+
Character* ch = new Character(document, sourceid, streamid, name, colour, true);
65121
App::GetGfxScene()->RegisterGfxCharacter(ch);
66122
m_remote_characters.push_back(std::unique_ptr<Character>(ch));
67123
#endif // USE_SOCKETW

source/main/gameplay/CharacterFactory.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,13 @@ class CharacterFactory
4646
void DeleteAllCharacters();
4747
void UndoRemoteActorCoupling(Actor* actor);
4848
void Update(float dt);
49-
void DefineCharacter(CharacterDocumentPtr doc) { m_character_defs.push_back(doc); }
49+
CharacterDocumentPtr FetchCharacterDef(CacheEntry* cache_entry);
5050
#ifdef USE_SOCKETW
5151
void handleStreamData(std::vector<RoR::NetRecvPacket> packet);
5252
#endif // USE_SOCKETW
5353

5454
private:
5555

56-
std::vector<CharacterDocumentPtr> m_character_defs;
57-
5856
std::unique_ptr<Character> m_local_character;
5957
std::vector<std::unique_ptr<Character>> m_remote_characters;
6058

0 commit comments

Comments
 (0)