diff --git a/SQCSim-common/booster.cpp b/SQCSim-common/booster.cpp index 677a28d..61d8731 100644 --- a/SQCSim-common/booster.cpp +++ b/SQCSim-common/booster.cpp @@ -4,12 +4,7 @@ Booster::Booster() { } -Booster::Booster(Vector3f tpos, BOOST_TYPE ttype) -{ - pos = tpos; - type = ttype; - available = true; -} +Booster::Booster(Vector3f tpos, BOOST_TYPE ttype, uint64_t id): m_id(id), pos(tpos), type(ttype){} Booster::~Booster() { @@ -26,6 +21,11 @@ BOOST_TYPE Booster::GetType() return type; } +uint64_t Booster::GetId() const +{ + return m_id; +} + bool Booster::GetAvailability() { return available; @@ -34,5 +34,6 @@ bool Booster::GetAvailability() void Booster::SetAvailability(bool value) { available = value; + modified = true; } diff --git a/SQCSim-common/booster.h b/SQCSim-common/booster.h index 6bfbed5..db9f09f 100644 --- a/SQCSim-common/booster.h +++ b/SQCSim-common/booster.h @@ -6,15 +6,18 @@ class Booster { public: Booster(); - Booster(Vector3f tpos, BOOST_TYPE ttype); + Booster(Vector3f tpos, BOOST_TYPE ttype, uint64_t id); ~Booster(); Vector3f GetPosition(); BOOST_TYPE GetType(); + uint64_t GetId() const; bool GetAvailability(); void SetAvailability(bool value); + bool modified = true; private: Vector3f pos; BOOST_TYPE type; - bool available; + uint64_t m_id; + bool available = true; }; #endif diff --git a/SQCSim-common/bullet.cpp b/SQCSim-common/bullet.cpp index a6d8002..94e52d7 100644 --- a/SQCSim-common/bullet.cpp +++ b/SQCSim-common/bullet.cpp @@ -12,8 +12,12 @@ Bullet::~Bullet() {} bool Bullet::Update(World* world, float elapsedtime, int perframe, std::unordered_map mapPlayer, netprot::ChunkMod** chunkmod) { int max = 100 / perframe; - Player* shooter = mapPlayer.at(m_shooter_id); - float damage = shooter->boostdamage? 0.123f: 0.098f; + Player* shooter = nullptr; + float damage = 0.098f; + if (mapPlayer.count(m_shooter_id)) { + shooter = mapPlayer.at(m_shooter_id); + damage = shooter->boostdamage ? 0.123f : 0.098f; + } for (int x = 0; x < max; ++x) { m_currentpos += m_velocity * elapsedtime; diff --git a/SQCSim-common/netprotocol.cpp b/SQCSim-common/netprotocol.cpp index 984a8e2..98c3643 100644 --- a/SQCSim-common/netprotocol.cpp +++ b/SQCSim-common/netprotocol.cpp @@ -553,7 +553,7 @@ void netprot::Serialize(PickupMod* pmod, char* buf[], uint32_t* buflen) { (uint8_t)((vec[2] >> 8) & 0xFF), (uint8_t)(vec[2] & 0xFF) }; - memcpy(*buf + sizeof(uint64_t) + 1, vec8, sizeof(uint32_t) * 3); + memcpy(*buf + sizeof(uint64_t) + 2, vec8, sizeof(uint32_t) * 3); Boosts boost = pmod->boost; uint8_t boost8 = // Reste 5 bits. diff --git a/SQCSim-common/netprotocol.h b/SQCSim-common/netprotocol.h index bbe732f..ea4c7b2 100644 --- a/SQCSim-common/netprotocol.h +++ b/SQCSim-common/netprotocol.h @@ -133,7 +133,7 @@ namespace netprot { Vector3f pos; Boosts boost; bool available = true; - PickupMod(); + PickupMod() {} PickupMod(PickupMod* pmod) : id(pmod->id), pos(pmod->pos), boost(pmod->boost), available(pmod->available) {} }; diff --git a/SQCSim-common/player.cpp b/SQCSim-common/player.cpp index cb4c395..8e6586d 100644 --- a/SQCSim-common/player.cpp +++ b/SQCSim-common/player.cpp @@ -84,7 +84,7 @@ Vector3f Player::GetInput(bool front, bool back, bool left, bool right, bool jum return delta; } -Player::Sound Player::ApplyPhysics(Vector3f input, World* world, float elapsedTime, Booster booster_table[]) { +Player::Sound Player::ApplyPhysics(Vector3f input, World* world, float elapsedTime, std::unordered_map booster_table) { Player::Sound snd = Player::Sound::NOSOUND; static float timing = 0.f; /* Gestion de collisions */ @@ -196,16 +196,16 @@ void Player::ApplyTransformation(Transformation& transformation, bool rel, bool if (rel) transformation.ApplyTranslation(-GetPOV()); } -void Player::TakeBooster(Booster booster_table[], float elapsedtime) +void Player::TakeBooster(std::unordered_map booster_table, float elapsedtime) { Vector3f playerpos = GetPosition(); - for (int i = 0; i < sizeof(booster_table); i++) + for (auto& [key, booster]: booster_table) { - Vector3f pos = booster_table[i].GetPosition(); - if (abs(playerpos.x - pos.x) <= 0.5f && abs(playerpos.y - pos.y) <= 1.0f && abs(playerpos.z - pos.z) <= 0.5f && booster_table[i].GetAvailability() == true) + Vector3f pos = booster->GetPosition(); + if (booster->GetAvailability() && abs(playerpos.x - pos.x) <= 0.5f && abs(playerpos.y - pos.y) <= 1.0f && abs(playerpos.z - pos.z) <= 0.5f) { - GetBooster(booster_table[i].GetType(), elapsedtime); - booster_table[i].SetAvailability(false); + GetBooster(booster->GetType(), elapsedtime); + booster->SetAvailability(false); break; } } diff --git a/SQCSim-common/player.h b/SQCSim-common/player.h index 02084c8..fdc3853 100644 --- a/SQCSim-common/player.h +++ b/SQCSim-common/player.h @@ -2,6 +2,7 @@ #define PLAYER_H__ #include +#include #include "transformation.h" #include "vector3.h" #include "booster.h" @@ -21,8 +22,8 @@ public: void TurnLeftRight(float value, float sensitivity); void TurnTopBottom(float value, float sensitivity); Vector3f GetInput(bool front, bool back, bool left, bool right, bool jump, bool dash, float elapsedTime); - Sound ApplyPhysics(Vector3f input, World* world, float elapsedTime, Booster booster_table[]); - void TakeBooster(Booster booster_table[], float elapsedTime); + Sound ApplyPhysics(Vector3f input, World* world, float elapsedTime, std::unordered_map booster_table); + void TakeBooster(std::unordered_map booster_table, float elapsedTime); void GetBooster(BOOST_TYPE boosttype, float elapsedTime); void RemoveBooster(float elapsedtime); void ApplyTransformation(Transformation& transformation, bool rel = true, bool rot = true) const; diff --git a/SQCSim-srv/connection.cpp b/SQCSim-srv/connection.cpp index 19469ad..f20ed5c 100644 --- a/SQCSim-srv/connection.cpp +++ b/SQCSim-srv/connection.cpp @@ -132,7 +132,7 @@ void Connection::sendPacks(SOCKET sock, std::unordered_map boosters) { Input in, last; Output out; Timestamp tstamp = 0; @@ -169,7 +169,8 @@ Timestamp Connection::Run(World* world) { in.keys.backward, in.keys.left, in.keys.right, - in.keys.jump, false, el), world, el); + in.keys.jump, false, el), + world, el, boosters); if (player->GetPosition().y < -20.) { player->InflictDamage(9000.); diff --git a/SQCSim-srv/connection.h b/SQCSim-srv/connection.h index 3c5ac23..01032be 100644 --- a/SQCSim-srv/connection.h +++ b/SQCSim-srv/connection.h @@ -36,7 +36,7 @@ public: void getPacks(SOCKET sock); void sendPacks(SOCKET sock, std::unordered_map conns, const uint32_t timer); - Timestamp Run(World* world); + Timestamp Run(World* world, std::unordered_map boosters); void CleanInputManifest(Timestamp time); diff --git a/SQCSim-srv/define.h b/SQCSim-srv/define.h index a334446..0a526db 100644 --- a/SQCSim-srv/define.h +++ b/SQCSim-srv/define.h @@ -21,6 +21,7 @@ const std::vector DEATHMESSAGES = { "@ has gone to meet their maker "So long, @, and thanks for all the lols!", "@ has a bad case of being dead.", "@ has finally seen the light!", + "$ sees dead people; in this case they see a dead @.", "Thought @ was hot; guess what? He's not. He is dead, dead, dead.", "@ did not want to live forever.", "$ made @ die for their country.", diff --git a/SQCSim-srv/server.cpp b/SQCSim-srv/server.cpp index 09ad867..410430d 100644 --- a/SQCSim-srv/server.cpp +++ b/SQCSim-srv/server.cpp @@ -83,18 +83,18 @@ int Server::Ready() { m_game.countdown = 0; } } while (m_game.countdown < 1); - m_game.seed = 9370707; - /*do { + // m_game.seed = 9370707; + do { Log("Entrez le seed de la partie: ", false, false); std::cin.getline(m_buf.ptr, BUFFER_LENGTH); try { - std::stoi(m_buf.ptr); + m_game.seed = std::stoi(m_buf.ptr); } catch (const std::exception& e) { Log(e.what(), true, false); m_game.seed = 0; } - } while (m_game.seed < 1);*/ + } while (m_game.seed < 1); do { Log("Entrez le nombre de joueurs: ", false, false); std::cin.getline(m_buf.ptr, BUFFER_LENGTH); @@ -108,7 +108,17 @@ int Server::Ready() { if (nbrjoueurs <= 0 || nbrjoueurs > MAX_CONNECTIONS) Log("Nombre de joueurs invalide.", true, false); } while (nbrjoueurs <= 0 || nbrjoueurs > MAX_CONNECTIONS); - + do { + Log("Entrez le nombre de boosters: ", false, false); + std::cin.getline(m_buf.ptr, BUFFER_LENGTH); + try { + m_boostcount = std::stoi(m_buf.ptr); + } + catch (const std::exception& e) { + Log(e.what(), true, false); + m_boostcount = -1; + } + } while (m_boostcount < 0); m_game.gameType = 1; if (listen(m_sock_tcp, MAX_CONNECTIONS) < 0) { @@ -202,8 +212,8 @@ void Server::Run() { m_conns.erase(key); continue; } - int x = (rand() % (CHUNK_SIZE_X * WORLD_SIZE_X - 1) - (CHUNK_SIZE_X * WORLD_SIZE_X / 2)) / 16, - y = (rand() % (CHUNK_SIZE_Y * WORLD_SIZE_Y - 1) - (CHUNK_SIZE_Y * WORLD_SIZE_Y / 2)) / 16; + int x = (rand() % (CHUNK_SIZE_X * WORLD_SIZE_X - 1) - (CHUNK_SIZE_X * WORLD_SIZE_X / 2)) / 4, + y = (rand() % (CHUNK_SIZE_Z * WORLD_SIZE_Y - 1) - (CHUNK_SIZE_Z * WORLD_SIZE_Y / 2)) / 4; conn->player = new Player(Vector3f(x + .5f, CHUNK_SIZE_Y + 1.8f, y + .5f)); conn->player->m_username = conn->GetName(); m_players[key] = conn->player; @@ -225,8 +235,21 @@ void Server::Run() { std::vector bullets; std::vector::iterator> bullit; std::vector netbull; + std::vector netboosters; std::vector lsPck; + int max = 0; + for (int64_t x = 0; x < m_boostcount; ++x) { + Vector3f pos = Vector3f(rand() % (WORLD_SIZE_X * CHUNK_SIZE_X) + .5f, rand() % CHUNK_SIZE_Y + .5f, rand() % (WORLD_SIZE_Y * CHUNK_SIZE_Z) + .5f); + if (m_world->BlockAt(pos) == BTYPE_AIR) { + Booster* boost = new Booster(pos, (BOOST_TYPE)(rand() % BTYPE_BOOST_LAST), getUniqueId()); + m_boosters[boost->GetId()] = boost; + } + else --x; + if (++max > 1000) + break; + } + Chat* startchat = new Chat(); startchat->src_id = 0; char startmess[] = "How would -YOU- like to die today, motherf-words?"; @@ -283,7 +306,7 @@ void Server::Run() { if (conn->m_nsync) { - Timestamp tstamp = conn->Run(m_world); + Timestamp tstamp = conn->Run(m_world, m_boosters); if (conn->player->AmIDead() && !conn->player->Eulogy) { Chat* chat = new Chat(); @@ -367,6 +390,33 @@ void Server::Run() { } } + for (auto& [key, booster] : m_boosters) { + if (booster->modified) { + PickupMod pmod; + pmod.available = booster->GetAvailability(); + pmod.id = booster->GetId(); + pmod.pos = booster->GetPosition(); + + Boosts boost; + switch (booster->GetType()) { + case BTYPE_DAMAGE: + boost.damage = true; + break; + case BTYPE_HEAL: + boost.hp = true; + break; + case BTYPE_INVINCIBLE: + boost.invincible = true; + break; + default: continue; + } + pmod.boost = boost; + booster->modified = false; + for (auto& [key, conn] : m_conns) + sendPackTo(m_sock_udp, &pmod, &m_buf, conn->getAddr()); + } + } + for (auto& bull : netbull) { for (auto& [key, conn] : m_conns) if (bull->id != conn->GetHash(false)) // Pour pas repitcher au joueur sa propre balle. diff --git a/SQCSim-srv/server.h b/SQCSim-srv/server.h index c70a457..46470c4 100644 --- a/SQCSim-srv/server.h +++ b/SQCSim-srv/server.h @@ -43,12 +43,15 @@ private: std::unordered_map m_players; std::unordered_map m_conns; std::unordered_map m_chatlog; + std::unordered_map m_boosters; std::vector m_ids; GameInfo m_game; World* m_world = nullptr; bool m_exit = true; + int64_t m_boostcount = -1; + std::string LogTimestamp(); void Log(std::string str, bool is_error, bool is_fatal); void buildIdList(size_t size); diff --git a/SQCSim2021/engine.cpp b/SQCSim2021/engine.cpp index 94f21b1..ba95d94 100644 --- a/SQCSim2021/engine.cpp +++ b/SQCSim2021/engine.cpp @@ -619,8 +619,8 @@ bool Engine::StartMultiplayerGame() { for (auto& [key, player] : m_conn.m_players) m_players[key] = new RemotePlayer(&player); - //m_world.SetSeed(m_conn.getSeed()); - m_world.SetSeed(9370707); + m_world.SetSeed(m_conn.getSeed()); + //m_world.SetSeed(9370707); m_networkgame = true; m_player.m_username = m_username; } @@ -684,11 +684,6 @@ void Engine::DisplayInfo(float elapsedTime, BlockType bloc) { ss.str(""); fPosY -= charSize; - //ss << " Block : "; - //if (bloc == BTYPE_LAST) - // ss << "Weapon"; - //else - // ss << (int)bloc; PrintText(fPosX, fPosYJump, ss.str()); } @@ -1307,8 +1302,6 @@ void Engine::Render(float elapsedTime) { } if (m_gamestate == GameState::PAUSE) { - booster_table[0] = Booster({ 215, 15, 195 }, BTYPE_SPEED); - booster_table[1] = Booster({ 213, 15, 195 }, BTYPE_HEAL); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); @@ -1350,7 +1343,7 @@ void Engine::Render(float elapsedTime) { static bool leftright = false; if (pollTime >= .005f) { - Player::Sound snd = m_player.ApplyPhysics(m_player.GetInput(m_keyW, m_keyS, m_keyA, m_keyD, m_keySpace, (bloc == BTYPE_LAST && bulletTime <= 0.f && m_mouseL), elapsedTime), &m_world, elapsedTime, booster_table); + Player::Sound snd = m_player.ApplyPhysics(m_player.GetInput(m_keyW, m_keyS, m_keyA, m_keyD, m_keySpace, (bloc == BTYPE_LAST && bulletTime <= 0.f && m_mouseL), elapsedTime), &m_world, elapsedTime, m_boosters); switch (snd) { case Player::Sound::STEP: if (leftright) @@ -1413,35 +1406,16 @@ void Engine::Render(float elapsedTime) { m_chunkmod = nullptr; } m_bullets[x] = nullptr; - /*if (m_whoosh[x]){ - m_whoosh[x]->drop(); - m_whoosh[x] = nullptr; - }*/ break; } - /*else if (!m_whoosh[x]) { - m_whoosh[x] = m_audio.Create3DAudioObj(m_whoosh[x], AUDIO_PATH "noise.wav", m_bullets[x]->getPos(), m_bullets[x]->getVel(), true, (m_bullets[x]->getPos() - m_player.GetPosition()).Length()); - } - else { - Vector3f pos = m_bullets[x]->getPos(), vel = m_bullets[x]->getVel(); - m_audio.Render3DAudioObj(m_whoosh[x], pos, vel, m_sfxvolume); - }*/ } } } m_world.Update(m_bullets, m_player.GetPosition(), m_blockinfo); m_renderer.UpdateMesh(&m_world, m_player.GetPosition(), m_blockinfo); - glDisable(GL_CULL_FACE); - for (Booster booster : booster_table) { - m_renderer.RenderBooster(m_textureAtlas, m_shader01, all, m_player, booster); - } - glEnable(GL_CULL_FACE); if (m_isSkybox) m_renderer.RenderWorld(&m_world, m_renderCount, m_player.GetPosition(), m_player.GetDirection(), all, m_shader01, m_textureAtlas); - //glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - //m_remotePlayer.Render(m_textureAtlas, m_shader01, all, elapsedTime); - m_renderer.RenderWorld(&m_world, m_renderCount, m_player.GetPosition(), m_player.GetDirection(), all, m_shader01, m_textureAtlas); glEnable(GL_BLEND); @@ -1460,10 +1434,6 @@ void Engine::Render(float elapsedTime) { m_player.m_username = user; m_player.InflictDamage(-m_player.GetHP()); } - /*if (m_player.GetPosition().y < -21.f || died) { - died = false; - - }*/ m_time += elapsedTime; @@ -1539,8 +1509,28 @@ void Engine::Render(float elapsedTime) { using enum PACKET_TYPE; case PICKUPMOD: if (Deserialize(&pmod, pck, &bsize)) { - // TODO pikoppe + if (m_boosters.count(pmod.id)) { + Booster* boost = m_boosters.at(pmod.id); + + boost->SetAvailability(pmod.available); + } + else { + BOOST_TYPE btype; + if (pmod.boost.damage) + btype = BOOST_TYPE::BTYPE_DAMAGE; + else if (pmod.boost.hp) + btype = BOOST_TYPE::BTYPE_HEAL; + else if (pmod.boost.invincible) + btype = BOOST_TYPE::BTYPE_INVINCIBLE; + + Booster* boost = new Booster(pmod.pos, btype, pmod.id); + + boost->SetAvailability(pmod.available); + + m_boosters[pmod.id] = boost; + } } + break; case SYNC: if (Deserialize(&sync, pck, &bsize)) { if (sync.sid != m_conn.getId()) { @@ -1639,6 +1629,10 @@ void Engine::Render(float elapsedTime) { glClear(GL_STENCIL_BUFFER_BIT); rt->Render(m_animeAtlas, m_shader01, all, elapsedTime, m_player); } + for (auto& [key, booster] : m_boosters) { + if (booster->GetAvailability()) + m_renderer.RenderBooster(m_textureAtlas, m_shader01, all, m_player, *booster); + } glEnable(GL_CULL_FACE); } else { diff --git a/SQCSim2021/engine.h b/SQCSim2021/engine.h index b16b73d..b00994e 100644 --- a/SQCSim2021/engine.h +++ b/SQCSim2021/engine.h @@ -107,7 +107,6 @@ private: Renderer m_renderer = Renderer(); - Booster booster_table[NB_BOOST]; BlockInfo* m_blockinfo[BTYPE_LAST]; BoostInfo* m_boostinfo[BTYPE_BOOST_LAST]; GameState m_gamestate = GameState::SPLASH; @@ -259,7 +258,7 @@ private: std::set m_deadplayers; netprot::Buffer m_buf, m_bufout; netprot::ChunkMod* m_chunkmod = nullptr; - std::map m_boosters; + std::unordered_map m_boosters; std::unordered_map m_syncs; std::string m_messageNotification = "";