From 1267b308062a7b4b3a6d558f3023ab59176bc67d Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Thu, 14 Apr 2016 04:45:30 +1000 Subject: [PATCH] Creatures are replaced with barriers --- server/combat/barrier_manager.cpp | 48 +++++++++++++++-- server/combat/barrier_manager.hpp | 10 +++- server/creatures/creature_manager.cpp | 6 +-- server/rooms/room_data.cpp | 75 ++++++++++----------------- 4 files changed, 84 insertions(+), 55 deletions(-) diff --git a/server/combat/barrier_manager.cpp b/server/combat/barrier_manager.cpp index a174459..040ec7f 100644 --- a/server/combat/barrier_manager.cpp +++ b/server/combat/barrier_manager.cpp @@ -32,12 +32,52 @@ BarrierManager::~BarrierManager() { } //arg: a list of barriers to be updated in the clients -void BarrierManager::Update(std::list>* barrierList) { - int ret; +void BarrierManager::Update( + std::list>* barrierList, + std::list>* creatureList, + std::list* characterList + ) +{ + //for each given creature, if a collision was detected, make a new barrier + for (auto& it : *creatureList) { + if (std::get<2>(it) & 2) { + Create(-1); //instance from creature index? + } + } + + //TODO: merge barriers + //TODO: absorb creatures into existing barriers + + //update the barriers + //TODO: how to delete the barriers? + int ret; //0 = no action, ret&1 = update clients, ret&2 = collision detected for (auto& it : elementMap) { - ret = it.second.Update(lua); + //normal update + ret = it.second.Update(lua) ? 1 : 0; + + //check for collision with a character + BoundingBox barrierBox = it.second.GetRealBounds(); + for (auto& it : *characterList) { + if (barrierBox.CheckOverlap(it->GetRealBounds())) { + //this will need updating + ret |= 2; + } + + //TODO: absorb characters + } + if (ret) { - barrierList->push_back(std::pair(it.first, &it.second)); + //push to the return list + barrierList->push_back(std::make_tuple(it.first, &it.second, ret)); + } + } +} + +void BarrierManager::Cleanup(std::list>* barrierList) { + //unload the given barrier objects + for (auto& it : *barrierList) { + if (std::get<2>(it) & 2) { + Unload(std::get<0>(it)); } } } diff --git a/server/combat/barrier_manager.hpp b/server/combat/barrier_manager.hpp index c1d443e..8ae5ee1 100644 --- a/server/combat/barrier_manager.hpp +++ b/server/combat/barrier_manager.hpp @@ -22,6 +22,8 @@ #pragma once #include "barrier_data.hpp" +#include "character_data.hpp" +#include "creature_data.hpp" #include "lua.hpp" #include "sqlite3.h" @@ -29,6 +31,7 @@ #include #include #include +#include class BarrierManager { public: @@ -36,7 +39,12 @@ public: ~BarrierManager(); //common public methods - void Update(std::list>* barrierList); + void Update( + std::list>* barrierList, + std::list>* creatureList, + std::list* characterList + ); + void Cleanup(std::list>* barrierList); int Create(int instanceIndex); void Unload(int uid); diff --git a/server/creatures/creature_manager.cpp b/server/creatures/creature_manager.cpp index dba777d..14284e6 100644 --- a/server/creatures/creature_manager.cpp +++ b/server/creatures/creature_manager.cpp @@ -38,7 +38,7 @@ void CreatureManager::Update( ) { //for each creature - int ret; //0 = no action, ret&1 = update clients, ret&2 = unload during cleanup step + int ret; //0 = no action, ret&1 = update clients, ret&2 = collision detected for (auto& it : elementMap) { //normal update ret = it.second.Update(lua) ? 1 : 0; @@ -48,7 +48,7 @@ void CreatureManager::Update( for (auto& it : *characterList) { if (creatureBox.CheckOverlap(it->GetRealBounds())) { //this will need updating - ret += 2; + ret |= 2; break; } } @@ -64,7 +64,7 @@ void CreatureManager::Cleanup(std::list(it) & 2) { -// Unload(std::get<0>(it)); + Unload(std::get<0>(it)); } } } diff --git a/server/rooms/room_data.cpp b/server/rooms/room_data.cpp index 37d8326..679f351 100644 --- a/server/rooms/room_data.cpp +++ b/server/rooms/room_data.cpp @@ -30,6 +30,7 @@ #include #include #include +#include //TODO: (9) character collisions should be preformed client-side void RoomData::RunFrame() { @@ -48,15 +49,38 @@ void RoomData::RunFrame() { } //lists of non-character entities that need updating client-side - std::list> creatureList; - std::list> barrierList; + //types are index, ptr, action (0 = update, 1 = unload) + std::list> creatureList; + std::list> barrierList; //update the entities in the room for (auto& it : characterList) { it->Update(); } - creatureMgr.Update(&creatureList); - barrierMgr.Update(&barrierList); + creatureMgr.Update(&creatureList, &characterList); + barrierMgr.Update(&barrierList, &creatureList, &characterList); + + //send the creature updates + for (auto& it : creatureList) { + CreaturePacket packet; + copyCreatureToPacket(&packet, std::get<1>(it), std::get<0>(it)); + packet.type = std::get<2>(it) != 0 ? SerialPacketType::CREATURE_UPDATE : SerialPacketType::CREATURE_UNLOAD; + packet.roomIndex = roomIndex; + pumpPacketProximity(reinterpret_cast(&packet), roomIndex, std::get<1>(it)->GetOrigin(), INFLUENCE_RADIUS); + } + + //send the barrier updates + for (auto& it : barrierList) { + BarrierPacket packet; + copyBarrierToPacket(&packet, std::get<1>(it), std::get<0>(it)); + packet.type = std::get<2>(it) != 0 ? SerialPacketType::BARRIER_UPDATE : SerialPacketType::BARRIER_UNLOAD; + packet.roomIndex = roomIndex; + pumpPacketProximity(reinterpret_cast(&packet), roomIndex, std::get<1>(it)->GetOrigin(), INFLUENCE_RADIUS); + } + + //cleanup the lists + creatureMgr.Cleanup(&creatureList); + barrierMgr.Cleanup(&barrierList); //build a list of entities for use with the triggers std::stack entityStack; @@ -66,49 +90,6 @@ void RoomData::RunFrame() { //Compare the triggers to the entities, using their real hitboxes triggerMgr.Compare(entityStack); - - //Creature/character collisions, O(m*n) - for (auto characterIt : characterList) { - BoundingBox characterBox = characterIt->GetBounds() + characterIt->GetOrigin(); - - for (auto creatureIt : *creatureMgr.GetContainer()) { - BoundingBox creatureBox = creatureIt.second.GetBounds() + creatureIt.second.GetOrigin(); - - if (characterBox.CheckOverlap(creatureBox)) { - int barrierIndex = barrierMgr.Create(-1); - BarrierData* barrierData = barrierMgr.Find(barrierIndex); - barrierData->SetRoomIndex(roomIndex); - barrierData->SetOrigin({ - (CREATURE_BOUNDS_WIDTH - BARRIER_BOUNDS_WIDTH) / 2 + creatureBox.x, - (CREATURE_BOUNDS_HEIGHT - BARRIER_BOUNDS_HEIGHT) / 2 + creatureBox.y, - }); - - BarrierPacket barrierPacket; - barrierPacket.type = SerialPacketType::BARRIER_CREATE; - copyBarrierToPacket(&barrierPacket, barrierData, barrierIndex); - - pumpPacketProximity(reinterpret_cast(&barrierPacket), roomIndex, characterIt->GetOrigin(), INFLUENCE_RADIUS); - } - } - } - - //send the creature updates - for (auto& it : creatureList) { - CreaturePacket packet; - copyCreatureToPacket(&packet, it.second, it.first); - packet.type = SerialPacketType::CREATURE_UPDATE; - packet.roomIndex = roomIndex; - pumpPacketProximity(reinterpret_cast(&packet), roomIndex, it.second->GetOrigin(), INFLUENCE_RADIUS); - } - - //send the barrier updates - for (auto& it : barrierList) { - BarrierPacket packet; - copyBarrierToPacket(&packet, it.second, it.first); - packet.type = SerialPacketType::BARRIER_UPDATE; - packet.roomIndex = roomIndex; - pumpPacketProximity(reinterpret_cast(&packet), roomIndex, it.second->GetOrigin(), INFLUENCE_RADIUS); - } } std::string RoomData::SetName(std::string s) {