Character bounds are stored in the server database

This allows for customization of bounding boxes, as well as highlighting
aspects needed when adding new fields to the characters.
This commit is contained in:
Kayne Ruse
2015-03-04 04:06:16 +11:00
parent 18a7143926
commit 74ed93ddc7
10 changed files with 118 additions and 12 deletions
+5 -4
View File
@@ -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<LocalCharacter*>(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);
@@ -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...
}
@@ -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);
+1 -1
View File
@@ -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;
+5 -1
View File
@@ -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),
+56 -6
View File
@@ -23,6 +23,8 @@
#include "sqlite3.h"
#include "character_defines.hpp"
#include <algorithm>
#include <stdexcept>
@@ -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...
+8
View File
@@ -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;
}
+4
View File
@@ -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
+22
View File
@@ -42,6 +42,17 @@ static int setMotion(lua_State* L) {
return 0;
}
static int setBounds(lua_State* L) {
Entity* entity = static_cast<Entity*>(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<Entity*>(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<Entity*>(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}
};
@@ -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();
}