diff --git a/config.json b/config.json index ed04a3c3..5cfcdfca 100644 --- a/config.json +++ b/config.json @@ -13,14 +13,14 @@ "server": { "lobby_name": "Hope you're doing well!1", "lobby_broadcast": true, - "max_players": 1, + "max_players": 2, "disable_dm": true, - "skip_intro": false + "skip_intro": true }, "client": { "default_name": "Conan O'Brien", "lobby_discovery": true, - "fullscreen": true, + "fullscreen": false, "draw_bboxes": false, "fps_counter": true, "presentation": false diff --git a/include/client/animationmanager.hpp b/include/client/animationmanager.hpp index 44196a41..60ebabf2 100644 --- a/include/client/animationmanager.hpp +++ b/include/client/animationmanager.hpp @@ -15,7 +15,7 @@ class AnimationManager { public: - explicit AnimationManager(Animation* animation); + explicit 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 685e590d..6164d9d2 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 12a22362..f6cf888d 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 834f66cb..ca20d983 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_deltaTime = 0; // Tyler: is this still used? linter complaining about it not being initialized @@ -31,6 +31,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; @@ -58,19 +62,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 3d975004..c2382b1f 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -235,7 +235,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"; @@ -243,22 +242,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_rename/char1.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); + 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(); @@ -825,7 +842,7 @@ void Client::geometryPass() { break; // don't render dead players } - animManager->setAnimation(sharedObject->globalID, sharedObject->type, sharedObject->animState); + animManager->setAnimation(sharedObject->globalID, sharedObject->modelType, sharedObject->animState); /* Update model animation */ animManager->updateAnimation(timeElapsed); @@ -846,11 +863,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); @@ -859,29 +893,29 @@ void Client::geometryPass() { } // CHANGE THIS case ObjectType::DungeonMaster: { - // don't render yourself + // 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); + // 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/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); 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) )), diff --git a/src/server/server.cpp b/src/server/server.cpp index 7eb96733..990ae0cd 100644 --- a/src/server/server.cpp +++ b/src/server/server.cpp @@ -303,7 +303,30 @@ std::chrono::milliseconds Server::doTick() { } std::cout << "Assigned player " + std::to_string(index) + " to be the DM" << std::endl; - std::cout << "Starting game!" << 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) { + 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; + } } if (this->config.server.skip_intro) {