From b30c8e5387f3e46c659c9aa096f2773d4cd401ae Mon Sep 17 00:00:00 2001 From: Tyler Lentz Date: Tue, 4 Jun 2024 15:43:12 -0700 Subject: [PATCH 1/8] attempt to refactor animation manager: EVERYTHING IS BROKEN! --- config.json | 4 +- include/client/animationmanager.hpp | 8 +- include/client/client.hpp | 5 +- include/shared/game/sharedmodel.hpp | 4 +- src/client/animationmanager.cpp | 22 +++-- src/client/client.cpp | 127 ++++++++++++++++++---------- src/server/game/object.cpp | 5 +- src/server/game/player.cpp | 2 +- 8 files changed, 111 insertions(+), 66 deletions(-) diff --git a/config.json b/config.json index 73a02df0..d6f31c9f 100644 --- a/config.json +++ b/config.json @@ -14,8 +14,8 @@ "lobby_name": "Hope you're doing well!1", "lobby_broadcast": true, "max_players": 1, - "disable_dm": true, - "skip_intro": true + "disable_dm": false, + "skip_intro": false }, "client": { "default_name": "Conan O'Brien", diff --git a/include/client/animationmanager.hpp b/include/client/animationmanager.hpp index 044cd352..d104540b 100644 --- a/include/client/animationmanager.hpp +++ b/include/client/animationmanager.hpp @@ -15,7 +15,7 @@ class AnimationManager { public: - AnimationManager(Animation* animation); + AnimationManager(); void updateAnimation(float dt); @@ -23,16 +23,16 @@ class AnimationManager void calculateBoneTransform(const AssimpNodeData* node, glm::mat4 parentTransform); - void addAnimation(Animation* anim, ObjectType objType, AnimState animState); + void addAnimation(Animation* anim, ModelType modelType, AnimState animState); - void setAnimation(EntityID id, ObjectType objType, AnimState animState); + void setAnimation(EntityID id, ModelType modelType, AnimState animState); std::vector getFinalBoneMatrices() { return m_finalBoneMatrices; } private: std::vector m_finalBoneMatrices; std::unordered_map> entityAnimMap; - std::unordered_map> objAnimMap; + std::unordered_map> objAnimMap; Animation* m_currentAnimation; EntityID currEntity; float m_currentTime; diff --git a/include/client/client.hpp b/include/client/client.hpp index c0baeb11..826051ff 100644 --- a/include/client/client.hpp +++ b/include/client/client.hpp @@ -255,7 +255,10 @@ class Client { std::shared_ptr deferred_light_box_shader; /* Character models and lighting objects, might need to move to different classes later */ - std::unique_ptr player_model; + std::unique_ptr fire_player_model; + std::unique_ptr lightning_player_model; + std::unique_ptr water_player_model; + std::unique_ptr bear_model; std::unique_ptr torchlight_model; std::unique_ptr wall_model; diff --git a/include/shared/game/sharedmodel.hpp b/include/shared/game/sharedmodel.hpp index 29248a9e..dab0d105 100644 --- a/include/shared/game/sharedmodel.hpp +++ b/include/shared/game/sharedmodel.hpp @@ -5,7 +5,9 @@ */ enum class ModelType { Cube, - Player, + PlayerFire, + PlayerLightning, + PlayerWater, WarrenBear, HealthPotion, InvisibilityPotion, diff --git a/src/client/animationmanager.cpp b/src/client/animationmanager.cpp index 8c5e2e81..773d6acb 100644 --- a/src/client/animationmanager.cpp +++ b/src/client/animationmanager.cpp @@ -1,9 +1,9 @@ #include "client/animationmanager.hpp" -AnimationManager::AnimationManager(Animation* animation) { +AnimationManager::AnimationManager() { currEntity = 0; m_currentTime = 0.0; - m_currentAnimation = animation; + m_currentAnimation = nullptr; m_finalBoneMatrices.reserve(100); @@ -29,6 +29,10 @@ void AnimationManager::playAnimation(Animation* pAnimation) { } void AnimationManager::calculateBoneTransform(const AssimpNodeData* node, glm::mat4 parentTransform) { + if (m_currentAnimation == nullptr) { + return; // note from tyler: added this check because no longer setting currentAnimation in constructor + } + std::string nodeName = node->name; glm::mat4 nodeTransform = node->transformation; @@ -56,19 +60,19 @@ void AnimationManager::calculateBoneTransform(const AssimpNodeData* node, glm::m calculateBoneTransform(&node->children[i], globalTransformation); } -void AnimationManager::setAnimation(EntityID id, ObjectType objType, AnimState animState) { - if (entityAnimMap.find(id) == entityAnimMap.end() || entityAnimMap[id].second != objAnimMap[objType][animState]) { - entityAnimMap[id] = std::make_pair(0.0f, objAnimMap[objType][animState]); +void AnimationManager::setAnimation(EntityID id, ModelType modelType, AnimState animState) { + if (entityAnimMap.find(id) == entityAnimMap.end() || entityAnimMap[id].second != objAnimMap[modelType][animState]) { + entityAnimMap[id] = std::make_pair(0.0f, objAnimMap[modelType][animState]); } currEntity = id; } -void AnimationManager::addAnimation(Animation* anim, ObjectType objType, AnimState animState) { - if (objAnimMap.find(objType) == objAnimMap.end()) { +void AnimationManager::addAnimation(Animation* anim, ModelType modelType, AnimState animState) { + if (objAnimMap.find(modelType) == objAnimMap.end()) { std::unordered_map animMap; - objAnimMap[objType] = animMap; + objAnimMap[modelType] = animMap; } - this->objAnimMap[objType][animState] = anim; + this->objAnimMap[modelType][animState] = anim; } diff --git a/src/client/client.cpp b/src/client/client.cpp index 6ba42f5c..324a410a 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -238,7 +238,6 @@ bool Client::init() { auto exit_model_path = env_models_dir / "exit.obj"; this->exit_model = std::make_unique(exit_model_path.string(), true); - auto player_model_path = graphics_assets_dir / "player_models/char_3/model_char_3.fbx"; auto player_walk_path = graphics_assets_dir / "animations/walk.fbx"; auto player_jump_path = graphics_assets_dir / "animations/jump.fbx"; auto player_idle_path = graphics_assets_dir / "animations/idle.fbx"; @@ -246,22 +245,40 @@ bool Client::init() { auto player_atk_path = graphics_assets_dir / "animations/slash.fbx"; auto player_use_potion_path = graphics_assets_dir / "animations/drink.fbx"; - this->player_model = std::make_unique(player_model_path.string(), false); - Animation* player_walk = new Animation(player_walk_path.string(), this->player_model.get()); - Animation* player_jump = new Animation(player_jump_path.string(), this->player_model.get()); - Animation* player_idle = new Animation(player_idle_path.string(), this->player_model.get()); - Animation* player_run = new Animation(player_run_path.string(), this->player_model.get()); - Animation* player_atk = new Animation(player_atk_path.string(), this->player_model.get()); - Animation* player_use_potion = new Animation(player_use_potion_path.string(), this->player_model.get()); - - animManager = new AnimationManager(player_idle); - - animManager->addAnimation(player_walk, ObjectType::Player, AnimState::WalkAnim); - animManager->addAnimation(player_jump, ObjectType::Player, AnimState::JumpAnim); - animManager->addAnimation(player_idle, ObjectType::Player, AnimState::IdleAnim); - animManager->addAnimation(player_run, ObjectType::Player, AnimState::SprintAnim); - animManager->addAnimation(player_atk, ObjectType::Player, AnimState::AttackAnim); - animManager->addAnimation(player_use_potion, ObjectType::Player, AnimState::DrinkPotionAnim); + auto fire_player_model_path = player_models_dir / "char_1/model_char_1.fbx"; + auto lightning_player_model_path = player_models_dir / "char_2/model_char_2.fbx"; + auto water_player_model_path = player_models_dir / "char_3/model_char_3.fbx"; + + this->fire_player_model = std::make_unique(fire_player_model_path.string(), false); + this->lightning_player_model = std::make_unique(lightning_player_model_path.string(), false); + this->water_player_model = std::make_unique(water_player_model_path.string(), false); + + const int NUM_PLAYER_MODELS = 3; + std::array, NUM_PLAYER_MODELS> player_models = { + // for some reason the first one only works if it is std::make_pair but the other two are fine with the + // curly brace syntax... WTF, just making them all use std::make_pair so they line up + std::make_pair(ModelType::PlayerFire, this->fire_player_model.get()), + std::make_pair(ModelType::PlayerLightning, this->lightning_player_model.get()), + std::make_pair(ModelType::PlayerWater, this->water_player_model.get()) + }; + + animManager = new AnimationManager(); + + for (int i = 0; i < NUM_PLAYER_MODELS; i++) { + Animation* player_walk = new Animation(player_walk_path.string(), player_models.at(i).second); + Animation* player_jump = new Animation(player_jump_path.string(), player_models.at(i).second); + Animation* player_idle = new Animation(player_idle_path.string(), player_models.at(i).second); + Animation* player_run = new Animation(player_run_path.string(), player_models.at(i).second); + Animation* player_atk = new Animation(player_atk_path.string(), player_models.at(i).second); + Animation* player_use_potion = new Animation(player_use_potion_path.string(), player_models.at(i).second); + + animManager->addAnimation(player_walk, player_models.at(i).first, AnimState::WalkAnim); + animManager->addAnimation(player_jump, player_models.at(i).first, AnimState::JumpAnim); + animManager->addAnimation(player_idle, player_models.at(i).first, AnimState::IdleAnim); + animManager->addAnimation(player_run, player_models.at(i).first, AnimState::SprintAnim); + animManager->addAnimation(player_atk, player_models.at(i).first, AnimState::AttackAnim); + animManager->addAnimation(player_use_potion, player_models.at(i).first, AnimState::DrinkPotionAnim); + } this->configureGBuffer(); @@ -820,7 +837,7 @@ void Client::geometryPass() { } break; } - animManager->setAnimation(sharedObject->globalID, sharedObject->type, sharedObject->animState); + animManager->setAnimation(sharedObject->globalID, sharedObject->modelType, sharedObject->animState); /* Update model animation */ animManager->updateAnimation(timeElapsed); @@ -841,11 +858,28 @@ void Client::geometryPass() { player_dir = glm::vec3(0.0f, 0.0f, 1.0f); } player_dir.y = 0.0f; - this->player_model->rotateAbsolute(glm::normalize(player_dir), true); - this->player_model->translateAbsolute(player_pos); - // this->player_model->setDimensions(sharedObject->physics.dimensions); - this->player_model->scaleAbsolute(PLAYER_MODEL_SCALE); - this->player_model->draw( + + Model* curr_player_model; + switch (sharedObject->modelType) { + case ModelType::PlayerFire: + curr_player_model = this->fire_player_model.get(); + break; + case ModelType::PlayerLightning: + curr_player_model = this->lightning_player_model.get(); + break; + case ModelType::PlayerWater: + curr_player_model = this->water_player_model.get(); + break; + default: + std::cerr << "WARNING: player with non valid model type detected, defaulting to fire..."; + curr_player_model = this->fire_player_model.get(); + break; + } + + curr_player_model->rotateAbsolute(glm::normalize(player_dir), true); + curr_player_model->translateAbsolute(player_pos); + curr_player_model->scaleAbsolute(PLAYER_MODEL_SCALE); + curr_player_model->draw( this->deferred_geometry_shader.get(), this->cam->getPos(), true); @@ -854,29 +888,30 @@ void Client::geometryPass() { } // CHANGE THIS case ObjectType::DungeonMaster: { - // don't render yourself - if (sharedObject->globalID == self_eid) { - // TODO: Update the player eye level to an acceptable level - glm::vec3 pos = sharedObject->physics.getCenterPosition(); - pos.y += PLAYER_EYE_LEVEL; - cam->updatePos(pos); - break; - } - - auto player_pos = sharedObject->physics.corner; - auto player_dir = sharedObject->physics.facing; - - // this->player_model->setDimensions(sharedObject->physics.dimensions); - this->player_model->translateAbsolute(player_pos); - if (player_dir == glm::vec3(0.0f)) { - player_dir = glm::vec3(0.0f, 0.0f, 1.0f); - } - player_dir.y = 0.0f; - this->player_model->rotateAbsolute(glm::normalize(player_dir), true); - this->player_model->draw( - this->deferred_geometry_shader.get(), - this->cam->getPos(), - true); + // shouldn't render DM at all? + + // if (sharedObject->globalID == self_eid) { + // // TODO: Update the player eye level to an acceptable level + // glm::vec3 pos = sharedObject->physics.getCenterPosition(); + // pos.y += PLAYER_EYE_LEVEL; + // cam->updatePos(pos); + // break; + // } + + // auto player_pos = sharedObject->physics.corner; + // auto player_dir = sharedObject->physics.facing; + + // // this->player_model->setDimensions(sharedObject->physics.dimensions); + // this->player_model->translateAbsolute(player_pos); + // if (player_dir == glm::vec3(0.0f)) { + // player_dir = glm::vec3(0.0f, 0.0f, 1.0f); + // } + // player_dir.y = 0.0f; + // this->player_model->rotateAbsolute(glm::normalize(player_dir), true); + // this->player_model->draw( + // this->deferred_geometry_shader.get(), + // this->cam->getPos(), + // true); break; } case ObjectType::Slime: { diff --git a/src/server/game/object.cpp b/src/server/game/object.cpp index 273c9efd..d8526b4d 100644 --- a/src/server/game/object.cpp +++ b/src/server/game/object.cpp @@ -39,8 +39,9 @@ std::unordered_map Object::models ({ // can't move around anywhere. we should eventually solve this // by tucking in the player's arms since right now they're // spread out in the model - {ModelType::Player, {FIRE_PLAYER_DIMENSIONS * PLAYER_BBOX_SCALE}}, // for bbox, rendering is done separately in geometryPass b/c weird - // discrepencies between the model size in world and reported dimensions + {ModelType::PlayerFire, {FIRE_PLAYER_DIMENSIONS * PLAYER_BBOX_SCALE}}, + {ModelType::PlayerLightning, {LIGHTNING_PLAYER_DIMENSIONS * PLAYER_BBOX_SCALE}}, + {ModelType::PlayerWater, {WATER_PLAYER_DIMENSIONS * PLAYER_BBOX_SCALE}}, {ModelType::WarrenBear, (BEAR_DIMENSIONS / 4.0f)}, {ModelType::Torchlight, glm::vec3(1.0f)}, {ModelType::SunGod, (SUNGOD_DIMENSIONS / 2.0f)} diff --git a/src/server/game/player.cpp b/src/server/game/player.cpp index b1d3afec..a816c3d3 100644 --- a/src/server/game/player.cpp +++ b/src/server/game/player.cpp @@ -14,7 +14,7 @@ SharedObject Player::toShared() { } Player::Player(glm::vec3 corner, glm::vec3 facing): - Creature(ObjectType::Player, corner, facing, ModelType::Player, SharedStats( + Creature(ObjectType::Player, corner, facing, ModelType::PlayerFire, SharedStats( Stat(0, 100, 100), Stat(0, 10, 5) )), From 59b1bb0626f838ed922fbbc661e6a0c6a735fb04 Mon Sep 17 00:00:00 2001 From: Tyler Lentz Date: Tue, 4 Jun 2024 15:45:52 -0700 Subject: [PATCH 2/8] ok everything wasn't broken i just did a minor troll --- src/client/client.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/client/client.cpp b/src/client/client.cpp index 324a410a..44f16e58 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -890,13 +890,12 @@ void Client::geometryPass() { case ObjectType::DungeonMaster: { // shouldn't render DM at all? - // if (sharedObject->globalID == self_eid) { - // // TODO: Update the player eye level to an acceptable level - // glm::vec3 pos = sharedObject->physics.getCenterPosition(); - // pos.y += PLAYER_EYE_LEVEL; - // cam->updatePos(pos); - // break; - // } + if (sharedObject->globalID == self_eid) { + // TODO: Update the player eye level to an acceptable level + glm::vec3 pos = sharedObject->physics.getCenterPosition(); + pos.y += PLAYER_EYE_LEVEL; + cam->updatePos(pos); + } // auto player_pos = sharedObject->physics.corner; // auto player_dir = sharedObject->physics.facing; From 82c565d2c864387a2d1e87830dad9eb0de56e34b Mon Sep 17 00:00:00 2001 From: Tyler Lentz Date: Wed, 5 Jun 2024 11:17:42 -0700 Subject: [PATCH 3/8] make each player a different model in the intro cutscene --- config.json | 6 +++--- src/server/game/introcutscene.cpp | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/config.json b/config.json index 8f2544e5..42b9d329 100644 --- a/config.json +++ b/config.json @@ -14,15 +14,15 @@ "lobby_name": "Hope you're doing well!1", "lobby_broadcast": true, "max_players": 1, - "disable_dm": false, + "disable_dm": true, "skip_intro": false }, "client": { "default_name": "Conan O'Brien", "lobby_discovery": true, - "fullscreen": true, + "fullscreen": false, "draw_bboxes": false, "fps_counter": true, - "presentation": true + "presentation": false } } diff --git a/src/server/game/introcutscene.cpp b/src/server/game/introcutscene.cpp index 0d205fc4..14fd2991 100644 --- a/src/server/game/introcutscene.cpp +++ b/src/server/game/introcutscene.cpp @@ -23,7 +23,9 @@ IntroCutscene::IntroCutscene(): // hard code direction to face right based on the intro cutscene maze orientation Player* player = new Player(this->state.getGrid().getRandomSpawnPoint(), directionToFacing(Direction::RIGHT)); Player* player_left = new Player(this->state.getGrid().getRandomSpawnPoint(), directionToFacing(Direction::RIGHT)); + player_left->modelType = ModelType::PlayerLightning; Player* player_right = new Player(this->state.getGrid().getRandomSpawnPoint(), directionToFacing(Direction::RIGHT)); + player_right->modelType = ModelType::PlayerWater; this->state.objects.createObject(player); this->state.objects.createObject(player_left); From cf34fb791a3d604d5b23900fe07960dbd197af34 Mon Sep 17 00:00:00 2001 From: Tyler Lentz Date: Wed, 5 Jun 2024 17:15:14 -0700 Subject: [PATCH 4/8] assign models to players upon DM assignment --- src/server/server.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/server/server.cpp b/src/server/server.cpp index 7eb96733..534e246b 100644 --- a/src/server/server.cpp +++ b/src/server/server.cpp @@ -302,6 +302,29 @@ std::chrono::milliseconds Server::doTick() { sendUpdateToAllClients(Event(this->world_eid, EventType::LoadGameState, LoadGameStateEvent(partial_update))); } + + int player_idx = 0; // only increment when assigning a model + + auto players = this->state.objects.getPlayers(); + for (int i = 0; i < players.size(); i++) { + auto player = players.get(i); + if (player == nullptr) continue; + + if (player_idx == 0) { + player->modelType = ModelType::PlayerFire; + } else if (player_idx == 1) { + player->modelType = ModelType::PlayerLightning; + } else if (player_idx == 2) { + player->modelType = ModelType::PlayerWater; + } + + player_idx++; + + if (player_idx > 2) { + player_idx = 0; + } + } + std::cout << "Assigned player " + std::to_string(index) + " to be the DM" << std::endl; std::cout << "Starting game!" << std::endl; } From 15893a28be81e920899a284a9ee804c5eccda5f6 Mon Sep 17 00:00:00 2001 From: Tyler Lentz Date: Wed, 5 Jun 2024 17:36:46 -0700 Subject: [PATCH 5/8] load in player 1 rename --- src/client/client.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/client.cpp b/src/client/client.cpp index bd30a555..8beec681 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -242,7 +242,7 @@ bool Client::init() { auto player_atk_path = graphics_assets_dir / "animations/slash.fbx"; auto player_use_potion_path = graphics_assets_dir / "animations/drink.fbx"; - auto fire_player_model_path = player_models_dir / "char_3/model_char_3.fbx"; + auto fire_player_model_path = player_models_dir / "char_1_rename/char1.fbx"; auto lightning_player_model_path = player_models_dir / "char_3/model_char_3.fbx"; auto water_player_model_path = player_models_dir / "char_3/model_char_3.fbx"; From d622d76ef511e931947c6d22660df74ec6f3f0a7 Mon Sep 17 00:00:00 2001 From: Tyler Lentz Date: Wed, 5 Jun 2024 17:41:50 -0700 Subject: [PATCH 6/8] add char 2 model --- src/client/client.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/client.cpp b/src/client/client.cpp index 8beec681..c2382b1f 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -243,7 +243,7 @@ bool Client::init() { auto player_use_potion_path = graphics_assets_dir / "animations/drink.fbx"; auto fire_player_model_path = player_models_dir / "char_1_rename/char1.fbx"; - auto lightning_player_model_path = player_models_dir / "char_3/model_char_3.fbx"; + auto lightning_player_model_path = player_models_dir / "char_2_rename/char2.fbx"; auto water_player_model_path = player_models_dir / "char_3/model_char_3.fbx"; this->fire_player_model = std::make_unique(fire_player_model_path.string(), false); From d9cb5ce1c4c3c330bab256e374defd3892be01f9 Mon Sep 17 00:00:00 2001 From: Tyler Lentz Date: Wed, 5 Jun 2024 17:49:35 -0700 Subject: [PATCH 7/8] debug print --- config.json | 6 +++--- src/server/server.cpp | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/config.json b/config.json index 144818bb..5cfcdfca 100644 --- a/config.json +++ b/config.json @@ -13,9 +13,9 @@ "server": { "lobby_name": "Hope you're doing well!1", "lobby_broadcast": true, - "max_players": 1, - "disable_dm": false, - "skip_intro": false + "max_players": 2, + "disable_dm": true, + "skip_intro": true }, "client": { "default_name": "Conan O'Brien", diff --git a/src/server/server.cpp b/src/server/server.cpp index 534e246b..f317b535 100644 --- a/src/server/server.cpp +++ b/src/server/server.cpp @@ -311,10 +311,13 @@ std::chrono::milliseconds Server::doTick() { if (player == nullptr) continue; if (player_idx == 0) { + std::cout << "assigning player " << i << " to fire\n"; player->modelType = ModelType::PlayerFire; } else if (player_idx == 1) { + std::cout << "assigning player " << i << " to lightning\n"; player->modelType = ModelType::PlayerLightning; } else if (player_idx == 2) { + std::cout << "assigning player " << i << " to water\n"; player->modelType = ModelType::PlayerWater; } From 380c6480634b9a3934e1c51b7c79dc7c38c874ad Mon Sep 17 00:00:00 2001 From: Tyler Lentz Date: Wed, 5 Jun 2024 17:54:57 -0700 Subject: [PATCH 8/8] fix player model assignment not working --- src/server/server.cpp | 43 ++++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/src/server/server.cpp b/src/server/server.cpp index f317b535..990ae0cd 100644 --- a/src/server/server.cpp +++ b/src/server/server.cpp @@ -302,34 +302,31 @@ std::chrono::milliseconds Server::doTick() { sendUpdateToAllClients(Event(this->world_eid, EventType::LoadGameState, LoadGameStateEvent(partial_update))); } + std::cout << "Assigned player " + std::to_string(index) + " to be the DM" << std::endl; + } - int player_idx = 0; // only increment when assigning a model - - auto players = this->state.objects.getPlayers(); - for (int i = 0; i < players.size(); i++) { - auto player = players.get(i); - if (player == nullptr) continue; - - if (player_idx == 0) { - std::cout << "assigning player " << i << " to fire\n"; - player->modelType = ModelType::PlayerFire; - } else if (player_idx == 1) { - std::cout << "assigning player " << i << " to lightning\n"; - player->modelType = ModelType::PlayerLightning; - } else if (player_idx == 2) { - std::cout << "assigning player " << i << " to water\n"; - player->modelType = ModelType::PlayerWater; - } + int player_idx = 0; // only increment when assigning a model - player_idx++; + auto players = this->state.objects.getPlayers(); + for (int i = 0; i < players.size(); i++) { + auto player = players.get(i); + if (player == nullptr) continue; - if (player_idx > 2) { - player_idx = 0; - } + if (player_idx == 0) { + player->modelType = ModelType::PlayerFire; + } + else if (player_idx == 1) { + player->modelType = ModelType::PlayerLightning; + } + else if (player_idx == 2) { + player->modelType = ModelType::PlayerWater; } - std::cout << "Assigned player " + std::to_string(index) + " to be the DM" << std::endl; - std::cout << "Starting game!" << std::endl; + player_idx++; + + if (player_idx > 2) { + player_idx = 0; + } } if (this->config.server.skip_intro) {