Compare commits

..

3 Commits

Author SHA1 Message Date
Kayne Ruse ab6207d4f3 Barriers are working corretly, but are way too slow 2016-04-14 12:43:00 +10:00
Kayne Ruse 1267b30806 Creatures are replaced with barriers 2016-04-14 04:45:30 +10:00
Kayne Ruse 5d217d7cf9 CreatureManager now uses Tuples 2016-04-14 04:19:59 +10:00
98 changed files with 621 additions and 1619 deletions
+2 -2
View File
@@ -7,7 +7,7 @@ This game is inspired by classic 2D RPGs (Final Fantasy, The Legend of Zelda), a
## Releases
* The most recent stable build for Windows can be found [here](https://dl.dropboxusercontent.com/u/46669050/Tortuga-win.rar).
* The most recent stable build for Linux can be found [here](https://dl.dropboxusercontent.com/u/46669050/Tortuga-linux.tar).
* The most recent stable build for Windows can be found [here](https://dl.dropboxusercontent.com/u/46669050/Tortuga-linux.tar).
## Documentation
@@ -52,4 +52,4 @@ Permission is granted to anyone to use this software for any purpose, including
### Items not made by me
* [Coolvetica Font](http://typodermicfonts.com/coolvetica/)
* Creative Commons Artwork from [Artsader](http://www.moosader.com/artsader/)
* Creative Commons Artwork from [Artsader](http://www.moosader.com/artsader/)
+9 -21
View File
@@ -22,7 +22,7 @@
#include "barrier_manager.hpp"
void BarrierManager::DrawTo(SDL_Renderer* const dest, Sint16 x, Sint16 y, double scaleX, double scaleY) {
for (auto& it : elementMap) {
for (auto& it : barrierMap) {
it.second.DrawTo(dest, x, y);
}
}
@@ -47,38 +47,26 @@ void BarrierManager::UnloadTemplateImages() {
}
BaseBarrier* BarrierManager::Create(int index) {
elementMap.emplace(index, BaseBarrier(baseImage, templateImages));
return &elementMap[index];
barrierMap.emplace(index, BaseBarrier(baseImage, templateImages));
return &barrierMap[index];
}
void BarrierManager::Unload(int i) {
elementMap.erase(i);
barrierMap.erase(i);
}
void BarrierManager::UnloadAll() {
elementMap.clear();
}
void BarrierManager::UnloadIf(std::function<bool(std::pair<const int, BaseBarrier const&>)> fn) {
std::map<int, BaseBarrier>::iterator it = elementMap.begin();
while (it != elementMap.end()) {
if (fn(*it)) {
it = elementMap.erase(it);
}
else {
++it;
}
}
barrierMap.clear();
}
int BarrierManager::Size() {
return elementMap.size();
return barrierMap.size();
}
BaseBarrier* BarrierManager::Find(int i) {
std::map<int, BaseBarrier>::iterator it = elementMap.find(i);
std::map<int, BaseBarrier>::iterator it = barrierMap.find(i);
if (it == elementMap.end()) {
if (it == barrierMap.end()) {
return nullptr;
}
@@ -86,7 +74,7 @@ BaseBarrier* BarrierManager::Find(int i) {
}
std::map<int, BaseBarrier>* BarrierManager::GetContainer() {
return &elementMap;
return &barrierMap;
}
std::map<std::string, Image>* BarrierManager::GetTemplateContainer() {
+1 -3
View File
@@ -23,7 +23,6 @@
#include "base_barrier.hpp"
#include <functional>
#include <list>
#include <string>
@@ -43,7 +42,6 @@ public:
BaseBarrier* Create(int index);
void Unload(int i);
void UnloadAll();
void UnloadIf(std::function<bool(std::pair<const int, BaseBarrier const&>)> fn);
int Size();
@@ -54,5 +52,5 @@ public:
private:
Image baseImage;
std::map<std::string, Image> templateImages;
std::map<int, BaseBarrier> elementMap;
std::map<int, BaseBarrier> barrierMap;
};
-58
View File
@@ -1,58 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013-2016
*
* 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 "heartbeat_utility.hpp"
#include "channels.hpp"
#include "ip_operators.hpp"
//heartbeat system
void HeartbeatUtility::hPing(ServerPacket* const argPacket) {
ServerPacket newPacket;
newPacket.type = SerialPacketType::PONG;
network.SendTo(argPacket->srcAddress, &newPacket);
}
void HeartbeatUtility::hPong(ServerPacket* const argPacket) {
if (*network.GetIPAddress(Channels::SERVER) != argPacket->srcAddress) {
throw(std::runtime_error("Heartbeat message received from an unknown source"));
}
attemptedBeats = 0;
lastBeat = Clock::now();
}
int HeartbeatUtility::CheckHeartBeat() {
//check the connection (heartbeat)
if (Clock::now() - lastBeat > std::chrono::seconds(3)) {
if (attemptedBeats > 2) {
return 1;
}
else {
ServerPacket newPacket;
newPacket.type = SerialPacketType::PING;
network.SendTo(Channels::SERVER, &newPacket);
attemptedBeats++;
lastBeat = Clock::now();
}
}
return 0;
}
-42
View File
@@ -1,42 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013-2016
*
* 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.
*/
#pragma once
#include "server_packet.hpp"
#include "udp_network_utility.hpp"
#include <chrono>
class HeartbeatUtility {
public:
//heartbeat system
void hPing(ServerPacket* const);
void hPong(ServerPacket* const);
int CheckHeartBeat();
private:
UDPNetworkUtility& network = UDPNetworkUtility::GetSingleton();
typedef std::chrono::steady_clock Clock;
Clock::time_point lastBeat = Clock::now();
int attemptedBeats = 0;
};
+3 -7
View File
@@ -28,8 +28,6 @@
#include <sstream>
#include <stdexcept>
constexpr SDL_Color WHITE = {255, 255, 255, 255};
//-------------------------
//Public access members
//-------------------------
@@ -51,16 +49,14 @@ DisconnectedScreen::DisconnectedScreen() {
//setup the button
backButton.SetBackgroundTexture(GetRenderer(), image.GetTexture());
backButton.SetText(GetRenderer(), font, WHITE, "Back");
backButton.SetText(GetRenderer(), font, "Back", COLOR_WHITE);
//set the button positions
backButton.SetX(50);
backButton.SetY(50);
//set the disconnection message text
textLine.SetX(50);
textLine.SetY(30);
textLine.SetText(GetRenderer(), font, WHITE, config["client.disconnectMessage"]);
textLine.SetText(GetRenderer(), font, config["client.disconnectMessage"], {255, 255, 255, 255});
//full reset
UDPNetworkUtility::GetSingleton().Unbind(Channels::SERVER);
@@ -96,7 +92,7 @@ void DisconnectedScreen::FrameEnd() {
void DisconnectedScreen::RenderFrame(SDL_Renderer* renderer) {
backButton.DrawTo(renderer);
textLine.DrawTo(renderer);
textLine.DrawTo(renderer, 50, 30);
}
//-------------------------
+7 -15
View File
@@ -27,8 +27,6 @@
#include <stdexcept>
#include <sstream>
constexpr SDL_Color WHITE = {255, 255, 255, 255};
//-------------------------
//Public access members
//-------------------------
@@ -54,11 +52,11 @@ LobbyMenu::LobbyMenu(int* const argClientIndex, int* const argAccountIndex):
//setup the buttons
searchButton.SetBackgroundTexture(GetRenderer(), buttonImage.GetTexture());
searchButton.SetText(GetRenderer(), font, WHITE, "Search");
searchButton.SetText(GetRenderer(), font, "Search", COLOR_WHITE);
joinButton.SetBackgroundTexture(GetRenderer(), buttonImage.GetTexture());
joinButton.SetText(GetRenderer(), font, WHITE, "Join");
joinButton.SetText(GetRenderer(), font, "Join", COLOR_WHITE);
backButton.SetBackgroundTexture(GetRenderer(), buttonImage.GetTexture());
backButton.SetText(GetRenderer(), font, WHITE, "Back");
backButton.SetText(GetRenderer(), font, "Back", COLOR_WHITE);
//set the button positions (assumed)
searchButton.SetX(50);
@@ -69,7 +67,6 @@ LobbyMenu::LobbyMenu(int* const argClientIndex, int* const argAccountIndex):
backButton.SetY(90);
//pseudo-list selection
//TODO: move this into the UI library?
boundingBox = {300, 50, 200, 12};
//hacked together a highlight box
@@ -124,13 +121,8 @@ void LobbyMenu::RenderFrame(SDL_Renderer* renderer) {
}
//draw the server's info
serverVector[i].nameImage.SetX(boundingBox.x);
serverVector[i].nameImage.SetY(boundingBox.y + boundingBox.h * i);
serverVector[i].nameImage.DrawTo(renderer);
serverVector[i].playerCountImage.SetX(boundingBox.x+276);
serverVector[i].playerCountImage.SetY(boundingBox.y + boundingBox.h * i);
serverVector[i].playerCountImage.DrawTo(renderer);
serverVector[i].nameImage.DrawTo(renderer, boundingBox.x, boundingBox.y + boundingBox.h * i);
serverVector[i].playerCountImage.DrawTo(renderer, boundingBox.x+276, boundingBox.y + boundingBox.h * i);
}
}
@@ -256,8 +248,8 @@ void LobbyMenu::HandleBroadcastResponse(ServerPacket* const argPacket) {
};
//text graphics
serverVector.back().nameImage.SetText(GetRenderer(), font, color, newServer.name);
serverVector.back().playerCountImage.SetText(GetRenderer(), font, color, itoa_base10(newServer.playerCount));
serverVector.back().nameImage.SetText(GetRenderer(), font, newServer.name, color);
serverVector.back().playerCountImage.SetText(GetRenderer(), font, itoa_base10(newServer.playerCount), color);
}
void LobbyMenu::HandleJoinResponse(ClientPacket* const argPacket) {
+11 -15
View File
@@ -26,8 +26,6 @@
#include <sstream>
#include <stdexcept>
constexpr SDL_Color WHITE = {255, 255, 255, 255};
//-------------------------
//Public access members
//-------------------------
@@ -48,11 +46,11 @@ MainMenu::MainMenu() {
//setup the buttons
startButton.SetBackgroundTexture(GetRenderer(), buttonImage.GetTexture());
startButton.SetText(GetRenderer(), font, WHITE, "Start");
startButton.SetText(GetRenderer(), font, "Start", COLOR_WHITE);
optionsButton.SetBackgroundTexture(GetRenderer(), buttonImage.GetTexture());
optionsButton.SetText(GetRenderer(), font, WHITE, "Options");
optionsButton.SetText(GetRenderer(), font, "Options", COLOR_WHITE);
quitButton.SetBackgroundTexture(GetRenderer(), buttonImage.GetTexture());
quitButton.SetText(GetRenderer(), font, WHITE, "Quit");
quitButton.SetText(GetRenderer(), font, "Quit", COLOR_WHITE);
//set the button positions
startButton.SetX(50);
@@ -63,15 +61,9 @@ MainMenu::MainMenu() {
quitButton.SetY(50 + 20 * 2);
//text box
int h = -1;
SDL_RenderGetLogicalSize(GetRenderer(), nullptr, &h);
textBox.SetX(50);
textBox.SetY(h-100);
textBox.PushLine(GetRenderer(), font, WHITE, "Thanks for playing!");
textBox.PushLine(GetRenderer(), font, WHITE, "You can get the latest version at: ");
textBox.PushLine(GetRenderer(), font, WHITE, "krgamestudios.com"); //TODO: (9) click to open the website/update
textBox.PushLine(GetRenderer(), font, "Thanks for playing!", {255, 255, 255, 255});
textBox.PushLine(GetRenderer(), font, "You can get the latest version at: ", {255, 255, 255, 255});
textBox.PushLine(GetRenderer(), font, "krgamestudios.com", {255, 255, 255, 255}); //TODO: (9) click to open the website/update
//debug
//
@@ -101,7 +93,11 @@ void MainMenu::RenderFrame(SDL_Renderer* renderer) {
startButton.DrawTo(renderer);
optionsButton.DrawTo(renderer);
quitButton.DrawTo(renderer);
textBox.DrawTo(renderer);
int h = -1;
SDL_RenderGetLogicalSize(GetRenderer(), nullptr, &h);
textBox.DrawTo(renderer, 50, h-50, -12);
}
//-------------------------
+3 -7
View File
@@ -26,8 +26,6 @@
#include <sstream>
#include <stdexcept>
constexpr SDL_Color WHITE = {255, 255, 255, 255};
//-------------------------
//Public access members
//-------------------------
@@ -48,16 +46,14 @@ OptionsMenu::OptionsMenu() {
//setup the button
backButton.SetBackgroundTexture(GetRenderer(), buttonImage.GetTexture());
backButton.SetText(GetRenderer(), font, WHITE, "Back");
backButton.SetText(GetRenderer(), font, "Back", COLOR_WHITE);
//set the button positions
backButton.SetX(50);
backButton.SetY(50);
//text line
textLine.SetX(50);
textLine.SetY(30);
textLine.SetText(GetRenderer(), font, WHITE, "Am I making any progress?");
textLine.SetText(GetRenderer(), font, "This code is fucking hard to refactor.", {255, 255, 255, 255});
}
OptionsMenu::~OptionsMenu() {
@@ -82,7 +78,7 @@ void OptionsMenu::FrameEnd() {
void OptionsMenu::RenderFrame(SDL_Renderer* renderer) {
backButton.DrawTo(renderer);
textLine.DrawTo(renderer);
textLine.DrawTo(renderer, 50, 30);
}
//-------------------------
+77 -56
View File
@@ -34,8 +34,6 @@
#include <sstream>
#include <stdexcept>
constexpr SDL_Color WHITE = {255, 255, 255, 255};
//-------------------------
//static functions
//-------------------------
@@ -74,9 +72,9 @@ World::World(int* const argClientIndex, int* const argAccountIndex):
//setup the buttons
disconnectButton.SetBackgroundTexture(GetRenderer(), buttonImage.GetTexture());
disconnectButton.SetText(GetRenderer(), font, WHITE, "Disconnect");
disconnectButton.SetText(GetRenderer(), font, "Disconnect", COLOR_WHITE);
shutdownButton.SetBackgroundTexture(GetRenderer(), buttonImage.GetTexture());
shutdownButton.SetText(GetRenderer(), font, WHITE, "Shutdown");
shutdownButton.SetText(GetRenderer(), font, "Shutdown", COLOR_WHITE);
//set the button positions
disconnectButton.SetX(50);
@@ -118,8 +116,8 @@ World::World(int* const argClientIndex, int* const argAccountIndex):
"slot 7 red.png",
"slot 8 red.png"
};
barrierMgr.LoadBaseImage(GetRenderer(), config["dir.sprites"] + "barrier/base.png");
barrierMgr.LoadTemplateImages(GetRenderer(), config["dir.sprites"] + "barrier/", slotNames);
barrierMgr.LoadBaseImage(GetRenderer(), config["dir.sprites"] + "/barrier/base.png");
barrierMgr.LoadTemplateImages(GetRenderer(), config["dir.sprites"] + "/barrier/", slotNames);
std::cout << "Templates loaded: " << barrierMgr.GetTemplateContainer()->size() << std::endl;
}
@@ -161,12 +159,7 @@ void World::Update() {
delete reinterpret_cast<char*>(packetBuffer);
//heartbeat system
if (heartbeatUtility.CheckHeartBeat()) {
//escape to the disconnect screen
SendDisconnectRequest();
SetSceneSignal(SceneSignal::DISCONNECTEDSCREEN);
ConfigUtility::GetSingleton()["client.disconnectMessage"] = "Error: Lost connection to the server";
}
CheckHeartBeat();
//update all entities
for (auto& it : characterMap) {
@@ -192,27 +185,7 @@ void World::Update() {
return;
}
//TODO: (0) regular query interval
if (Clock::now() - queryTime > std::chrono::seconds(3)) {
queryTime = Clock::now();
//query the world state (room)
CharacterPacket characterPacket;
memset(&characterPacket, 0, MAX_PACKET_SIZE);
characterPacket.type = SerialPacketType::QUERY_CHARACTER_EXISTS;
characterPacket.roomIndex = roomIndex;
network.SendTo(Channels::SERVER, &characterPacket);
CreaturePacket creaturePacket;
creaturePacket.type = SerialPacketType::QUERY_CREATURE_EXISTS;
creaturePacket.roomIndex = roomIndex;
network.SendTo(Channels::SERVER, &creaturePacket);
BarrierPacket barrierPacket;
barrierPacket.type = SerialPacketType::QUERY_BARRIER_EXISTS;
barrierPacket.roomIndex = roomIndex;
network.SendTo(Channels::SERVER, &barrierPacket);
}
//TODO: (1) regular query interval
//cull creatures
for (std::map<int, BaseCreature>::iterator it = creatureMap.begin(); it != creatureMap.end(); /* */) {
if ( (localCharacter->GetOrigin() - it->second.GetOrigin()).Length() > INFLUENCE_RADIUS) {
@@ -223,10 +196,7 @@ void World::Update() {
}
}
//cull barriers
barrierMgr.UnloadIf([&](std::pair<const int, BaseBarrier const&> barrierIt) -> bool {
return (localCharacter->GetOrigin() - barrierIt.second.GetOrigin()).Length() > INFLUENCE_RADIUS;
});
//TODO: cull barriers
//get the collidable boxes
std::list<BoundingBox> boxList = GenerateCollisionGrid(localCharacter, tileSheet.GetTileW(), tileSheet.GetTileH());
@@ -268,12 +238,12 @@ void World::RenderFrame(SDL_Renderer* renderer) {
shutdownButton.DrawTo(renderer);
//FPS
fpsTextLine.DrawTo(renderer);
fpsTextLine.DrawTo(renderer, 0, 0);
int fpsRet = fps.Calculate();
if (fpsRet != -1) {
std::ostringstream msg;
msg << "FPS: " << fpsRet;
fpsTextLine.SetText(renderer, font, WHITE, msg.str());
fpsTextLine.SetText(renderer, font, msg.str(), {255, 255, 255, 255});
}
}
@@ -416,10 +386,10 @@ void World::HandlePacket(SerialPacket* const argPacket) {
switch(argPacket->type) {
//heartbeat system
case SerialPacketType::PING:
heartbeatUtility.hPing(static_cast<ServerPacket*>(argPacket));
hPing(static_cast<ServerPacket*>(argPacket));
break;
case SerialPacketType::PONG:
heartbeatUtility.hPong(static_cast<ServerPacket*>(argPacket));
hPong(static_cast<ServerPacket*>(argPacket));
break;
//game server connections
@@ -525,6 +495,44 @@ void World::HandlePacket(SerialPacket* const argPacket) {
}
}
//-------------------------
//heartbeat system
//-------------------------
void World::hPing(ServerPacket* const argPacket) {
ServerPacket newPacket;
newPacket.type = SerialPacketType::PONG;
network.SendTo(argPacket->srcAddress, &newPacket);
}
void World::hPong(ServerPacket* const argPacket) {
if (*network.GetIPAddress(Channels::SERVER) != argPacket->srcAddress) {
throw(std::runtime_error("Heartbeat message received from an unknown source"));
}
attemptedBeats = 0;
lastBeat = Clock::now();
}
void World::CheckHeartBeat() {
//check the connection (heartbeat)
if (Clock::now() - lastBeat > std::chrono::seconds(3)) {
if (attemptedBeats > 2) {
//escape to the disconnect screen
SendDisconnectRequest();
SetSceneSignal(SceneSignal::DISCONNECTEDSCREEN);
ConfigUtility::GetSingleton()["client.disconnectMessage"] = "Error: Lost connection to the server";
}
else {
ServerPacket newPacket;
newPacket.type = SerialPacketType::PING;
network.SendTo(Channels::SERVER, &newPacket);
attemptedBeats++;
lastBeat = Clock::now();
}
}
}
//-------------------------
//Connection control
//-------------------------
@@ -719,9 +727,6 @@ void World::hCharacterCreate(CharacterPacket* const argPacket) {
if (character->GetOwner() == accountIndex) {
localCharacter = static_cast<LocalCharacter*>(character);
//reset queries
queryTime = Clock::now() - std::chrono::seconds(4); //back 4 seconds to trigger automatically
//focus the camera on this character's sprite
camera.marginX = (camera.width / 2 - localCharacter->GetSprite()->GetClipW() / 2);
camera.marginY = (camera.height/ 2 - localCharacter->GetSprite()->GetClipH() / 2);
@@ -729,6 +734,26 @@ void World::hCharacterCreate(CharacterPacket* const argPacket) {
//focus on this character's info
characterIndex = argPacket->characterIndex;
roomIndex = argPacket->roomIndex;
//query the world state (room)
CharacterPacket characterPacket;
memset(&characterPacket, 0, MAX_PACKET_SIZE);
characterPacket.type = SerialPacketType::QUERY_CHARACTER_EXISTS;
characterPacket.roomIndex = roomIndex;
characterPacket.origin = localCharacter->GetOrigin();
network.SendTo(Channels::SERVER, &characterPacket);
CreaturePacket creaturePacket;
creaturePacket.type = SerialPacketType::QUERY_CREATURE_EXISTS;
creaturePacket.roomIndex = roomIndex;
creaturePacket.origin = localCharacter->GetOrigin();
network.SendTo(Channels::SERVER, &creaturePacket);
BarrierPacket barrierPacket;
barrierPacket.type = SerialPacketType::QUERY_BARRIER_EXISTS;
barrierPacket.roomIndex = roomIndex;
barrierPacket.origin = localCharacter->GetOrigin();
network.SendTo(Channels::SERVER, &barrierPacket);
}
//debug
@@ -769,12 +794,12 @@ void World::hCharacterUnload(CharacterPacket* const argPacket) {
void World::hQueryCharacterExists(CharacterPacket* const argPacket) {
//prevent a double message about this player's character
//TODO: why is this commented out?
if (argPacket->accountIndex == accountIndex) {
return;
}
// if (argPacket->accountIndex == accountIndex) {
// return;
// }
//ignore characters in a different room (sub-optimal)
if (argPacket->roomIndex != roomIndex || (localCharacter->GetOrigin() - argPacket->origin).Length() > INFLUENCE_RADIUS) {
if (argPacket->roomIndex != roomIndex) {
return;
}
@@ -891,12 +916,10 @@ void World::hCreatureUnload(CreaturePacket* const argPacket) {
}
void World::hQueryCreatureExists(CreaturePacket* const argPacket) {
if (!localCharacter) {
return;
}
std::cout << "Creature Query" << std::endl;
//ignore creatures in a different room (sub-optimal)
if (argPacket->roomIndex != roomIndex || (localCharacter->GetOrigin() - argPacket->origin).Length() > INFLUENCE_RADIUS) {
if (argPacket->roomIndex != roomIndex) {
return;
}
@@ -1001,12 +1024,10 @@ void World::hBarrierUnload(BarrierPacket* const argPacket) {
}
void World::hQueryBarrierExists(BarrierPacket* const argPacket) {
if (!localCharacter) {
return;
}
std::cout << "Barrier Query" << std::endl;
//ignore barriers in a different room (sub-optimal)
if (argPacket->roomIndex != roomIndex || (localCharacter->GetOrigin() - argPacket->origin).Length() > INFLUENCE_RADIUS) {
if (argPacket->roomIndex != roomIndex) {
return;
}
+9 -3
View File
@@ -43,7 +43,6 @@
#include "base_scene.hpp"
#include "base_barrier.hpp"
#include "base_creature.hpp"
#include "heartbeat_utility.hpp"
#include "local_character.hpp"
#include "SDL2/SDL.h"
@@ -81,6 +80,12 @@ private:
//handle incoming traffic
void HandlePacket(SerialPacket* const);
//heartbeat system
void hPing(ServerPacket* const);
void hPong(ServerPacket* const);
void CheckHeartBeat();
//basic connections
void SendLogoutRequest();
void SendDisconnectRequest();
@@ -160,9 +165,10 @@ private:
LocalCharacter* localCharacter = nullptr;
//heartbeat
HeartbeatUtility heartbeatUtility;
//TODO: (2) Heartbeat needs it's own utility
typedef std::chrono::steady_clock Clock;
Clock::time_point queryTime = Clock::now() - std::chrono::seconds(4); //back 4 seconds to trigger automatically
Clock::time_point lastBeat = Clock::now();
int attemptedBeats = 0;
//ugly references; I hate this
ConfigUtility& config = ConfigUtility::GetSingleton();
-32
View File
@@ -1,32 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013-2016
*
* 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.
*/
#pragma once
enum ItemType {
//basics
POTION = 101,
//weapons
SWORD = 201,
DAGGER = 202,
STAFF = 203
};
+20 -20
View File
@@ -21,8 +21,6 @@
*/
#include "button.hpp"
#include "render_text_texture.hpp"
#include <stdexcept>
void Button::DrawTo(SDL_Renderer* renderer) {
@@ -53,9 +51,19 @@ void Button::SetBackgroundTexture(SDL_Renderer* renderer, SDL_Texture* texture)
image.SetClipH(image.GetClipH() / 3);
}
void Button::SetText(SDL_Renderer* renderer, TTF_Font* font, SDL_Color color, std::string s) {
void Button::SetText(SDL_Renderer* renderer, TTF_Font* font, std::string s, SDL_Color color) {
//make the surface (from SDL_ttf)
SDL_Surface* surf = TTF_RenderText_Solid(font, s.c_str(), color);
if (!surf) {
throw(std::runtime_error("Failed to create a TTF surface"));
}
//convert to texture
SDL_Texture* text = renderTextTexture(renderer, font, color, s);
SDL_Texture* text = SDL_CreateTextureFromSurface(renderer, surf);
SDL_FreeSurface(surf);
if (!text) {
throw(std::runtime_error("Failed to create a TTF texture"));
}
//get the dimensions & rects
int x, y, w, h;
@@ -79,6 +87,14 @@ void Button::SetText(SDL_Renderer* renderer, TTF_Font* font, SDL_Color color, st
SDL_DestroyTexture(text);
}
void Button::SetX(int x) {
posX = x;
}
void Button::SetY(int y) {
posY = y;
}
Button::State Button::MouseMotion(SDL_MouseMotionEvent const& event) {
//if out of bounds, exit
if (!CheckBounds(event.x, event.y)) {
@@ -140,22 +156,6 @@ Button::State Button::GetState() {
return state;
}
int Button::SetX(int i) {
return posX = i;
}
int Button::SetY(int i) {
return posY = i;
}
int Button::GetX() const {
return posX;
}
int Button::GetY() const {
return posY;
}
bool Button::CheckBounds(int x, int y) {
//return if true (x, y) is within bounds, otherwise return false
return !(
+9 -8
View File
@@ -27,6 +27,11 @@
#include <string>
constexpr SDL_Color COLOR_WHITE = {255, 255, 255, 255};
constexpr SDL_Color COLOR_RED = {255, 0, 0, 255};
constexpr SDL_Color COLOR_ORANGE = {255, 127, 0, 255};
constexpr SDL_Color COLOR_BLUE = {0, 0, 255, 255};
class Button {
public:
enum State {
@@ -41,7 +46,9 @@ public:
//setup
void SetBackgroundTexture(SDL_Renderer*, SDL_Texture*);
void SetText(SDL_Renderer*, TTF_Font*, SDL_Color, std::string);
void SetText(SDL_Renderer*, TTF_Font*, std::string, SDL_Color);
void SetX(int x);
void SetY(int y);
//capture input
State MouseMotion(SDL_MouseMotionEvent const&);
@@ -52,16 +59,10 @@ public:
void SetState(State); //TODO: idle, busy or disabled
State GetState();
//accessors & mutators
int SetX(int x);
int SetY(int y);
int GetX() const;
int GetY() const;
protected:
bool CheckBounds(int x, int y);
Image image;
State state = State::IDLE;
int posX = 0, posY = 0;
State state = State::IDLE;
};
+1 -1
View File
@@ -1,5 +1,5 @@
#config
INCLUDES+=. ../utilities
INCLUDES+=.
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
-46
View File
@@ -1,46 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013-2016
*
* 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 "render_text_texture.hpp"
#include <stdexcept>
SDL_Texture* renderTextTexture(SDL_Renderer* renderer, TTF_Font* font, SDL_Color color, std::string str) {
//make the surface (from SDL_ttf)
SDL_Surface* surface = TTF_RenderText_Solid(font, str.c_str(), color);
if (!surface) {
throw(std::runtime_error("Failed to create a TTF surface"));
}
//convert to texture
SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface);
//cleanup
SDL_FreeSurface(surface);
//check
if (!texture) {
throw(std::runtime_error("Failed to create a TTF texture"));
}
//NOTE: free the texture yourself
return texture;
}
-29
View File
@@ -1,29 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013-2016
*
* 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.
*/
#pragma once
#include "SDL2/SDL.h"
#include "SDL2/SDL_ttf.h"
#include <string>
SDL_Texture* renderTextTexture(SDL_Renderer*, TTF_Font*, SDL_Color color, std::string);
+6 -25
View File
@@ -31,18 +31,15 @@ TextBox::~TextBox() {
//
}
void TextBox::DrawTo(SDL_Renderer* renderer) {
int renderY = posY;
void TextBox::DrawTo(SDL_Renderer* renderer, int posX, int posY, int pointSize) {
for (std::list<TextLine>::iterator it = lineList.begin(); it != lineList.end(); it++) {
it->SetX(posX);
it->SetY(renderY);
it->DrawTo(renderer);
renderY += it->GetPointHeight();
it->DrawTo(renderer, posX, posY);
posY += pointSize;
}
}
void TextBox::PushLine(SDL_Renderer* renderer, TTF_Font* font, SDL_Color color, std::string str) {
lineList.emplace_back(renderer, font, color, str, 0, 0);
void TextBox::PushLine(SDL_Renderer* renderer, TTF_Font* font, std::string str, SDL_Color color) {
lineList.emplace_front(renderer, font, str, color);
}
void TextBox::PopLine(int num) {
@@ -50,26 +47,10 @@ void TextBox::PopLine(int num) {
num < lineList.size() ? num : lineList.size();
for (int i = 0; i < num; ++i) {
lineList.pop_front();
lineList.pop_back();
}
}
void TextBox::ClearLines() {
lineList.clear();
}
int TextBox::SetX(int i) {
return posX = i;
}
int TextBox::SetY(int i) {
return posY = i;
}
int TextBox::GetX() const {
return posX;
}
int TextBox::GetY() const {
return posY;
}
+2 -8
View File
@@ -34,18 +34,12 @@ public:
TextBox();
~TextBox();
void DrawTo(SDL_Renderer*);
void DrawTo(SDL_Renderer*, int posX, int posY, int pointSize);
void PushLine(SDL_Renderer*, TTF_Font*, SDL_Color color, std::string);
void PushLine(SDL_Renderer*, TTF_Font*, std::string, SDL_Color color);
void PopLine(int num = 1);
void ClearLines();
int SetX(int i);
int SetY(int i);
int GetX() const;
int GetY() const;
private:
std::list<TextLine> lineList;
int posX = 0, posY = 0;
};
-109
View File
@@ -1,109 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013-2016
*
* 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 "text_field.hpp"
#include "render_text_texture.hpp"
TextField::TextField() {
//
}
TextField::~TextField() {
SDL_DestroyTexture(texture);
}
void TextField::DrawTo(SDL_Renderer* renderer) {
if (!texture) {
return;
}
SDL_Rect dclip = {posX, posY, 0, 0};
SDL_QueryTexture(texture, nullptr, nullptr, &dclip.w, &dclip.h);
SDL_RenderCopy(renderer, texture, nullptr, &dclip);
}
std::string TextField::PushText(SDL_Renderer* renderer, TTF_Font* font, SDL_Color color, std::string s) {
text += s;
return SetText(renderer, font, color, text);
}
std::string TextField::SetText(SDL_Renderer* renderer, TTF_Font* font, SDL_Color color, std::string s) {
text = s;
SDL_DestroyTexture(texture);
if (text.size()) {
texture = renderTextTexture(renderer, font, color, text);
}
else {
texture = nullptr;
}
return text;
}
std::string TextField::PopChars(SDL_Renderer* renderer, TTF_Font* font, SDL_Color color, int i) {
if (text.size() > 0) {
text.erase(text.size() - i);
}
return SetText(renderer, font, color, text);
}
std::string TextField::GetText() {
return text;
}
bool TextField::MouseButtonDown(SDL_MouseButtonEvent const& event) {
BoundingBox cursorBox = {event.x, event.y, 0, 0};
BoundingBox fieldBox = bounds;
fieldBox.x += posX;
fieldBox.y += posY;
return focus = fieldBox.CheckOverlap(cursorBox);
}
BoundingBox TextField::SetBounds(BoundingBox b) {
return bounds = b;
}
BoundingBox TextField::GetBounds() {
return bounds;
}
bool TextField::SetFocus(bool b) {
return focus = b;
}
bool TextField::GetFocus() {
return focus;
}
int TextField::SetX(int i) {
return posX = i;
}
int TextField::SetY(int i) {
return posY = i;
}
int TextField::GetX() const {
return posX;
}
int TextField::GetY() const {
return posY;
}
-65
View File
@@ -1,65 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013-2016
*
* 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.
*/
#pragma once
#include "bounding_box.hpp"
#include "SDL2/SDL.h"
#include "SDL2/SDL_ttf.h"
#include <string>
class TextField {
public:
TextField();
~TextField();
void DrawTo(SDL_Renderer*);
//input
std::string PushText(SDL_Renderer*, TTF_Font*, SDL_Color color, std::string);
std::string SetText(SDL_Renderer*, TTF_Font*, SDL_Color color, std::string);
std::string PopChars(SDL_Renderer*, TTF_Font*, SDL_Color color, int i);
std::string GetText();
bool MouseButtonDown(SDL_MouseButtonEvent const& event);
BoundingBox SetBounds(BoundingBox b);
BoundingBox GetBounds();
bool SetFocus(bool b);
bool GetFocus();
//accessors & mutators
int SetX(int i);
int SetY(int i);
int GetX() const;
int GetY() const;
private:
SDL_Texture* texture = nullptr;
std::string text;
BoundingBox bounds;
bool focus = false;
int posX = 0, posY = 0;
};
+25 -33
View File
@@ -21,58 +21,50 @@
*/
#include "text_line.hpp"
#include "render_text_texture.hpp"
#include <stdexcept>
SDL_Texture* renderTextTexture(SDL_Renderer* renderer, TTF_Font* font, std::string str, SDL_Color color) {
//make the surface (from SDL_ttf)
SDL_Surface* surface = TTF_RenderText_Solid(font, str.c_str(), color);
if (!surface) {
throw(std::runtime_error("Failed to create a TTF surface"));
}
//convert to texture
SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface);
//cleanup
SDL_FreeSurface(surface);
//check
if (!texture) {
throw(std::runtime_error("Failed to create a TTF texture"));
}
//NOTE: free the texture yourself
return texture;
}
TextLine::TextLine() {
//
}
TextLine::TextLine(SDL_Renderer* renderer, TTF_Font* font, SDL_Color color, std::string str, int x, int y) {
SetText(renderer, font, color, str);
posX = x;
posY = y;
}
TextLine::~TextLine() {
ClearText();
}
void TextLine::DrawTo(SDL_Renderer* renderer) {
void TextLine::DrawTo(SDL_Renderer* renderer, int posX, int posY) {
SDL_Rect dclip = {posX, posY, 0, 0};
SDL_QueryTexture(texture, nullptr, nullptr, &dclip.w, &dclip.h);
SDL_RenderCopy(renderer, texture, nullptr, &dclip);
}
void TextLine::SetText(SDL_Renderer* renderer, TTF_Font* font, SDL_Color color, std::string str) {
void TextLine::SetText(SDL_Renderer* renderer, TTF_Font* font, std::string str, SDL_Color color) {
//just use the above global function
SDL_DestroyTexture(texture);
texture = renderTextTexture(renderer, font, color, str);
pointHeight = TTF_FontHeight(font);
texture = renderTextTexture(renderer, font, str, color);
}
void TextLine::ClearText() {
SDL_DestroyTexture(texture);
pointHeight = 0;
}
int TextLine::SetX(int i) {
return posX = i;
}
int TextLine::SetY(int i) {
return posY = i;
}
int TextLine::GetX() const {
return posX;
}
int TextLine::GetY() const {
return posY;
}
int TextLine::GetPointHeight() {
return pointHeight;
}
+6 -14
View File
@@ -26,28 +26,20 @@
#include <string>
SDL_Texture* renderTextTexture(SDL_Renderer*, TTF_Font*, std::string, SDL_Color color);
class TextLine {
public:
TextLine();
TextLine(SDL_Renderer*, TTF_Font*, SDL_Color, std::string, int x, int y);
TextLine(SDL_Renderer* r, TTF_Font* f, std::string s, SDL_Color c)
{ SetText(r, f, s, c); }
virtual ~TextLine();
void DrawTo(SDL_Renderer*);
void DrawTo(SDL_Renderer*, int posX, int posY);
void SetText(SDL_Renderer*, TTF_Font*, SDL_Color, std::string);
void SetText(SDL_Renderer*, TTF_Font*, std::string, SDL_Color color);
void ClearText();
//accessors & mutators
int SetX(int i);
int SetY(int i);
int GetX() const;
int GetY() const;
//utility
int GetPointHeight();
protected:
SDL_Texture* texture = nullptr;
int posX = 0, posY = 0;
int pointHeight = 0; //internal use for TextBox
};
+7 -8
View File
@@ -34,16 +34,15 @@
typedef SerialPacketBase SerialPacket;
//DOCS: NETWORK_VERSION is used to discern compatible servers and clients
constexpr int NETWORK_VERSION = 20160825;
constexpr int NETWORK_VERSION = 20160404;
union MaxPacket {
BarrierPacket a;
CharacterPacket b;
ClientPacket c;
CreaturePacket d;
RegionPacket e;
ServerPacket f;
TextPacket g;
CharacterPacket a;
ClientPacket b;
CreaturePacket c;
RegionPacket d;
ServerPacket e;
TextPacket f;
};
constexpr int MAX_PACKET_SIZE = sizeof(MaxPacket);
+19 -22
View File
@@ -142,6 +142,25 @@ enum class SerialPacketType {
FORMAT_END_CREATURE = 599,
//-------------------------
//BarrierPacket
// barrier index,
// bounds,
// roomIndex, origin, motion
// status
//-------------------------
FORMAT_COMBAT = 700,
BARRIER_UPDATE = 701,
BARRIER_CREATE = 702,
BARRIER_UNLOAD = 703,
QUERY_BARRIER_EXISTS = 704,
FORMAT_END_COMBAT = 799,
//-------------------------
//TextPacket
// name, text
@@ -165,28 +184,6 @@ enum class SerialPacketType {
FORMAT_END_TEXT = 699,
//-------------------------
//BarrierPacket
// barrier index,
// bounds,
// roomIndex, origin, motion
// status
//-------------------------
FORMAT_BARRIER = 700,
BARRIER_UPDATE = 701,
BARRIER_CREATE = 702,
BARRIER_UNLOAD = 703,
QUERY_BARRIER_EXISTS = 704,
BARRIER_ENTRY = 705,
BARRIER_EXIT = 706,
FORMAT_END_BARRIER = 799,
//-------------------------
//not used
//-------------------------
+8 -8
View File
@@ -70,12 +70,12 @@ void serializePacket(void* buffer, SerialPacketBase* packet) {
serializeCreature(buffer, static_cast<CreaturePacket*>(packet));
}
if (BOUNDS(packet->type, SerialPacketType::FORMAT_TEXT, SerialPacketType::FORMAT_END_TEXT)) {
serializeText(buffer, static_cast<TextPacket*>(packet));
if (BOUNDS(packet->type, SerialPacketType::FORMAT_COMBAT, SerialPacketType::FORMAT_END_COMBAT)) {
serializeBarrier(buffer, static_cast<BarrierPacket*>(packet));
}
if (BOUNDS(packet->type, SerialPacketType::FORMAT_BARRIER, SerialPacketType::FORMAT_END_BARRIER)) {
serializeBarrier(buffer, static_cast<BarrierPacket*>(packet));
if (BOUNDS(packet->type, SerialPacketType::FORMAT_TEXT, SerialPacketType::FORMAT_END_TEXT)) {
serializeText(buffer, static_cast<TextPacket*>(packet));
}
}
@@ -104,11 +104,11 @@ void deserializePacket(void* buffer, SerialPacketBase* packet) {
deserializeCreature(buffer, static_cast<CreaturePacket*>(packet));
}
if (BOUNDS(type, SerialPacketType::FORMAT_COMBAT, SerialPacketType::FORMAT_END_COMBAT)) {
deserializeBarrier(buffer, static_cast<BarrierPacket*>(packet));
}
if (BOUNDS(type, SerialPacketType::FORMAT_TEXT, SerialPacketType::FORMAT_END_TEXT)) {
deserializeText(buffer, static_cast<TextPacket*>(packet));
}
if (BOUNDS(type, SerialPacketType::FORMAT_BARRIER, SerialPacketType::FORMAT_END_BARRIER)) {
deserializeBarrier(buffer, static_cast<BarrierPacket*>(packet));
}
}
-125
View File
@@ -1,125 +0,0 @@
/* Copyright: (c) Kayne Ruse 2015
*
* 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.
*/
#pragma once
//DOCS: this is a generic CSV reading tool
//DOCS: empty lines and comment lines begining with '#' are ignored
//DOCS: whitespace characters are valid field values
//DOCS: if the file is invalid, then the behavior is undefined
#include <array>
#include <cstring>
#include <fstream>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>
//define the container types
template<int N>
using CSVElement = std::array<std::string, N>;
template<int N>
using CSVObject = std::vector<CSVElement<N>>;
//read a file into an object
template<int N>
CSVObject<N> readCSV(std::string fname, char delim = ',') {
//open the file
std::ifstream is(fname);
if (!is.is_open()) {
std::ostringstream msg;
msg << "Failed to open file: " << fname;
throw(std::runtime_error(msg.str()));
}
//build the scanf format
std::ostringstream format;
format << "%[^\0" << delim << "]";
//read and store each record (one per line)
CSVObject<N> object;
while(!is.eof()) {
//get a line
std::string tmpLine;
getline(is, tmpLine);
//skip blank and comment lines
if (tmpLine.size() == 0 || tmpLine[0] == '#') {
continue;
}
//read and store each field
CSVElement<N> record;
for (int i = 0; i < N; ++i) {
//get a field
char tmpField[256];
memset(tmpField, 0, 256);
sscanf(tmpLine.c_str(), format.str().c_str(), tmpField);
//prune the input
int len = std::min(strlen(tmpField)+1, tmpLine.size());
tmpLine = tmpLine.substr(len);
//store the field
record[i] = tmpField;
}
object.push_back(record);
}
//finally, close the file
is.close();
return object;
}
template<int N>
void writeCSV(std::string fname, CSVObject<N> const& object, char delim = ',') {
//open the file
std::ofstream os(fname);
if (!os.is_open()) {
std::ostringstream msg;
msg << "Failed to open file: " << fname;
throw(std::runtime_error(msg.str()));
}
//write each record, one at a time
for(auto& record : object) {
//write each field, one at a time
for (int i = 0; i < N; i++) {
os << record[i];
//print delimiter
if (i != N -1) {
os << delim;
}
}
os << std::endl;
}
//finish
os.close();
}
-5
View File
@@ -1,5 +0,0 @@
#Format (4 columns): "name", type, "sprite.png", stackable
"Sword",weapon,"sword.png",false
"Staff",weapon,"staff.png",false
"Dagger",weapon,"dagger.png",false
"Potion",consumable,"potion.png",true
Can't render this file because it contains an unexpected character in line 1 and column 22.
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1009 B

Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 316 B

Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 738 B

After

Width:  |  Height:  |  Size: 738 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 763 B

After

Width:  |  Height:  |  Size: 763 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 273 B

After

Width:  |  Height:  |  Size: 273 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 270 B

After

Width:  |  Height:  |  Size: 270 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 305 B

After

Width:  |  Height:  |  Size: 305 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 302 B

After

Width:  |  Height:  |  Size: 302 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 423 B

After

Width:  |  Height:  |  Size: 423 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 422 B

After

Width:  |  Height:  |  Size: 422 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 301 B

After

Width:  |  Height:  |  Size: 301 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 299 B

After

Width:  |  Height:  |  Size: 299 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 385 B

After

Width:  |  Height:  |  Size: 385 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 383 B

After

Width:  |  Height:  |  Size: 383 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 412 B

After

Width:  |  Height:  |  Size: 412 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 402 B

After

Width:  |  Height:  |  Size: 402 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 431 B

After

Width:  |  Height:  |  Size: 431 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 429 B

After

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 407 B

After

Width:  |  Height:  |  Size: 407 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 400 B

After

Width:  |  Height:  |  Size: 400 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 656 B

After

Width:  |  Height:  |  Size: 656 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 680 B

+3 -15
View File
@@ -130,14 +130,14 @@ roomManagerAPI.SetOnCreate(function(room, index)
--
end)
creatureManagerAPI.Create(roomAPI.GetCreatureMgr(room), "anibunny.png", bunnySquare)
--creatureManager with SetOnCreate, SetOnUnload & create & unload
barrierManagerAPI.SetOnCreate(roomAPI.GetBarrierMgr(room), function(barrier)
barrierAPI.SetScript(barrier, barrierTick)
end)
roomAPI.SetOnTick(room, function(room)
ret = 0
--placeholders
roomAPI.ForEachCharacter(room, function(character)
--
end)
@@ -146,19 +146,7 @@ roomManagerAPI.SetOnCreate(function(room, index)
--
end)
roomAPI.ForEachBarrier(room, function(creature)
--
end)
--respawn a new rabbit when needed
if creatureManagerAPI.GetLoadedCount(roomAPI.GetCreatureMgr(room)) < 1 and
barrierManagerAPI.GetLoadedCount(roomAPI.GetBarrierMgr(room)) < 2
then
--make a new creature
creatureManagerAPI.Create(roomAPI.GetCreatureMgr(room), "anibunny.png", bunnySquare)
ret = 1
end
return ret
--TODO: for each barrier
end)
end)
+87 -51
View File
@@ -20,23 +20,13 @@
* distribution.
*/
-------------------------
--defines
-------------------------
PRAGMA foreign_keys = ON;
-------------------------
--table definitions
-------------------------
CREATE TABLE IF NOT EXISTS UserAccounts (
uid INTEGER PRIMARY KEY AUTOINCREMENT,
username varchar(100) UNIQUE, --TODO: (3) Swap username for email address
--server-client security
passhash varchar(100),
passsalt varchar(100),
-- passhash varchar(100),
-- passsalt varchar(100),
--server controls
blacklisted BIT DEFAULT 0,
@@ -49,8 +39,8 @@ CREATE TABLE IF NOT EXISTS LiveCharacters (
uid INTEGER PRIMARY KEY AUTOINCREMENT,
--metadata
owner INTEGER REFERENCES UserAccounts(uid),
handle varchar(100),
owner INTEGER REFERENCES Accounts(uid),
handle varchar(100) UNIQUE,
avatar varchar(100),
birth timestamp NOT NULL DEFAULT (datetime()),
@@ -58,8 +48,59 @@ CREATE TABLE IF NOT EXISTS LiveCharacters (
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
);
--combat stats
CREATE TABLE IF NOT EXISTS DeadCharacters (
uid INTEGER PRIMARY KEY,
--metadata
owner INTEGER REFERENCES Accounts(uid),
handle varchar(100),
avatar varchar(100),
birth timestamp NOT NULL
);
CREATE TABLE IF NOT EXISTS LiveMonsters (
uid INTEGER PRIMARY KEY AUTOINCREMENT,
--metadata
handle varchar(100) UNIQUE,
avatar varchar(100),
--actions
-- script
--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
);
CREATE TABLE IF NOT EXISTS DeadMonsters (
uid INTEGER PRIMARY KEY,
--metadata
handle varchar(100) UNIQUE,
avatar varchar(100)
);
-------------------------
--Utility tables
-------------------------
CREATE TABLE IF NOT EXISTS StatisticSets (
--metadata
uid INTEGER PRIMARY KEY AUTOINCREMENT,
--general use statistics
level INTEGER DEFAULT 0,
exp INTEGER DEFAULT 0,
maxHP INTEGER DEFAULT 0,
@@ -70,53 +111,48 @@ CREATE TABLE IF NOT EXISTS LiveCharacters (
defence INTEGER DEFAULT 0,
intelligence INTEGER DEFAULT 0,
resistance INTEGER DEFAULT 0,
accuracy INTEGER DEFAULT 0,
evasion INTEGER DEFAULT 0,
speed INTEGER DEFAULT 0,
luck INTEGER DEFAULT 0
accuracy REAL DEFAULT 0.0,
evasion REAL DEFAULT 0.0,
luck REAL DEFAULT 0.0
);
CREATE TABLE IF NOT EXISTS DeadCharacters (
uid INTEGER PRIMARY KEY,
CREATE TABLE IF NOT EXISTS InWorldItems (
--metadata
owner INTEGER REFERENCES UserAccounts(uid),
handle varchar(100),
avatar varchar(100),
birth timestamp NOT NULL,
death timestamp NOT NULL DEFAULT (datetime()),
uid INTEGER PRIMARY KEY AUTOINCREMENT,
itemType INTEGER,
--combat stats
level INTEGER DEFAULT 0,
exp INTEGER DEFAULT 0,
maxHP INTEGER DEFAULT 0,
maxMP INTEGER DEFAULT 0,
attack INTEGER DEFAULT 0,
defence INTEGER DEFAULT 0,
intelligence INTEGER DEFAULT 0,
resistance INTEGER DEFAULT 0,
accuracy INTEGER DEFAULT 0,
evasion INTEGER DEFAULT 0,
speed INTEGER DEFAULT 0,
luck INTEGER DEFAULT 0
--position in the world
roomIndex INTEGER DEFAULT 0,
originX INTEGER DEFAULT 0,
originY INTEGER DEFAULT 0,
--unique information
stackSize INTEGER DEFAULT 0,
durability INTEGER DEFAULT 0,
stats INTEGER REFERENCES StatisticSets(uid)
);
-------------------------
--global tables
-------------------------
CREATE TABLE IF NOT EXISTS InventoryItems (
--metadata
uid INTEGER PRIMARY KEY AUTOINCREMENT,
name varchar(100) UNIQUE,
type varchar(100), --tmp type
uid INTEGER PRIMARY KEY AUTOINCREMENT,
owner INTEGER REFERENCES Characters(uid),
itemType INTEGER,
--unique information
durability INTEGER DEFAULT 0
stackSize INTEGER DEFAULT 0,
durability INTEGER DEFAULT 0,
stats INTEGER REFERENCES StatisticSets(uid)
);
-------------------------
--member tables
-------------------------
CREATE TABLE IF NOT EXISTS WornEquipment (
--metadata
uid INTEGER PRIMARY KEY AUTOINCREMENT,
owner INTEGER REFERENCES Characters(uid),
itemType INTEGER,
--TODO
--unique information
durability INTEGER DEFAULT 0,
stats INTEGER REFERENCES StatisticSets(uid)
--attached script?
);
-23
View File
@@ -1,23 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013-2016
*
* 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 "inventory.hpp"
-35
View File
@@ -1,35 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013-2016
*
* 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.
*/
#pragma once
#include "item_data.hpp"
#include <list>
class Inventory {
public:
Inventory() = default;
~Inventory() = default;
private:
std::list<ItemData> itemList;
};
-23
View File
@@ -1,23 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013-2016
*
* 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 "inventory_manager.hpp"
-33
View File
@@ -1,33 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013-2016
*
* 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.
*/
#pragma once
#include "inventory.hpp"
class InventoryManager {
public:
InventoryManager() = default;
~InventoryManager() = default;
private:
//
};
-41
View File
@@ -1,41 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013-2016
*
* 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.
*/
#pragma once
#include "item_type.hpp"
class ItemData {
public:
ItemData() = default;
~ItemData() = default;
//accessors and mutators
ItemType SetItemType(ItemType);
ItemType GetItemType();
int SetQuantity(int);
int GetQuantity();
private:
ItemType type;
int quantity = 1;
};
-32
View File
@@ -1,32 +0,0 @@
#config
INCLUDES+=. .. ../characters ../creatures ../entities ../inventory ../../common/gameplay ../../common/utilities
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
#source
CXXSRC=$(wildcard *.cpp)
#objects
OBJDIR=obj
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
#output
OUTDIR=..
OUT=$(addprefix $(OUTDIR)/,server.a)
#targets
all: $(OBJ) $(OUT)
ar -crs $(OUT) $(OBJ)
$(OBJ): | $(OBJDIR)
$(OUT): | $(OUTDIR)
$(OBJDIR):
mkdir $(OBJDIR)
$(OUTDIR):
mkdir $(OUTDIR)
$(OBJDIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
-75
View File
@@ -1,75 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013-2016
*
* 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 "battle_data.hpp"
#include <algorithm>
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
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;
}
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;
}
int BattleData::PushCreature(CreatureData* const creatureData) {
//TODO: (0) EMPTY
}
int BattleData::PopCreature(CreatureData const * const creatureData) {
//TODO: (0) EMPTY
}
-32
View File
@@ -1,32 +0,0 @@
#config
INCLUDES+=. .. ../characters ../creatures ../entities ../inventory ../../common/gameplay ../../common/utilities
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
#source
CXXSRC=$(wildcard *.cpp)
#objects
OBJDIR=obj
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
#output
OUTDIR=..
OUT=$(addprefix $(OUTDIR)/,server.a)
#targets
all: $(OBJ) $(OUT)
ar -crs $(OUT) $(OBJ)
$(OBJ): | $(OBJDIR)
$(OUT): | $(OUTDIR)
$(OBJDIR):
mkdir $(OBJDIR)
$(OUTDIR):
mkdir $(OUTDIR)
$(OBJDIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
+26 -25
View File
@@ -28,51 +28,53 @@
#include "server_utilities.hpp"
#include <stdexcept>
#include <iostream>
static int setRoom(lua_State* L) {
//variables
//reverse engineer the character index
int characterIndex = -1;
CharacterData* character = static_cast<CharacterData*>(lua_touserdata(L, 1));
CharacterManager& characterMgr = CharacterManager::GetSingleton();
for (auto& it : *characterMgr.GetContainer()) {
if (character == &it.second) {
characterIndex = it.first;
break;
}
}
//error checking
if (characterMgr.Find(character->GetIndex()) != character) {
throw(std::runtime_error("Lua Error: Failed to verify character index by reference"));
if (characterIndex == -1) {
throw(std::runtime_error("Lua Error: Failed to find character index by reference"));
}
//get the room index, depending on the parameter type
int roomIndex = -1;
RoomManager& roomMgr = RoomManager::GetSingleton();
switch(lua_type(L, 2)) {
case LUA_TNUMBER:
//simple integer
roomIndex = lua_tointeger(L, 2);
break;
case LUA_TLIGHTUSERDATA: {
//check that this is a room first
RoomData* room = static_cast<RoomData*>(lua_touserdata(L, 2));
RoomManager& roomMgr = RoomManager::GetSingleton();
if (roomMgr.Find(room->GetRoomIndex()) != room) {
std::cout << room->GetRoomIndex() << std::endl;
throw(std::runtime_error("Lua Error: Failed to verify room index by reference"));
case LUA_TLIGHTUSERDATA:
//reverse engineer the room index
for (auto& it : *roomMgr.GetContainer()) {
if (lua_touserdata(L, 2) == &it.second) {
roomIndex = it.first;
break;
}
}
roomIndex = room->GetRoomIndex();
}
break;
default:
throw(std::runtime_error("Lua Error: Failed to find room index by reference"));
}
//error checking
if (roomIndex == -1) {
throw(std::runtime_error("Lua Error: Failed to find room index by reference"));
}
//send the delete & create messages
pumpAndChangeRooms(character, roomIndex, character->GetIndex());
pumpAndChangeRooms(character, roomIndex, characterIndex);
return 0;
}
static int getIndex(lua_State* L) {
CharacterData* character = static_cast<CharacterData*>(lua_touserdata(L, 1));
lua_pushinteger(L, character->GetIndex());
return 1;
}
static int getOwner(lua_State* L) {
CharacterData* character = static_cast<CharacterData*>(lua_touserdata(L, 1));
lua_pushinteger(L, character->GetOwner());
@@ -93,7 +95,6 @@ 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},
-12
View File
@@ -30,14 +30,6 @@ CharacterData::CharacterData(): Entity("character") {
});
}
//-------------------------
//database stuff
//-------------------------
int CharacterData::GetIndex() {
return index;
}
int CharacterData::GetOwner() {
return owner;
}
@@ -48,8 +40,4 @@ std::string CharacterData::GetHandle() {
std::string CharacterData::GetAvatar() {
return avatar;
}
Inventory* CharacterData::GetInventory() {
return &inventory;
}
-6
View File
@@ -24,7 +24,6 @@
//components
#include "character_defines.hpp"
#include "entity.hpp"
#include "inventory.hpp"
//std namespace
#include <string>
@@ -36,19 +35,14 @@ public:
~CharacterData() = default;
//database stuff
int GetIndex();
int GetOwner();
std::string GetHandle();
std::string GetAvatar();
Inventory* GetInventory();
private:
friend class CharacterManager;
//database stuff
int index = -1;
int owner = -1;
std::string handle;
std::string avatar;
Inventory inventory;
};
+29 -10
View File
@@ -39,8 +39,12 @@
static const char* CREATE_CHARACTER = "INSERT INTO LiveCharacters ("
"owner, "
"handle, "
"avatar "
") VALUES (?1, ?2, ?3);";
"avatar, "
"boundsX, "
"boundsY, "
"boundsW, "
"boundsH"
") VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7);";
static const char* LOAD_CHARACTER = "SELECT "
"uid, "
@@ -49,13 +53,21 @@ static const char* LOAD_CHARACTER = "SELECT "
"avatar, "
"roomIndex, "
"originX, "
"originY "
"originY, "
"boundsX, "
"boundsY, "
"boundsW, "
"boundsH "
"FROM LiveCharacters WHERE handle = ?;";
static const char* SAVE_CHARACTER = "UPDATE OR FAIL LiveCharacters SET "
"roomIndex = ?2, "
"originX = ?3, "
"originY = ?4 "
"originY = ?4, "
"boundsX = ?5, "
"boundsY = ?6, "
"boundsW = ?7, "
"boundsH = ?8 "
"WHERE uid = ?1;";
static const char* DELETE_CHARACTER = "DELETE FROM LiveCharacters WHERE uid = ?;";
@@ -81,6 +93,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) {
@@ -141,7 +157,6 @@ int CharacterManager::Load(int owner, std::string handle, std::string avatar) {
CharacterData& newChar = elementMap[uid];
//metadata
newChar.index = uid;
newChar.owner = owner;
newChar.handle = reinterpret_cast<const char*>(sqlite3_column_text(statement, 2));
newChar.avatar = reinterpret_cast<const char*>(sqlite3_column_text(statement, 3));
@@ -152,10 +167,10 @@ int CharacterManager::Load(int owner, std::string handle, std::string avatar) {
newChar.origin.x = (double)sqlite3_column_int(statement, 5);
newChar.origin.y = (double)sqlite3_column_int(statement, 6);
//bounds
newChar.bounds.x = CHARACTER_BOUNDS_X;
newChar.bounds.y = CHARACTER_BOUNDS_Y;
newChar.bounds.w = CHARACTER_BOUNDS_WIDTH;
newChar.bounds.h = CHARACTER_BOUNDS_HEIGHT;
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...
@@ -197,8 +212,12 @@ 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;
//TODO: gameplay components: equipment, items, buffs, debuffs...
//gameplay components: equipment, items, buffs, debuffs...
//check for binding errors
if (ret) {
+1 -1
View File
@@ -1,5 +1,5 @@
#config
INCLUDES+=. .. ../barriers ../battles ../creatures ../entities ../monsters ../inventory ../rooms ../triggers ../../common/gameplay ../../common/map ../../common/network ../../common/network/packet_types ../../common/utilities
INCLUDES+=. .. ../combat ../creatures ../entities ../monsters ../rooms ../triggers ../../common/gameplay ../../common/map ../../common/network ../../common/network/packet_types ../../common/utilities
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
@@ -52,17 +52,15 @@ static int getTag(lua_State* L) {
return 1;
}
/*
static int setBattleIndex(lua_State* L) {
static int setInstance(lua_State* L) {
BarrierData* barrier = static_cast<BarrierData*>(lua_touserdata(L, 1));
barrier->SetBattleIndex(lua_tointeger(L, 2));
barrier->SetInstanceIndex(lua_tointeger(L, 2));
return 0;
}
*/
static int getBattleIndex(lua_State* L) {
static int getInstance(lua_State* L) {
BarrierData* barrier = static_cast<BarrierData*>(lua_touserdata(L, 1));
lua_pushinteger(L, barrier->GetBattleIndex());
lua_pushinteger(L, barrier->GetInstanceIndex());
return 1;
}
@@ -83,8 +81,8 @@ static const luaL_Reg barrierLib[] = {
{"GetScript", getScript},
{"SetTag", setTag},
{"GetTag", getTag},
// {"SetBattleIndex", setBattleIndex},
{"GetBattleIndex", getBattleIndex},
{"SetInstance", setInstance},
{"GetInstance", getInstance},
{"SetStatus", setStatus},
{"GetStatus", getStatus},
{nullptr, nullptr}
@@ -28,15 +28,8 @@
BarrierData::BarrierData(int i):
Entity::Entity("barrier")
{
battleIndex = i;
instanceIndex = i;
memset(status, 0, sizeof(int) * 8);
SetBounds({
BARRIER_BOUNDS_X,
BARRIER_BOUNDS_Y,
BARRIER_BOUNDS_WIDTH,
BARRIER_BOUNDS_HEIGHT
});
}
BarrierData::~BarrierData() {
@@ -46,7 +39,6 @@ BarrierData::~BarrierData() {
int BarrierData::Update(lua_State* L) {
int ret = 0;
//NOTE: this is here mostly for the "barrier tick" effect
if (scriptRef != LUA_NOREF) {
//Call the script reference
lua_pushinteger(L, scriptRef);
@@ -85,12 +77,12 @@ std::string BarrierData::GetTag(std::string key) {
return tags[key];
}
int BarrierData::SetBattleIndex(int i) {
return battleIndex = i;
int BarrierData::SetInstanceIndex(int i) {
return instanceIndex = i;
}
int BarrierData::GetBattleIndex() const {
return battleIndex;
int BarrierData::GetInstanceIndex() const {
return instanceIndex;
}
int BarrierData::SetStatus(int k, int v) {
@@ -21,7 +21,6 @@
*/
#pragma once
#include "barrier_defines.hpp"
#include "entity.hpp"
#include "lua.hpp"
@@ -31,7 +30,7 @@
class BarrierData: public Entity {
public:
BarrierData(int battleIndex);
BarrierData(int instanceIndex);
~BarrierData();
int Update(lua_State*);
@@ -39,12 +38,11 @@ public:
int SetScriptReference(int);
int GetScriptReference();
//NOTE: Why does this have tags? Are the tags used?
std::string SetTag(std::string key, std::string value);
std::string GetTag(std::string key);
int SetBattleIndex(int i);
int GetBattleIndex() const;
int SetInstanceIndex(int i);
int GetInstanceIndex() const;
int SetStatus(int k, int v);
int GetStatus(int k);
@@ -55,7 +53,7 @@ private:
int scriptRef = LUA_NOREF;
std::map<std::string, std::string> tags;
int battleIndex;
int instanceIndex;
int status[8];
};
@@ -23,6 +23,8 @@
#include "lua_utilities.hpp"
#include "barrier_defines.hpp"
BarrierManager::BarrierManager() {
//EMPTY
}
@@ -32,12 +34,57 @@ BarrierManager::~BarrierManager() {
}
//arg: a list of barriers to be updated in the clients
void BarrierManager::Update(std::list<std::pair<const int, BarrierData*>>* barrierList, bool updateAll) {
int ret;
void BarrierManager::Update(
std::list<std::tuple<const int, BarrierData*, int>>* barrierList,
std::list<std::tuple<const int, CreatureData*, int>>* creatureList,
std::list<CharacterData*>* characterList
)
{
//for each given creature, if a collision was detected, make a new barrier
for (auto& it : *creatureList) {
if (std::get<2>(it) & 2) {
int index = Create(-1); //instance from creature index?
BarrierData* barrierData = Find(index);
barrierData->SetOrigin({
(CREATURE_BOUNDS_WIDTH - BARRIER_BOUNDS_WIDTH) / 2 + std::get<1>(it)->GetOrigin().x,
(CREATURE_BOUNDS_HEIGHT - BARRIER_BOUNDS_HEIGHT) / 2 + std::get<1>(it)->GetOrigin().y
});
}
}
//TODO: merge barriers
//TODO: absorb creatures into existing barriers
//update the barriers
//TODO: how to delete the barriers?
int ret; //0 = no action, ret&1 = update clients, ret&2 = collision detected
for (auto& it : elementMap) {
ret = it.second.Update(lua);
if (ret || updateAll) {
barrierList->push_back(std::pair<const int, BarrierData*>(it.first, &it.second));
//normal update
ret = it.second.Update(lua) ? 1 : 0;
//check for collision with a character
BoundingBox barrierBox = it.second.GetRealBounds();
for (auto& it : *characterList) {
if (barrierBox.CheckOverlap(it->GetRealBounds())) {
//this will need updating
ret |= 2;
}
//TODO: absorb characters
}
if (ret) {
//push to the return list
barrierList->push_back(std::make_tuple(it.first, &it.second, ret));
}
}
}
void BarrierManager::Cleanup(std::list<std::tuple<const int, BarrierData*, int>>* barrierList) {
//unload the given barrier objects
for (auto& it : *barrierList) {
if (std::get<2>(it) & 4) {
Unload(std::get<0>(it));
}
}
}
@@ -22,14 +22,16 @@
#pragma once
#include "barrier_data.hpp"
#include "character_data.hpp"
#include "creature_data.hpp"
#include "lua.hpp"
#include "sqlite3.h"
#include <algorithm>
#include <functional>
#include <list>
#include <map>
#include <tuple>
class BarrierManager {
public:
@@ -37,7 +39,12 @@ public:
~BarrierManager();
//common public methods
void Update(std::list<std::pair<const int, BarrierData*>>* barrierList, bool updateAll);
void Update(
std::list<std::tuple<const int, BarrierData*, int>>* barrierList,
std::list<std::tuple<const int, CreatureData*, int>>* creatureList,
std::list<CharacterData*>* characterList
);
void Cleanup(std::list<std::tuple<const int, BarrierData*, int>>* barrierList);
int Create(int instanceIndex);
void Unload(int uid);
@@ -19,20 +19,33 @@
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "item_data.hpp"
#include "combat_instance.hpp"
ItemType ItemData::SetItemType(ItemType t) {
return type = t;
CombatInstance::CombatInstance() {
//
}
ItemType ItemData::GetItemType() {
return type;
CombatInstance::~CombatInstance() {
//
}
int ItemData::SetQuantity(int i) {
return quantity = i;
void CombatInstance::Update() {
//
}
int ItemData::GetQuantity() {
return quantity;
//accessors and mutators
void CombatInstance::PushCharacter(CharacterData* const characterData) {
//
}
void CombatInstance::PopCharacter(CharacterData* const characterData) {
//
}
void CombatInstance::PushCreature(CreatureData* const creatureData) {
//
}
void CombatInstance::PopCreature(CreatureData* const creatureData) {
//
}
@@ -24,25 +24,21 @@
#include "character_data.hpp"
#include "creature_data.hpp"
#include <functional>
class BattleData {
class CombatInstance {
public:
constexpr static int BATTLE_SIZE = 8;
BattleData();
~BattleData();
CombatInstance();
~CombatInstance();
void Update();
//accessors and mutators
int PushCharacter(CharacterData* const characterData);
int PopCharacter(CharacterData const * const characterData);
void PushCharacter(CharacterData* const characterData);
void PopCharacter(CharacterData* const characterData);
int PushCreature(CreatureData* const creatureData);
int PopCreature(CreatureData const * const creatureData);
void PushCreature(CreatureData* const creatureData);
void PopCreature(CreatureData* const creatureData);
private:
std::array<CharacterData*, BATTLE_SIZE> characterArray;
std::array<CreatureData*, BATTLE_SIZE> creatureArray;
std::array<CharacterData*, 8> characterArray;
std::array<CreatureData*, 8> creatureArray;
};
@@ -19,26 +19,26 @@
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "battle_manager.hpp"
#include "combat_instance_manager.hpp"
BattleManager::BattleManager() {
CombatInstanceManager::CombatInstanceManager() {
//EMPTY
}
BattleManager::~BattleManager() {
CombatInstanceManager::~CombatInstanceManager() {
UnloadAll();
}
//arg: a list of combats to be updated in the clients
void BattleManager::Update() {
void CombatInstanceManager::Update() {
for (auto& it : elementMap) {
it.second.Update();
}
}
int BattleManager::Create() {
int CombatInstanceManager::Create() {
//implicitly create the new object
elementMap.emplace( std::pair<int, BattleData>(counter, BattleData()) );
elementMap.emplace( std::pair<int, CombatInstance>(counter, CombatInstance()) );
//TODO: do various things like saving to the database
return counter++;
@@ -46,16 +46,16 @@ int BattleManager::Create() {
//TODO: (1) combat load, save
void BattleManager::Unload(int uid) {
void CombatInstanceManager::Unload(int uid) {
elementMap.erase(uid);
}
void BattleManager::UnloadAll() {
void CombatInstanceManager::UnloadAll() {
elementMap.clear();
}
void BattleManager::UnloadIf(std::function<bool(std::pair<const int, BattleData const&>)> fn) {
std::map<int, BattleData>::iterator it = elementMap.begin();
void CombatInstanceManager::UnloadIf(std::function<bool(std::pair<const int, CombatInstance const&>)> fn) {
std::map<int, CombatInstance>::iterator it = elementMap.begin();
while (it != elementMap.end()) {
if (fn(*it)) {
it = elementMap.erase(it);
@@ -66,8 +66,8 @@ void BattleManager::UnloadIf(std::function<bool(std::pair<const int, BattleData
}
}
BattleData* BattleManager::Find(int uid) {
std::map<int, BattleData>::iterator it = elementMap.find(uid);
CombatInstance* CombatInstanceManager::Find(int uid) {
std::map<int, CombatInstance>::iterator it = elementMap.find(uid);
if (it == elementMap.end()) {
return nullptr;
@@ -76,26 +76,26 @@ BattleData* BattleManager::Find(int uid) {
return &it->second;
}
int BattleManager::GetLoadedCount() {
int CombatInstanceManager::GetLoadedCount() {
return elementMap.size();
}
std::map<int, BattleData>* BattleManager::GetContainer() {
std::map<int, CombatInstance>* CombatInstanceManager::GetContainer() {
return &elementMap;
}
lua_State* BattleManager::SetLuaState(lua_State* L) {
lua_State* CombatInstanceManager::SetLuaState(lua_State* L) {
return lua = L;
}
lua_State* BattleManager::GetLuaState() {
lua_State* CombatInstanceManager::GetLuaState() {
return lua;
}
sqlite3* BattleManager::SetDatabase(sqlite3* db) {
sqlite3* CombatInstanceManager::SetDatabase(sqlite3* db) {
return database = db;
}
sqlite3* BattleManager::GetDatabase() {
sqlite3* CombatInstanceManager::GetDatabase() {
return database;
}
@@ -21,7 +21,7 @@
*/
#pragma once
#include "battle_data.hpp"
#include "combat_instance.hpp"
#include "lua.hpp"
#include "sqlite3.h"
@@ -29,10 +29,10 @@
#include <algorithm>
#include <map>
class BattleManager {
class CombatInstanceManager {
public:
BattleManager();
~BattleManager();
CombatInstanceManager();
~CombatInstanceManager();
//common public methods
void Update();
@@ -41,12 +41,12 @@ public:
void Unload(int uid);
void UnloadAll();
void UnloadIf(std::function<bool(std::pair<const int, BattleData const&>)> fn);
void UnloadIf(std::function<bool(std::pair<const int, CombatInstance const&>)> fn);
//accessors & mutators
BattleData* Find(int uid);
CombatInstance* Find(int uid);
int GetLoadedCount();
std::map<int, BattleData>* GetContainer();
std::map<int, CombatInstance>* GetContainer();
//hooks
lua_State* SetLuaState(lua_State* L);
@@ -56,7 +56,7 @@ public:
private:
//members
std::map<int, BattleData> elementMap;
std::map<int, CombatInstance> elementMap;
int counter = 0;
lua_State* lua = nullptr;
sqlite3* database = nullptr;
@@ -1,5 +1,5 @@
#config
INCLUDES+=. ../../common/gameplay
INCLUDES+=. .. ../characters ../creatures ../entities ../../common/gameplay ../../common/utilities
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
+32 -5
View File
@@ -32,12 +32,39 @@ CreatureManager::~CreatureManager() {
}
//arg: a list of creatures to be updated in the clients
void CreatureManager::Update(std::list<std::pair<const int, CreatureData*>>* creatureList, bool updateAll) {
int ret;
void CreatureManager::Update(
std::list<std::tuple<const int, CreatureData*, int>>* creatureList,
std::list<CharacterData*>* characterList
)
{
//for each creature
int ret; //0 = no action, ret&1 = update clients, ret&2 = collision detected
for (auto& it : elementMap) {
ret = it.second.Update(lua);
if (ret || updateAll) {
creatureList->push_back(std::pair<const int, CreatureData*>(it.first, &it.second));
//normal update
ret = it.second.Update(lua) ? 1 : 0;
//check for collision with a character
BoundingBox creatureBox = it.second.GetRealBounds();
for (auto& it : *characterList) {
if (creatureBox.CheckOverlap(it->GetRealBounds())) {
//this will need updating
ret |= 2;
break;
}
}
if (ret) {
//push to the return list
creatureList->push_back(std::make_tuple(it.first, &it.second, ret));
}
}
}
void CreatureManager::Cleanup(std::list<std::tuple<const int, CreatureData*, int>>* creatureList) {
//unload the given creature objects
for (auto& it : *creatureList) {
if (std::get<2>(it) & 2) {
Unload(std::get<0>(it));
}
}
}
+7 -1
View File
@@ -21,6 +21,7 @@
*/
#pragma once
#include "character_data.hpp"
#include "creature_data.hpp"
#include "lua.hpp"
@@ -30,6 +31,7 @@
#include <list>
#include <map>
#include <string>
#include <tuple>
class CreatureManager {
public:
@@ -37,7 +39,11 @@ public:
~CreatureManager();
//common public methods
void Update(std::list<std::pair<const int, CreatureData*>>* creatureList, bool updateAll);
void Update(
std::list<std::tuple<const int, CreatureData*, int>>* creatureList,
std::list<CharacterData*>* characterList
);
void Cleanup(std::list<std::tuple<const int, CreatureData*, int>>* creatureList);
int Create(std::string avatar, int scriptRef);
void Unload(int uid);
+1 -1
View File
@@ -1,5 +1,5 @@
#config
INCLUDES+=. .. ../entities ../../common/gameplay ../../common/utilities
INCLUDES+=. .. ../characters ../entities ../../common/gameplay ../../common/utilities
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
+4
View File
@@ -63,6 +63,10 @@ BoundingBox Entity::GetBounds() const {
return bounds;
}
BoundingBox Entity::GetRealBounds() const {
return bounds + origin;
}
const char* Entity::GetType() const {
return type;
}
+1
View File
@@ -41,6 +41,7 @@ public:
Vector2 GetOrigin() const;
Vector2 GetMotion() const;
BoundingBox GetBounds() const;
BoundingBox GetRealBounds() const;
const char* GetType() const;
+2 -4
View File
@@ -1,5 +1,5 @@
#include directories
INCLUDES+=. accounts barriers battles characters clients creatures entities inventory rooms triggers ../common/debugging ../common/gameplay ../common/map ../common/network ../common/network/packet_types ../common/utilities
INCLUDES+=. accounts characters clients combat creatures entities rooms triggers ../common/debugging ../common/gameplay ../common/map ../common/network ../common/network/packet_types ../common/utilities
#libraries
#the order of the $(LIBS) is important, at least for MinGW
@@ -30,13 +30,11 @@ OUT=$(addprefix $(OUTDIR)/,server)
#targets
all: $(OBJ) $(OUT)
$(MAKE) -C accounts
$(MAKE) -C barriers
$(MAKE) -C battles
$(MAKE) -C characters
$(MAKE) -C clients
$(MAKE) -C combat
$(MAKE) -C creatures
$(MAKE) -C entities
$(MAKE) -C inventory
$(MAKE) -C rooms
$(MAKE) -C triggers
$(CXX) $(CXXFLAGS) -o $(OUT) $(OBJ) $(LIBS)
+1 -1
View File
@@ -1,5 +1,5 @@
#config
INCLUDES+=. .. ../barriers ../battles ../characters ../creatures ../entities ../inventory ../monsters ../triggers ../../common/gameplay ../../common/map ../../common/network ../../common/network/packet_types ../../common/utilities
INCLUDES+=. .. ../characters ../combat ../creatures ../entities ../monsters ../triggers ../../common/gameplay ../../common/map ../../common/network ../../common/network/packet_types ../../common/utilities
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
-35
View File
@@ -109,24 +109,6 @@ static int forEachCreature(lua_State* L) {
return 0;
}
static int forEachBarrier(lua_State* L) {
RoomData* room = reinterpret_cast<RoomData*>(lua_touserdata(L, 1));
BarrierManager* barrierMgr = room->GetBarrierMgr();
//pass each barrier to the given function
for (auto& it : *barrierMgr->GetContainer()) {
lua_pushvalue(L, -1);
lua_pushlightuserdata(L, static_cast<void*>(&it.second));
//call each iteration, throwing an exception if something happened
if (lua_pcall(L, 1, 0, 0) != LUA_OK) {
std::ostringstream os;
os << "Lua error: ";
os << lua_tostring(L, -1);
throw(std::runtime_error(os.str()));
}
}
return 0;
}
static int setOnTick(lua_State* L) {
RoomData* room = reinterpret_cast<RoomData*>(lua_touserdata(L, 1));
luaL_unref(L, LUA_REGISTRYINDEX, room->GetTickReference());
@@ -140,19 +122,6 @@ static int getOnTick(lua_State* L) {
return 1;
}
//TODO: autogen docs
static int setTag(lua_State* L) {
RoomData* room = static_cast<RoomData*>(lua_touserdata(L, 1));
room->SetTag(lua_tostring(L, 2), lua_tostring(L, 3));
return 0;
}
static int getTag(lua_State* L) {
RoomData* room = static_cast<RoomData*>(lua_touserdata(L, 1));
lua_pushstring(L, room->GetTag(lua_tostring(L, 2)).c_str());
return 1;
}
static int initialize(lua_State* L) {
RoomData* room = static_cast<RoomData*>(lua_touserdata(L, 1));
@@ -179,14 +148,10 @@ static const luaL_Reg roomLib[] = {
{"ForEachCharacter", forEachCharacter},
{"ForEachCreature", forEachCreature},
{"ForEachBarrier", forEachBarrier},
{"SetOnTick", setOnTick},
{"GetOnTick", getOnTick},
{"SetTag", setTag},
{"GetTag", getTag},
{"Initialize", initialize},
{nullptr, nullptr}
};
+30 -214
View File
@@ -30,115 +30,72 @@
#include <iostream>
#include <stack>
#include <stdexcept>
#include <tuple>
/* DOCS: this is the process for RoomData::RunFrame(), read more
*
* updateAll = OnTick()
*
* characterList .UpdateAll()
* creatureMgr .Update(updateAll)
* barrierMgr .Update(updateAll)
* battleMgr .Update(updateAll)
*
* creatureMgr .SendUpdates()
* barrierMgr .SendUpdates()
* //battleMgr .SendUpdates() //TODO: incomplete
*
* triggerMgr .Compare(characterList)
*
* if (a character collides with a creature)
* barrierMgr .Create()
* battleMgr .Create()
*
* barrierMgr .Send()
*
* creatureMgr .Delete()
* endif
*
* if (a character collides with a barrier)
* //TODO: incomplete
* endif
*/
//NOTE: character collisions should be preformed client-side
//TODO: (9) character collisions should be preformed client-side
void RoomData::RunFrame() {
RunFrameUpdates(RunFrameLuaOnTick());
RunFrameTriggers();
RunFrameCharacterCreatureCollisions();
RunFrameCharacterBarrierCollisions();
}
//-------------------------
//hi-cohesion methods for one-time use
//-------------------------
bool RoomData::RunFrameLuaOnTick() {
//get the hook
lua_rawgeti(lua, LUA_REGISTRYINDEX, tickRef);
//returning 1 means pump all
bool updateAll = false;
if (!lua_isnil(lua, -1)) {
//call the tick function, with this as a parameter
lua_pushlightuserdata(lua, this);
if (lua_pcall(lua, 1, 1, 0) != LUA_OK) {
if (lua_pcall(lua, 1, 0, 0) != LUA_OK) {
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) ));
}
//pump creatures & barriers
if (lua_tonumber(lua, -1) > 0) {
updateAll = true;
}
lua_pop(lua, 1);
}
else {
lua_pop(lua, 1);
}
return updateAll;
}
void RoomData::RunFrameUpdates(bool updateAll) {
//lists of non-character entities that need updating client-side
std::list<std::pair<const int, CreatureData*>> creatureList;
std::list<std::pair<const int, BarrierData*>> barrierList;
//types are index, ptr, action (0 = update, 1 = unload)
std::list<std::tuple<const int, CreatureData*, int>> creatureList;
std::list<std::tuple<const int, BarrierData*, int>> barrierList;
//update the entities in the room
for (auto& it : characterList) {
it->Update();
}
creatureMgr.Update(&creatureList, updateAll);
barrierMgr.Update(&barrierList, updateAll);
//update the battles
battleMgr.Update();
creatureMgr.Update(&creatureList, &characterList);
barrierMgr.Update(&barrierList, &creatureList, &characterList);
//send the creature updates
for (auto& it : creatureList) {
CreaturePacket packet;
copyCreatureToPacket(&packet, it.second, it.first);
packet.type = SerialPacketType::CREATURE_UPDATE;
copyCreatureToPacket(&packet, std::get<1>(it), std::get<0>(it));
//interpret the event
if (std::get<2>(it) & 1) {
packet.type = SerialPacketType::CREATURE_UPDATE;
}
if (std::get<2>(it) & 2) {
packet.type = SerialPacketType::CREATURE_UNLOAD;
}
packet.roomIndex = roomIndex;
pumpPacketProximity(reinterpret_cast<SerialPacket*>(&packet), roomIndex, it.second->GetOrigin(), INFLUENCE_RADIUS);
pumpPacketProximity(reinterpret_cast<SerialPacket*>(&packet), roomIndex, std::get<1>(it)->GetOrigin(), INFLUENCE_RADIUS);
}
//send the barrier updates
for (auto& it : barrierList) {
BarrierPacket packet;
copyBarrierToPacket(&packet, it.second, it.first);
packet.type = SerialPacketType::BARRIER_UPDATE;
copyBarrierToPacket(&packet, std::get<1>(it), std::get<0>(it));
//interpret the event
if (std::get<2>(it) & 1 || std::get<2>(it) & 2) {
packet.type = SerialPacketType::BARRIER_UPDATE;
}
packet.roomIndex = roomIndex;
pumpPacketProximity(reinterpret_cast<SerialPacket*>(&packet), roomIndex, it.second->GetOrigin(), INFLUENCE_RADIUS);
pumpPacketProximity(reinterpret_cast<SerialPacket*>(&packet), roomIndex, std::get<1>(it)->GetOrigin(), INFLUENCE_RADIUS);
}
//TODO: send the battle updates
}
//cleanup the lists
creatureMgr.Cleanup(&creatureList);
barrierMgr.Cleanup(&barrierList);
void RoomData::RunFrameTriggers() {
//build a list of entities for use with the triggers
//currently, this only uses characters
std::stack<Entity*> entityStack;
for (auto& it : characterList) {
entityStack.push(it);
@@ -148,101 +105,6 @@ void RoomData::RunFrameTriggers() {
triggerMgr.Compare(entityStack);
}
void RoomData::RunFrameCharacterCreatureCollisions() {
//Creature/character collisions, O(m*n), making the barriers
for (auto characterIt : characterList) {
BoundingBox characterBox = characterIt->GetBounds() + characterIt->GetOrigin();
std::list<int> creatureUnloadList;
for (auto creatureIt : *creatureMgr.GetContainer()) {
BoundingBox creatureBox = creatureIt.second.GetBounds() + creatureIt.second.GetOrigin();
if (characterBox.CheckOverlap(creatureBox)) {
//create the barrier and battle
//TODO: Barrier needs data about the creatures inside it.
int barrierIndex = barrierMgr.Create(battleMgr.Create()); //link the barrier to a battle
BarrierData* barrierData = barrierMgr.Find(barrierIndex);
barrierData->SetRoomIndex(roomIndex);
barrierData->SetOrigin({
(CREATURE_BOUNDS_WIDTH - BARRIER_BOUNDS_WIDTH) / 2 + creatureBox.x,
(CREATURE_BOUNDS_HEIGHT - BARRIER_BOUNDS_HEIGHT) / 2 + creatureBox.y,
});
BarrierPacket barrierPacket;
barrierPacket.type = SerialPacketType::BARRIER_CREATE;
copyBarrierToPacket(&barrierPacket, barrierData, barrierIndex);
pumpPacketProximity(reinterpret_cast<SerialPacket*>(&barrierPacket), roomIndex, characterIt->GetOrigin(), INFLUENCE_RADIUS);
//delete this creature
creatureUnloadList.push_back(creatureIt.first);
}
}
//actually unload these creatures
for (auto& it : creatureUnloadList) {
CreatureData* creatureData = creatureMgr.Find(it);
CreaturePacket creaturePacket;
creaturePacket.type = SerialPacketType::CREATURE_UNLOAD;
copyCreatureToPacket(&creaturePacket, creatureData, it);
pumpPacketProximity(reinterpret_cast<SerialPacket*>(&creaturePacket), roomIndex, creatureData->GetOrigin(), INFLUENCE_RADIUS);
creatureMgr.Unload(it);
}
}
}
void RoomData::RunFrameCharacterBarrierCollisions() {
//TODO: check for character collisions with barriers, O(m*n)
for (auto characterIt : characterList) {
//character bounds
BoundingBox characterBox = characterIt->GetBounds() + characterIt->GetOrigin();
for (auto barrierIt : *barrierMgr.GetContainer()) {
//barrier bounds
BoundingBox barrierBox = barrierIt.second.GetBounds() + barrierIt.second.GetOrigin();
//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;
charPacket.characterIndex = characterIt->GetIndex();
pumpPacketProximity(static_cast<SerialPacket*>(&charPacket), characterIt->GetRoomIndex());
std::cout << "CharacterList size: " << characterList.size() << std::endl;
//Actually move the character to a battle
BattleData* battle = battleMgr.Find(barrierIt.second.GetBattleIndex()); //TODO: barriers should hold the battle's pointer
battle->PushCharacter(characterIt);
PopCharacter(characterIt);
//DEBUG: output barrierIndex, battleIndex
std::cout << "CharacterList size: " << characterList.size() << std::endl;
//Send the entry message to the client
// BarrierPacket newPacket;
// newPacket.type = SerialPacketType::BARRIER_ENTRY;
// newPacket.barrierIndex = barrierIt.first;
// udpNetworkUtility.Send();
//only confirm one barrier/character collison per frame
return;
}
}
}
}
//-------------------------
//Utility methods
//-------------------------
std::string RoomData::SetName(std::string s) {
return roomName = s;
}
@@ -267,44 +129,6 @@ int RoomData::GetRoomIndex() {
return roomIndex;
}
void RoomData::PushCharacter(CharacterData* const character) {
if (!character) {
throw(std::logic_error("Failed to push a null character to RoomData"));
}
//check to see if the character is already here
for (auto& it : characterList) {
if (it == character) {
throw(std::logic_error("double insertion of CharacterData in RoomData"));
}
}
characterList.push_back(character);
}
void RoomData::PopCharacter(CharacterData const * const character) {
if (!character) {
throw(std::logic_error("Failed to pop a null character to RoomData"));
}
//check to see if the character isn't here
for (auto& it : characterList) {
if (it == character) {
characterList.remove(it);
return;
}
}
//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"));
}
BarrierManager* RoomData::GetBarrierMgr() {
return &barrierMgr;
}
@@ -354,12 +178,4 @@ int RoomData::SetTickReference(int i) {
int RoomData::GetTickReference() {
return tickRef;
}
std::string RoomData::SetTag(std::string key, std::string value) {
return tags[key] = value;
}
std::string RoomData::GetTag(std::string key) {
return tags[key];
}
+2 -16
View File
@@ -23,7 +23,7 @@
#include "barrier_manager.hpp"
#include "character_data.hpp"
#include "battle_manager.hpp"
#include "combat_instance_manager.hpp"
#include "creature_manager.hpp"
#include "region_pager_lua.hpp"
#include "trigger_manager.hpp"
@@ -53,9 +53,6 @@ public:
int SetRoomIndex(int i);
int GetRoomIndex();
void PushCharacter(CharacterData* const character);
void PopCharacter(CharacterData const * const character);
BarrierManager* GetBarrierMgr();
std::list<CharacterData*>* GetCharacterList();
CreatureManager* GetCreatureMgr();
@@ -73,17 +70,7 @@ public:
int GetTickReference();
//TODO: other triggers like player entry & exit, etc.
std::string SetTag(std::string key, std::string value);
std::string GetTag(std::string key);
private:
//hi-cohesion methods for one-time use
bool RunFrameLuaOnTick();
void RunFrameUpdates(bool updateAll);
void RunFrameTriggers();
void RunFrameCharacterCreatureCollisions();
void RunFrameCharacterBarrierCollisions();
//metadata
std::string roomName;
std::string tilesetName;
@@ -92,7 +79,7 @@ private:
int roomIndex = 0;
BarrierManager barrierMgr;
std::list<CharacterData*> characterList;
BattleManager battleMgr;
CombatInstanceManager combatInstanceMgr;
CreatureManager creatureMgr;
RegionPagerLua pager;
TriggerManager triggerMgr;
@@ -103,5 +90,4 @@ private:
//hooks
int tickRef = LUA_NOREF;
std::map<std::string, std::string> tags;
};
+9 -7
View File
@@ -111,7 +111,7 @@ void RoomManager::UnloadIf(std::function<bool(std::pair<const int, RoomData cons
lua_pop(lua, 1);
}
void RoomManager::PushCharacter(CharacterData* const character) {
void RoomManager::PushCharacter(CharacterData* character) {
if (!character) {
throw(std::runtime_error("Failed to push a null character to a room"));
}
@@ -119,25 +119,27 @@ void RoomManager::PushCharacter(CharacterData* const character) {
RoomData* room = Find(character->GetRoomIndex());
if (!room) {
throw(std::runtime_error("Failed to push a character to a non-existant room"));
throw(std::runtime_error("Failed to push an character to a non-existant room"));
}
room->PushCharacter(character);
room->GetCharacterList()->push_back(character);
}
void RoomManager::PopCharacter(CharacterData const * const character) {
void RoomManager::PopCharacter(CharacterData const* character) {
//NOTE: to pop an character from a room, the character must first exist
if (!character) {
throw(std::runtime_error("Failed to pop a null character from a room"));
throw(std::runtime_error("Failed to pop a null character to a room"));
}
RoomData* room = Find(character->GetRoomIndex());
if (!room) {
throw(std::runtime_error("Failed to pop a character to a non-existant room"));
throw(std::runtime_error("Failed to pop an character to a non-existant room"));
}
room->PopCharacter(character);
room->GetCharacterList()->remove_if([character](CharacterData* ptr) {
return character == ptr;
});
}
//TODO: rename these functions from Get to Find
+2 -2
View File
@@ -39,8 +39,8 @@ public:
void UnloadAll();
void UnloadIf(std::function<bool(std::pair<const int, RoomData const&>)> fn);
void PushCharacter(CharacterData* const character);
void PopCharacter(CharacterData const * const character);
void PushCharacter(CharacterData* character);
void PopCharacter(CharacterData const* character);
//accessors and mutators
RoomData* Find(int uid);
+4 -29
View File
@@ -596,36 +596,11 @@ void ServerApplication::hQueryCharacterExists(CharacterPacket* const argPacket)
//respond with all character data
CharacterPacket newPacket;
//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<SerialPacket*>(&newPacket));
for (auto& it : *characterMgr.GetContainer()) {
if (argPacket->roomIndex != -1 && it.second.GetRoomIndex() != argPacket->roomIndex) {
continue;
}
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<SerialPacket*>(&newPacket));
return;
}
for (auto& it : *room->GetCharacterList()) {
copyCharacterToPacket(&newPacket, it, it->GetIndex());
copyCharacterToPacket(&newPacket, it.first);
newPacket.type = SerialPacketType::QUERY_CHARACTER_EXISTS;
network.SendTo(argPacket->srcAddress, static_cast<SerialPacket*>(&newPacket));
}
+1 -1
View File
@@ -195,7 +195,7 @@ void pumpAndChangeRooms(int characterIndex, int newRoomIndex) {
pumpAndChangeRooms(character, newRoomIndex, characterIndex);
}
//NOTE: This is one of those ugly things that you just need to put up with
//TODO: (0) refactor this
void pumpAndChangeRooms(CharacterData* const characterData, int newRoomIndex, int characterIndex) {
//delete the character from the old room
CharacterPacket newPacket;
+20 -19
View File
@@ -1,25 +1,26 @@
TODO: Resource manager
TODO: Add the TextureLoader
TODO: Consistency for bounds names
TODO: Cross compiler (to replace dead linux PC ;_;)
TODO: New button graphics?
TODO: New button graphics
TODO: New typeface
TODO: Account passwords (list)
TODO: backbone account server OR
TODO: social network login OR
TODO: salts & hashes
TODO: login screen prompting for username & password
* backbone account server OR
* social network login OR
* ...
* salts & hashes
* login screen prompting for username & password
TODO: Features
TODO: Make sure login errors are sent to the client
TODO: Add the "home" parameter to the server's config file
TODO: Fix shoddy movement
TODO: Better UI system
TODO: Make a way for the server owner to control the server directly
TODO: The TileSheet class should implement the surface itself
TODO: Time delay for requesting region packets
TODO: A proper logging system
TODO: Fix the const-ness of accessors
TODO: Add a screenshot of the game to README.md
TODO: joystick/gamepad support
TODO: add the tilesheet to the map system
TODO: Better collision logic
* Make sure login errors are sent to the client
* Add the "home" parameter to the server's config file
* Waypoints, with positions and trigger zones (collision areas) for doors, monster spawns, etc. (trigger system)
* Fix shoddy movement
* Remove the big "Shut Down" button (currently broken...)
* Make a way for the server owner to control the server directly
* The TileSheet class should implement the surface itself
* Time delay for requesting region packets
* A proper logging system
* Fix the const-ness of accessors
* Add a screenshot of the game to README.md
* joystick/gamepad support
* add the tilesheet to the map system