diff --git a/client/gameplay_scenes/world_characters.cpp b/client/gameplay_scenes/world_characters.cpp index c790bb6..b0ada57 100644 --- a/client/gameplay_scenes/world_characters.cpp +++ b/client/gameplay_scenes/world_characters.cpp @@ -67,19 +67,20 @@ void World::hCharacterCreate(CharacterPacket* const argPacket) { BaseCharacter* character = &characterMap[argPacket->characterIndex]; //fill the character's info - character->SetOrigin(argPacket->origin); - character->SetMotion(argPacket->motion); - character->SetBounds({CHARACTER_BOUNDS_X, CHARACTER_BOUNDS_Y, CHARACTER_BOUNDS_WIDTH, CHARACTER_BOUNDS_HEIGHT}); //TODO: (2) send the bounds from the server character->SetHandle(argPacket->handle); character->SetAvatar(argPacket->avatar); character->SetOwner(argPacket->accountIndex); + character->SetOrigin(argPacket->origin); + character->SetMotion(argPacket->motion); + character->SetBounds(argPacket->bounds); + character->CorrectSprite(); //check for this player's character if (character->GetOwner() == accountIndex) { localCharacter = static_cast(character); - //focus the camera on this character + //focus the camera on this character's sprite camera.marginX = (camera.width / 2 - localCharacter->GetSprite()->GetImage()->GetClipW() / 2); camera.marginY = (camera.height/ 2 - localCharacter->GetSprite()->GetImage()->GetClipH() / 2); diff --git a/common/network/packet_types/character_packet.cpp b/common/network/packet_types/character_packet.cpp index 98083f3..7906230 100644 --- a/common/network/packet_types/character_packet.cpp +++ b/common/network/packet_types/character_packet.cpp @@ -36,11 +36,18 @@ void serializeCharacter(void* buffer, CharacterPacket* packet) { //location serialCopy(&buffer, &packet->roomIndex, sizeof(int)); + serialCopy(&buffer, &packet->origin.x, sizeof(double)); serialCopy(&buffer, &packet->origin.y, sizeof(double)); + serialCopy(&buffer, &packet->motion.x, sizeof(double)); serialCopy(&buffer, &packet->motion.y, sizeof(double)); + serialCopy(&buffer, &packet->bounds.x, sizeof(int)); + serialCopy(&buffer, &packet->bounds.y, sizeof(int)); + serialCopy(&buffer, &packet->bounds.w, sizeof(int)); + serialCopy(&buffer, &packet->bounds.h, sizeof(int)); + //gameplay components: equipment, items, buffs, debuffs... } @@ -57,10 +64,17 @@ void deserializeCharacter(void* buffer, CharacterPacket* packet) { //location deserialCopy(&buffer, &packet->roomIndex, sizeof(int)); + deserialCopy(&buffer, &packet->origin.x, sizeof(double)); deserialCopy(&buffer, &packet->origin.y, sizeof(double)); + deserialCopy(&buffer, &packet->motion.x, sizeof(double)); deserialCopy(&buffer, &packet->motion.y, sizeof(double)); + deserialCopy(&buffer, &packet->bounds.x, sizeof(int)); + deserialCopy(&buffer, &packet->bounds.y, sizeof(int)); + deserialCopy(&buffer, &packet->bounds.w, sizeof(int)); + deserialCopy(&buffer, &packet->bounds.h, sizeof(int)); + //gameplay components: equipment, items, buffs, debuffs... } diff --git a/common/network/packet_types/character_packet.hpp b/common/network/packet_types/character_packet.hpp index c7e1040..a791bf9 100644 --- a/common/network/packet_types/character_packet.hpp +++ b/common/network/packet_types/character_packet.hpp @@ -24,6 +24,7 @@ #include "serial_packet_base.hpp" +#include "bounding_box.hpp" #include "vector2.hpp" struct CharacterPacket : SerialPacketBase { @@ -39,6 +40,7 @@ struct CharacterPacket : SerialPacketBase { int roomIndex; Vector2 origin; Vector2 motion; + BoundingBox bounds; }; void serializeCharacter(void* buffer, CharacterPacket* packet); diff --git a/common/network/serial_packet.hpp b/common/network/serial_packet.hpp index 180c8dd..dc6083a 100644 --- a/common/network/serial_packet.hpp +++ b/common/network/serial_packet.hpp @@ -34,7 +34,7 @@ typedef SerialPacketBase SerialPacket; //DOCS: NETWORK_VERSION is used to discern compatible servers and clients -constexpr int NETWORK_VERSION = 20150221; +constexpr int NETWORK_VERSION = 20150304; union MaxPacket { CharacterPacket a; diff --git a/rsc/scripts/setup_server.sql b/rsc/scripts/setup_server.sql index a4e3e5b..e8f1ec3 100644 --- a/rsc/scripts/setup_server.sql +++ b/rsc/scripts/setup_server.sql @@ -24,10 +24,14 @@ CREATE TABLE IF NOT EXISTS Characters ( avatar varchar(100), birth timestamp NOT NULL DEFAULT (datetime()), - --position in the world + --physically exists in the world roomIndex INTEGER DEFAULT 0, originX INTEGER DEFAULT 0, originY INTEGER DEFAULT 0, + boundsX INTEGER DEFAULT 0, + boundsY INTEGER DEFAULT 0, + boundsW INTEGER DEFAULT 0, + boundsH INTEGER DEFAULT 0, --statistics baseStats INTEGER REFERENCES StatisticSets(uid), diff --git a/server/characters/character_manager.cpp b/server/characters/character_manager.cpp index 300ee18..a094f51 100644 --- a/server/characters/character_manager.cpp +++ b/server/characters/character_manager.cpp @@ -23,6 +23,8 @@ #include "sqlite3.h" +#include "character_defines.hpp" + #include #include @@ -30,10 +32,45 @@ //Define the queries //------------------------- -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 roomIndex = ?2, originX = ?3, originY = ?4 WHERE uid = ?1;"; +//NOTE: Programmer set variables are NOT zero-indexed +//NOTE: SQLite3 returned variables (i.e. loading) ARE zero-indexed + +static const char* CREATE_CHARACTER = "INSERT INTO Characters (" + "owner, " + "handle, " + "avatar, " + "boundsX, " + "boundsY, " + "boundsW, " + "boundsH" + ") VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7);"; + +static const char* LOAD_CHARACTER = "SELECT " + "uid, " + "owner, " + "handle, " + "avatar, " + "roomIndex, " + "originX, " + "originY, " + "boundsX, " + "boundsY, " + "boundsW, " + "boundsH " + "FROM Characters WHERE handle = ?;"; + +static const char* SAVE_CHARACTER = "UPDATE OR FAIL Characters SET " + "roomIndex = ?2, " + "originX = ?3, " + "originY = ?4, " + "boundsX = ?5, " + "boundsY = ?6, " + "boundsW = ?7, " + "boundsH = ?8 " + "WHERE uid = ?1;"; + static const char* DELETE_CHARACTER = "DELETE FROM Characters WHERE uid = ?;"; + static const char* COUNT_CHARACTER_RECORDS = "SELECT COUNT(*) FROM Characters;"; //------------------------- @@ -55,6 +92,10 @@ int CharacterManager::Create(int owner, std::string handle, std::string avatar) ret |= sqlite3_bind_int(statement, 1, owner); ret |= sqlite3_bind_text(statement, 2, handle.c_str(), handle.size() + 1, SQLITE_STATIC); ret |= sqlite3_bind_text(statement, 3, avatar.c_str(), avatar.size() + 1, SQLITE_STATIC); + ret |= sqlite3_bind_int(statement, 4, CHARACTER_BOUNDS_X); + ret |= sqlite3_bind_int(statement, 5, CHARACTER_BOUNDS_Y); + ret |= sqlite3_bind_int(statement, 6, CHARACTER_BOUNDS_WIDTH); + ret |= sqlite3_bind_int(statement, 7, CHARACTER_BOUNDS_HEIGHT); //check for binding errors if (ret) { @@ -121,9 +162,14 @@ int CharacterManager::Load(int owner, std::string handle, std::string avatar) { //Don't cache the birth //world origin - newChar.roomIndex = sqlite3_column_int(statement, 5); - newChar.origin.x = (double)sqlite3_column_int(statement, 6); - newChar.origin.y = (double)sqlite3_column_int(statement, 7); + newChar.roomIndex = sqlite3_column_int(statement, 4); + newChar.origin.x = (double)sqlite3_column_int(statement, 5); + newChar.origin.y = (double)sqlite3_column_int(statement, 6); + //bounds + newChar.bounds.x = (int)sqlite3_column_int(statement, 7); + newChar.bounds.y = (int)sqlite3_column_int(statement, 8); + newChar.bounds.w = (int)sqlite3_column_int(statement, 9); + newChar.bounds.h = (int)sqlite3_column_int(statement, 10); //gameplay components: equipment, items, buffs, debuffs... @@ -165,6 +211,10 @@ int CharacterManager::Save(int uid) { ret |= sqlite3_bind_int(statement, 2, character.roomIndex) != 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; + ret |= sqlite3_bind_int(statement, 5, character.bounds.x) != SQLITE_OK; + ret |= sqlite3_bind_int(statement, 6, character.bounds.y) != SQLITE_OK; + ret |= sqlite3_bind_int(statement, 7, character.bounds.w) != SQLITE_OK; + ret |= sqlite3_bind_int(statement, 8, character.bounds.h) != SQLITE_OK; //gameplay components: equipment, items, buffs, debuffs... diff --git a/server/entities/entity.cpp b/server/entities/entity.cpp index 5587e81..2c3ec33 100644 --- a/server/entities/entity.cpp +++ b/server/entities/entity.cpp @@ -33,6 +33,10 @@ Vector2 Entity::SetMotion(Vector2 v) { return motion = v; } +BoundingBox Entity::SetBounds(BoundingBox b) { + return bounds = b; +} + int Entity::GetRoomIndex() const { return roomIndex; } @@ -43,4 +47,8 @@ Vector2 Entity::GetOrigin() const { Vector2 Entity::GetMotion() const { return motion; +} + +BoundingBox Entity::GetBounds() const { + return bounds; } \ No newline at end of file diff --git a/server/entities/entity.hpp b/server/entities/entity.hpp index 6874a7e..ab819c7 100644 --- a/server/entities/entity.hpp +++ b/server/entities/entity.hpp @@ -22,6 +22,7 @@ #ifndef ENTITY_HPP_ #define ENTITY_HPP_ +#include "bounding_box.hpp" #include "vector2.hpp" //The base class for all objects in the world @@ -31,10 +32,12 @@ public: int SetRoomIndex(int i); Vector2 SetOrigin(Vector2 v); Vector2 SetMotion(Vector2 v); + BoundingBox SetBounds(BoundingBox b); int GetRoomIndex() const; Vector2 GetOrigin() const; Vector2 GetMotion() const; + BoundingBox GetBounds() const; protected: Entity() = default; @@ -43,6 +46,7 @@ protected: int roomIndex = -1; Vector2 origin; Vector2 motion; + BoundingBox bounds; }; #endif \ No newline at end of file diff --git a/server/entities/entity_api.cpp b/server/entities/entity_api.cpp index bd7d702..584df5c 100644 --- a/server/entities/entity_api.cpp +++ b/server/entities/entity_api.cpp @@ -42,6 +42,17 @@ static int setMotion(lua_State* L) { return 0; } +static int setBounds(lua_State* L) { + Entity* entity = static_cast(lua_touserdata(L, 1)); + entity->SetBounds({ + lua_tointeger(L, 2), + lua_tointeger(L, 3), + lua_tointeger(L, 4), + lua_tointeger(L, 5) + }); + return 0; +} + static int getRoomIndex(lua_State* L) { Entity* entity = static_cast(lua_touserdata(L, 1)); lua_pushinteger(L, entity->GetRoomIndex()); @@ -62,13 +73,24 @@ static int getMotion(lua_State* L) { return 2; } +static int getBounds(lua_State* L) { + Entity* entity = static_cast(lua_touserdata(L, 1)); + lua_pushinteger(L, entity->GetBounds().x); + lua_pushinteger(L, entity->GetBounds().y); + lua_pushinteger(L, entity->GetBounds().w); + lua_pushinteger(L, entity->GetBounds().h); + return 4; +} + static const luaL_Reg entityLib[] = { {"SetRoomIndex", setRoomIndex}, {"SetOrigin", setOrigin}, {"SetMotion", setMotion}, + {"SetBounds", setBounds}, {"GetRoomIndex", getRoomIndex}, {"GetOrigin", getOrigin}, {"GetMotion", getMotion}, + {"GetBounds", getBounds}, {nullptr, nullptr} }; diff --git a/server/server_utilities/server_utilities.cpp b/server/server_utilities/server_utilities.cpp index 58b81ee..edc664f 100644 --- a/server/server_utilities/server_utilities.cpp +++ b/server/server_utilities/server_utilities.cpp @@ -148,4 +148,5 @@ void copyCharacterToPacket(CharacterPacket* const packet, int characterIndex) { packet->roomIndex = characterData->GetRoomIndex(); packet->origin = characterData->GetOrigin(); packet->motion = characterData->GetMotion(); + packet->bounds = characterData->GetBounds(); }