From 2e8a47479263a9abc4e9fe5ef293e40bee4e571b Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Thu, 29 May 2014 00:30:25 +1000 Subject: [PATCH 1/8] Committing todo.txt --- todo.txt | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 todo.txt diff --git a/todo.txt b/todo.txt new file mode 100644 index 0000000..f03386a --- /dev/null +++ b/todo.txt @@ -0,0 +1,39 @@ +TODO: I need to keep the documentation up to date. Namely, the GDD is getting out of date. +TODO: I completely forgot about status ailments +TODO: Time delay for requesting region packets +TODO: command line parameters overriding config.cfg settings + +--Battle System-- + +TODO + +--Requirements-- + +The enemies need AI scripts +The scripts need to be able to generate other enemies (frog king). +The characters need a flag to show if they're in a combat instance or not, to signify of they should be unloaded client-side +On each game loop, the server should envoke each combat instance's update function + Each combat instance invokes each enemy's and character's update functions + These update functions increase the ATB guagues + if an ATB guage is full + than the stored command is executed + the players issue their commands during the build up + if there isn't a command ready, then the player is still choosing + for the enemies, the stored commands are driven by scripts, so when the enemies need to attack, their attached scripts are called. + after the commands are called, the ATB is reset to 0. + etc... + +--Enemy API-- + +enemyTables -- The global store of enemy tables. Only accessed by C++ code (unless you want to break something). + +enemy.new(parameters) -- return a new enemy object + +table.logic: the AI logic. If null, do nothing +table.ref: reference to the enemy itself, for use by API functions, set by constructor? + +combat -- the combat API +combat.new(mapIndex, x, y) -- return combat instance's index +combat.pushenemy(c, enemy) -- return the enemy's position +combat.popenemy(c, position) -- + From 1cfb814ee45b502e21d0883bf37269bc030d5765 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sun, 1 Jun 2014 23:07:02 +1000 Subject: [PATCH 2/8] Added the rest of the combat info to the network code --- common/gameplay/combat_data.hpp | 9 ++++ common/gameplay/room_data.hpp | 35 ++++++++++++++ common/gameplay/sanity_check.cpp | 1 + common/network/serial.cpp | 52 +++++++++++++++++--- common/network/serial_packet.hpp | 78 +++++++++++++++++------------- server/enemy_factory_interface.hpp | 16 ++---- 6 files changed, 140 insertions(+), 51 deletions(-) create mode 100644 common/gameplay/room_data.hpp diff --git a/common/gameplay/combat_data.hpp b/common/gameplay/combat_data.hpp index a013577..23bf1f4 100644 --- a/common/gameplay/combat_data.hpp +++ b/common/gameplay/combat_data.hpp @@ -40,7 +40,16 @@ #include #include +#define COMBAT_MAX_CHARACTER_COUNT 12 +#define COMBAT_MAX_ENEMY_COUNT 12 + struct CombatData { + enum class Terrain { + //TODO: types of terrains + NONE = 0, + GRASSLANDS, + }; + typedef std::chrono::steady_clock Clock; //combatants, point to the std::map's internal pairs diff --git a/common/gameplay/room_data.hpp b/common/gameplay/room_data.hpp new file mode 100644 index 0000000..ae49465 --- /dev/null +++ b/common/gameplay/room_data.hpp @@ -0,0 +1,35 @@ +/* Copyright: (c) Kayne Ruse 2014 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. +*/ +#ifndef ROOMDATA_HPP_ +#define ROOMDATA_HPP_ + +struct RoomData { + enum class RoomType { + OVERWORLD, + RUINS, + TOWERS, + FORESTS, + CAVES, + }; +}; + +#endif diff --git a/common/gameplay/sanity_check.cpp b/common/gameplay/sanity_check.cpp index 529cd0f..1e20ccf 100644 --- a/common/gameplay/sanity_check.cpp +++ b/common/gameplay/sanity_check.cpp @@ -24,6 +24,7 @@ #include "client_data.hpp" #include "combat_data.hpp" #include "enemy_data.hpp" +#include "room_data.hpp" #include "statistics.hpp" /* DOCS: Sanity check, read more diff --git a/common/network/serial.cpp b/common/network/serial.cpp index 81aecea..44c4bfd 100644 --- a/common/network/serial.cpp +++ b/common/network/serial.cpp @@ -99,7 +99,19 @@ void serializeCombat(SerialPacket* packet, char* buffer) { //integers SERIALIZE(buffer, &packet->combatInfo.combatIndex, sizeof(int)); SERIALIZE(buffer, &packet->combatInfo.difficulty, sizeof(int)); - //TODO: more comabat info + + SERIALIZE(buffer, &packet->combatInfo.terrainType, sizeof(CombatData::Terrain)); + + //arrays + SERIALIZE(buffer, &packet->combatInfo.characterArray, COMBAT_MAX_CHARACTER_COUNT); + SERIALIZE(buffer, &packet->combatInfo.enemyArray, COMBAT_MAX_ENEMY_COUNT); + + //position + SERIALIZE(buffer, &packet->combatInfo.mapIndex, sizeof(int)); + SERIALIZE(buffer, &packet->combatInfo.position.x, sizeof(double)); + SERIALIZE(buffer, &packet->combatInfo.position.y, sizeof(double)); + + //TODO: rewards } void serializeStatistics(Statistics* stats, char* buffer) { @@ -231,7 +243,19 @@ void deserializeCombat(SerialPacket* packet, char* buffer) { //integers DESERIALIZE(buffer, &packet->combatInfo.combatIndex, sizeof(int)); DESERIALIZE(buffer, &packet->combatInfo.difficulty, sizeof(int)); - //TODO: more comabat info + + DESERIALIZE(buffer, &packet->combatInfo.terrainType, sizeof(CombatData::Terrain)); + + //arrays + DESERIALIZE(buffer, &packet->combatInfo.characterArray, COMBAT_MAX_CHARACTER_COUNT); + DESERIALIZE(buffer, &packet->combatInfo.enemyArray, COMBAT_MAX_ENEMY_COUNT); + + //position + DESERIALIZE(buffer, &packet->combatInfo.mapIndex, sizeof(int)); + DESERIALIZE(buffer, &packet->combatInfo.position.x, sizeof(double)); + DESERIALIZE(buffer, &packet->combatInfo.position.y, sizeof(double)); + + //TODO: rewards } @@ -337,8 +361,16 @@ void serialize(SerialPacket* packet, void* buffer) { break; //combat info - case SerialPacket::Type::COMBAT_ENTER: - case SerialPacket::Type::COMBAT_EXIT: + case SerialPacket::Type::COMBAT_NEW: + case SerialPacket::Type::COMBAT_DELETE: + case SerialPacket::Type::COMBAT_UPDATE: + + //TODO: is this the best fit? + case SerialPacket::Type::COMBAT_ENTER_REQUEST: + case SerialPacket::Type::COMBAT_ENTER_RESPONSE: + case SerialPacket::Type::COMBAT_EXIT_REQUEST: + case SerialPacket::Type::COMBAT_EXIT_RESPONSE: + serializeCombat(packet, reinterpret_cast(buffer)); break; @@ -407,8 +439,16 @@ void deserialize(SerialPacket* packet, void* buffer) { break; //combat info - case SerialPacket::Type::COMBAT_ENTER: - case SerialPacket::Type::COMBAT_EXIT: + case SerialPacket::Type::COMBAT_NEW: + case SerialPacket::Type::COMBAT_DELETE: + case SerialPacket::Type::COMBAT_UPDATE: + + //TODO: is this the best fit? + case SerialPacket::Type::COMBAT_ENTER_REQUEST: + case SerialPacket::Type::COMBAT_ENTER_RESPONSE: + case SerialPacket::Type::COMBAT_EXIT_REQUEST: + case SerialPacket::Type::COMBAT_EXIT_RESPONSE: + serializeCombat(packet, reinterpret_cast(buffer)); break; diff --git a/common/network/serial_packet.hpp b/common/network/serial_packet.hpp index 27de13b..f157df1 100644 --- a/common/network/serial_packet.hpp +++ b/common/network/serial_packet.hpp @@ -25,10 +25,11 @@ #include "vector2.hpp" #include "region.hpp" #include "statistics.hpp" +#include "combat_data.hpp" #include "SDL/SDL_net.h" -#define NETWORK_VERSION 20140528 +#define NETWORK_VERSION 20140601 #define PACKET_STRING_SIZE 100 union SerialPacket { @@ -38,60 +39,67 @@ union SerialPacket { NONE = 0, //keep alive - PING = 1, - PONG = 2, + PING, + PONG, //searching for a server to join - BROADCAST_REQUEST = 3, - BROADCAST_RESPONSE = 4, - BROADCAST_REJECTION = 5, + BROADCAST_REQUEST, + BROADCAST_RESPONSE, + BROADCAST_REJECTION, //try to join the server - JOIN_REQUEST = 6, - JOIN_RESPONSE = 7, - JOIN_REJECTION = 8, + JOIN_REQUEST, + JOIN_RESPONSE, + JOIN_REJECTION, //mass update - SYNCHRONIZE = 9, + SYNCHRONIZE, //disconnect from the server - DISCONNECT = 10, + DISCONNECT, //shut down the server - SHUTDOWN = 11, + SHUTDOWN, //map data - REGION_REQUEST = 12, - REGION_CONTENT = 13, - REGION_REJECTION = 14, + REGION_REQUEST, + REGION_CONTENT, + REGION_REJECTION, //combat data - COMBAT_ENTER = 15, - COMBAT_EXIT = 16, + COMBAT_NEW, + COMBAT_DELETE, + COMBAT_UPDATE, - COMBAT_UPDATE = 17, + COMBAT_ENTER_REQUEST, + COMBAT_ENTER_RESPONSE, - COMBAT_REJECTION = 18, + COMBAT_EXIT_REQUEST, + COMBAT_EXIT_RESPONSE, + + //TODO: COMBAT info + + COMBAT_REJECTION, //character data - CHARACTER_NEW = 19, - CHARACTER_DELETE = 20, - CHARACTER_UPDATE = 21, + CHARACTER_NEW, + CHARACTER_DELETE, + CHARACTER_UPDATE, - CHARACTER_STATS_REQUEST = 22, - CHARACTER_STATS_RESPONSE = 23, + CHARACTER_STATS_REQUEST, + CHARACTER_STATS_RESPONSE, - CHARACTER_REJECTION = 24, + CHARACTER_REJECTION, //enemy data - ENEMY_NEW = 25, - ENEMY_DELETE = 26, - ENEMY_UPDATE = 27, + ENEMY_NEW, + ENEMY_DELETE, + ENEMY_UPDATE, - ENEMY_STATS_REQUEST = 28, - ENEMY_STATS_RESPONSE = 29, + ENEMY_STATS_REQUEST, + ENEMY_STATS_RESPONSE, - ENEMY_REJECTION = 30, + ENEMY_REJECTION, //more packet types go here @@ -138,8 +146,11 @@ union SerialPacket { Metadata meta; int combatIndex; int difficulty; - //TODO: background image, based on terrain type - //TODO: array of combatants + CombatData::Terrain terrainType; + int characterArray[COMBAT_MAX_CHARACTER_COUNT]; + int enemyArray[COMBAT_MAX_ENEMY_COUNT]; + int mapIndex; + Vector2 position; //TODO: rewards }combatInfo; @@ -163,6 +174,7 @@ union SerialPacket { char handle[PACKET_STRING_SIZE]; char avatar[PACKET_STRING_SIZE]; Statistics stats; + //TODO: rewards }enemyInfo; //defaults diff --git a/server/enemy_factory_interface.hpp b/server/enemy_factory_interface.hpp index bceedf5..335814e 100644 --- a/server/enemy_factory_interface.hpp +++ b/server/enemy_factory_interface.hpp @@ -23,18 +23,10 @@ #define ENEMYFACTORYINTERFACE_HPP_ #include "enemy_data.hpp" +#include "room_data.hpp" #include -//TODO: move this elsewhere -enum RoomType { - OVERWORLD, - RUINS, - TOWERS, - FORESTS, - CAVES, -}; - //NOTE: Based on biome, world difficulty, etc. class EnemyFactoryInterface { public: @@ -44,12 +36,12 @@ public: virtual void Generate(std::list* container) = 0; //control the difficulty of the room - RoomType SetType(RoomType t) { return type = t; } + RoomData::RoomType SetType(RoomData::RoomType t) { return type = t; } int SetDifficulty(int d) { return difficulty = d; } - RoomType GetType() { return type; } + RoomData::RoomType GetType() { return type; } int GetDifficulty() { return difficulty; } protected: - RoomType type; + RoomData::RoomType type; int difficulty; }; From 9d83abbd3819190b97e512d7be69b6d23e6d2f0b Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sun, 1 Jun 2014 23:42:30 +1000 Subject: [PATCH 3/8] Copied some boilerplate code from InWorld to InCombat --- client/in_combat.cpp | 114 +++++++++++++++++++++++++++++++++++++++++-- client/in_combat.hpp | 3 +- client/in_world.cpp | 3 +- 3 files changed, 113 insertions(+), 7 deletions(-) diff --git a/client/in_combat.cpp b/client/in_combat.cpp index f20f765..992643e 100644 --- a/client/in_combat.cpp +++ b/client/in_combat.cpp @@ -21,6 +21,11 @@ */ #include "in_combat.hpp" +#include "channels.hpp" +#include "utility.hpp" + +#include + //------------------------- //Public access members //------------------------- @@ -44,6 +49,26 @@ InCombat::InCombat( characterMap(*argCharacterMap), enemyMap(*argEnemyMap) { +/* //setup the utility objects + buttonImage.LoadSurface(config["dir.interface"] + "button_menu.bmp"); + buttonImage.SetClipH(buttonImage.GetClipH()/3); + font.LoadSurface(config["dir.fonts"] + "pk_white_8.bmp"); + + //pass the utility objects + backButton.SetImage(&buttonImage); + backButton.SetFont(&font); + + //set the button positions + backButton.SetX(50); + backButton.SetY(50 + buttonImage.GetClipH() * 0); + + //set the button texts + backButton.SetText("Back"); + + //request a sync + RequestSynchronize(); +*/ + //debug // } @@ -60,7 +85,14 @@ void InCombat::FrameStart() { } void InCombat::Update(double delta) { - // + SerialPacket packet; + + //suck in all waiting packets + while(network.Receive(&packet)) { + HandlePacket(packet); + } + + //TODO: more } void InCombat::FrameEnd() { @@ -75,7 +107,13 @@ void InCombat::RenderFrame() { } void InCombat::Render(SDL_Surface* const screen) { - // + //TODO: draw the background + + //TODO: draw the characters + + //TODO: draw the enemies + + //TODO: draw the UI } //------------------------- @@ -84,7 +122,7 @@ void InCombat::Render(SDL_Surface* const screen) { void InCombat::QuitEvent() { //exit the game AND the server -// RequestDisconnect(); + RequestDisconnect(); SetNextScene(SceneList::MAINMENU); } @@ -116,10 +154,76 @@ void InCombat::KeyUp(SDL_KeyboardEvent const& key) { //Network handlers //------------------------- -//TODO: network handlers +void InCombat::HandlePacket(SerialPacket packet) { + switch(packet.meta.type) { + case SerialPacket::Type::DISCONNECT: + HandleDisconnect(packet); + break; + //handle errors + default: + throw(std::runtime_error(std::string() + "Unknown SerialPacket::Type encountered in InCombat: " + to_string_custom(int(packet.meta.type)))); + break; + } +} + +void InCombat::HandleDisconnect(SerialPacket) { + //TODO: stuff + //TODO: I probably need a separate disconnection scene, for setting the client state back to normal +} + +//TODO: more network handlers //------------------------- //Server control //------------------------- -//TODO: server control +void InCombat::RequestSynchronize() { + SerialPacket packet; + + //request a sync + packet.meta.type = SerialPacket::Type::SYNCHRONIZE; + packet.clientInfo.clientIndex = clientIndex; + packet.clientInfo.accountIndex = accountIndex; + packet.clientInfo.characterIndex = characterIndex; + + network.SendTo(Channels::SERVER, &packet); +} + +void InCombat::SendPlayerUpdate() { + SerialPacket packet; + + //pack the packet + packet.meta.type = SerialPacket::Type::CHARACTER_UPDATE; + packet.characterInfo.clientIndex = clientIndex; + packet.characterInfo.accountIndex = accountIndex; + packet.characterInfo.characterIndex = characterIndex; +// packet.characterInfo.position = localCharacter->position; +// packet.characterInfo.motion = localCharacter->motion; + //TODO: stats + + network.SendTo(Channels::SERVER, &packet); +} + +void InCombat::RequestDisconnect() { + SerialPacket packet; + + //send a disconnect request + packet.meta.type = SerialPacket::Type::DISCONNECT; + packet.clientInfo.clientIndex = clientIndex; + packet.clientInfo.accountIndex = accountIndex; + packet.clientInfo.characterIndex = characterIndex; + + network.SendTo(Channels::SERVER, &packet); +} + +void InCombat::RequestShutdown() { + SerialPacket packet; + + //send a shutdown request + packet.meta.type = SerialPacket::Type::SHUTDOWN; + packet.clientInfo.clientIndex = clientIndex; + packet.clientInfo.accountIndex = accountIndex; + packet.clientInfo.characterIndex = characterIndex; + + network.SendTo(Channels::SERVER, &packet); +} diff --git a/client/in_combat.hpp b/client/in_combat.hpp index 15df345..ea8dad1 100644 --- a/client/in_combat.hpp +++ b/client/in_combat.hpp @@ -75,9 +75,10 @@ protected: //Network handlers void HandlePacket(SerialPacket); void HandleDisconnect(SerialPacket); - //TODO: more + //TODO: more network handlers //Server control + void RequestSynchronize(); void SendPlayerUpdate(); void RequestDisconnect(); void RequestShutdown(); diff --git a/client/in_world.cpp b/client/in_world.cpp index 9822a2a..b9a5002 100644 --- a/client/in_world.cpp +++ b/client/in_world.cpp @@ -77,7 +77,7 @@ InWorld::InWorld( RequestSynchronize(); //debug -// RequestRegion(0, 0); + // } InWorld::~InWorld() { @@ -273,6 +273,7 @@ void InWorld::HandlePacket(SerialPacket packet) { } void InWorld::HandleDisconnect(SerialPacket packet) { + //TODO: I probably need a separate disconnection scene, for setting the client state back to normal network.Unbind(Channels::SERVER); clientIndex = -1; accountIndex = -1; From 4acd3502197664e96af56e0f420386a2e05f9e5f Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Mon, 2 Jun 2014 00:45:57 +1000 Subject: [PATCH 4/8] Added the restart scene --- client/client_application.cpp | 4 + client/in_combat.cpp | 3 +- client/in_world.cpp | 7 +- client/restart.cpp | 138 ++++++++++++++++++++++++++++++++++ client/restart.hpp | 98 ++++++++++++++++++++++++ client/scene_list.hpp | 1 + 6 files changed, 243 insertions(+), 8 deletions(-) create mode 100644 client/restart.cpp create mode 100644 client/restart.hpp diff --git a/client/client_application.cpp b/client/client_application.cpp index ebc9f18..267440c 100644 --- a/client/client_application.cpp +++ b/client/client_application.cpp @@ -37,6 +37,7 @@ #include "lobby_menu.hpp" #include "in_world.hpp" #include "in_combat.hpp" +#include "restart.hpp" //------------------------- //Public access members @@ -127,6 +128,9 @@ void ClientApplication::LoadScene(SceneList sceneIndex) { case SceneList::INCOMBAT: activeScene = new InCombat(&config, &network, &clientIndex, &accountIndex, &characterIndex, &combatMap, &characterMap, &enemyMap); break; + case SceneList::RESTART: + activeScene = new Restart(&config, &network, &clientIndex, &accountIndex, &characterIndex, &combatMap, &characterMap, &enemyMap); + break; default: throw(std::logic_error("Failed to recognize the scene index")); } diff --git a/client/in_combat.cpp b/client/in_combat.cpp index 992643e..6be762f 100644 --- a/client/in_combat.cpp +++ b/client/in_combat.cpp @@ -167,8 +167,7 @@ void InCombat::HandlePacket(SerialPacket packet) { } void InCombat::HandleDisconnect(SerialPacket) { - //TODO: stuff - //TODO: I probably need a separate disconnection scene, for setting the client state back to normal + SetNextScene(SceneList::RESTART); } //TODO: more network handlers diff --git a/client/in_world.cpp b/client/in_world.cpp index b9a5002..8063de6 100644 --- a/client/in_world.cpp +++ b/client/in_world.cpp @@ -273,12 +273,7 @@ void InWorld::HandlePacket(SerialPacket packet) { } void InWorld::HandleDisconnect(SerialPacket packet) { - //TODO: I probably need a separate disconnection scene, for setting the client state back to normal - network.Unbind(Channels::SERVER); - clientIndex = -1; - accountIndex = -1; - characterIndex = -1; - SetNextScene(SceneList::MAINMENU); + SetNextScene(SceneList::RESTART); } void InWorld::HandleRegionContent(SerialPacket packet) { diff --git a/client/restart.cpp b/client/restart.cpp new file mode 100644 index 0000000..91f266e --- /dev/null +++ b/client/restart.cpp @@ -0,0 +1,138 @@ +/* Copyright: (c) Kayne Ruse 2014 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. +*/ +#include "restart.hpp" + +#include "channels.hpp" + +#include + +//------------------------- +//Public access members +//------------------------- + +Restart::Restart( + ConfigUtility* const argConfig, + UDPNetworkUtility* const argNetwork, + int* const argClientIndex, + int* const argAccountIndex, + int* const argCharacterIndex, + std::map* argCombatMap, + std::map* argCharacterMap, + std::map* argEnemyMap + ): + config(*argConfig), + network(*argNetwork), + clientIndex(*argClientIndex), + accountIndex(*argAccountIndex), + characterIndex(*argCharacterIndex), + combatMap(*argCombatMap), + characterMap(*argCharacterMap), + enemyMap(*argEnemyMap) +{ + //setup the utility objects + image.LoadSurface(config["dir.interface"] + "button_menu.bmp"); + image.SetClipH(image.GetClipH()/3); + font.LoadSurface(config["dir.fonts"] + "pk_white_8.bmp"); + + //pass the utility objects + backButton.SetImage(&image); + backButton.SetFont(&font); + + //set the button positions + backButton.SetX(50); + backButton.SetY(50 + image.GetClipH() * 0); + + //set the button texts + backButton.SetText("Back"); + + //full reset + network.Unbind(Channels::SERVER); + clientIndex = -1; + accountIndex = -1; + characterIndex = -1; + combatMap.clear(); + characterMap.clear(); + enemyMap.clear(); + + //auto return + startTick = std::chrono::steady_clock::now(); +} + +Restart::~Restart() { + // +} + +//------------------------- +//Frame loop +//------------------------- + +void Restart::Update(double delta) { + if (std::chrono::steady_clock::now() - startTick > std::chrono::duration(10)) { + QuitEvent(); + } +} + +void Restart::RenderFrame() { + SDL_FillRect(GetScreen(), 0, 0); + Render(GetScreen()); + SDL_Flip(GetScreen()); + fps.Calculate(); +} + +void Restart::Render(SDL_Surface* const screen) { + backButton.DrawTo(screen); + font.DrawStringTo("You have been disconnected.", screen, 50, 30); +} + +//------------------------- +//Event handlers +//------------------------- + +void Restart::QuitEvent() { + SetNextScene(SceneList::MAINMENU); +} + +void Restart::MouseMotion(SDL_MouseMotionEvent const& motion) { + backButton.MouseMotion(motion); +} + +void Restart::MouseButtonDown(SDL_MouseButtonEvent const& button) { + backButton.MouseButtonDown(button); +} + +void Restart::MouseButtonUp(SDL_MouseButtonEvent const& button) { + if (backButton.MouseButtonUp(button) == Button::State::HOVER) { + QuitEvent(); + } +} + +void Restart::KeyDown(SDL_KeyboardEvent const& key) { + switch(key.keysym.sym) { + case SDLK_ESCAPE: + QuitEvent(); + break; + } +} + +void Restart::KeyUp(SDL_KeyboardEvent const& key) { + // +} diff --git a/client/restart.hpp b/client/restart.hpp new file mode 100644 index 0000000..4012a80 --- /dev/null +++ b/client/restart.hpp @@ -0,0 +1,98 @@ +/* Copyright: (c) Kayne Ruse 2014 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. +*/ +#ifndef RESTART_HPP_ +#define RESTART_HPP_ + +//network +#include "udp_network_utility.hpp" + +//graphics +#include "image.hpp" +#include "raster_font.hpp" +#include "button.hpp" + +//common +#include "config_utility.hpp" +#include "frame_rate.hpp" + +#include "combat_data.hpp" +#include "character_data.hpp" +#include "enemy_data.hpp" + +//client +#include "base_scene.hpp" + +//std namespace +#include + +class Restart : public BaseScene { +public: + //Public access members + Restart( + ConfigUtility* const argConfig, + UDPNetworkUtility* const argNetwork, + int* const argClientIndex, + int* const argAccountIndex, + int* const argCharacterIndex, + std::map* argCombatMap, + std::map* argCharacterMap, + std::map* argEnemyMap + ); + ~Restart(); + +protected: + //Frame loop + void Update(double delta); + void RenderFrame(); + void Render(SDL_Surface* const); + + //Event handlers + void QuitEvent(); + void MouseMotion(SDL_MouseMotionEvent const&); + void MouseButtonDown(SDL_MouseButtonEvent const&); + void MouseButtonUp(SDL_MouseButtonEvent const&); + void KeyDown(SDL_KeyboardEvent const&); + void KeyUp(SDL_KeyboardEvent const&); + + //shared parameters + ConfigUtility& config; + UDPNetworkUtility& network; + int& clientIndex; + int& accountIndex; + int& characterIndex; + std::map& combatMap; + std::map& characterMap; + std::map& enemyMap; + + //graphics + Image image; + RasterFont font; + + //UI + Button backButton; + FrameRate fps; + + //auto return + std::chrono::steady_clock::time_point startTick; +}; + +#endif diff --git a/client/scene_list.hpp b/client/scene_list.hpp index a124237..79d396c 100644 --- a/client/scene_list.hpp +++ b/client/scene_list.hpp @@ -35,6 +35,7 @@ enum class SceneList { LOBBYMENU, INWORLD, INCOMBAT, + RESTART, }; #endif From d2f03b98dc8db4ad3cb3f344e6c64221d57d20fe Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Mon, 2 Jun 2014 20:02:19 +1000 Subject: [PATCH 5/8] Screwing around with some settings --- client/client_application.cpp | 6 +++++- client/options_menu.hpp | 1 + client/restart.cpp | 4 ++++ common/map/region.hpp | 2 +- rsc/config.cfg | 21 ++++++++++----------- rsc/graphics/tilesets/blank.bmp | Bin 0 -> 786486 bytes server/server_internals.cpp | 3 +-- 7 files changed, 22 insertions(+), 15 deletions(-) create mode 100644 rsc/graphics/tilesets/blank.bmp diff --git a/client/client_application.cpp b/client/client_application.cpp index 267440c..b9a31bd 100644 --- a/client/client_application.cpp +++ b/client/client_application.cpp @@ -51,7 +51,11 @@ void ClientApplication::Init(int argc, char** argv) { if (SDL_Init(SDL_INIT_VIDEO)) { throw(std::runtime_error("Failed to initialize SDL")); } - BaseScene::SetScreen(config.Int("screen.w"), config.Int("screen.h"), 0, (config.Bool("screen.f")) ? SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_FULLSCREEN : SDL_HWSURFACE|SDL_DOUBLEBUF); + int w = config.Int("client.screen.w"); + int h = config.Int("client.screen.h"); + int f = config.Bool("client.screen.f") ? SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_FULLSCREEN : SDL_HWSURFACE|SDL_DOUBLEBUF; + + BaseScene::SetScreen(w ? w : 800, h ? h : 600, 0, f); //initialize SDL_net if (SDLNet_Init()) { diff --git a/client/options_menu.hpp b/client/options_menu.hpp index 94008d3..37e4e64 100644 --- a/client/options_menu.hpp +++ b/client/options_menu.hpp @@ -29,6 +29,7 @@ #include "raster_font.hpp" #include "button.hpp" +//TODO: The options screen needs to be USED class OptionsMenu : public BaseScene { public: //Public access members diff --git a/client/restart.cpp b/client/restart.cpp index 91f266e..66377c1 100644 --- a/client/restart.cpp +++ b/client/restart.cpp @@ -89,6 +89,10 @@ void Restart::Update(double delta) { if (std::chrono::steady_clock::now() - startTick > std::chrono::duration(10)) { QuitEvent(); } + + while(network.Receive()) { + //EAT INCOMING PACKETS + } } void Restart::RenderFrame() { diff --git a/common/map/region.hpp b/common/map/region.hpp index d45628f..560161b 100644 --- a/common/map/region.hpp +++ b/common/map/region.hpp @@ -28,7 +28,7 @@ class Region { public: - typedef unsigned short type_t; + typedef unsigned char type_t; Region() = delete; Region(int x, int y); diff --git a/rsc/config.cfg b/rsc/config.cfg index b93fe60..b2f34d9 100644 --- a/rsc/config.cfg +++ b/rsc/config.cfg @@ -1,13 +1,18 @@ #configuration of the programs + +#server specific settings server.host = 255.255.255.255 server.port = 21795 server.name = local server.dbname = database.db -screen.w = 800 -screen.h = 600 -screen.f = false +#client specific settings +client.screen.f = false + +client.username = Kayne Ruse +client.handle = Ratstail91 +client.avatar = elliot2.bmp #directories dir.fonts = rsc/graphics/fonts/ @@ -16,15 +21,9 @@ dir.sprites = rsc/graphics/sprites/ dir.tilesets = rsc/graphics/tilesets/ dir.interface = rsc/graphics/interface/ dir.scripts = rsc/scripts/ +dir.maps = rsc/maps/ #map system -map.pager.width = 20 -map.pager.height = 20 -map.pager.depth = 3 - -#player options -client.username = Kayne Ruse -client.handle = Ratstail91 -client.avatar = elliot2.bmp +map.savename = servermap #debugging diff --git a/rsc/graphics/tilesets/blank.bmp b/rsc/graphics/tilesets/blank.bmp new file mode 100644 index 0000000000000000000000000000000000000000..44b11c7863f0547b40c1550c7442547b48baa404 GIT binary patch literal 786486 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 zw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(L zXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuR zz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+! z>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_Uyp zFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~ zUT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870 zdcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw z!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3 zLoc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN z(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNny zoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xv zw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(L zXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuR zz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+! z>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_Uyp zFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~ zUT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870 zdcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw z!RwuRz0+Q3LofVagJ0L_^y_+|4cqSv_z#VN(_UypFSNnyoqD~~ zUT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870 zdcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw z!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3 zLoc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN z(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNny zoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xv zw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(L zXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuR zz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+! z>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_Uyp zFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~ zUT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870 zdcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw z!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3 zLoc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN z(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNny zoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xv zw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(L 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 zuXpP8PJ5vZz0d})ck1;{d!Y@z&<3w}>h(^0p$)yz2CsMO^-g=C4ZY9?uXpP8PJ5vZ zz0d})ck1;{d!Y@z&<3w}>h(^0p$)yz2CsMO^-g=C4ZY9?uXpP8PJ5vZz0d})ck1;{ zd!Y@z&<3w}>h(^0p$)yz2CsMO^-g=C4ZY9?uXpP8PJ5vZz0d})ck1;{d!Y@z&<3w} z>h(^0p$)yz2CsMO^-g=C4ZY9?uXpP8PJ5vZz0d})ck1;{d!Y@z&<3w}>h(^0p$)yz z2CsMO^-g=C4ZY9?uXpP8PJ5vZz0d})ck1;{d!Y@z&<3w}>h(^0p$)yz2CsMO^-g=C z4ZY9?uXpP8PJ5vZz0d})ck1;{d!Y@z&<3w}>h(^0p$)yz2CsMO^-g=C4ZY9?uXpP8 zPJ5vZz0d})ck1;{d!Y@z&<3w}>h(^0p$)yz2CsMO^-g=C4ZY9?uXpP8PJ5vZz0d}) zck1;{d!Y@z&<3w}>h(^0p$)yz2CsMO^-g=C4ZY9?uXpP8PJ5vZz0d})ck1;{d!Y@z z&<3w}>h(^0p$)yz2CsMO^-g=C4ZY9?uXpP8PJ5vZz0d})ck1;{d!Y@z&<3w}>h(^0 zp$)yz2CsMO^-g=C4ZY9?uXpP8PJ5vZz0d})ck1;{d!Y@z&<3w}>h(^0p$)yz2CsMO z^-g=C4ZY9?uXpP8PJ5vZz0d})ck1;{d!Y@z&<3w}>h(^0p$)yz2CsMO^-g=C4ZY9? zuXpP8PJ5vZz0d})ck1;{d!Y@z&<3w}>h(^0p$)yz2CsMO^-g=C4ZY9?uXpP8PJ5vZ zz0d})ck1;{d!Y@z&<3w}>h(^0p$)yz2CsMO^-g=C4ZY9?uXpP8PJ5vZz0d})ck1;{ zd!Y@z&<3w}>h(^0p$)yz2CsMO^-g=C4ZY9?uXpP8PJ5vZz0d})ck1;{d!Y@z&<3w} z>h(^0p$)yz2CsMO^-g=C4ZY9?uXpP8PJ5vZz0d})ck1;{d!Y@z&<3w}>h(^0p$)yz z2CsMO^-g=C4ZY9?uXpP8PJ5vZz0d})ck1;{d!Y@z&<3w}>h(^0p$)yz2CsMO^-g=C z4ZY9?uXpP8PJ5vZz0d})ck1;{d!Y@z&<3w}>h(^0p$)yz2CsMO^-g=C4ZY9?uXpP8 zPJ5vZz0d})ck1;{d!Y@z&<3w}>h(^0p$)yz2CsMO^-g=C4ZY9?uXpP8PJ5vZz0d}) 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 z^-jIsX)m;)7uw+UPQBh~FSMZ-+Tit0z20drw4oQ;;PpcV^-jIsX)m;) z7uw+UPQBh~FSMZ-+Tit0z20drw4oQ;;PpcV^-jIsX)m;)7uw+UPQBh~ zFSMZ-+Tit0z20drw4oQ;;PpcV^-jIsX)m;)7uw+UPQBh~FSMZ-+Tit0 zz20drw4oQ;;PpcV^-jIsX)m;)7uw+UPQBh~FSMZ-+Tit0z20drw4oQ; z;PpcV^-jIsX)m;)7uw+UPQBh~FSMZ-+Tit0z20drw4oQ;;PpcV^-jIsX)m;)7uw+UPQBh~FSMZ-+Tit0z20drw4oQ;;PpcV^-jIs zX)m;)7uw+UPQBh~FSMZ-+Tit0z20drw4oQ;;PpcV^-jIsX)m;)7uw+U zPQBh~FSMZ-+Tit0z20drw4oQ;;PpcV^-jIsX)m;)7uw+UPQBh~FSMZ- z+Tit0z20drw4oQ;;PpcV^-jIsX)m;)7uw+UPQBh~FSMZ-+Tit0z20dr zw4oQ;;PpcV^-jIsX)m;)7uw+UPQBh~FSMZ-+Tit0z20drw4oQ;;PpcV^-jIsX)m;)7uw+UPQBh~FSMZ-+Tit0z20drw4oQ;;PpcV z^-jIsX)m;)7uw+UPQBh~FSMZ-+Tit0z20drw4oQ;;PpcV^-jIsX)m;) z7uw+UPQBh~FSMZ-+Tit0z20drw4oQ;;PpcV^-jIsX)m;)7uw+UPQBh~ zFSMZ-+Tit0z20drw4oQ;;PpcV^-jIsX)m;)7uw+UPQBh~FSMZ-+Tit0 zz20drw4oQ;;PpcV^-jIsX)m;)7uw+UPQBh~FSMZ-+Tit0z20drw4oQ; z;PpcV^-jIsX)m;)7uw+UPQBh~FSMZ-+Tit0z20drw4oQ;;PpcV^-jIsX)m;)7uw+UPQBh~FSMZ-+Tit0z20drw4oQ;;PpcV^-jIs zX)m;)7uw+UPQBh~FSMZ-+Tit0z20drw4oQ;;PpcV^-jIsX)m;)7uw+U zPQBh~FSMZ-+Tit0z20drw4oQ;;PpcV^-jIsX)m;)7uw+UPQBh~FSMZ- z+Tit0z20drw4oQ;;PpcV^-jIsX)m;)7uw+UPQBh~FSMZ-+Tit0z20dr zw4oQ;;PpcV^-jIsX)m;)7uw+UPQBh~FSMZ-+Tit0z20drw4oQ;;PpcV^-jIsX)m;)7uw+UPQBh~FSMZ-+Tit0z20drw4oQ;;PpcV z^-jIsX)m;)7uw+UPQBh~FSMZ-+Tit0z20drw4oQ;;PpcV^-jIsX)m;) z7uw+UPQBh~FSMZ-+Tit0z20drw4oQ;;PpcV^-jIsX)m;)7uw+UPQBh~ zFSMZ-+Tit0z20drw4oQ;;PpcV^-jIsX)m;)7uw+U^Qm9g>GTD9p$*&b z3;24SdcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(L zXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuR zz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+! z>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_Uyp zFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~ zUT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870 zdcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw z!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3 zLoc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN z(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNny zoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xv zw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(L zXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuR zz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+! z>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_Uyp zFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~ zUT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870 zdcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw z!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3 zLoc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN z(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNny zoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xv zw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(L zXhScw!RwuRz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuR zz0+Q3Loc+!>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+! z>z#VN(_UypFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+!>z#VN(_Uyp zFSNnyoqD~~UT8xvw8870dcD(LXhScw!RwuRz0+Q3Loc+!>*rIyuG8rY^g27wCmHY`-ty>vih& zPJ5vZz0d})ck1;{d!Y@z&<3w}>h(^0p$)yz2CsMO^-g=C4ZY9?uXpP8PJ5vZz0d}) zck1;{d!Y@z&<3w}>h(^0p$)yz2CsMO^-g=C4ZY9?uXpP8PJ5vZz0d})ck1;{d!Y@z z&<3w}>h(^0p$)yz2CsMO^-g=C4ZY9?uXpP8PJ5vZz0d})ck1;{d!Y@z&<3w}>h(^0 zp$)yz2CsMO^-g=C4ZY9?uXpP8PJ5vZz0d})ck1;{d!Y@z&<3w}>h(^0p$)yz2CsMO z^-g=C4ZY9?uXpP8PJ5vZz0d})ck1;{d!Y@z&<3w}>h(^0p$)yz2CsMO^-g=C4ZY9? zuXpP8PJ5vZz0d})ck1;{d!Y@z&<3w}>h(^0p$)yz2CsMO^-g=C4ZY9?uXpP8PJ5vZ zz0d})ck1;{d!Y@z&<3w}>h(^0p$)yz2CsMO^-g=C4ZY9?uXpP8PJ5vZz0d})ck1;{ zd!Y@z&<3w}>h(^0p$)yz2CsMO^-g=C4ZY9?uXpP8PJ5vZz0d})ck1;{d!Y@z&<3w} z>h(^0p$)yz2CsMO^-g=C4ZY9?uXpP8PJ5vZz0d})ck1;{d!Y@z&<3w}>h(^0p$)yz z2CsMO^-g=C4ZY9?uXpP8PJ5vZz0d})ck1;{d!Y@z&<3w}>h(^0p$)yz2CsMO^-g=C z4ZY9?uXpP8PJ5vZz0d})ck1;{d!Y@z&<3w}>h(^0p$)yz2CsMO^-g=C4ZY9?uXpP8 zPJ5vZz0d})ck1;{d!Y@z&<3w}>h(^0p$)yz2CsMO^-g=C4ZY9?uXpP8PJ5vZz0d}) zck1;{d!Y@z&<3w}>h(^0p$)yz2CsMO^-g=C4ZY9?uXpP8PJ5vZz0d})ck1;{d!Y@z z&<3w}>h(^0p$)yz2CsMO^-g=C4ZY9?uXpP8PJ5vZz0d})ck1;{d!Y@z&<3w}>h(^0 zp$)yz2CsMO^-g=C4ZY9?uXpP8PJ5vZz0d})ck1;{d!Y@z&<3w}>h(^0p$)yz2CsMO z^-g=C4ZY9?uXpP8PJ5vZz0d})ck1;{d!Y@z&<3w}>h(^0p$)yz2CsMO^-g=C4ZY9? zuXpP8PJ5vZz0d})ck1;{d!Y@z&<3w}>h(^0p$)yz2CsMO^-g=C4ZY9?uXpP8PJ5vZ zz0d})ck1;{d!Y@z&<3w}>h(^0p$)yz2CsMO^-g=C4ZY9?uXpP8PJ5vZz0d})ck1;{ zd!Y@z&<3w}>h(^0p$)yz2CsMO^-g=C4ZY9?uXpP8PJ5vZz0d})ck1;{d!Y@z&<3w} z>h(^0p$)yz2CsMO^-g=C4ZY9?uXpP8PJ5vZz0d})ck1;{d!Y@z&<3w}>h(^0p$)yz z2CsMO^-g=C4ZY9?uXpP8PJ5vZz0d})ck1;{d!Y@z&<3w}>h(^0p$)yz2CsMO^-g=C z4ZY9?uXpP8PJ5vZz0d})ck1;{d!Y@z&<3w}>h(^0p$)yz2CsMO^-g=C4ZY9?uXpP8 zPJ5vZz0d})ck1;{d!Y@z&<3w}>h(^0p$)yz2CsMO^-g=C4ZY9?uXpP8PJ5vZz0d}) zck1;{d!Y@z&<3w}>h(^0p$)yz2CsMO^-g=C4ZY9?uXpP8PJ5vZz0d})ck1;{d!Y@z z&<3w}>h(^0p$)yz2CsMO^-g=C4ZY9?uXpP8PJ5vZz0d})ck1;{d!Y@z&<3w}>h(^0 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 zc)e4vciIbW=!G_Ty;HAu+6!&yg*JG-Q?Ga03vK9yHh8^LuXoxDZRmwIc)e4vciIbW z=!G_Ty;HAu+6!&yg*JG-Q?Ga03vK9yHh8^LuXoxDZRmwIc)e4vciIbW=!G_Ty;HAu z+6!&yg*JG-Q?Ga03vK9yHh8^LuXoxDZRmwIc)e4vciIbW=!G_Ty;HAu+6!&yg*JG- zQ?Ga03vK9yHh8^LuXoxDZRmwIc)e4vciIbW=!G_Ty;HAu+6!&yg*JG-Q?Ga03vK9y zHh8^LuXoxDZRmwIc)e4vciIbW=!G_Ty;HAu+6!&yg*JG-Q?Ga03vK9yHh8^LuXoxD zZRmwIc)e4vciIbW=!G_Ty;HAu+6!&yg*JG-Q?Ga03vK9yHh8^LuXoxDZRmwIc)e4v zciIbW=!G_Ty;HAu+6!&yg*JG-Q?Ga03vK9yHh8^LuXoxDZRmwIc)e4vciIbW=!G_T zy;HAu+6!&yg*JG-Q?Ga03vK9yHh8^LuXoxDZRmwIc)e4vciIbW=!G_Ty;HAu+6!&y zg*JG-Q?Ga03vK9yHh8^LuXoxDZRmwIc)e4vciIbW=!G_Ty;HAu+6!&yg*JG-Q?Ga0 z3vK9yHh8^LuXoxDZRmwIc)e4vciIbW=!G_Ty;HAu+6!&yg*JG-Q?Ga03vK9yHh8^L zuXoxDZRmwIc)e4vciIbW=!G_Ty;HAu+6!&yg*JG-Q?Ga03vK9yHh8^LuXoxDZRmwI zc)e4vciIbW=!G_Ty;HAu+6!&yg*JG-Q?Ga03vK9yHh8^LuXoxDZRmwIc)e4vciIbW z=!G_Ty;HAu+6!&yg*JG-Q?Ga03vK9yHh8^LuXoxDZRmwIc)e4vciIbW=!G_Ty;HAu z+6!&yg*JG-Q?Ga03vK9yHh8^LuXoxDZRmwIc)e4vciIbW=!G_Ty;HAu+6!&yg*JG- zQ?Ga03vK9yHh8^LuXoxDZRmwIc)e4vciIbW=!G_Ty;HAu+6!&yg*JG-Q?Ga03vK9y zHh8^LuXoxDZRmwIc)e4vciIbW=!G_Ty;HAu+6!&yg*JG-Q?Ga03vK9yHh8^LuXoxD zZRmwIc)e4vciIbW=!G_Ty;HAu+6!&yg*JG-Q?Ga03vK9yHh8^LuXoxDZRmwIc)e4v zciIbW=!G_Ty;HAu+6!&yg*JG-Q?Ga03vK9yHh8^LuXoxDZRmwIc)e4vciIbW=!G_T cy;HAu+6!&yg*JG-Q?Ga03vK9yHh8_$A9ZJRF8}}l literal 0 HcmV?d00001 diff --git a/server/server_internals.cpp b/server/server_internals.cpp index 1cfeb4c..4ee835f 100644 --- a/server/server_internals.cpp +++ b/server/server_internals.cpp @@ -78,8 +78,7 @@ void ServerApplication::Init(int argc, char** argv) { //setup the map object regionPager.GetAllocator()->SetLuaState(luaState); regionPager.GetFormat()->SetLuaState(luaState); - //TODO: config parameter - regionPager.GetFormat()->SetSaveDir("save/mapname/"); + regionPager.GetFormat()->SetSaveDir(config["dir.maps"] + config["map.savename"]); std::cout << "Prepared the map system" << std::endl; //push the pager onto the lua registry From fb6fba956473b40cf1928f3ecdf0e091d15a5475 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Mon, 2 Jun 2014 21:05:49 +1000 Subject: [PATCH 6/8] Removed BBox, renamed position to origin I've replaced the BBox class with a pair of inline functions in check_bounds.hpp. I've also renamed the 'position' variable to 'origin' in several locations. These changes are mostly to alleviate ambiguity. --- client/in_world.cpp | 12 ++--- common/gameplay/character_data.cpp | 6 +-- common/gameplay/character_data.hpp | 6 +-- common/gameplay/combat_data.hpp | 6 +-- common/gameplay/enemy_data.hpp | 4 +- common/network/serial.cpp | 16 +++---- common/network/serial_packet.hpp | 4 +- common/utilities/bbox.hpp | 75 ------------------------------ common/utilities/check_bounds.cpp | 40 ++++++++++++++++ common/utilities/check_bounds.hpp | 30 ++++++++++++ common/utilities/vector2.hpp | 6 --- rsc/scripts/setup_server.sql | 4 +- server/character_management.cpp | 12 ++--- server/server_connections.cpp | 6 +-- 14 files changed, 107 insertions(+), 120 deletions(-) delete mode 100644 common/utilities/bbox.hpp create mode 100644 common/utilities/check_bounds.cpp create mode 100644 common/utilities/check_bounds.hpp diff --git a/client/in_world.cpp b/client/in_world.cpp index 8063de6..01a8ed0 100644 --- a/client/in_world.cpp +++ b/client/in_world.cpp @@ -107,8 +107,8 @@ void InWorld::Update(double delta) { //update the camera if(localCharacter) { - camera.x = localCharacter->position.x - camera.marginX; - camera.y = localCharacter->position.y - camera.marginY; + camera.x = localCharacter->origin.x - camera.marginX; + camera.y = localCharacter->origin.y - camera.marginY; } //check the map @@ -134,7 +134,7 @@ void InWorld::Render(SDL_Surface* const screen) { //draw characters for (auto& it : characterMap) { - //TODO: drawing order according to Y position + //TODO: drawing order according to Y origin it.second.DrawTo(screen, camera.x, camera.y); } @@ -291,7 +291,7 @@ void InWorld::HandleCharacterUpdate(SerialPacket packet) { //update only if the message didn't originate from here if (packet.characterInfo.clientIndex != clientIndex) { - characterMap[packet.characterInfo.characterIndex].position = packet.characterInfo.position; + characterMap[packet.characterInfo.characterIndex].origin = packet.characterInfo.origin; characterMap[packet.characterInfo.characterIndex].motion = packet.characterInfo.motion; } characterMap[packet.characterInfo.characterIndex].CorrectSprite(); @@ -310,7 +310,7 @@ void InWorld::HandleCharacterNew(SerialPacket packet) { character.avatar = packet.characterInfo.avatar; character.sprite.LoadSurface(config["dir.sprites"] + character.avatar, 4, 4); character.mapIndex = packet.characterInfo.mapIndex; - character.position = packet.characterInfo.position; + character.origin = packet.characterInfo.origin; character.motion = packet.characterInfo.motion; character.stats = packet.characterInfo.stats; @@ -366,7 +366,7 @@ void InWorld::SendPlayerUpdate() { packet.characterInfo.clientIndex = clientIndex; packet.characterInfo.accountIndex = accountIndex; packet.characterInfo.characterIndex = characterIndex; - packet.characterInfo.position = localCharacter->position; + packet.characterInfo.origin = localCharacter->origin; packet.characterInfo.motion = localCharacter->motion; network.SendTo(Channels::SERVER, &packet); diff --git a/common/gameplay/character_data.cpp b/common/gameplay/character_data.cpp index e86706c..9824c79 100644 --- a/common/gameplay/character_data.cpp +++ b/common/gameplay/character_data.cpp @@ -23,10 +23,10 @@ void CharacterData::Update(double delta) { if (motion.x && motion.y) { - position += motion * delta * CHARACTER_WALKING_MOD; + origin += motion * delta * CHARACTER_WALKING_MOD; } else if (motion != 0) { - position += motion * delta; + origin += motion * delta; } #ifdef GRAPHICS sprite.Update(delta); @@ -36,7 +36,7 @@ void CharacterData::Update(double delta) { #ifdef GRAPHICS void CharacterData::DrawTo(SDL_Surface* const dest, int camX, int camY) { - sprite.DrawTo(dest, position.x - camX, position.y - camY); + sprite.DrawTo(dest, origin.x - camX, origin.y - camY); } void CharacterData::CorrectSprite() { diff --git a/common/gameplay/character_data.hpp b/common/gameplay/character_data.hpp index 128fe16..9547d4e 100644 --- a/common/gameplay/character_data.hpp +++ b/common/gameplay/character_data.hpp @@ -22,8 +22,6 @@ #ifndef CHARACTERDATA_HPP_ #define CHARACTERDATA_HPP_ -//POD members -#include "bbox.hpp" #include "vector2.hpp" #include "statistics.hpp" @@ -48,7 +46,7 @@ struct CharacterData { //world position int mapIndex = 0; - Vector2 position = {0.0,0.0}; + Vector2 origin = {0.0,0.0}; Vector2 motion = {0.0,0.0}; //base statistics @@ -71,7 +69,7 @@ struct CharacterData { #ifdef GRAPHICS SpriteSheet sprite; #endif - BBox bbox = {0,0,0,0}; + Vector2 bounds = {0.0,0.0}; bool inCombat = false; int atbGauge = 0; //TODO: stored command diff --git a/common/gameplay/combat_data.hpp b/common/gameplay/combat_data.hpp index 23bf1f4..db87851 100644 --- a/common/gameplay/combat_data.hpp +++ b/common/gameplay/combat_data.hpp @@ -22,9 +22,7 @@ #ifndef COMBATDATA_HPP_ #define COMBATDATA_HPP_ -//POD members #include "vector2.hpp" -#include "bbox.hpp" //gameplay members #include "character_data.hpp" @@ -58,8 +56,8 @@ struct CombatData { //world interaction int mapIndex = 0; - Vector2 position = {0.0,0.0}; - BBox bbox = {0,0,0,0}; + Vector2 origin = {0.0,0.0}; + Vector2 bounds = {0.0,0.0}; //time interval Clock::time_point lastTick = Clock::now(); diff --git a/common/gameplay/enemy_data.hpp b/common/gameplay/enemy_data.hpp index d0edd0a..62de98c 100644 --- a/common/gameplay/enemy_data.hpp +++ b/common/gameplay/enemy_data.hpp @@ -22,7 +22,7 @@ #ifndef ENEMYDATA_HPP_ #define ENEMYDATA_HPP_ -//gameplay +#include "vector2.hpp" #include "statistics.hpp" //graphics @@ -50,6 +50,8 @@ struct EnemyData { //NOTE: these are lost when unloaded #ifdef GRAPHICS SpriteSheet sprite; + Vector2 origin = {0.0,0.0}; + Vector2 bounds = {0.0,0.0}; #endif int tableIndex; int atbGauge = 0; diff --git a/common/network/serial.cpp b/common/network/serial.cpp index 44c4bfd..961afd4 100644 --- a/common/network/serial.cpp +++ b/common/network/serial.cpp @@ -108,8 +108,8 @@ void serializeCombat(SerialPacket* packet, char* buffer) { //position SERIALIZE(buffer, &packet->combatInfo.mapIndex, sizeof(int)); - SERIALIZE(buffer, &packet->combatInfo.position.x, sizeof(double)); - SERIALIZE(buffer, &packet->combatInfo.position.y, sizeof(double)); + SERIALIZE(buffer, &packet->combatInfo.origin.x, sizeof(double)); + SERIALIZE(buffer, &packet->combatInfo.origin.y, sizeof(double)); //TODO: rewards } @@ -147,8 +147,8 @@ void serializeCharacter(SerialPacket* packet, char* buffer) { SERIALIZE(buffer, packet->clientInfo.avatar, PACKET_STRING_SIZE); //vectors - SERIALIZE(buffer, &packet->characterInfo.position.x, sizeof(double)); - SERIALIZE(buffer, &packet->characterInfo.position.y, sizeof(double)); + SERIALIZE(buffer, &packet->characterInfo.origin.x, sizeof(double)); + SERIALIZE(buffer, &packet->characterInfo.origin.y, sizeof(double)); SERIALIZE(buffer, &packet->characterInfo.motion.x, sizeof(double)); SERIALIZE(buffer, &packet->characterInfo.motion.y, sizeof(double)); @@ -252,8 +252,8 @@ void deserializeCombat(SerialPacket* packet, char* buffer) { //position DESERIALIZE(buffer, &packet->combatInfo.mapIndex, sizeof(int)); - DESERIALIZE(buffer, &packet->combatInfo.position.x, sizeof(double)); - DESERIALIZE(buffer, &packet->combatInfo.position.y, sizeof(double)); + DESERIALIZE(buffer, &packet->combatInfo.origin.x, sizeof(double)); + DESERIALIZE(buffer, &packet->combatInfo.origin.y, sizeof(double)); //TODO: rewards } @@ -292,8 +292,8 @@ void deserializeCharacter(SerialPacket* packet, char* buffer) { DESERIALIZE(buffer, packet->clientInfo.avatar, PACKET_STRING_SIZE); //vectors - DESERIALIZE(buffer, &packet->characterInfo.position.x, sizeof(double)); - DESERIALIZE(buffer, &packet->characterInfo.position.y, sizeof(double)); + DESERIALIZE(buffer, &packet->characterInfo.origin.x, sizeof(double)); + DESERIALIZE(buffer, &packet->characterInfo.origin.y, sizeof(double)); DESERIALIZE(buffer, &packet->characterInfo.motion.x, sizeof(double)); DESERIALIZE(buffer, &packet->characterInfo.motion.y, sizeof(double)); diff --git a/common/network/serial_packet.hpp b/common/network/serial_packet.hpp index f157df1..540494b 100644 --- a/common/network/serial_packet.hpp +++ b/common/network/serial_packet.hpp @@ -150,7 +150,7 @@ union SerialPacket { int characterArray[COMBAT_MAX_CHARACTER_COUNT]; int enemyArray[COMBAT_MAX_ENEMY_COUNT]; int mapIndex; - Vector2 position; + Vector2 origin; //TODO: rewards }combatInfo; @@ -163,7 +163,7 @@ union SerialPacket { char handle[PACKET_STRING_SIZE]; char avatar[PACKET_STRING_SIZE]; int mapIndex; - Vector2 position; + Vector2 origin; Vector2 motion; Statistics stats; }characterInfo; diff --git a/common/utilities/bbox.hpp b/common/utilities/bbox.hpp deleted file mode 100644 index 5b29944..0000000 --- a/common/utilities/bbox.hpp +++ /dev/null @@ -1,75 +0,0 @@ -/* Copyright: (c) Kayne Ruse 2013, 2014 - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. -*/ -#ifndef BBOX_HPP_ -#define BBOX_HPP_ - -#include -#include -#include - -//TODO: This is supposed to interact with the vector -class BBox { -public: - double x, y; - double w, h; - - BBox() = default; - BBox(double i, double j, double k, double l): x(i), y(j), w(k), h(l) {}; - ~BBox() = default; - BBox& operator=(BBox const&) = default; - - double Size() { - return std::max(w*h,0.0); - } - - bool IsCollision(BBox rhs) { - return not ( - x >= rhs.x + rhs.w || - y >= rhs.y + rhs.h || - rhs.x >= x + w || - rhs.y >= y + h - ); - } - - BBox Intersection(BBox rhs) { - if (!IsCollision(rhs)) { - return {0, 0, 0, 0}; - } - BBox ret; - ret.x = std::max(x, rhs.x); - ret.y = std::max(y, rhs.y); - ret.w = std::min(x+w, rhs.x+rhs.w) - ret.x; - ret.h = std::min(y+h, rhs.y+rhs.h) - ret.y; - return ret; - } - - double operator[](size_t i) { - if (i >= 4) - throw(std::domain_error("Out of range")); - return *(&x+i); - } -}; - -//This is explicitly a POD -static_assert(std::is_pod::value, "BBox is not a POD"); - -#endif \ No newline at end of file diff --git a/common/utilities/check_bounds.cpp b/common/utilities/check_bounds.cpp new file mode 100644 index 0000000..b0d42f8 --- /dev/null +++ b/common/utilities/check_bounds.cpp @@ -0,0 +1,40 @@ +/* Copyright: (c) Kayne Ruse 2014 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. +*/ +#include "check_bounds.hpp" + +bool checkPoint(Vector2 const& origin, Vector2 const& bound, Vector2 const& point) { + return !( + point.x < origin.x || + point.y < origin.y || + point.x >= origin.x + bound.x || + point.y >= origin.y + bound.y + ); +} + +bool checkOverlap(Vector2 const& originOne, Vector2 const& boundOne, Vector2 const& originTwo, Vector2 const& boundTwo) { + return !( + originOne.x >= originTwo.x + boundTwo.x || + originOne.x + boundOne.x >= originTwo.x || + originOne.y >= originTwo.y + boundTwo.y || + originOne.y + boundOne.y >= originTwo.y + ); +} diff --git a/common/utilities/check_bounds.hpp b/common/utilities/check_bounds.hpp new file mode 100644 index 0000000..e02d6cd --- /dev/null +++ b/common/utilities/check_bounds.hpp @@ -0,0 +1,30 @@ +/* Copyright: (c) Kayne Ruse 2014 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. +*/ +#ifndef CHECKBOUNDS_HPP_ +#define CHECKBOUNDS_HPP_ + +#include "vector2.hpp" + +bool checkPoint(Vector2 const& origin, Vector2 const& bound, Vector2 const& point); +bool checkOverlap(Vector2 const& originOne, Vector2 const& boundOne, Vector2 const& originTwo, Vector2 const& boundTwo); + +#endif diff --git a/common/utilities/vector2.hpp b/common/utilities/vector2.hpp index a165018..1d8882d 100644 --- a/common/utilities/vector2.hpp +++ b/common/utilities/vector2.hpp @@ -42,12 +42,6 @@ public: return x*x+y*y; } - double operator[](size_t i) { - if (i >= 2) - throw(std::domain_error("Out of range")); - return *(&x+i); - } - //Arithmetic operators Vector2 operator+(Vector2 v) const { Vector2 ret; diff --git a/rsc/scripts/setup_server.sql b/rsc/scripts/setup_server.sql index 9ea5498..7d041bf 100644 --- a/rsc/scripts/setup_server.sql +++ b/rsc/scripts/setup_server.sql @@ -19,8 +19,8 @@ CREATE TABLE IF NOT EXISTS Characters ( --position mapIndex INTEGER DEFAULT 0, - positionX INTEGER DEFAULT 0, - positionY INTEGER DEFAULT 0, + originX INTEGER DEFAULT 0, + originY INTEGER DEFAULT 0, --statistics level INTEGER DEFAULT 0, diff --git a/server/character_management.cpp b/server/character_management.cpp index fe7de3e..4414e13 100644 --- a/server/character_management.cpp +++ b/server/character_management.cpp @@ -32,7 +32,7 @@ //TODO: save and load the statistics static const char* CREATE_CHARACTER = "INSERT INTO Characters (owner, handle, avatar) VALUES (?, ?, ?);"; static const char* LOAD_CHARACTER = "SELECT * FROM Characters WHERE handle = ?;"; -static const char* SAVE_CHARACTER = "UPDATE OR FAIL Characters SET mapIndex = ?2, positionX = ?3, positionY = ?4 WHERE uid = ?1;"; +static const char* SAVE_CHARACTER = "UPDATE OR FAIL Characters SET mapIndex = ?2, originX = ?3, originY = ?4 WHERE uid = ?1;"; static const char* DELETE_CHARACTER = "DELETE FROM Characters WHERE uid = ?;"; //------------------------- @@ -117,10 +117,10 @@ int ServerApplication::LoadCharacter(int owner, std::string handle, std::string newChar.avatar = reinterpret_cast(sqlite3_column_text(statement, 3)); //Don't cache the birth - //world position + //world origin newChar.mapIndex = sqlite3_column_int(statement, 5); - newChar.position.x = (double)sqlite3_column_int(statement, 6); - newChar.position.y = (double)sqlite3_column_int(statement, 7); + newChar.origin.x = (double)sqlite3_column_int(statement, 6); + newChar.origin.y = (double)sqlite3_column_int(statement, 7); //statistics newChar.stats.level = sqlite3_column_int(statement, 8); @@ -176,8 +176,8 @@ int ServerApplication::SaveCharacter(int uid) { bool ret = false; ret |= sqlite3_bind_int(statement, 1, uid) != SQLITE_OK; ret |= sqlite3_bind_int(statement, 2, character.mapIndex) != SQLITE_OK; - ret |= sqlite3_bind_int(statement, 3, (int)character.position.x) != SQLITE_OK; - ret |= sqlite3_bind_int(statement, 4, (int)character.position.y) != SQLITE_OK; + ret |= sqlite3_bind_int(statement, 3, (int)character.origin.x) != SQLITE_OK; + ret |= sqlite3_bind_int(statement, 4, (int)character.origin.y) != SQLITE_OK; //TODO: stats, etc. //check for binding errors diff --git a/server/server_connections.cpp b/server/server_connections.cpp index 11e99ce..6b7f296 100644 --- a/server/server_connections.cpp +++ b/server/server_connections.cpp @@ -75,7 +75,7 @@ void ServerApplication::HandleJoinRequest(SerialPacket packet) { packet.characterInfo.characterIndex = characterIndex; strncpy(packet.characterInfo.handle, characterMap[characterIndex].handle.c_str(), PACKET_STRING_SIZE); strncpy(packet.characterInfo.avatar, characterMap[characterIndex].avatar.c_str(), PACKET_STRING_SIZE); - packet.characterInfo.position = characterMap[characterIndex].position; + packet.characterInfo.origin = characterMap[characterIndex].origin; packet.characterInfo.motion = characterMap[characterIndex].motion; PumpPacket(packet); @@ -99,7 +99,7 @@ void ServerApplication::HandleSynchronize(SerialPacket packet) { snprintf(newPacket.characterInfo.handle, PACKET_STRING_SIZE, "%s", it.second.handle.c_str()); snprintf(newPacket.characterInfo.avatar, PACKET_STRING_SIZE, "%s", it.second.avatar.c_str()); newPacket.characterInfo.mapIndex = it.second.mapIndex; - newPacket.characterInfo.position = it.second.position; + newPacket.characterInfo.origin = it.second.origin; newPacket.characterInfo.motion = it.second.motion; newPacket.characterInfo.stats = it.second.stats; @@ -155,7 +155,7 @@ void ServerApplication::HandleCharacterUpdate(SerialPacket packet) { } //TODO: the server needs it's own movement system too - characterMap[packet.characterInfo.characterIndex].position = packet.characterInfo.position; + characterMap[packet.characterInfo.characterIndex].origin = packet.characterInfo.origin; characterMap[packet.characterInfo.characterIndex].motion = packet.characterInfo.motion; PumpPacket(packet); From 2bebfdfb97f830b82288f00ef27788b897c461f2 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Mon, 2 Jun 2014 22:22:11 +1000 Subject: [PATCH 7/8] Updated database control, character stats are saving Just for the record, I don't like the way SAVE_CHARACTER is expanded like that. --- common/gameplay/account_data.hpp | 2 ++ common/gameplay/character_data.hpp | 2 +- rsc/scripts/setup_server.sql | 7 +++- server/account_management.cpp | 8 +++-- server/character_management.cpp | 51 +++++++++++++++++++++++++++--- 5 files changed, 62 insertions(+), 8 deletions(-) diff --git a/common/gameplay/account_data.hpp b/common/gameplay/account_data.hpp index 7ebc98c..9c3d735 100644 --- a/common/gameplay/account_data.hpp +++ b/common/gameplay/account_data.hpp @@ -29,6 +29,8 @@ struct AccountData { //TODO: password bool blackListed = false; bool whiteListed = true; + bool mod = false; + bool admin = false; int clientIndex; }; diff --git a/common/gameplay/character_data.hpp b/common/gameplay/character_data.hpp index 9547d4e..ff129b2 100644 --- a/common/gameplay/character_data.hpp +++ b/common/gameplay/character_data.hpp @@ -48,6 +48,7 @@ struct CharacterData { int mapIndex = 0; Vector2 origin = {0.0,0.0}; Vector2 motion = {0.0,0.0}; + Vector2 bounds = {0.0,0.0}; //base statistics Statistics stats; @@ -69,7 +70,6 @@ struct CharacterData { #ifdef GRAPHICS SpriteSheet sprite; #endif - Vector2 bounds = {0.0,0.0}; bool inCombat = false; int atbGauge = 0; //TODO: stored command diff --git a/rsc/scripts/setup_server.sql b/rsc/scripts/setup_server.sql index 7d041bf..04a6aab 100644 --- a/rsc/scripts/setup_server.sql +++ b/rsc/scripts/setup_server.sql @@ -1,3 +1,7 @@ +--TODO: why is the database setup script scripted, while accessing, etc. hardcoded? +--there should be a way to control the database more directly +--TODO: move this script into a hardocded Init() method? + CREATE TABLE IF NOT EXISTS Accounts ( uid INTEGER PRIMARY KEY AUTOINCREMENT, username varchar(100) UNIQUE, @@ -5,7 +9,8 @@ CREATE TABLE IF NOT EXISTS Accounts ( -- password varchar(100), blacklisted BIT DEFAULT 0, whitelisted BIT DEFAULT 1, - administrator BIT DEFAULT 0 + mod BIT DEFAULT 0, + admin BIT DEFAULT 0 ); CREATE TABLE IF NOT EXISTS Characters ( diff --git a/server/account_management.cpp b/server/account_management.cpp index cca3630..eb298d8 100644 --- a/server/account_management.cpp +++ b/server/account_management.cpp @@ -31,7 +31,7 @@ static const char* CREATE_USER_ACCOUNT = "INSERT INTO Accounts (username) VALUES (?);"; static const char* LOAD_USER_ACCOUNT = "SELECT * FROM Accounts WHERE username = ?;"; -static const char* SAVE_USER_ACCOUNT = "UPDATE OR FAIL Accounts SET blacklisted = ?2, whitelisted = ?3 WHERE uid = ?1;"; +static const char* SAVE_USER_ACCOUNT = "UPDATE OR FAIL Accounts SET blacklisted = ?2, whitelisted = ?3, mod = ?4, admin = ?5 WHERE uid = ?1;"; static const char* DELETE_USER_ACCOUNT = "DELETE FROM Accounts WHERE uid = ?;"; //------------------------- @@ -98,6 +98,8 @@ int ServerApplication::LoadUserAccount(std::string username, int clientIndex) { newAccount.username = reinterpret_cast(sqlite3_column_text(statement, 1)); newAccount.blackListed = sqlite3_column_int(statement, 2); newAccount.whiteListed = sqlite3_column_int(statement, 3); + newAccount.mod = sqlite3_column_int(statement, 4); + newAccount.admin = sqlite3_column_int(statement, 5); newAccount.clientIndex = clientIndex; //finish the routine @@ -137,6 +139,8 @@ int ServerApplication::SaveUserAccount(int uid) { ret |= sqlite3_bind_int(statement, 1, uid) != SQLITE_OK; ret |= sqlite3_bind_int(statement, 2, account.blackListed) != SQLITE_OK; ret |= sqlite3_bind_int(statement, 3, account.whiteListed) != SQLITE_OK; + ret |= sqlite3_bind_int(statement, 4, account.mod) != SQLITE_OK; + ret |= sqlite3_bind_int(statement, 5, account.admin) != SQLITE_OK; //check for binding errors if (ret) { @@ -165,7 +169,7 @@ void ServerApplication::UnloadUserAccount(int uid) { void ServerApplication::DeleteUserAccount(int uid) { //delete a user account from the database, and remove it from memory - //NOTE: the associated characters are unloaded externally + //NOTE: the associated characters should be deleted externally sqlite3_stmt* statement = nullptr; //prep diff --git a/server/character_management.cpp b/server/character_management.cpp index 4414e13..3991305 100644 --- a/server/character_management.cpp +++ b/server/character_management.cpp @@ -29,17 +29,37 @@ //Define the queries //------------------------- -//TODO: save and load the statistics static const char* CREATE_CHARACTER = "INSERT INTO Characters (owner, handle, avatar) VALUES (?, ?, ?);"; static const char* LOAD_CHARACTER = "SELECT * FROM Characters WHERE handle = ?;"; -static const char* SAVE_CHARACTER = "UPDATE OR FAIL Characters SET mapIndex = ?2, originX = ?3, originY = ?4 WHERE uid = ?1;"; + +static const char* SAVE_CHARACTER = "UPDATE OR FAIL Characters SET " + "mapIndex = ?2," + "originX = ?3," + "originY = ?4," + "level = ?5," + "exp = ?6," + "maxHP = ?7," + "health = ?8," + "maxMP = ?9," + "mana = ?10," + "attack = ?11," + "defence = ?12," + "intelligence = ?13," + "resistance = ?14," + "speed = ?15," + "accuracy = ?16," + "evasion = ?17," + "luck = ?18" +" WHERE uid = ?1;"; + static const char* DELETE_CHARACTER = "DELETE FROM Characters WHERE uid = ?;"; //------------------------- //Define the methods //------------------------- -//TODO: default stats as a parameter +//TODO: should statistics be stored separately? +//TODO: default stats as a parameter? This would be good for differing beggining states or multiple classes int ServerApplication::CreateCharacter(int owner, std::string handle, std::string avatar) { //Create the character, failing if it exists sqlite3_stmt* statement = nullptr; @@ -139,6 +159,9 @@ int ServerApplication::LoadCharacter(int owner, std::string handle, std::string newChar.stats.luck = sqlite3_column_double(statement, 21); //TODO: equipment + //TODO: items + //TODO: buffs + //TODO: debuffs //finish the routine sqlite3_finalize(statement); @@ -178,7 +201,27 @@ int ServerApplication::SaveCharacter(int uid) { ret |= sqlite3_bind_int(statement, 2, character.mapIndex) != SQLITE_OK; ret |= sqlite3_bind_int(statement, 3, (int)character.origin.x) != SQLITE_OK; ret |= sqlite3_bind_int(statement, 4, (int)character.origin.y) != SQLITE_OK; - //TODO: stats, etc. + + //statistics + ret |= sqlite3_bind_int(statement, 5, character.stats.level) != SQLITE_OK; + ret |= sqlite3_bind_int(statement, 6, character.stats.exp) != SQLITE_OK; + ret |= sqlite3_bind_int(statement, 7, character.stats.maxHP) != SQLITE_OK; + ret |= sqlite3_bind_int(statement, 8, character.stats.health) != SQLITE_OK; + ret |= sqlite3_bind_int(statement, 9, character.stats.maxMP) != SQLITE_OK; + ret |= sqlite3_bind_int(statement, 10, character.stats.mana) != SQLITE_OK; + ret |= sqlite3_bind_int(statement, 11, character.stats.attack) != SQLITE_OK; + ret |= sqlite3_bind_int(statement, 12, character.stats.defence) != SQLITE_OK; + ret |= sqlite3_bind_int(statement, 13, character.stats.intelligence) != SQLITE_OK; + ret |= sqlite3_bind_int(statement, 14, character.stats.resistance) != SQLITE_OK; + ret |= sqlite3_bind_int(statement, 15, character.stats.speed) != SQLITE_OK; + ret |= sqlite3_bind_double(statement, 16, character.stats.accuracy) != SQLITE_OK; + ret |= sqlite3_bind_double(statement, 17, character.stats.evasion) != SQLITE_OK; + ret |= sqlite3_bind_double(statement, 18, character.stats.luck) != SQLITE_OK; + + //TODO: equipment + //TODO: items + //TODO: buffs + //TODO: debuffs //check for binding errors if (ret) { From 0a03535ecb7835035c945732d4d2b17bdb70f136 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Mon, 2 Jun 2014 22:35:55 +1000 Subject: [PATCH 8/8] Replaced several lookups to the same object with a reference --- common/network/serial_packet.hpp | 1 + server/server_connections.cpp | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/common/network/serial_packet.hpp b/common/network/serial_packet.hpp index 540494b..d378fde 100644 --- a/common/network/serial_packet.hpp +++ b/common/network/serial_packet.hpp @@ -32,6 +32,7 @@ #define NETWORK_VERSION 20140601 #define PACKET_STRING_SIZE 100 +//TODO: would it be possible to serialize structures directly? union SerialPacket { //types of packets enum class Type { diff --git a/server/server_connections.cpp b/server/server_connections.cpp index 6b7f296..047462f 100644 --- a/server/server_connections.cpp +++ b/server/server_connections.cpp @@ -70,13 +70,21 @@ void ServerApplication::HandleJoinRequest(SerialPacket packet) { //bounce this packet network.SendTo(&newClient.address, &packet); + //reference to prevent multiple lookups + //TODO: I need a way to pack structures unto packets more easily + //NOTE: this chunk of code is similar to HandleSynchronize + CharacterData& character = characterMap[characterIndex]; + //send the new character to all clients packet.meta.type = SerialPacket::Type::CHARACTER_NEW; packet.characterInfo.characterIndex = characterIndex; - strncpy(packet.characterInfo.handle, characterMap[characterIndex].handle.c_str(), PACKET_STRING_SIZE); - strncpy(packet.characterInfo.avatar, characterMap[characterIndex].avatar.c_str(), PACKET_STRING_SIZE); - packet.characterInfo.origin = characterMap[characterIndex].origin; - packet.characterInfo.motion = characterMap[characterIndex].motion; + strncpy(packet.characterInfo.handle, character.handle.c_str(), PACKET_STRING_SIZE); + strncpy(packet.characterInfo.avatar, character.avatar.c_str(), PACKET_STRING_SIZE); + packet.characterInfo.mapIndex = character.mapIndex; + packet.characterInfo.origin = character.origin; + packet.characterInfo.motion = character.motion; + packet.characterInfo.stats = character.stats; + PumpPacket(packet); //TODO: don't send anything to a certain client until they send the OK (the sync packet? or ignore client side?)