From 4cce98dba405bdc411bcf043eec533feeae9f7f7 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Mon, 29 Aug 2016 19:05:41 +1000 Subject: [PATCH] BattleData can hold a limited number of characters --- server/battles/battle_data.cpp | 46 +++++++++++++++++++++------- server/battles/battle_data.hpp | 14 +++++---- server/characters/character_api.cpp | 7 +++++ server/characters/character_data.cpp | 4 +++ server/characters/character_data.hpp | 1 + server/rooms/room_data.cpp | 9 ++++++ server/server_application.cpp | 34 +++++++++++++++++--- 7 files changed, 93 insertions(+), 22 deletions(-) diff --git a/server/battles/battle_data.cpp b/server/battles/battle_data.cpp index ff9a2bb..e6efc68 100644 --- a/server/battles/battle_data.cpp +++ b/server/battles/battle_data.cpp @@ -21,31 +21,55 @@ */ #include "battle_data.hpp" +#include + BattleData::BattleData() { - // + for (int i = 0; i < BATTLE_SIZE; i++) { + characterArray[i] = nullptr; + creatureArray[i] = nullptr; + } } BattleData::~BattleData() { - // + for (int i = 0; i < BATTLE_SIZE; i++) { + if (characterArray[i] != nullptr || creatureArray[i] != nullptr) { + //breaking a cardinal sin + throw(std::runtime_error("BattleData not empty on destruction")); + } + } } void BattleData::Update() { - // + //TODO: (0) EMPTY } //accessors and mutators -void BattleData::PushCharacter(CharacterData* const characterData) { - // +int BattleData::PushCharacter(CharacterData* const characterData) { + //push the character into the battle object + for (int i = 0; i < BATTLE_SIZE; i++) { + if (characterArray[i] == nullptr) { + characterArray[i] = characterData; + return 1; + } + } + return 0; } -void BattleData::PopCharacter(CharacterData* const characterData) { - // +int BattleData::PopCharacter(CharacterData const * const characterData) { + //pop the character from the battle object + for (int i = 0; i < BATTLE_SIZE; i++) { + if (characterArray[i] == characterData) { + characterArray[i] = nullptr; + return 1; + } + } + return 0; } -void BattleData::PushCreature(CreatureData* const creatureData) { - // +int BattleData::PushCreature(CreatureData* const creatureData) { + //TODO: (0) EMPTY } -void BattleData::PopCreature(CreatureData* const creatureData) { - // +int BattleData::PopCreature(CreatureData const * const creatureData) { + //TODO: (0) EMPTY } diff --git a/server/battles/battle_data.hpp b/server/battles/battle_data.hpp index 5493249..ced1dfe 100644 --- a/server/battles/battle_data.hpp +++ b/server/battles/battle_data.hpp @@ -28,19 +28,21 @@ class BattleData { public: + constexpr static int BATTLE_SIZE = 8; + BattleData(); ~BattleData(); void Update(); //accessors and mutators - void PushCharacter(CharacterData* const characterData); - void PopCharacter(CharacterData* const characterData); + int PushCharacter(CharacterData* const characterData); + int PopCharacter(CharacterData const * const characterData); - void PushCreature(CreatureData* const creatureData); - void PopCreature(CreatureData* const creatureData); + int PushCreature(CreatureData* const creatureData); + int PopCreature(CreatureData const * const creatureData); private: - std::array characterArray; - std::array creatureArray; + std::array characterArray; + std::array creatureArray; }; \ No newline at end of file diff --git a/server/characters/character_api.cpp b/server/characters/character_api.cpp index ead28ac..c4e8145 100644 --- a/server/characters/character_api.cpp +++ b/server/characters/character_api.cpp @@ -67,6 +67,12 @@ static int setRoom(lua_State* L) { return 0; } +static int getIndex(lua_State* L) { + CharacterData* character = static_cast(lua_touserdata(L, 1)); + lua_pushinteger(L, character->GetIndex()); + return 1; +} + static int getOwner(lua_State* L) { CharacterData* character = static_cast(lua_touserdata(L, 1)); lua_pushinteger(L, character->GetOwner()); @@ -87,6 +93,7 @@ static int getAvatar(lua_State* L) { static const luaL_Reg characterLib[] = { {"SetRoom", setRoom}, + {"GetIndex", getIndex}, // {"GetOwner", getOwner}, //unusable without account API {"GetHandle", getHandle}, {"GetAvatar", getAvatar}, diff --git a/server/characters/character_data.cpp b/server/characters/character_data.cpp index 9b32090..00a5b7d 100644 --- a/server/characters/character_data.cpp +++ b/server/characters/character_data.cpp @@ -30,6 +30,10 @@ CharacterData::CharacterData(): Entity("character") { }); } +//------------------------- +//database stuff +//------------------------- + int CharacterData::GetIndex() { return index; } diff --git a/server/characters/character_data.hpp b/server/characters/character_data.hpp index 099fd1e..17074db 100644 --- a/server/characters/character_data.hpp +++ b/server/characters/character_data.hpp @@ -45,6 +45,7 @@ public: private: friend class CharacterManager; + //database stuff int index = -1; int owner = -1; std::string handle; diff --git a/server/rooms/room_data.cpp b/server/rooms/room_data.cpp index 7b09528..c3da0fb 100644 --- a/server/rooms/room_data.cpp +++ b/server/rooms/room_data.cpp @@ -207,6 +207,8 @@ void RoomData::RunFrameCharacterBarrierCollisions() { //move the character to the battle screen if (characterBox.CheckOverlap(barrierBox)) { + //TODO: (0) What if the barrier is full? + //TODO: (0) What if the player logs in on top of a barrier? //pump character unload CharacterPacket charPacket; charPacket.type = SerialPacketType::CHARACTER_UNLOAD; @@ -293,6 +295,13 @@ void RoomData::PopCharacter(CharacterData const * const character) { } } + //check the battles to see if the character isn't there + for (auto& it : *battleMgr.GetContainer()) { + if (it.second.PopCharacter(character)) { + return; + } + } + throw(std::logic_error("cannot remove a non-existant instance of CharacterData in RoomData")); } diff --git a/server/server_application.cpp b/server/server_application.cpp index 48c3404..2a808ab 100644 --- a/server/server_application.cpp +++ b/server/server_application.cpp @@ -596,12 +596,36 @@ void ServerApplication::hQueryCharacterExists(CharacterPacket* const argPacket) //respond with all character data CharacterPacket newPacket; - //TODO: move this expensive lookup - for (auto& it : *characterMgr.GetContainer()) { - if (argPacket->roomIndex != -1 && it.second.GetRoomIndex() != argPacket->roomIndex) { - continue; + //retrieve all character data + if (argPacket->roomIndex == -1) { + for (auto& it : *characterMgr.GetContainer()) { + copyCharacterToPacket(&newPacket, &it.second, it.first); + newPacket.type = SerialPacketType::QUERY_CHARACTER_EXISTS; + network.SendTo(argPacket->srcAddress, static_cast(&newPacket)); } - copyCharacterToPacket(&newPacket, it.first); + return; + } + + //look for the room + RoomData* room = roomMgr.Find(argPacket->roomIndex); + + //room not found + if (!room) { + //build the error message + std::ostringstream msg; + msg << "Room not found: " << argPacket->roomIndex; + + //build & send the packet + TextPacket newPacket; + newPacket.type = SerialPacketType::CHARACTER_REJECTION; + strncpy(newPacket.text, msg.str().c_str(), PACKET_STRING_SIZE); + network.SendTo(argPacket->srcAddress, static_cast(&newPacket)); + + return; + } + + for (auto& it : *room->GetCharacterList()) { + copyCharacterToPacket(&newPacket, it, it->GetIndex()); newPacket.type = SerialPacketType::QUERY_CHARACTER_EXISTS; network.SendTo(argPacket->srcAddress, static_cast(&newPacket)); }