diff --git a/SQCSim-common/SQCSim-common.vcxproj b/SQCSim-common/SQCSim-common.vcxproj index c618082..4ba7bd4 100644 --- a/SQCSim-common/SQCSim-common.vcxproj +++ b/SQCSim-common/SQCSim-common.vcxproj @@ -48,7 +48,7 @@ StaticLibrary false - ClangCL + v143 true Unicode diff --git a/SQCSim-common/bullet.cpp b/SQCSim-common/bullet.cpp index a489c55..a88509e 100644 --- a/SQCSim-common/bullet.cpp +++ b/SQCSim-common/bullet.cpp @@ -3,27 +3,34 @@ Bullet::Bullet(Vector3f pos, Vector3f dir) : m_startpos(pos), m_currentpos(pos), m_velocity(dir) {} -Bullet::Bullet(Vector3f pos, Vector3f dir, uint64_t shooter_id): m_startpos(pos), m_currentpos(pos), m_velocity(dir), m_shooter_id(shooter_id) {} +Bullet::Bullet(Vector3f pos, Vector3f dir, uint64_t shooter_id) : m_startpos(pos), m_currentpos(pos), m_velocity(dir), m_shooter_id(shooter_id) {} + + +Bullet::Bullet(Vector3f pos, Vector3f dir, uint64_t shooter_id, bool canhurt): m_startpos(pos), m_currentpos(pos), m_velocity(dir), m_shooter_id(shooter_id), m_canhurt(canhurt) {} Bullet::~Bullet() {} bool Bullet::Update(World* world, float elapsedtime, int perframe, std::unordered_map mapPlayer, netprot::ChunkMod** chunkmod) { int max = 100 / perframe; - float damage = 0.057f; + float damage = 0.098f; for (int x = 0; x < max; ++x) { m_currentpos += m_velocity * elapsedtime; for (auto& [key, player] : mapPlayer) { + if (key == m_shooter_id) + continue; + bool hit = false; - if ((m_currentpos - player->GetPosition()).Length() < .6f) { + if ((m_currentpos - player->GetPosition()).Length() < 1.5f) { hit = true; } - if ((m_currentpos - player->GetPOV()).Length() < .2f) { + else if ((m_currentpos - player->GetPOV()).Length() < .7f) { damage *= 2; // HEADSHOT! hit = true; } if (hit && !player->AmIDead()) { - player->InflictDamage(damage); + if (m_canhurt) + player->InflictDamage(damage); player->m_hit = true; if (player->AmIDead()) @@ -36,15 +43,17 @@ bool Bullet::Update(World* world, float elapsedtime, int perframe, std::unordere if (!world->ChunkAt(m_currentpos)) return true; else if (world->BlockAt(m_currentpos) != BTYPE_AIR) { - if (chunkmod) { - using namespace netprot; - *chunkmod = new ChunkMod(); - (*chunkmod)->old_b_type = world->BlockAt(m_currentpos); - (*chunkmod)->b_type = BTYPE_AIR; - (*chunkmod)->pos = m_currentpos; - } + if (m_canhurt) { + if (chunkmod) { + using namespace netprot; + *chunkmod = new ChunkMod(); + (*chunkmod)->old_b_type = world->BlockAt(m_currentpos); + (*chunkmod)->b_type = BTYPE_AIR; + (*chunkmod)->pos = m_currentpos; + } - world->ChangeBlockAtPosition(BTYPE_AIR, m_currentpos); + world->ChangeBlockAtPosition(BTYPE_AIR, m_currentpos); + } return true; } else if ((m_currentpos - m_startpos).Length() > VIEW_DISTANCE) return true; diff --git a/SQCSim-common/bullet.h b/SQCSim-common/bullet.h index 3f875d9..252fd70 100644 --- a/SQCSim-common/bullet.h +++ b/SQCSim-common/bullet.h @@ -14,6 +14,7 @@ class Bullet { public: Bullet(Vector3f pos, Vector3f dir); Bullet(Vector3f pos, Vector3f dir, uint64_t tid); + Bullet(Vector3f pos, Vector3f dir, uint64_t tid, bool canhurt); ~Bullet(); bool Update(World* world, float elapsedtime, int perframe, std::unordered_map m_mapPlayer, netprot::ChunkMod** chunkmod); @@ -27,6 +28,8 @@ private: m_currentpos, m_velocity; uint64_t m_shooter_id = 0; + + bool m_canhurt = true; }; diff --git a/SQCSim-common/define.h b/SQCSim-common/define.h index 685bf5d..4ad61c0 100644 --- a/SQCSim-common/define.h +++ b/SQCSim-common/define.h @@ -35,7 +35,10 @@ #define TIME_DAMAGE_BOOST 10 //secondes #define TIME_INVINCIBLE_BOOST 4 //secondes #define STRENGTH_SPEED_BOOST 10 //Pourcentage -#define BULLET_TIME .1 +#define BULLET_TIME .2 //secondes + +#define SYNC_ACC 600 // ms +#define CMOD_ACC 1000 // ms typedef uint8_t BlockType; enum BLOCK_TYPE { BTYPE_AIR, BTYPE_DIRT, BTYPE_GRASS, BTYPE_METAL, BTYPE_ICE, BTYPE_GREENGRASS, BTYPE_LAST }; diff --git a/SQCSim-common/player.cpp b/SQCSim-common/player.cpp index a0ed584..5b322d5 100644 --- a/SQCSim-common/player.cpp +++ b/SQCSim-common/player.cpp @@ -123,35 +123,55 @@ Player::Sound Player::ApplyPhysics(Vector3f input, World* world, float elapsedTi bt1 = world->BlockAt(GetPosition().x + input.x, GetPosition().y, GetPosition().z); bt2 = world->BlockAt(GetPosition().x + input.x, GetPosition().y - 0.9f, GetPosition().z); bt3 = world->BlockAt(GetPosition().x + input.x, GetPosition().y - 1.7f, GetPosition().z); - if (bt1 == BTYPE_AIR && bt2 != BTYPE_AIR && bt3 != BTYPE_AIR) { - if (input.x > 0) - input.x = m_velocity.x = 0.5f; - else - input.x = m_velocity.x = -0.5f; - m_velocity.y = 0.3; - m_velocity.z *= .5f; - } - else if (bt1 != BTYPE_AIR || bt2 != BTYPE_AIR || bt3 != BTYPE_AIR) { - input.x = m_velocity.x = 0; + if (bt1 != BTYPE_AIR || bt2 != BTYPE_AIR || bt3 != BTYPE_AIR) { + //input.x = m_velocity.x = 0; + m_velocity.y += .04f; m_velocity.z *= .5f; + m_velocity.x *= .5f; } bt1 = world->BlockAt(GetPosition().x, GetPosition().y, GetPosition().z + input.z); bt2 = world->BlockAt(GetPosition().x, GetPosition().y - 0.9f, GetPosition().z + input.z); bt3 = world->BlockAt(GetPosition().x, GetPosition().y - 1.7f, GetPosition().z + input.z); - if (bt1 == BTYPE_AIR && bt2 != BTYPE_AIR && bt3 != BTYPE_AIR) { - if (input.z > 0) - input.z = m_velocity.z = 0.5f; - else - input.z = m_velocity.z = -0.5f; - m_velocity.y = 0.3; - m_velocity.x *= .5f; - } - else if (bt1 != BTYPE_AIR || bt2 != BTYPE_AIR || bt3 != BTYPE_AIR) { - input.z = m_velocity.z = 0; + if (bt1 != BTYPE_AIR || bt2 != BTYPE_AIR || bt3 != BTYPE_AIR) { + //input.z = m_velocity.z = 0; + m_velocity.y += .04f; + m_velocity.z *= .5f; m_velocity.x *= .5f; } + //bt1 = world->BlockAt(GetPosition().x + input.x, GetPosition().y, GetPosition().z); + //bt2 = world->BlockAt(GetPosition().x + input.x, GetPosition().y - 0.9f, GetPosition().z); + //bt3 = world->BlockAt(GetPosition().x + input.x, GetPosition().y - 1.7f, GetPosition().z); + //if (bt1 == BTYPE_AIR && bt2 != BTYPE_AIR && bt3 != BTYPE_AIR) { + // if (input.x > 0) + // input.x = m_velocity.x = 0.5f; + // else + // input.x = m_velocity.x = -0.5f; + // m_velocity.y = 0.3; + // m_velocity.z *= .5f; + //} + //else if (bt1 != BTYPE_AIR || bt2 != BTYPE_AIR || bt3 != BTYPE_AIR) { + // input.x = m_velocity.x = 0; + // m_velocity.z *= .5f; + //} + + //bt1 = world->BlockAt(GetPosition().x, GetPosition().y, GetPosition().z + input.z); + //bt2 = world->BlockAt(GetPosition().x, GetPosition().y - 0.9f, GetPosition().z + input.z); + //bt3 = world->BlockAt(GetPosition().x, GetPosition().y - 1.7f, GetPosition().z + input.z); + //if (bt1 == BTYPE_AIR && bt2 != BTYPE_AIR && bt3 != BTYPE_AIR) { + // if (input.z > 0) + // input.z = m_velocity.z = 0.5f; + // else + // input.z = m_velocity.z = -0.5f; + // m_velocity.y = 0.3; + // m_velocity.x *= .5f; + //} + //else if (bt1 != BTYPE_AIR || bt2 != BTYPE_AIR || bt3 != BTYPE_AIR) { + // input.z = m_velocity.z = 0; + // m_velocity.x *= .5f; + //} + /* Fin gestion de collisions */ /* Gestion de la friction */ @@ -205,11 +225,7 @@ Player::Sound Player::ApplyPhysics(Vector3f input, World* world, float elapsedTi void Player::ApplyTransformation(Transformation& transformation, bool rel, bool rot) const { transformation.ApplyRotation(-m_rotX, 1, 0, 0); transformation.ApplyRotation(-m_rotY, 0, 1, 0); - - if (rel) transformation.ApplyTranslation(-GetPOV()); - - } void Player::GetBooster(Booster boosttype) @@ -285,6 +301,10 @@ void Player::SetSensitivity(float sensitivity) { float Player::GetHP() const { return m_hp; } +void Player::SetHP(float hp) { + m_hp = hp; +} + void Player::Teleport(int& x, int& z) { m_position.x -= x * CHUNK_SIZE_X; m_position.z -= z * CHUNK_SIZE_Z; @@ -298,9 +318,6 @@ void Player::InflictDamage(float hitPoints) { if (m_hp < 0) m_hp == 0; - //if (AmIDead()) - //{ // Quand le joueur est mort. - //} } int Player::getScore() const { return m_score; } diff --git a/SQCSim-common/player.h b/SQCSim-common/player.h index 8a91cb5..3a52e92 100644 --- a/SQCSim-common/player.h +++ b/SQCSim-common/player.h @@ -36,6 +36,7 @@ public: float GetSensitivity() const; void SetSensitivity(float sensitivity); float GetHP() const; + void SetHP(float hp); void Teleport(int& x, int& z); bool GetIsAirborne() const; @@ -47,6 +48,8 @@ public: std::string m_username; bool m_hit = false; + bool Eulogy = false; + private: uint64_t getId() const; diff --git a/SQCSim-common/world.cpp b/SQCSim-common/world.cpp index 2791ca1..039bd6b 100644 --- a/SQCSim-common/world.cpp +++ b/SQCSim-common/world.cpp @@ -49,8 +49,6 @@ void World::RemoveChunk(int nbReduit) if (x > WORLD_SIZE_X - nbReduit) chk = m_chunks.Remove(x, y); - // TODO: MakeDirty() les voisins pour qu'ils se redessinent. - if (!chk) continue; @@ -167,7 +165,6 @@ void World::GetScope(unsigned int& x, unsigned int& y) { void World::Update(Bullet* bullets[MAX_BULLETS], const Vector3f& player_pos, BlockInfo* blockinfo[BTYPE_LAST]) { UpdateWorld(player_pos, blockinfo); - //TransposeWorld(player_pos, bullets); } netprot::ChunkMod* World::ChangeBlockAtCursor(BlockType blockType, const Vector3f& player_pos, const Vector3f& player_dir, bool& block, bool net) { @@ -258,7 +255,6 @@ void World::UpdateWorld(const Vector3f& player, BlockInfo* blockinfo[BTYPE_LAST] int side = 0; int threads = 0; std::future genThList[THREADS_GENERATE_CHUNKS]; - //std::future delThList[THREADS_DELETE_CHUNKS]; if (frameGenerate > 0) --frameGenerate; if (frameUpdate > 0) --frameUpdate; @@ -349,101 +345,6 @@ void World::UpdateWorld(const Vector3f& player, BlockInfo* blockinfo[BTYPE_LAST] side = 0; threads = 0; - - //if (!frameUpdate) - // while (side * CHUNK_SIZE_X <= VIEW_DISTANCE * 2) { - // int tx = -side, ty = -side; - - // for (; tx <= side; ++tx) { - // if (frameUpdate) - // break; - // unsigned int chx = cx + tx * CHUNK_SIZE_X, chy = cy + ty * CHUNK_SIZE_Z; - // if (ChunkAt(chx, 1, chy) && - // ChunkAt(chx, 1, chy)->IsDirty()) { - // updateThList[threads++] = - // std::async(std::launch::async, - // [](Chunk* chunk, BlockInfo* blockinfo[BTYPE_LAST], World* world) { - // chunk->Update(blockinfo, world); return chunk; }, ChunkAt(chx, 1, chy), blockinfo, this); - // if (threads == THREADS_UPDATE_CHUNKS) frameUpdate = FRAMES_UPDATE_CHUNKS; - // } - // } - // for (; ty <= side; ++ty) { - // if (frameUpdate) - // break; - // unsigned int chx = cx + tx * CHUNK_SIZE_X, chy = cy + ty * CHUNK_SIZE_Z; - // if (ChunkAt(chx, 1, chy) && - // ChunkAt(chx, 1, chy)->IsDirty()) { - // updateThList[threads++] = - // std::async(std::launch::async, - // [](Chunk* chunk, BlockInfo* blockinfo[BTYPE_LAST], World* world) { - // chunk->Update(blockinfo, world); return chunk; }, ChunkAt(chx, 1, chy), blockinfo, this); - // if (threads == THREADS_UPDATE_CHUNKS) frameUpdate = FRAMES_UPDATE_CHUNKS; - // } - // } - // for (; tx >= -side; --tx) { - // if (frameUpdate) - // break; - // unsigned int chx = cx + tx * CHUNK_SIZE_X, chy = cy + ty * CHUNK_SIZE_Z; - // if (ChunkAt(chx, 1, chy) && - // ChunkAt(chx, 1, chy)->IsDirty()) { - // updateThList[threads++] = - // std::async(std::launch::async, - // [](Chunk* chunk, BlockInfo* blockinfo[BTYPE_LAST], World* world) { - // chunk->Update(blockinfo, world); return chunk; }, ChunkAt(chx, 1, chy), blockinfo, this); - // if (threads == THREADS_UPDATE_CHUNKS) frameUpdate = FRAMES_UPDATE_CHUNKS; - // } - // } - // for (; ty >= -side; --ty) { - // if (frameUpdate) - // break; - // unsigned int chx = cx + tx * CHUNK_SIZE_X, chy = cy + ty * CHUNK_SIZE_Z; - // if (ChunkAt(chx, 1, chy) && - // ChunkAt(chx, 1, chy)->IsDirty()) { - // updateThList[threads++] = - // std::async(std::launch::async, - // [](Chunk* chunk, BlockInfo* blockinfo[BTYPE_LAST], World* world) { - // chunk->Update(blockinfo, world); return chunk; }, ChunkAt(chx, 1, chy), blockinfo, this); - // if (threads == THREADS_UPDATE_CHUNKS) frameUpdate = FRAMES_UPDATE_CHUNKS; - // } - // } - // if (frameUpdate) - // break; - // ++side; - // } - - //if (threads > 0) { - // for (int i = 0; i < threads; ++i) { - // updateThList[i].wait(); - // Chunk* chunk = updateThList[i].get(); - // chunk->FlushMeshToVBO(); - // } - //} - - threads = 0; - - //int del = THREADS_DELETE_CHUNKS; - //while (!m_tbDeleted.empty() && del--) { // Moins rapide que le bout en dessous, mais -beaucoup- plus stable. - // m_tbDeleted.back()->FlushVBO(); - // m_tbDeleted.back()->~Chunk(); - // m_tbDeleted.pop_back(); - //} - - /*while (!m_tbDeleted.empty() && !frameDelete) { - if (m_tbDeleted.back()) { - m_tbDeleted.back()->FlushVBO(); - delThList[threads] = - std::async(std::launch::async, - [](Chunk* chunk) { delete chunk; }, m_tbDeleted.back()); - m_tbDeleted.pop_back(); - if (++threads > THREADS_DELETE_CHUNKS) frameDelete = FRAMES_DELETE_CHUNKS; - } - else m_tbDeleted.pop_back(); - }*/ - - /*for (int x = 0; x < threads; ++x) { - delThList[x].wait(); - delThList[x].get(); - }*/ } int World::GettbDeleted() const { return m_tbDeleted.size(); } diff --git a/SQCSim-srv/SQCSim-srv.vcxproj b/SQCSim-srv/SQCSim-srv.vcxproj index b0dcd9c..d080276 100644 --- a/SQCSim-srv/SQCSim-srv.vcxproj +++ b/SQCSim-srv/SQCSim-srv.vcxproj @@ -48,7 +48,7 @@ Application false - ClangCL + v143 true Unicode diff --git a/SQCSim-srv/connection.cpp b/SQCSim-srv/connection.cpp index 669ae8f..19469ad 100644 --- a/SQCSim-srv/connection.cpp +++ b/SQCSim-srv/connection.cpp @@ -59,7 +59,9 @@ void Connection::getPacks(SOCKET sock) { switch (netprot::getType(pck, 1)) { using enum netprot::PACKET_TYPE; case INPUT: - if (Deserialize(&in, pck, &bsize)) { + if (player->AmIDead()) + break; + else if (Deserialize(&in, pck, &bsize)) { m_input_manifest[in.timestamp] = in; m_input_vector.push_back(in); } @@ -77,8 +79,23 @@ void Connection::getPacks(SOCKET sock) { void Connection::sendPacks(SOCKET sock, std::unordered_map conns, const uint32_t timer) { static int outs = 0; static Timestamp last = 0; + static uint32_t lasttimer = timer; + + if (m_output_vector.empty() && player->AmIDead()) { + if (timer != lasttimer) { + lasttimer = timer; + Sync sync; + sync.timestamp = sync.sid = m_loginfo.sid; + sync.hp = 0; + sync.ammo = -1; + sync.timer = timer; + sendPackTo(sock, &sync, &m_bufout, &m_addr); + } + } + while (!m_output_vector.empty()) { Output out = m_output_vector.front(); + for (auto& [key, conn] : conns) { if (m_playinfo.id == conn->GetHash(false)) continue; @@ -91,16 +108,23 @@ void Connection::sendPacks(SOCKET sock, std::unordered_map= 1000) { - outs -= 1000; + static bool syncdead = false; + bool dead = player->AmIDead(); + + if (outs >= SYNC_ACC || (!syncdead && dead)) { Sync sync; - sync.hp = player->GetHP(); + outs -= SYNC_ACC; sync.timestamp = out.timestamp; sync.position = out.position; sync.sid = m_loginfo.sid; sync.timer = timer; sync.timestamp = out.timestamp; sync.ammo = -1; + sync.hp = player->GetHP(); + if (dead) { + sync.timestamp = m_loginfo.sid; + syncdead = true; + } sendPackTo(sock, &sync, &m_bufout, &m_addr); } @@ -114,27 +138,33 @@ Timestamp Connection::Run(World* world) { Timestamp tstamp = 0; float el; - if (m_input_manifest.size() < 2) + bool dead = player->AmIDead(); + + if (m_input_manifest.size() < 2 && !dead) return tstamp; - if (player->AmIDead()) { - m_input_manifest.clear(); - return tstamp; - } - - while (m_last_in < m_input_vector.size() - 1) { - in = m_input_vector.at(m_last_in + 1); - last = m_input_vector.at(m_last_in); - - el = (double)(in.timestamp - last.timestamp) / 1000.; - - if (m_shoot_acc > 0.) { - m_shoot_acc -= el; - if (m_shoot_acc < 0.) - m_shoot_acc = 0; + while (m_last_in < m_input_vector.size() - 1 || dead) { + if (!dead) { + in = m_input_vector.at(m_last_in + 1); + last = m_input_vector.at(m_last_in); + if (in.timestamp <= m_tstamp) { + ++m_last_in; + continue; + } + el = (double)(in.timestamp - last.timestamp) / 1000.; + if (m_shoot_acc > 0.) { + m_shoot_acc -= el; + if (m_shoot_acc < 0.) + m_shoot_acc = 0.; + } + player->SetDirection(in.direction); } - - player->SetDirection(in.direction); + else { + el = 1. / 60.; + in = Input(); + + } + player->ApplyPhysics(player->GetInput(in.keys.forward, in.keys.backward, in.keys.left, @@ -147,7 +177,10 @@ Timestamp Connection::Run(World* world) { } out.states.jumping = player->GetIsAirborne(); - out.states.running = player->GetVelocity().Length() > .5f; + + Vector3f horSpeed = player->GetVelocity(); + horSpeed.y = 0; + out.states.running = horSpeed.Length() > .2f; out.states.still = !out.states.running && !out.states.jumping; out.states.hit = player->m_hit; player->m_hit = false; @@ -180,7 +213,7 @@ Timestamp Connection::Run(World* world) { else out.states.jumpshot = false; if (in.keys.shoot && m_shoot_acc <= 0.) { - Bullets.push_back(std::move(new Bullet(player->GetPOV() + player->GetDirection(), player->GetDirection(), GetHash(true)))); + Bullets.emplace_back(new Bullet(player->GetPOV() + player->GetDirection(), player->GetDirection(), GetHash(true))); m_shoot_acc = BULLET_TIME; } @@ -190,9 +223,12 @@ Timestamp Connection::Run(World* world) { out.id = m_playinfo.id; m_output_manifest[out.timestamp] = out; m_output_vector.push_back(out); - tstamp = out.timestamp; + m_tstamp = tstamp = out.timestamp; - ++m_last_in; + if (!dead) + ++m_last_in; + + dead = false; } return tstamp; diff --git a/SQCSim-srv/server.cpp b/SQCSim-srv/server.cpp index edf740c..09ad867 100644 --- a/SQCSim-srv/server.cpp +++ b/SQCSim-srv/server.cpp @@ -202,8 +202,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)) / 8, - y = (rand() % (CHUNK_SIZE_Y * WORLD_SIZE_Y - 1) - (CHUNK_SIZE_Y * WORLD_SIZE_Y / 2)) / 8; + 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; 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; @@ -217,7 +217,7 @@ void Server::Run() { sendPackTo(m_sock_udp, &sync, &m_buf, conn->getAddr()); } - int timer = m_game.countdown, sync_acc = 0, deadplayers = 0; + int timer = m_game.countdown, timer_acc = 0, deadplayers = 0; std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now(); Timestamp last = 0; std::vector chatlog; @@ -230,22 +230,23 @@ void Server::Run() { Chat* startchat = new Chat(); startchat->src_id = 0; char startmess[] = "How would -YOU- like to die today, motherf-words?"; - + float endtime = 0.; strcpy(startchat->mess, 140, startmess); chatlog.emplace_back(startchat); - while (!endgame) { + while (!endgame && endtime < 1.) { using namespace std::chrono; Timestamp tstamp = duration_cast(high_resolution_clock::now() - start).count(); if (last == 0) last = tstamp; - sync_acc += tstamp - last; - if (sync_acc >= 1000) { - while (sync_acc >= 1000) - sync_acc -= 1000; - --timer; + timer_acc += tstamp - last; + if (timer_acc >= 1000) { + while (timer_acc >= 1000) + timer_acc -= 1000; + if (!endgame) + --timer; std::string str = "Timer: "; Log(str.append(std::to_string(timer)), false, false); } @@ -275,34 +276,43 @@ void Server::Run() { default: break; } } - lsPck.clear(); + if (!lsPck.empty()) + lsPck.clear(); /* Process */ if (conn->m_nsync) { + Timestamp tstamp = conn->Run(m_world); - if (conn->player->AmIDead()) { + if (conn->player->AmIDead() && !conn->player->Eulogy) { Chat* chat = new Chat(); - chat->dest_id = chat->dest_team_id = chat->src_id = 0; + chat->dest_id = chat->dest_team_id = chat->src_id = 0; - std::string killer = m_conns.at(conn->player->Killer)->player->GetUsername(); + Player* murderer = m_conns.at(conn->player->Killer)->player; + + if (murderer != conn->player) + murderer->addPoint(); + + std::string killer = murderer->GetUsername(); std::string mess = getDeathMessage(conn->player->GetUsername(), killer); strcpy(chat->mess, 140, mess.c_str()); chatlog.emplace_back(chat); ++deadplayers; + + conn->player->Eulogy = true; conn->m_nsync = false; } else { for (auto& chmo : conn->ChunkDiffs) chunkdiffs.emplace_back(std::move(chmo)); - conn->ChunkDiffs.clear(); + if (!conn->ChunkDiffs.empty()) + conn->ChunkDiffs.clear(); for (auto& bull : conn->Bullets) { bullets.emplace_back(bull); - //Log("POW!", false, false); BulletAdd* nbul = new BulletAdd(); nbul->pos = bull->getPos(); nbul->dir = bull->getVel(); @@ -311,53 +321,95 @@ void Server::Run() { netbull.emplace_back(std::move(nbul)); } - conn->Bullets.clear(); + if (!conn->Bullets.empty()) + conn->Bullets.clear(); } - - /* Out */ - - conn->sendPacks(m_sock_udp, m_conns, timer); } - if ((deadplayers == players - 1 && deadplayers != 0) || timer <= 0) + /* Out */ + conn->sendPacks(m_sock_udp, m_conns, timer); + + if ((deadplayers == players - 1 && deadplayers != 0) || timer < 0) { + if (!endgame) { + Chat* gameover = new Chat(); + gameover->dest_id = gameover->dest_team_id = gameover->src_id = 0; + std::string winner, winmess; + int score = 0; + bool plural = false; + for (auto& [key, conn] : m_conns) { + if (conn->player->getScore() > score) { + winner = conn->player->GetUsername(); + score = conn->player->getScore(); + plural = false; + } + else if (conn->player->getScore() == score) { + winner = winner.append(" and ").append(conn->player->GetUsername()); + plural = true; + } + } + + winmess = "And the winner"; + if (!plural) + winmess = winmess.append(" is "); + else winmess = winmess.append("s are "); + + winmess = winmess.append(winner).append(" with ").append(std::to_string(score)).append(" point"); + + if (score > 1) + winmess = winmess.append("s."); + else winmess = winmess.append("."); + + strcpy(gameover->mess, 140, winmess.c_str()); + + chatlog.emplace_back(gameover); + } endgame = true; + endtime += .001; + } } - + for (auto& bull : netbull) { for (auto& [key, conn] : m_conns) if (bull->id != conn->GetHash(false)) // Pour pas repitcher au joueur sa propre balle. sendPackTo(m_sock_udp, bull, &m_buf, conn->getAddr()); delete bull; } - netbull.clear(); - + if (!netbull.empty()) + netbull.clear(); + for (auto bull = bullets.begin(); bull != bullets.end(); ++bull) { ChunkMod* cmod = nullptr; Bullet* bullet = *bull; - if (bullet->Update(m_world, (1. / 60.), 20, m_players, &cmod)) { + if (bullet->Update(m_world, (1. / 60.), 50, m_players, &cmod)) { if (cmod) chunkdiffs.emplace_back(cmod); bullit.push_back(bull); - delete bullet; } } - for (auto& bull: bullit) + + for (auto& bull : bullit) { + delete* bull; bullets.erase(bull); - bullit.clear(); + } + + if (!bullit.empty()) + bullit.clear(); for (auto& chat : chatlog) { - Log(chat->mess, false, false); + Log(chat->mess, false, false); for (auto& [key, conn] : m_conns) sendPackTo(m_sock_udp, chat, &m_buf, conn->getAddr()); delete chat; } - chatlog.clear(); + if (!chatlog.empty()) + chatlog.clear(); for (auto& chmo : chunkdiffs) { for (auto& [key, conn] : m_conns) sendPackTo(m_sock_udp, chmo, &m_buf, conn->getAddr()); delete chmo; } - chunkdiffs.clear(); + if (!chunkdiffs.empty()) + chunkdiffs.clear(); } Chat end; @@ -367,8 +419,7 @@ void Server::Run() { for (auto& [key, conn] : m_conns) { std::string str = conn->player->GetUsername(); - Log(str.append(" ").append(std::to_string(conn->player->GetHP())), false, false); - + Log(str.append(" ").append(std::to_string(conn->player->getScore())), false, false); } for (auto& [key, conn] : m_conns) diff --git a/SQCSim2021/SQCSim2021.vcxproj b/SQCSim2021/SQCSim2021.vcxproj index 7d14bc6..661f995 100644 --- a/SQCSim2021/SQCSim2021.vcxproj +++ b/SQCSim2021/SQCSim2021.vcxproj @@ -91,7 +91,7 @@ false true Unicode - ClangCL + v143 diff --git a/SQCSim2021/engine.cpp b/SQCSim2021/engine.cpp index 5461f80..4de61f3 100644 --- a/SQCSim2021/engine.cpp +++ b/SQCSim2021/engine.cpp @@ -384,7 +384,7 @@ void Engine::DisplayHud(int timer) { // HP Bar float playerHp = m_player.GetHP(); if (playerHp < 0.) - playerHp == 0; + playerHp = 0; float facteurOmbrage = m_displayInfo ? 0.5f : 1.0f; float hpBarWidthProportion = 0.25f; @@ -618,11 +618,12 @@ bool Engine::StartMultiplayerGame() { m_player = Player(m_conn.getOrigin().position); for (auto& [key, player] : m_conn.m_players) - m_players[key] = new RemotePlayer(player); + m_players[key] = new RemotePlayer(&player); //m_world.SetSeed(m_conn.getSeed()); m_world.SetSeed(9370707); m_networkgame = true; + m_player.m_username = m_username; } else { std::cout << "Erreur de connexion." << std::endl; @@ -633,6 +634,7 @@ bool Engine::StartMultiplayerGame() { std::cout << "Erreur de creation de socket." << std::endl; ok = false; } + m_world.BuildWorld(); return ok; } @@ -677,7 +679,8 @@ void Engine::DisplayInfo(float elapsedTime, BlockType bloc) { ss.str(""); fPosY -= charSize; - ss << " Remote Position : " << m_otherplayerpos; + Vector3f pos = Vector3f(m_otherplayerpos.x + CHUNK_SIZE_X * WORLD_SIZE_X / 2, m_otherplayerpos.y, m_otherplayerpos.z + CHUNK_SIZE_Z * WORLD_SIZE_Y / 2); + ss << " Remote Position : " << pos; PrintText(fPosX, fPosY, ss.str()); ss.str(""); fPosY -= charSize; @@ -1409,19 +1412,19 @@ void Engine::Render(float elapsedTime) { m_chunkmod = nullptr; } m_bullets[x] = nullptr; - if (m_whoosh[x]){ + /*if (m_whoosh[x]){ m_whoosh[x]->drop(); m_whoosh[x] = nullptr; - } + }*/ break; } - else if (!m_whoosh[x]) { + /*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); - } + }*/ } } } @@ -1442,14 +1445,15 @@ void Engine::Render(float elapsedTime) { if ((m_player.GetPosition().y < -1.7f || m_player.AmIDead()) && !died) { m_audio.Create3DAudioObj(m_scream, AUDIO_PATH "scream.wav", m_player.GetPOV(), m_player.GetVelocity(), false, m_sfxvolume); died = true; - } - if (m_player.GetPosition().y < -21.f || died) { - died = false; std::string user = m_player.m_username.append(" (Dead)"); m_player = Player(Vector3f(.5, CHUNK_SIZE_Y + 1.7f, .5), 0, 0); m_player.m_username = user; m_player.InflictDamage(-m_player.GetHP()); } + /*if (m_player.GetPosition().y < -21.f || died) { + died = false; + + }*/ m_time += elapsedTime; @@ -1475,8 +1479,8 @@ void Engine::Render(float elapsedTime) { cmod_acc += tstamp - last; last = tstamp; - if (sync_acc >= 1000) { - sync_acc -= 1000; + if (sync_acc >= SYNC_ACC) { + sync_acc -= SYNC_ACC; sync.sid = id; sync.timestamp = tstamp; sync.position = m_player.GetPositionAbs(); @@ -1488,9 +1492,9 @@ void Engine::Render(float elapsedTime) { m_syncs[sync.timestamp] = sync; } - if (cmod_acc >= 3000) { - while (cmod_acc >= 3000) - cmod_acc -= 3000; + if (cmod_acc >= CMOD_ACC) { + while (cmod_acc >= CMOD_ACC) + cmod_acc -= CMOD_ACC; if (!m_chunkmod_manifest.empty()) { ChunkMod* cmod = m_chunkmod_manifest.front(); m_chunkmod_manifest.pop_front(); @@ -1529,12 +1533,14 @@ void Engine::Render(float elapsedTime) { SystemNotification("syncsid be no good."); break; } + if (sync.timestamp == m_conn.getId()) { + m_player.SetHP(sync.hp); + } if (m_syncs.count(sync.timestamp)) { Sync comp = m_syncs[sync.timestamp]; - - std::cout << sync.hp << std::endl; - - m_player.InflictDamage(sync.hp - comp.hp); + m_otherplayerpos = sync.position; + + m_player.SetHP(sync.hp); Vector3f diff = sync.position - comp.position; @@ -1560,8 +1566,9 @@ void Engine::Render(float elapsedTime) { } RemotePlayer* rt = static_cast(m_players[out.id]); rt->Feed(out); - if (rt->AmIDead()) { + if (rt->AmIDead() && !m_deadplayers.count(out.id)) { m_audio.Create3DAudioObj(m_scream, AUDIO_PATH "scream.wav", m_player.GetPOV(), m_player.GetVelocity(), false, m_sfxvolume); + m_deadplayers.insert(out.id); } } break; @@ -1580,7 +1587,7 @@ void Engine::Render(float elapsedTime) { break; case BULLET: if (Deserialize(&bull, pck, &bsize)) { - Bullet* bult = new Bullet(bull.pos, bull.dir); + Bullet* bult = new Bullet(bull.pos, bull.dir, bull.id, false); for (int x = 0; x < MAX_BULLETS; ++x) // Ajouter une balle dans l'array (aussi connu sous le nom de "faire pow pow"). if (!m_bullets[x]) { m_bullets[x] = bult; @@ -2411,6 +2418,12 @@ void Engine::MousePressEvent(const MOUSE_BUTTON& button, int x, int y) { m_singleReady = false; m_multiReady = false; m_audio.ToggleMusicState(m_gamestate); + if (m_networkgame) { + if (m_conn.m_sock_udp) + closesocket(m_conn.m_sock_udp); + if (m_conn.m_sock_udp) + closesocket(m_conn.m_sock_udp); + } } } else if (m_gamestate == GameState::LOBBY) { diff --git a/SQCSim2021/engine.h b/SQCSim2021/engine.h index 1a1303a..cd3ee36 100644 --- a/SQCSim2021/engine.h +++ b/SQCSim2021/engine.h @@ -249,6 +249,7 @@ private: std::deque m_chunkmod_manifest; std::chrono::high_resolution_clock::time_point m_startTime; std::unordered_map m_players; + std::set m_deadplayers; netprot::Buffer m_buf, m_bufout; netprot::ChunkMod* m_chunkmod = nullptr; diff --git a/SQCSim2021/remoteplayer.cpp b/SQCSim2021/remoteplayer.cpp index 47bd809..3a47218 100644 --- a/SQCSim2021/remoteplayer.cpp +++ b/SQCSim2021/remoteplayer.cpp @@ -8,11 +8,11 @@ -RemotePlayer::RemotePlayer(netprot::PlayerInfo pinfo) : m_pinfo(pinfo), m_aminacc(0.0f), m_animstate(Anim::STILL), m_team_id(0), current(), previous(), m_texture_front(), Player(Vector3f(0, 0, 0)){ +RemotePlayer::RemotePlayer(netprot::PlayerInfo* pinfo) : m_pinfo(*pinfo), m_aminacc(0.0f), m_animstate(Anim::STILL), m_team_id(0), current(), previous(), m_texture_front(), Player(Vector3f(0, 0, 0)) { } -RemotePlayer::RemotePlayer(netprot::PlayerInfo pinfo, const Vector3f& pos) : m_pinfo(pinfo), m_aminacc(0.0f), m_animstate(Anim::STILL), m_team_id(0), current(), previous(), m_texture_front(), Player(pos) { +RemotePlayer::RemotePlayer(netprot::PlayerInfo* pinfo, const Vector3f& pos) : m_pinfo(*pinfo), m_aminacc(0.0f), m_animstate(Anim::STILL), m_team_id(0), current(), previous(), m_texture_front(), Player(pos) { } @@ -24,61 +24,16 @@ RemotePlayer::~RemotePlayer() void RemotePlayer::Init() { - + } void RemotePlayer::Feed(const netprot::Output out) { m_position = Vector3f(out.position); m_direction = Vector3f(out.direction); - current.states = out.states; + - //current.position = out.position; - //current.direction = out.direction; - //current.states = out.states; - //current.id = out.id; - - //if (current.position != previous.position) - //{ - // Vector3f positionDelta = current.position - previous.position; - // m_position = current.position + positionDelta; - // m_direction = current.direction; - - //} - - //if(current.direction != previous.direction) - //{ - // m_direction = current.direction; - // current.direction = current.direction; - //} - - //if (current.states.shooting) { - // m_animstate = Anim::SHOOTING; - //} - //else if (current.states.jumping) { - // m_animstate = Anim::JUMPING; - //} - //else if (current.states.dead) { - // m_animstate = Anim::DEAD; - //} - //else if(current.states.powerup){ - // m_animstate = Anim::POWERUP; - //} - //else if (current.states.still) { - // m_animstate = Anim::STILL; - //} - //else if (current.states.running) { - // m_animstate = Anim::RUNNING; - //} - - //previous.direction = current.direction; - //previous.position = current.position; - //previous.states = current.states; - //previous.id = current.id; - - //m_direction = current.direction; - //m_position = current.position; } @@ -108,7 +63,7 @@ void RemotePlayer::Render(TextureAtlas& atlas, Shader& shader, Transformation tr Vector3f angleRemote = GetDirection(); Vector3f angleCam = (v1 - v2).Cross(v3 - v2); - + angleCam.y = 0; angleRemote.y = 0; angleCam.Normalize(); @@ -118,26 +73,25 @@ void RemotePlayer::Render(TextureAtlas& atlas, Shader& shader, Transformation tr int index = 0; angle = -angle; Vector3f side = angleRemote.Cross(angleCam); + side = -side; static float time = 0.f; static bool Shooting = false; bool isLeft = side.y > 0; time += elapsedTime; - if (time >= 200) + if (time >= 0.05) { - time -= 200; - if (!current.states.shooting) - Shooting = false; - else - Shooting = !Shooting; + time -= 0.05; + + Shooting = !Shooting; } - - + + //std::cout << "shooting : " << current.states.shooting << " jumping : " << current.states.jumping << " jumpshot : " << current.states.jumpshot << " running : " << current.states.running << " still : " << current.states.still << " dead : " << current.states.dead << " hit : " << current.states.hit << std::endl; if (angle >= 0.75) //Face - side positif { - if(current.states.shooting){ + if (current.states.shooting) { if (Shooting) index = 17; else @@ -151,7 +105,7 @@ void RemotePlayer::Render(TextureAtlas& atlas, Shader& shader, Transformation tr } else if (current.states.jumping) index = 25; - else if (current.states.running && current.states.still) + else if (!current.states.jumping && !current.states.shooting && !current.states.jumpshot) index = 0; } @@ -162,6 +116,7 @@ void RemotePlayer::Render(TextureAtlas& atlas, Shader& shader, Transformation tr index = 18; else index = 10; + } else if (current.states.jumpshot) { if (Shooting) @@ -169,11 +124,12 @@ void RemotePlayer::Render(TextureAtlas& atlas, Shader& shader, Transformation tr else index = 34; } - else if (current.states.jumping ) + else if (current.states.jumping) index = 26; - else if (current.states.running && current.states.still) + else if (!current.states.jumping && !current.states.shooting && !current.states.jumpshot) index = 1; - + + } else if (angle >= -0.25 && isLeft) //ProfileLeft { @@ -182,18 +138,20 @@ void RemotePlayer::Render(TextureAtlas& atlas, Shader& shader, Transformation tr index = 20; else index = 12; + } - else if (current.states.jumpshot ) { + else if (current.states.jumpshot) { if (Shooting) index = 44; else index = 36; } - else if (current.states.jumping ) + else if (current.states.jumping) index = 28; - else if (current.states.running && current.states.still) + else if (!current.states.jumping && !current.states.shooting && !current.states.jumpshot) index = 3; - + + } else if (angle >= -0.75 && isLeft) //BackLeft { @@ -202,6 +160,7 @@ void RemotePlayer::Render(TextureAtlas& atlas, Shader& shader, Transformation tr index = 22; else index = 14; + } else if (current.states.jumpshot) { if (Shooting) @@ -211,8 +170,10 @@ void RemotePlayer::Render(TextureAtlas& atlas, Shader& shader, Transformation tr } else if (current.states.jumping) index = 30; - else if (current.states.running && current.states.still) + else if (!current.states.jumping && !current.states.shooting && !current.states.jumpshot) index = 5; + + } else if (angle < -0.75) //Dos - side négatif { @@ -221,6 +182,7 @@ void RemotePlayer::Render(TextureAtlas& atlas, Shader& shader, Transformation tr index = 24; else index = 16; + } else if (current.states.jumpshot) { if (Shooting) @@ -228,13 +190,14 @@ void RemotePlayer::Render(TextureAtlas& atlas, Shader& shader, Transformation tr else index = 40; } - else if (current.states.jumping ) + else if (current.states.jumping) index = 32; - else if (current.states.running && current.states.still) + else if (!current.states.jumping && !current.states.shooting && !current.states.jumpshot) index = 7; - + + } - else if (angle >= 0.25 && !isLeft) //FrontRight + else if (angle >= 0.25 && !isLeft) //FrontRight //REVOIR L'ANIME DE SHOOTING EST PAS DRETTE { if (current.states.shooting) { if (Shooting) @@ -250,9 +213,10 @@ void RemotePlayer::Render(TextureAtlas& atlas, Shader& shader, Transformation tr } else if (current.states.jumping) index = 27; - else if (current.states.running && current.states.still) + else if (!current.states.jumping && !current.states.shooting && !current.states.jumpshot) index = 2; + } else if (angle >= -0.25 && !isLeft) //ProfileRight { @@ -270,9 +234,10 @@ void RemotePlayer::Render(TextureAtlas& atlas, Shader& shader, Transformation tr } else if (current.states.jumping) index = 29; - else if (current.states.running && current.states.still) + else if (!current.states.jumping && !current.states.shooting && !current.states.jumpshot) index = 4; + } else if (angle >= -0.75 && !isLeft) //BackRight { @@ -281,6 +246,7 @@ void RemotePlayer::Render(TextureAtlas& atlas, Shader& shader, Transformation tr index = 23; else index = 15; + } else if (current.states.jumpshot) { if (Shooting) @@ -290,11 +256,12 @@ void RemotePlayer::Render(TextureAtlas& atlas, Shader& shader, Transformation tr } else if (current.states.jumping) index = 31; - else if (current.states.running && current.states.still) + else if (!current.states.jumping && !current.states.shooting && !current.states.jumpshot) index = 6; + } - + float u, v, w, h; @@ -304,10 +271,25 @@ void RemotePlayer::Render(TextureAtlas& atlas, Shader& shader, Transformation tr atlas.TextureIndexToCoord(index, u, v, w, h); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + + if (current.states.hit) + { + glBlendFunc(GL_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR); + glBlendColor(1.f, 0.f, 0.f, 1.f); + + } + else { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + glBlendEquation(GL_FUNC_ADD); + + + glLoadMatrixf(tran.GetMatrix().GetInternalValues()); + glDepthFunc(GL_LEQUAL); glBegin(GL_QUADS); glTexCoord2f(u, v); glVertex3f(v1.x, v1.y, v1.z); glTexCoord2f(u + w, v); glVertex3f(v2.x, v2.y, v2.z); diff --git a/SQCSim2021/remoteplayer.h b/SQCSim2021/remoteplayer.h index fcd5626..238360b 100644 --- a/SQCSim2021/remoteplayer.h +++ b/SQCSim2021/remoteplayer.h @@ -14,8 +14,8 @@ class RemotePlayer : public Player { public: enum Anim: uint8_t { STILL = 1, RUNNING = 2, JUMPING = 4, SHOOTING = 8, POWERUP = 16, DEAD = 32 }; // A REVOIR VOIR DEFINE.H POUR LES ANIMES - RemotePlayer(netprot::PlayerInfo pinfo); - RemotePlayer(netprot::PlayerInfo pinfo, const Vector3f& pos); + RemotePlayer(netprot::PlayerInfo* pinfo); + RemotePlayer(netprot::PlayerInfo* pinfo, const Vector3f& pos); ~RemotePlayer();