diff --git a/config.json b/config.json index 23872b00..8157691f 100644 --- a/config.json +++ b/config.json @@ -8,20 +8,20 @@ "disable_enemies": false }, "network": { - "server_ip": "localhost", - "server_port": 2355 + "server_ip": "localhost", + "server_port": 2355 }, "server": { - "lobby_name": "Hope you're doing well!", - "lobby_broadcast": true, - "max_players": 1, - "disable_dm": false, - "skip_intro": true + "lobby_name": "Hope you're doing well!", + "lobby_broadcast": true, + "max_players": 4, + "disable_dm": 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 94a41d44..13d075ec 100644 --- a/include/client/animationmanager.hpp +++ b/include/client/animationmanager.hpp @@ -13,6 +13,8 @@ #include "client/bone.hpp" #include "shared/game/sharedobject.hpp" +#define MAX_FRAME_TIME 0.033 + class AnimationManager { public: @@ -20,7 +22,7 @@ class AnimationManager void updateAnimation(float dt); - Model* updateFrameAnimation(float time); + Model* updateFrameAnimation(float dt); void playAnimation(Animation* pAnimation); @@ -36,7 +38,7 @@ class AnimationManager private: std::vector m_finalBoneMatrices; - std::unordered_map> entityAnimFrameMap; + std::unordered_map> entityAnimFrameMap; std::unordered_map> entityAnimMap; std::unordered_map> objAnimMap; Animation* m_currentAnimation; diff --git a/include/client/client.hpp b/include/client/client.hpp index c6c48bfe..d0a4259a 100644 --- a/include/client/client.hpp +++ b/include/client/client.hpp @@ -358,6 +358,7 @@ class Client { float mouse_ypos = 0.0f; double lastTime = 0.0; + double lastFrameTime = 0.0; GameConfig config; tcp::resolver resolver; diff --git a/include/server/game/projectile.hpp b/include/server/game/projectile.hpp index 9a8ad823..3e43a98e 100644 --- a/include/server/game/projectile.hpp +++ b/include/server/game/projectile.hpp @@ -76,9 +76,14 @@ class Projectile : public Object { */ bool doTick(ServerGameState& state); + virtual SharedObject toShared() override; + + private: Options opt; std::optional destroy_sound; + PointLightProperties properties; + }; class HomingFireball : public Projectile { @@ -90,7 +95,7 @@ class HomingFireball : public Projectile { inline static const int HOMING_DURATION_TICKS = 80; // 2.4s HomingFireball(glm::vec3 corner, glm::vec3 facing, std::optional target): - Projectile(corner, facing, glm::vec3(0.4f, 0.4f, 0.4f), ModelType::Cube, ServerSFX::FireballImpact, + Projectile(corner, facing, glm::vec3(0.4f, 0.4f, 0.4f), ModelType::Fireball, ServerSFX::FireballImpact, Options(false, DAMAGE, H_MULT, V_MULT, true, HOMING_STRENGTH, HOMING_DURATION_TICKS, target)) { this->physics.feels_gravity = false; @@ -149,7 +154,7 @@ class SpellOrb : public Projectile { SpellType sType; SpellOrb(glm::vec3 corner, glm::vec3 facing, SpellType type) : - Projectile(corner, facing, glm::vec3(0.4f, 0.4f, 0.4f), ModelType::Cube, ServerSFX::FireballImpact, + Projectile(corner, facing, glm::vec3(0.4f, 0.4f, 0.4f), ModelType::SpellOrb, ServerSFX::FireballImpact, Options(true, DAMAGE, H_MULT, V_MULT, false, 0.0f, 0, {})) { this->sType = type; diff --git a/include/shared/game/sharedmodel.hpp b/include/shared/game/sharedmodel.hpp index fbd54214..3c737da1 100644 --- a/include/shared/game/sharedmodel.hpp +++ b/include/shared/game/sharedmodel.hpp @@ -17,6 +17,7 @@ enum class ModelType { FireSpell, HealSpell, TeleportSpell, + SpellOrb, Frame, Orb, FloorSpikeHorizontal, @@ -37,6 +38,7 @@ enum class ModelType { Lightning, Arrow, ArrowTrap, + Fireball, FireballTrapLeft, FireballTrapRight, FireballTrapUp, diff --git a/maps/test/anim_test.maze b/maps/test/anim_test.maze index 5dff4513..a222b0dd 100644 --- a/maps/test/anim_test.maze +++ b/maps/test/anim_test.maze @@ -1,9 +1,9 @@ -###[### +####### #.....# -{..3..} +#..3..# #.....# +{.....} #.....# +#.@...# #.....# -{.@...} -#.....# -###]### \ No newline at end of file +####### \ No newline at end of file diff --git a/src/client/animationmanager.cpp b/src/client/animationmanager.cpp index dc833281..a3e37793 100644 --- a/src/client/animationmanager.cpp +++ b/src/client/animationmanager.cpp @@ -28,19 +28,13 @@ void AnimationManager::updateAnimation(float dt) { } } -Model* AnimationManager::updateFrameAnimation(float time) { +Model* AnimationManager::updateFrameAnimation(float dt) { if (entityAnimFrameMap[currEntity].second) { m_currentAnimation = entityAnimFrameMap[currEntity].second; - int currFrame = entityAnimFrameMap[currEntity].first + 1; - - // /* Change this to a constant */ - // if (time - lastFrameTime >= 0.01667) { - // std::cout << "time: " << time << ", lastTime: " << lastFrameTime << ", diff: " << (time - lastFrameTime) << ", currFrame: " << currFrame << std::endl; - // currFrame += 1; - // std::cout << currFrame << std::endl; - // lastFrameTime = time; - // } - entityAnimFrameMap[currEntity].first = currFrame; + m_currentTime = entityAnimFrameMap[currEntity].first; + m_currentTime += dt; + int currFrame = static_cast (m_currentTime / MAX_FRAME_TIME); + entityAnimFrameMap[currEntity].first = m_currentTime; return m_currentAnimation->getFrame(currFrame); } else { return nullptr; @@ -97,7 +91,7 @@ void AnimationManager::setFrameAnimation(EntityID id, ModelType modelType, AnimS static std::random_device dev; static std::mt19937 rng(dev()); static std::uniform_int_distribution dist(0,51); - entityAnimFrameMap[id] = std::make_pair(dist(rng), objAnimMap[modelType][animState]); + entityAnimFrameMap[id] = std::make_pair(dist(rng) * MAX_FRAME_TIME, objAnimMap[modelType][animState]); } currEntity = id; } diff --git a/src/client/client.cpp b/src/client/client.cpp index eae32cdf..5cfce042 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -272,7 +272,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 torchlight_anim_path = graphics_assets_dir / "animations/fire-fix"; - + auto fireball_anim_path = graphics_assets_dir / "animations/fireball"; 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"; @@ -294,7 +294,9 @@ bool Client::init() { animManager = new AnimationManager(); Animation* torchlight_animation = new Animation(torchlight_anim_path.string(), "fire-fix", 45); animManager->addAnimation(torchlight_animation, ModelType::Torchlight, AnimState::IdleAnim); - + Animation* fireball_animation = new Animation(fireball_anim_path.string(), "fireball", 60); + animManager->addAnimation(fireball_animation, ModelType::Fireball, AnimState::IdleAnim); + animManager->addAnimation(fireball_animation, ModelType::SpellOrb, AnimState::IdleAnim); 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); @@ -694,6 +696,9 @@ void Client::processServerInput(bool allow_defer) { } EntityID light_id = updated_light_source.lightSources[i].value().eid; this->closest_light_sources[i] = this->gameState.objects[light_id]; + if (!this->closest_light_sources[i].has_value()) { + continue; + } // update intensity with incoming intensity this->closest_light_sources[i]->pointLightInfo->intensity = updated_light_source.lightSources[i]->intensity; this->closest_light_sources[i]->pointLightInfo->is_cut = updated_light_source.lightSources[i]->is_cut; @@ -1112,12 +1117,15 @@ void Client::geometryPass() { this->arrow_model->draw(this->deferred_geometry_shader.get(), this->cam->getPos(), true); break; - } + } + // case ModelType::Fireball: { + // break; + // } default: - this->spike_trap_model->setDimensions(sharedObject->physics.dimensions); - this->spike_trap_model->translateAbsolute(sharedObject->physics.getCenterPosition()); - this->spike_trap_model->draw(this->deferred_geometry_shader.get(), - this->cam->getPos(), true); + // this->spike_trap_model->setDimensions(sharedObject->physics.dimensions); + // this->spike_trap_model->translateAbsolute(sharedObject->physics.getCenterPosition()); + // this->spike_trap_model->draw(this->deferred_geometry_shader.get(), + // this->cam->getPos(), true); break; } break; @@ -1340,6 +1348,14 @@ void Client::lightingPass() { glm::vec3 FAR_AWAY(10000, 10000, 10000); lighting_shader->setVec3("pointLights[" + std::to_string(i) + "].position", FAR_AWAY); continue; + } else if (!this->gameState.objects.contains(curr_source->globalID)) { + glm::vec3 FAR_AWAY(10000, 10000, 10000); + lighting_shader->setVec3("pointLights[" + std::to_string(i) + "].position", FAR_AWAY); + continue; + } else if (!this->gameState.objects.at(curr_source->globalID).has_value()) { + glm::vec3 FAR_AWAY(10000, 10000, 10000); + lighting_shader->setVec3("pointLights[" + std::to_string(i) + "].position", FAR_AWAY); + continue; } SharedPointLightInfo& properties = curr_source->pointLightInfo.value(); @@ -1397,6 +1413,10 @@ void Client::lightingPass() { glBlitFramebuffer(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, GL_DEPTH_BUFFER_BIT, GL_NEAREST); glBindFramebuffer(GL_FRAMEBUFFER, 0); + double currentTime = glfwGetTime(); + double timeElapsed = currentTime - lastFrameTime; + lastFrameTime = currentTime; + // render torch lights on top of scene this->deferred_light_box_shader->use(); glm::mat4 viewProj = this->cam->getViewProj(); @@ -1406,10 +1426,6 @@ void Client::lightingPass() { continue; } - if (sharedObject->type != ObjectType::Torchlight) { - continue; - } - auto dist = glm::distance(sharedObject->physics.corner, my_pos); if (!is_dm && dist > this->config.client.render) { continue; @@ -1418,37 +1434,70 @@ void Client::lightingPass() { if (!sharedObject->pointLightInfo.has_value()) { std::cout << "got a torch without point light info for some reason" << std::endl; continue; - } + } + SharedPointLightInfo& properties = sharedObject->pointLightInfo.value(); + + this->deferred_light_box_shader->use(); - glm::vec3 v(1.0f); + switch (sharedObject->type) { + case ObjectType::Torchlight: { + glm::vec3 v(1.0f); - animManager->setFrameAnimation(sharedObject->globalID, sharedObject->modelType, sharedObject->animState); + animManager->setFrameAnimation(sharedObject->globalID, sharedObject->modelType, sharedObject->animState); + Model* torch_frame_model = animManager->updateFrameAnimation(timeElapsed); + glm::vec3 dims = torch_frame_model->getDimensions(); - /* Update model animation */ - Model* torch_frame_model = animManager->updateFrameAnimation(glfwGetTime()); - glm::vec3 dims = torch_frame_model->getDimensions(); - this->deferred_light_box_shader->use(); + glm::vec3 flame_color; - glm::vec3 flame_color; + if (sharedObject->pointLightInfo->is_cut) { + glm::vec3 black(0.1f, 0.1f, 0.1f); + flame_color = black; + } else { + flame_color = properties.diffuse_color; + } - if (sharedObject->pointLightInfo->is_cut) { - glm::vec3 black(0.1f, 0.1f, 0.1f); - flame_color = black; - } else { - flame_color = properties.diffuse_color; - } + this->deferred_light_box_shader->setVec3("lightColor", flame_color); + torch_frame_model->setDimensions(2.0f * sharedObject->physics.dimensions); + torch_frame_model->translateAbsolute(sharedObject->physics.getCenterPosition()); + torch_frame_model->draw(this->deferred_light_box_shader.get(), this->cam->getPos(), true, flame_color); + break; + } + case ObjectType::Projectile: { + if (sharedObject->modelType == ModelType::Fireball) { + glm::vec3 flame_color = properties.diffuse_color; - this->deferred_light_box_shader->setVec3("lightColor", flame_color); + animManager->setFrameAnimation(sharedObject->globalID, sharedObject->modelType, sharedObject->animState); + Model* fireball_frame_model = animManager->updateFrameAnimation(timeElapsed); - // this->torchlight_model->setDimensions(2.0f * sharedObject->physics.dimensions); - // this->torchlight_model->translateAbsolute(sharedObject->physics.getCenterPosition()); - // this->torchlight_model->draw(this->deferred_light_box_shader.get(), this->cam->getPos(), true); - torch_frame_model->setDimensions(2.0f * sharedObject->physics.dimensions); - torch_frame_model->translateAbsolute(sharedObject->physics.getCenterPosition()); - // torch_frame_model->draw(this->deferred_light_box_shader.get(), this->cam->getPos(), true); - torch_frame_model->draw(this->deferred_light_box_shader.get(), this->cam->getPos(), true, flame_color); + this->deferred_light_box_shader->setVec3("lightColor", flame_color); + + fireball_frame_model->setDimensions(sharedObject->physics.dimensions); + fireball_frame_model->translateAbsolute(sharedObject->physics.getCenterPosition()); + fireball_frame_model->draw(this->deferred_light_box_shader.get(), + this->cam->getPos(), true); + break; + } else if (sharedObject->modelType == ModelType::SpellOrb) { + glm::vec3 flame_color = properties.diffuse_color; + + animManager->setFrameAnimation(sharedObject->globalID, sharedObject->modelType, sharedObject->animState); + Model* fireball_frame_model = animManager->updateFrameAnimation(timeElapsed); + + this->deferred_light_box_shader->setVec3("lightColor", flame_color); + + fireball_frame_model->setDimensions(sharedObject->physics.dimensions); + fireball_frame_model->translateAbsolute(sharedObject->physics.getCenterPosition()); + fireball_frame_model->draw(this->deferred_light_box_shader.get(), + this->cam->getPos(), true); + break; + } + break; + } + default: + continue; + } + } } diff --git a/src/server/game/object.cpp b/src/server/game/object.cpp index 86e228bb..a421c11d 100644 --- a/src/server/game/object.cpp +++ b/src/server/game/object.cpp @@ -58,6 +58,8 @@ std::unordered_map Object::models ({ {ModelType::Lightning, glm::vec3(3.0f, 100.0f, 3.0f)}, {ModelType::Orb, glm::vec3(0.887116, 0.941508, 0.950092)}, {ModelType::Chest, glm::vec3(1.377020, 1.355794, 1.092905)}, + {ModelType::Fireball, glm::vec3(0.4f, 0.4f, 0.4f)}, + {ModelType::SpellOrb, glm::vec3(0.4f, 0.4f, 0.4f)}, {ModelType::TeleporterTrap, glm::vec3(1.0f, 3.0f, 1.0f)} }); diff --git a/src/server/game/projectile.cpp b/src/server/game/projectile.cpp index 4fcdcf99..54644d5a 100644 --- a/src/server/game/projectile.cpp +++ b/src/server/game/projectile.cpp @@ -101,4 +101,50 @@ void Projectile::doCollision(Object* other, ServerGameState& state) { } } } +} + +/* SharedGameState generation */ +SharedObject Projectile::toShared() { + auto so = Object::toShared(); + if (so.modelType == ModelType::Fireball) { + so.pointLightInfo = SharedPointLightInfo { + .intensity = 1.0f, + .ambient_color = glm::vec3(0.72f, 0.14f, 0.01f), + .diffuse_color = glm::vec3(1.0f, 0.5f, 0.03f), + .specular_color = glm::vec3(0.1f, 0.1f, 0.1f), + .attenuation_linear = 0.35f, + .attenuation_quadratic = 0.44f + }; + } else if (so.modelType == ModelType::SpellOrb) { + SpellOrb* sOrb = dynamic_cast(this); + if (sOrb->sType == SpellType::Fireball) { + so.pointLightInfo = SharedPointLightInfo { + .intensity = 1.0f, + .ambient_color = glm::vec3(0.55f, 0.05f, 0.67f), + .diffuse_color = glm::vec3(0.65f, 0.12f, 0.75f), + .specular_color = glm::vec3(0.1f, 0.1f, 0.1f), + .attenuation_linear = 0.35f, + .attenuation_quadratic = 0.44f + }; + } else if (sOrb->sType == SpellType::HealOrb) { + so.pointLightInfo = SharedPointLightInfo { + .intensity = 1.0f, + .ambient_color = glm::vec3(0.0, 0.72f, 0.14f), + .diffuse_color = glm::vec3(0.12f, 1.0f, 0.35f), + .specular_color = glm::vec3(0.1f, 0.1f, 0.1f), + .attenuation_linear = 0.35f, + .attenuation_quadratic = 0.44f + }; + } + } else { + so.pointLightInfo = SharedPointLightInfo { + .intensity = 0.5f, + .ambient_color = glm::vec3(1.0f, 1.0f, 1.0f), + .diffuse_color = glm::vec3(1.0f, 1.0f, 1.0f), + .specular_color = glm::vec3(0.1f, 0.1f, 0.1f), + .attenuation_linear = 0.35f, + .attenuation_quadratic = 0.44f + }; + } + return so; } \ No newline at end of file diff --git a/src/server/game/spell.cpp b/src/server/game/spell.cpp index 9495d258..0d6ca871 100644 --- a/src/server/game/spell.cpp +++ b/src/server/game/spell.cpp @@ -10,7 +10,7 @@ #include "shared/audio/constants.hpp" Spell::Spell(glm::vec3 corner, glm::vec3 dimensions, SpellType spelltype): - Item(ObjectType::Spell, false, corner, ModelType::Cube, dimensions) + Item(ObjectType::Spell, false, corner, ModelType::SpellOrb, dimensions) { this->spellType = spelltype; diff --git a/src/server/server.cpp b/src/server/server.cpp index 8e95661d..87e103d5 100644 --- a/src/server/server.cpp +++ b/src/server/server.cpp @@ -28,6 +28,7 @@ #include "server/game/object.hpp" #include "shared/game/sharedmodel.hpp" #include "server/game/trap.hpp" +#include "server/game/projectile.hpp" #include "shared/network/session.hpp" #include "shared/network/packet.hpp" #include "shared/network/constants.hpp" @@ -161,6 +162,13 @@ void Server::sendLightSourceUpdates(EntityID playerID) { closestPointLights.push(lava->globalID); } + for(int i = 0; i < this->state.objects.getProjectiles().size(); i++) { + auto proj = this->state.objects.getProjectiles().get(i); + if (proj == nullptr) continue; + if (proj->modelType != ModelType::Arrow && proj->modelType != ModelType::Fireball && proj->modelType != ModelType::SpellOrb) continue; + closestPointLights.push(proj->globalID); + + } // put set into an array UpdateLightSourcesEvent event_data; @@ -449,8 +457,8 @@ void Server::_doAccept() { [this](boost::system::error_code ec) { if (!ec) { this->socket.set_option(boost::asio::ip::tcp::no_delay(true)); - boost::asio::socket_base::send_buffer_size option(10000000); // 10x buffer size - this->socket.set_option(option); + // boost::asio::socket_base::send_buffer_size option(10000000); // 10x buffer size + // this->socket.set_option(option); auto addr = this->socket.remote_endpoint().address(); auto new_session = this->_handleNewSession(addr);