Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ab6207d4f3 | |||
| 1267b30806 | |||
| 5d217d7cf9 |
@@ -7,7 +7,7 @@ This game is inspired by classic 2D RPGs (Final Fantasy, The Legend of Zelda), a
|
|||||||
## Releases
|
## 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 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
|
## Documentation
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
#include "barrier_manager.hpp"
|
#include "barrier_manager.hpp"
|
||||||
|
|
||||||
void BarrierManager::DrawTo(SDL_Renderer* const dest, Sint16 x, Sint16 y, double scaleX, double scaleY) {
|
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);
|
it.second.DrawTo(dest, x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -47,38 +47,26 @@ void BarrierManager::UnloadTemplateImages() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BaseBarrier* BarrierManager::Create(int index) {
|
BaseBarrier* BarrierManager::Create(int index) {
|
||||||
elementMap.emplace(index, BaseBarrier(baseImage, templateImages));
|
barrierMap.emplace(index, BaseBarrier(baseImage, templateImages));
|
||||||
return &elementMap[index];
|
return &barrierMap[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
void BarrierManager::Unload(int i) {
|
void BarrierManager::Unload(int i) {
|
||||||
elementMap.erase(i);
|
barrierMap.erase(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BarrierManager::UnloadAll() {
|
void BarrierManager::UnloadAll() {
|
||||||
elementMap.clear();
|
barrierMap.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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int BarrierManager::Size() {
|
int BarrierManager::Size() {
|
||||||
return elementMap.size();
|
return barrierMap.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseBarrier* BarrierManager::Find(int i) {
|
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;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +74,7 @@ BaseBarrier* BarrierManager::Find(int i) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::map<int, BaseBarrier>* BarrierManager::GetContainer() {
|
std::map<int, BaseBarrier>* BarrierManager::GetContainer() {
|
||||||
return &elementMap;
|
return &barrierMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string, Image>* BarrierManager::GetTemplateContainer() {
|
std::map<std::string, Image>* BarrierManager::GetTemplateContainer() {
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
|
|
||||||
#include "base_barrier.hpp"
|
#include "base_barrier.hpp"
|
||||||
|
|
||||||
#include <functional>
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@@ -43,7 +42,6 @@ public:
|
|||||||
BaseBarrier* Create(int index);
|
BaseBarrier* Create(int index);
|
||||||
void Unload(int i);
|
void Unload(int i);
|
||||||
void UnloadAll();
|
void UnloadAll();
|
||||||
void UnloadIf(std::function<bool(std::pair<const int, BaseBarrier const&>)> fn);
|
|
||||||
|
|
||||||
int Size();
|
int Size();
|
||||||
|
|
||||||
@@ -54,5 +52,5 @@ public:
|
|||||||
private:
|
private:
|
||||||
Image baseImage;
|
Image baseImage;
|
||||||
std::map<std::string, Image> templateImages;
|
std::map<std::string, Image> templateImages;
|
||||||
std::map<int, BaseBarrier> elementMap;
|
std::map<int, BaseBarrier> barrierMap;
|
||||||
};
|
};
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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;
|
|
||||||
};
|
|
||||||
@@ -28,8 +28,6 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
constexpr SDL_Color WHITE = {255, 255, 255, 255};
|
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
//Public access members
|
//Public access members
|
||||||
//-------------------------
|
//-------------------------
|
||||||
@@ -51,16 +49,14 @@ DisconnectedScreen::DisconnectedScreen() {
|
|||||||
|
|
||||||
//setup the button
|
//setup the button
|
||||||
backButton.SetBackgroundTexture(GetRenderer(), image.GetTexture());
|
backButton.SetBackgroundTexture(GetRenderer(), image.GetTexture());
|
||||||
backButton.SetText(GetRenderer(), font, WHITE, "Back");
|
backButton.SetText(GetRenderer(), font, "Back", COLOR_WHITE);
|
||||||
|
|
||||||
//set the button positions
|
//set the button positions
|
||||||
backButton.SetX(50);
|
backButton.SetX(50);
|
||||||
backButton.SetY(50);
|
backButton.SetY(50);
|
||||||
|
|
||||||
//set the disconnection message text
|
//set the disconnection message text
|
||||||
textLine.SetX(50);
|
textLine.SetText(GetRenderer(), font, config["client.disconnectMessage"], {255, 255, 255, 255});
|
||||||
textLine.SetY(30);
|
|
||||||
textLine.SetText(GetRenderer(), font, WHITE, config["client.disconnectMessage"]);
|
|
||||||
|
|
||||||
//full reset
|
//full reset
|
||||||
UDPNetworkUtility::GetSingleton().Unbind(Channels::SERVER);
|
UDPNetworkUtility::GetSingleton().Unbind(Channels::SERVER);
|
||||||
@@ -96,7 +92,7 @@ void DisconnectedScreen::FrameEnd() {
|
|||||||
|
|
||||||
void DisconnectedScreen::RenderFrame(SDL_Renderer* renderer) {
|
void DisconnectedScreen::RenderFrame(SDL_Renderer* renderer) {
|
||||||
backButton.DrawTo(renderer);
|
backButton.DrawTo(renderer);
|
||||||
textLine.DrawTo(renderer);
|
textLine.DrawTo(renderer, 50, 30);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
|
|||||||
@@ -27,8 +27,6 @@
|
|||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
constexpr SDL_Color WHITE = {255, 255, 255, 255};
|
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
//Public access members
|
//Public access members
|
||||||
//-------------------------
|
//-------------------------
|
||||||
@@ -54,11 +52,11 @@ LobbyMenu::LobbyMenu(int* const argClientIndex, int* const argAccountIndex):
|
|||||||
|
|
||||||
//setup the buttons
|
//setup the buttons
|
||||||
searchButton.SetBackgroundTexture(GetRenderer(), buttonImage.GetTexture());
|
searchButton.SetBackgroundTexture(GetRenderer(), buttonImage.GetTexture());
|
||||||
searchButton.SetText(GetRenderer(), font, WHITE, "Search");
|
searchButton.SetText(GetRenderer(), font, "Search", COLOR_WHITE);
|
||||||
joinButton.SetBackgroundTexture(GetRenderer(), buttonImage.GetTexture());
|
joinButton.SetBackgroundTexture(GetRenderer(), buttonImage.GetTexture());
|
||||||
joinButton.SetText(GetRenderer(), font, WHITE, "Join");
|
joinButton.SetText(GetRenderer(), font, "Join", COLOR_WHITE);
|
||||||
backButton.SetBackgroundTexture(GetRenderer(), buttonImage.GetTexture());
|
backButton.SetBackgroundTexture(GetRenderer(), buttonImage.GetTexture());
|
||||||
backButton.SetText(GetRenderer(), font, WHITE, "Back");
|
backButton.SetText(GetRenderer(), font, "Back", COLOR_WHITE);
|
||||||
|
|
||||||
//set the button positions (assumed)
|
//set the button positions (assumed)
|
||||||
searchButton.SetX(50);
|
searchButton.SetX(50);
|
||||||
@@ -69,7 +67,6 @@ LobbyMenu::LobbyMenu(int* const argClientIndex, int* const argAccountIndex):
|
|||||||
backButton.SetY(90);
|
backButton.SetY(90);
|
||||||
|
|
||||||
//pseudo-list selection
|
//pseudo-list selection
|
||||||
//TODO: move this into the UI library?
|
|
||||||
boundingBox = {300, 50, 200, 12};
|
boundingBox = {300, 50, 200, 12};
|
||||||
|
|
||||||
//hacked together a highlight box
|
//hacked together a highlight box
|
||||||
@@ -124,13 +121,8 @@ void LobbyMenu::RenderFrame(SDL_Renderer* renderer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//draw the server's info
|
//draw the server's info
|
||||||
serverVector[i].nameImage.SetX(boundingBox.x);
|
serverVector[i].nameImage.DrawTo(renderer, boundingBox.x, boundingBox.y + boundingBox.h * i);
|
||||||
serverVector[i].nameImage.SetY(boundingBox.y + boundingBox.h * i);
|
serverVector[i].playerCountImage.DrawTo(renderer, boundingBox.x+276, 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,8 +248,8 @@ void LobbyMenu::HandleBroadcastResponse(ServerPacket* const argPacket) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
//text graphics
|
//text graphics
|
||||||
serverVector.back().nameImage.SetText(GetRenderer(), font, color, newServer.name);
|
serverVector.back().nameImage.SetText(GetRenderer(), font, newServer.name, color);
|
||||||
serverVector.back().playerCountImage.SetText(GetRenderer(), font, color, itoa_base10(newServer.playerCount));
|
serverVector.back().playerCountImage.SetText(GetRenderer(), font, itoa_base10(newServer.playerCount), color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LobbyMenu::HandleJoinResponse(ClientPacket* const argPacket) {
|
void LobbyMenu::HandleJoinResponse(ClientPacket* const argPacket) {
|
||||||
|
|||||||
@@ -26,8 +26,6 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
constexpr SDL_Color WHITE = {255, 255, 255, 255};
|
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
//Public access members
|
//Public access members
|
||||||
//-------------------------
|
//-------------------------
|
||||||
@@ -48,11 +46,11 @@ MainMenu::MainMenu() {
|
|||||||
|
|
||||||
//setup the buttons
|
//setup the buttons
|
||||||
startButton.SetBackgroundTexture(GetRenderer(), buttonImage.GetTexture());
|
startButton.SetBackgroundTexture(GetRenderer(), buttonImage.GetTexture());
|
||||||
startButton.SetText(GetRenderer(), font, WHITE, "Start");
|
startButton.SetText(GetRenderer(), font, "Start", COLOR_WHITE);
|
||||||
optionsButton.SetBackgroundTexture(GetRenderer(), buttonImage.GetTexture());
|
optionsButton.SetBackgroundTexture(GetRenderer(), buttonImage.GetTexture());
|
||||||
optionsButton.SetText(GetRenderer(), font, WHITE, "Options");
|
optionsButton.SetText(GetRenderer(), font, "Options", COLOR_WHITE);
|
||||||
quitButton.SetBackgroundTexture(GetRenderer(), buttonImage.GetTexture());
|
quitButton.SetBackgroundTexture(GetRenderer(), buttonImage.GetTexture());
|
||||||
quitButton.SetText(GetRenderer(), font, WHITE, "Quit");
|
quitButton.SetText(GetRenderer(), font, "Quit", COLOR_WHITE);
|
||||||
|
|
||||||
//set the button positions
|
//set the button positions
|
||||||
startButton.SetX(50);
|
startButton.SetX(50);
|
||||||
@@ -63,15 +61,9 @@ MainMenu::MainMenu() {
|
|||||||
quitButton.SetY(50 + 20 * 2);
|
quitButton.SetY(50 + 20 * 2);
|
||||||
|
|
||||||
//text box
|
//text box
|
||||||
int h = -1;
|
textBox.PushLine(GetRenderer(), font, "Thanks for playing!", {255, 255, 255, 255});
|
||||||
SDL_RenderGetLogicalSize(GetRenderer(), nullptr, &h);
|
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
|
||||||
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
|
|
||||||
|
|
||||||
//debug
|
//debug
|
||||||
//
|
//
|
||||||
@@ -101,7 +93,11 @@ void MainMenu::RenderFrame(SDL_Renderer* renderer) {
|
|||||||
startButton.DrawTo(renderer);
|
startButton.DrawTo(renderer);
|
||||||
optionsButton.DrawTo(renderer);
|
optionsButton.DrawTo(renderer);
|
||||||
quitButton.DrawTo(renderer);
|
quitButton.DrawTo(renderer);
|
||||||
textBox.DrawTo(renderer);
|
|
||||||
|
int h = -1;
|
||||||
|
SDL_RenderGetLogicalSize(GetRenderer(), nullptr, &h);
|
||||||
|
|
||||||
|
textBox.DrawTo(renderer, 50, h-50, -12);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
|
|||||||
@@ -26,8 +26,6 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
constexpr SDL_Color WHITE = {255, 255, 255, 255};
|
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
//Public access members
|
//Public access members
|
||||||
//-------------------------
|
//-------------------------
|
||||||
@@ -48,16 +46,14 @@ OptionsMenu::OptionsMenu() {
|
|||||||
|
|
||||||
//setup the button
|
//setup the button
|
||||||
backButton.SetBackgroundTexture(GetRenderer(), buttonImage.GetTexture());
|
backButton.SetBackgroundTexture(GetRenderer(), buttonImage.GetTexture());
|
||||||
backButton.SetText(GetRenderer(), font, WHITE, "Back");
|
backButton.SetText(GetRenderer(), font, "Back", COLOR_WHITE);
|
||||||
|
|
||||||
//set the button positions
|
//set the button positions
|
||||||
backButton.SetX(50);
|
backButton.SetX(50);
|
||||||
backButton.SetY(50);
|
backButton.SetY(50);
|
||||||
|
|
||||||
//text line
|
//text line
|
||||||
textLine.SetX(50);
|
textLine.SetText(GetRenderer(), font, "This code is fucking hard to refactor.", {255, 255, 255, 255});
|
||||||
textLine.SetY(30);
|
|
||||||
textLine.SetText(GetRenderer(), font, WHITE, "Am I making any progress?");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OptionsMenu::~OptionsMenu() {
|
OptionsMenu::~OptionsMenu() {
|
||||||
@@ -82,7 +78,7 @@ void OptionsMenu::FrameEnd() {
|
|||||||
|
|
||||||
void OptionsMenu::RenderFrame(SDL_Renderer* renderer) {
|
void OptionsMenu::RenderFrame(SDL_Renderer* renderer) {
|
||||||
backButton.DrawTo(renderer);
|
backButton.DrawTo(renderer);
|
||||||
textLine.DrawTo(renderer);
|
textLine.DrawTo(renderer, 50, 30);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
|
|||||||
@@ -34,8 +34,6 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
constexpr SDL_Color WHITE = {255, 255, 255, 255};
|
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
//static functions
|
//static functions
|
||||||
//-------------------------
|
//-------------------------
|
||||||
@@ -74,9 +72,9 @@ World::World(int* const argClientIndex, int* const argAccountIndex):
|
|||||||
|
|
||||||
//setup the buttons
|
//setup the buttons
|
||||||
disconnectButton.SetBackgroundTexture(GetRenderer(), buttonImage.GetTexture());
|
disconnectButton.SetBackgroundTexture(GetRenderer(), buttonImage.GetTexture());
|
||||||
disconnectButton.SetText(GetRenderer(), font, WHITE, "Disconnect");
|
disconnectButton.SetText(GetRenderer(), font, "Disconnect", COLOR_WHITE);
|
||||||
shutdownButton.SetBackgroundTexture(GetRenderer(), buttonImage.GetTexture());
|
shutdownButton.SetBackgroundTexture(GetRenderer(), buttonImage.GetTexture());
|
||||||
shutdownButton.SetText(GetRenderer(), font, WHITE, "Shutdown");
|
shutdownButton.SetText(GetRenderer(), font, "Shutdown", COLOR_WHITE);
|
||||||
|
|
||||||
//set the button positions
|
//set the button positions
|
||||||
disconnectButton.SetX(50);
|
disconnectButton.SetX(50);
|
||||||
@@ -118,8 +116,8 @@ World::World(int* const argClientIndex, int* const argAccountIndex):
|
|||||||
"slot 7 red.png",
|
"slot 7 red.png",
|
||||||
"slot 8 red.png"
|
"slot 8 red.png"
|
||||||
};
|
};
|
||||||
barrierMgr.LoadBaseImage(GetRenderer(), config["dir.sprites"] + "barrier/base.png");
|
barrierMgr.LoadBaseImage(GetRenderer(), config["dir.sprites"] + "/barrier/base.png");
|
||||||
barrierMgr.LoadTemplateImages(GetRenderer(), config["dir.sprites"] + "barrier/", slotNames);
|
barrierMgr.LoadTemplateImages(GetRenderer(), config["dir.sprites"] + "/barrier/", slotNames);
|
||||||
|
|
||||||
std::cout << "Templates loaded: " << barrierMgr.GetTemplateContainer()->size() << std::endl;
|
std::cout << "Templates loaded: " << barrierMgr.GetTemplateContainer()->size() << std::endl;
|
||||||
}
|
}
|
||||||
@@ -161,12 +159,7 @@ void World::Update() {
|
|||||||
delete reinterpret_cast<char*>(packetBuffer);
|
delete reinterpret_cast<char*>(packetBuffer);
|
||||||
|
|
||||||
//heartbeat system
|
//heartbeat system
|
||||||
if (heartbeatUtility.CheckHeartBeat()) {
|
CheckHeartBeat();
|
||||||
//escape to the disconnect screen
|
|
||||||
SendDisconnectRequest();
|
|
||||||
SetSceneSignal(SceneSignal::DISCONNECTEDSCREEN);
|
|
||||||
ConfigUtility::GetSingleton()["client.disconnectMessage"] = "Error: Lost connection to the server";
|
|
||||||
}
|
|
||||||
|
|
||||||
//update all entities
|
//update all entities
|
||||||
for (auto& it : characterMap) {
|
for (auto& it : characterMap) {
|
||||||
@@ -192,27 +185,7 @@ void World::Update() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: (0) regular query interval
|
//TODO: (1) 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
//cull creatures
|
//cull creatures
|
||||||
for (std::map<int, BaseCreature>::iterator it = creatureMap.begin(); it != creatureMap.end(); /* */) {
|
for (std::map<int, BaseCreature>::iterator it = creatureMap.begin(); it != creatureMap.end(); /* */) {
|
||||||
if ( (localCharacter->GetOrigin() - it->second.GetOrigin()).Length() > INFLUENCE_RADIUS) {
|
if ( (localCharacter->GetOrigin() - it->second.GetOrigin()).Length() > INFLUENCE_RADIUS) {
|
||||||
@@ -223,10 +196,7 @@ void World::Update() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//cull barriers
|
//TODO: cull barriers
|
||||||
barrierMgr.UnloadIf([&](std::pair<const int, BaseBarrier const&> barrierIt) -> bool {
|
|
||||||
return (localCharacter->GetOrigin() - barrierIt.second.GetOrigin()).Length() > INFLUENCE_RADIUS;
|
|
||||||
});
|
|
||||||
|
|
||||||
//get the collidable boxes
|
//get the collidable boxes
|
||||||
std::list<BoundingBox> boxList = GenerateCollisionGrid(localCharacter, tileSheet.GetTileW(), tileSheet.GetTileH());
|
std::list<BoundingBox> boxList = GenerateCollisionGrid(localCharacter, tileSheet.GetTileW(), tileSheet.GetTileH());
|
||||||
@@ -268,12 +238,12 @@ void World::RenderFrame(SDL_Renderer* renderer) {
|
|||||||
shutdownButton.DrawTo(renderer);
|
shutdownButton.DrawTo(renderer);
|
||||||
|
|
||||||
//FPS
|
//FPS
|
||||||
fpsTextLine.DrawTo(renderer);
|
fpsTextLine.DrawTo(renderer, 0, 0);
|
||||||
int fpsRet = fps.Calculate();
|
int fpsRet = fps.Calculate();
|
||||||
if (fpsRet != -1) {
|
if (fpsRet != -1) {
|
||||||
std::ostringstream msg;
|
std::ostringstream msg;
|
||||||
msg << "FPS: " << fpsRet;
|
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) {
|
switch(argPacket->type) {
|
||||||
//heartbeat system
|
//heartbeat system
|
||||||
case SerialPacketType::PING:
|
case SerialPacketType::PING:
|
||||||
heartbeatUtility.hPing(static_cast<ServerPacket*>(argPacket));
|
hPing(static_cast<ServerPacket*>(argPacket));
|
||||||
break;
|
break;
|
||||||
case SerialPacketType::PONG:
|
case SerialPacketType::PONG:
|
||||||
heartbeatUtility.hPong(static_cast<ServerPacket*>(argPacket));
|
hPong(static_cast<ServerPacket*>(argPacket));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//game server connections
|
//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
|
//Connection control
|
||||||
//-------------------------
|
//-------------------------
|
||||||
@@ -719,9 +727,6 @@ void World::hCharacterCreate(CharacterPacket* const argPacket) {
|
|||||||
if (character->GetOwner() == accountIndex) {
|
if (character->GetOwner() == accountIndex) {
|
||||||
localCharacter = static_cast<LocalCharacter*>(character);
|
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
|
//focus the camera on this character's sprite
|
||||||
camera.marginX = (camera.width / 2 - localCharacter->GetSprite()->GetClipW() / 2);
|
camera.marginX = (camera.width / 2 - localCharacter->GetSprite()->GetClipW() / 2);
|
||||||
camera.marginY = (camera.height/ 2 - localCharacter->GetSprite()->GetClipH() / 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
|
//focus on this character's info
|
||||||
characterIndex = argPacket->characterIndex;
|
characterIndex = argPacket->characterIndex;
|
||||||
roomIndex = argPacket->roomIndex;
|
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
|
//debug
|
||||||
@@ -769,12 +794,12 @@ void World::hCharacterUnload(CharacterPacket* const argPacket) {
|
|||||||
void World::hQueryCharacterExists(CharacterPacket* const argPacket) {
|
void World::hQueryCharacterExists(CharacterPacket* const argPacket) {
|
||||||
//prevent a double message about this player's character
|
//prevent a double message about this player's character
|
||||||
//TODO: why is this commented out?
|
//TODO: why is this commented out?
|
||||||
if (argPacket->accountIndex == accountIndex) {
|
// if (argPacket->accountIndex == accountIndex) {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
//ignore characters in a different room (sub-optimal)
|
//ignore characters in a different room (sub-optimal)
|
||||||
if (argPacket->roomIndex != roomIndex || (localCharacter->GetOrigin() - argPacket->origin).Length() > INFLUENCE_RADIUS) {
|
if (argPacket->roomIndex != roomIndex) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -891,12 +916,10 @@ void World::hCreatureUnload(CreaturePacket* const argPacket) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void World::hQueryCreatureExists(CreaturePacket* const argPacket) {
|
void World::hQueryCreatureExists(CreaturePacket* const argPacket) {
|
||||||
if (!localCharacter) {
|
std::cout << "Creature Query" << std::endl;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//ignore creatures in a different room (sub-optimal)
|
//ignore creatures in a different room (sub-optimal)
|
||||||
if (argPacket->roomIndex != roomIndex || (localCharacter->GetOrigin() - argPacket->origin).Length() > INFLUENCE_RADIUS) {
|
if (argPacket->roomIndex != roomIndex) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1001,12 +1024,10 @@ void World::hBarrierUnload(BarrierPacket* const argPacket) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void World::hQueryBarrierExists(BarrierPacket* const argPacket) {
|
void World::hQueryBarrierExists(BarrierPacket* const argPacket) {
|
||||||
if (!localCharacter) {
|
std::cout << "Barrier Query" << std::endl;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//ignore barriers in a different room (sub-optimal)
|
//ignore barriers in a different room (sub-optimal)
|
||||||
if (argPacket->roomIndex != roomIndex || (localCharacter->GetOrigin() - argPacket->origin).Length() > INFLUENCE_RADIUS) {
|
if (argPacket->roomIndex != roomIndex) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,6 @@
|
|||||||
#include "base_scene.hpp"
|
#include "base_scene.hpp"
|
||||||
#include "base_barrier.hpp"
|
#include "base_barrier.hpp"
|
||||||
#include "base_creature.hpp"
|
#include "base_creature.hpp"
|
||||||
#include "heartbeat_utility.hpp"
|
|
||||||
#include "local_character.hpp"
|
#include "local_character.hpp"
|
||||||
|
|
||||||
#include "SDL2/SDL.h"
|
#include "SDL2/SDL.h"
|
||||||
@@ -81,6 +80,12 @@ private:
|
|||||||
//handle incoming traffic
|
//handle incoming traffic
|
||||||
void HandlePacket(SerialPacket* const);
|
void HandlePacket(SerialPacket* const);
|
||||||
|
|
||||||
|
//heartbeat system
|
||||||
|
void hPing(ServerPacket* const);
|
||||||
|
void hPong(ServerPacket* const);
|
||||||
|
|
||||||
|
void CheckHeartBeat();
|
||||||
|
|
||||||
//basic connections
|
//basic connections
|
||||||
void SendLogoutRequest();
|
void SendLogoutRequest();
|
||||||
void SendDisconnectRequest();
|
void SendDisconnectRequest();
|
||||||
@@ -160,9 +165,10 @@ private:
|
|||||||
LocalCharacter* localCharacter = nullptr;
|
LocalCharacter* localCharacter = nullptr;
|
||||||
|
|
||||||
//heartbeat
|
//heartbeat
|
||||||
HeartbeatUtility heartbeatUtility;
|
//TODO: (2) Heartbeat needs it's own utility
|
||||||
typedef std::chrono::steady_clock Clock;
|
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
|
//ugly references; I hate this
|
||||||
ConfigUtility& config = ConfigUtility::GetSingleton();
|
ConfigUtility& config = ConfigUtility::GetSingleton();
|
||||||
|
|||||||
@@ -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
|
|
||||||
};
|
|
||||||
@@ -21,8 +21,6 @@
|
|||||||
*/
|
*/
|
||||||
#include "button.hpp"
|
#include "button.hpp"
|
||||||
|
|
||||||
#include "render_text_texture.hpp"
|
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
void Button::DrawTo(SDL_Renderer* renderer) {
|
void Button::DrawTo(SDL_Renderer* renderer) {
|
||||||
@@ -53,9 +51,19 @@ void Button::SetBackgroundTexture(SDL_Renderer* renderer, SDL_Texture* texture)
|
|||||||
image.SetClipH(image.GetClipH() / 3);
|
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
|
//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
|
//get the dimensions & rects
|
||||||
int x, y, w, h;
|
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);
|
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) {
|
Button::State Button::MouseMotion(SDL_MouseMotionEvent const& event) {
|
||||||
//if out of bounds, exit
|
//if out of bounds, exit
|
||||||
if (!CheckBounds(event.x, event.y)) {
|
if (!CheckBounds(event.x, event.y)) {
|
||||||
@@ -140,22 +156,6 @@ Button::State Button::GetState() {
|
|||||||
return state;
|
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) {
|
bool Button::CheckBounds(int x, int y) {
|
||||||
//return if true (x, y) is within bounds, otherwise return false
|
//return if true (x, y) is within bounds, otherwise return false
|
||||||
return !(
|
return !(
|
||||||
|
|||||||
@@ -27,6 +27,11 @@
|
|||||||
|
|
||||||
#include <string>
|
#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 {
|
class Button {
|
||||||
public:
|
public:
|
||||||
enum State {
|
enum State {
|
||||||
@@ -41,7 +46,9 @@ public:
|
|||||||
|
|
||||||
//setup
|
//setup
|
||||||
void SetBackgroundTexture(SDL_Renderer*, SDL_Texture*);
|
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
|
//capture input
|
||||||
State MouseMotion(SDL_MouseMotionEvent const&);
|
State MouseMotion(SDL_MouseMotionEvent const&);
|
||||||
@@ -52,16 +59,10 @@ public:
|
|||||||
void SetState(State); //TODO: idle, busy or disabled
|
void SetState(State); //TODO: idle, busy or disabled
|
||||||
State GetState();
|
State GetState();
|
||||||
|
|
||||||
//accessors & mutators
|
|
||||||
int SetX(int x);
|
|
||||||
int SetY(int y);
|
|
||||||
int GetX() const;
|
|
||||||
int GetY() const;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool CheckBounds(int x, int y);
|
bool CheckBounds(int x, int y);
|
||||||
|
|
||||||
Image image;
|
Image image;
|
||||||
State state = State::IDLE;
|
|
||||||
int posX = 0, posY = 0;
|
int posX = 0, posY = 0;
|
||||||
|
State state = State::IDLE;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#config
|
#config
|
||||||
INCLUDES+=. ../utilities
|
INCLUDES+=.
|
||||||
LIBS+=
|
LIBS+=
|
||||||
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
|
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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);
|
|
||||||
@@ -31,18 +31,15 @@ TextBox::~TextBox() {
|
|||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextBox::DrawTo(SDL_Renderer* renderer) {
|
void TextBox::DrawTo(SDL_Renderer* renderer, int posX, int posY, int pointSize) {
|
||||||
int renderY = posY;
|
|
||||||
for (std::list<TextLine>::iterator it = lineList.begin(); it != lineList.end(); it++) {
|
for (std::list<TextLine>::iterator it = lineList.begin(); it != lineList.end(); it++) {
|
||||||
it->SetX(posX);
|
it->DrawTo(renderer, posX, posY);
|
||||||
it->SetY(renderY);
|
posY += pointSize;
|
||||||
it->DrawTo(renderer);
|
|
||||||
renderY += it->GetPointHeight();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextBox::PushLine(SDL_Renderer* renderer, TTF_Font* font, SDL_Color color, std::string str) {
|
void TextBox::PushLine(SDL_Renderer* renderer, TTF_Font* font, std::string str, SDL_Color color) {
|
||||||
lineList.emplace_back(renderer, font, color, str, 0, 0);
|
lineList.emplace_front(renderer, font, str, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextBox::PopLine(int num) {
|
void TextBox::PopLine(int num) {
|
||||||
@@ -50,26 +47,10 @@ void TextBox::PopLine(int num) {
|
|||||||
num < lineList.size() ? num : lineList.size();
|
num < lineList.size() ? num : lineList.size();
|
||||||
|
|
||||||
for (int i = 0; i < num; ++i) {
|
for (int i = 0; i < num; ++i) {
|
||||||
lineList.pop_front();
|
lineList.pop_back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextBox::ClearLines() {
|
void TextBox::ClearLines() {
|
||||||
lineList.clear();
|
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;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -34,18 +34,12 @@ public:
|
|||||||
TextBox();
|
TextBox();
|
||||||
~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 PopLine(int num = 1);
|
||||||
void ClearLines();
|
void ClearLines();
|
||||||
|
|
||||||
int SetX(int i);
|
|
||||||
int SetY(int i);
|
|
||||||
int GetX() const;
|
|
||||||
int GetY() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::list<TextLine> lineList;
|
std::list<TextLine> lineList;
|
||||||
int posX = 0, posY = 0;
|
|
||||||
};
|
};
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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;
|
|
||||||
};
|
|
||||||
@@ -21,58 +21,50 @@
|
|||||||
*/
|
*/
|
||||||
#include "text_line.hpp"
|
#include "text_line.hpp"
|
||||||
|
|
||||||
#include "render_text_texture.hpp"
|
|
||||||
|
|
||||||
#include <stdexcept>
|
#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() {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
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() {
|
TextLine::~TextLine() {
|
||||||
ClearText();
|
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_Rect dclip = {posX, posY, 0, 0};
|
||||||
SDL_QueryTexture(texture, nullptr, nullptr, &dclip.w, &dclip.h);
|
SDL_QueryTexture(texture, nullptr, nullptr, &dclip.w, &dclip.h);
|
||||||
SDL_RenderCopy(renderer, texture, nullptr, &dclip);
|
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
|
//just use the above global function
|
||||||
SDL_DestroyTexture(texture);
|
SDL_DestroyTexture(texture);
|
||||||
texture = renderTextTexture(renderer, font, color, str);
|
texture = renderTextTexture(renderer, font, str, color);
|
||||||
pointHeight = TTF_FontHeight(font);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextLine::ClearText() {
|
void TextLine::ClearText() {
|
||||||
SDL_DestroyTexture(texture);
|
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;
|
|
||||||
}
|
}
|
||||||
@@ -26,28 +26,20 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
SDL_Texture* renderTextTexture(SDL_Renderer*, TTF_Font*, std::string, SDL_Color color);
|
||||||
|
|
||||||
class TextLine {
|
class TextLine {
|
||||||
public:
|
public:
|
||||||
TextLine();
|
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();
|
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();
|
void ClearText();
|
||||||
|
|
||||||
//accessors & mutators
|
|
||||||
int SetX(int i);
|
|
||||||
int SetY(int i);
|
|
||||||
int GetX() const;
|
|
||||||
int GetY() const;
|
|
||||||
|
|
||||||
//utility
|
|
||||||
int GetPointHeight();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SDL_Texture* texture = nullptr;
|
SDL_Texture* texture = nullptr;
|
||||||
int posX = 0, posY = 0;
|
|
||||||
int pointHeight = 0; //internal use for TextBox
|
|
||||||
};
|
};
|
||||||
@@ -34,16 +34,15 @@
|
|||||||
typedef SerialPacketBase SerialPacket;
|
typedef SerialPacketBase SerialPacket;
|
||||||
|
|
||||||
//DOCS: NETWORK_VERSION is used to discern compatible servers and clients
|
//DOCS: NETWORK_VERSION is used to discern compatible servers and clients
|
||||||
constexpr int NETWORK_VERSION = 20160825;
|
constexpr int NETWORK_VERSION = 20160404;
|
||||||
|
|
||||||
union MaxPacket {
|
union MaxPacket {
|
||||||
BarrierPacket a;
|
CharacterPacket a;
|
||||||
CharacterPacket b;
|
ClientPacket b;
|
||||||
ClientPacket c;
|
CreaturePacket c;
|
||||||
CreaturePacket d;
|
RegionPacket d;
|
||||||
RegionPacket e;
|
ServerPacket e;
|
||||||
ServerPacket f;
|
TextPacket f;
|
||||||
TextPacket g;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr int MAX_PACKET_SIZE = sizeof(MaxPacket);
|
constexpr int MAX_PACKET_SIZE = sizeof(MaxPacket);
|
||||||
|
|||||||
@@ -142,6 +142,25 @@ enum class SerialPacketType {
|
|||||||
|
|
||||||
FORMAT_END_CREATURE = 599,
|
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
|
//TextPacket
|
||||||
// name, text
|
// name, text
|
||||||
@@ -165,28 +184,6 @@ enum class SerialPacketType {
|
|||||||
|
|
||||||
FORMAT_END_TEXT = 699,
|
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
|
//not used
|
||||||
//-------------------------
|
//-------------------------
|
||||||
|
|||||||
@@ -70,12 +70,12 @@ void serializePacket(void* buffer, SerialPacketBase* packet) {
|
|||||||
serializeCreature(buffer, static_cast<CreaturePacket*>(packet));
|
serializeCreature(buffer, static_cast<CreaturePacket*>(packet));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BOUNDS(packet->type, SerialPacketType::FORMAT_TEXT, SerialPacketType::FORMAT_END_TEXT)) {
|
if (BOUNDS(packet->type, SerialPacketType::FORMAT_COMBAT, SerialPacketType::FORMAT_END_COMBAT)) {
|
||||||
serializeText(buffer, static_cast<TextPacket*>(packet));
|
serializeBarrier(buffer, static_cast<BarrierPacket*>(packet));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BOUNDS(packet->type, SerialPacketType::FORMAT_BARRIER, SerialPacketType::FORMAT_END_BARRIER)) {
|
if (BOUNDS(packet->type, SerialPacketType::FORMAT_TEXT, SerialPacketType::FORMAT_END_TEXT)) {
|
||||||
serializeBarrier(buffer, static_cast<BarrierPacket*>(packet));
|
serializeText(buffer, static_cast<TextPacket*>(packet));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,11 +104,11 @@ void deserializePacket(void* buffer, SerialPacketBase* packet) {
|
|||||||
deserializeCreature(buffer, static_cast<CreaturePacket*>(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)) {
|
if (BOUNDS(type, SerialPacketType::FORMAT_TEXT, SerialPacketType::FORMAT_END_TEXT)) {
|
||||||
deserializeText(buffer, static_cast<TextPacket*>(packet));
|
deserializeText(buffer, static_cast<TextPacket*>(packet));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BOUNDS(type, SerialPacketType::FORMAT_BARRIER, SerialPacketType::FORMAT_END_BARRIER)) {
|
|
||||||
deserializeBarrier(buffer, static_cast<BarrierPacket*>(packet));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -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();
|
|
||||||
}
|
|
||||||
@@ -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.
|
|
Before Width: | Height: | Size: 1009 B |
|
Before Width: | Height: | Size: 316 B |
|
Before Width: | Height: | Size: 738 B After Width: | Height: | Size: 738 B |
|
Before Width: | Height: | Size: 763 B After Width: | Height: | Size: 763 B |
|
Before Width: | Height: | Size: 273 B After Width: | Height: | Size: 273 B |
|
Before Width: | Height: | Size: 270 B After Width: | Height: | Size: 270 B |
|
Before Width: | Height: | Size: 305 B After Width: | Height: | Size: 305 B |
|
Before Width: | Height: | Size: 302 B After Width: | Height: | Size: 302 B |
|
Before Width: | Height: | Size: 423 B After Width: | Height: | Size: 423 B |
|
Before Width: | Height: | Size: 422 B After Width: | Height: | Size: 422 B |
|
Before Width: | Height: | Size: 301 B After Width: | Height: | Size: 301 B |
|
Before Width: | Height: | Size: 299 B After Width: | Height: | Size: 299 B |
|
Before Width: | Height: | Size: 385 B After Width: | Height: | Size: 385 B |
|
Before Width: | Height: | Size: 383 B After Width: | Height: | Size: 383 B |
|
Before Width: | Height: | Size: 412 B After Width: | Height: | Size: 412 B |
|
Before Width: | Height: | Size: 402 B After Width: | Height: | Size: 402 B |
|
Before Width: | Height: | Size: 431 B After Width: | Height: | Size: 431 B |
|
Before Width: | Height: | Size: 429 B After Width: | Height: | Size: 429 B |
|
Before Width: | Height: | Size: 407 B After Width: | Height: | Size: 407 B |
|
Before Width: | Height: | Size: 400 B After Width: | Height: | Size: 400 B |
|
Before Width: | Height: | Size: 656 B After Width: | Height: | Size: 656 B |
|
After Width: | Height: | Size: 680 B |
@@ -130,14 +130,14 @@ roomManagerAPI.SetOnCreate(function(room, index)
|
|||||||
--
|
--
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
creatureManagerAPI.Create(roomAPI.GetCreatureMgr(room), "anibunny.png", bunnySquare)
|
||||||
|
|
||||||
--creatureManager with SetOnCreate, SetOnUnload & create & unload
|
--creatureManager with SetOnCreate, SetOnUnload & create & unload
|
||||||
barrierManagerAPI.SetOnCreate(roomAPI.GetBarrierMgr(room), function(barrier)
|
barrierManagerAPI.SetOnCreate(roomAPI.GetBarrierMgr(room), function(barrier)
|
||||||
barrierAPI.SetScript(barrier, barrierTick)
|
barrierAPI.SetScript(barrier, barrierTick)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
roomAPI.SetOnTick(room, function(room)
|
roomAPI.SetOnTick(room, function(room)
|
||||||
ret = 0
|
|
||||||
--placeholders
|
|
||||||
roomAPI.ForEachCharacter(room, function(character)
|
roomAPI.ForEachCharacter(room, function(character)
|
||||||
--
|
--
|
||||||
end)
|
end)
|
||||||
@@ -146,19 +146,7 @@ roomManagerAPI.SetOnCreate(function(room, index)
|
|||||||
--
|
--
|
||||||
end)
|
end)
|
||||||
|
|
||||||
roomAPI.ForEachBarrier(room, function(creature)
|
--TODO: for each barrier
|
||||||
--
|
|
||||||
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
|
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|||||||
@@ -20,23 +20,13 @@
|
|||||||
* distribution.
|
* distribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
-------------------------
|
|
||||||
--defines
|
|
||||||
-------------------------
|
|
||||||
|
|
||||||
PRAGMA foreign_keys = ON;
|
|
||||||
|
|
||||||
-------------------------
|
|
||||||
--table definitions
|
|
||||||
-------------------------
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS UserAccounts (
|
CREATE TABLE IF NOT EXISTS UserAccounts (
|
||||||
uid INTEGER PRIMARY KEY AUTOINCREMENT,
|
uid INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
username varchar(100) UNIQUE, --TODO: (3) Swap username for email address
|
username varchar(100) UNIQUE, --TODO: (3) Swap username for email address
|
||||||
|
|
||||||
--server-client security
|
--server-client security
|
||||||
passhash varchar(100),
|
-- passhash varchar(100),
|
||||||
passsalt varchar(100),
|
-- passsalt varchar(100),
|
||||||
|
|
||||||
--server controls
|
--server controls
|
||||||
blacklisted BIT DEFAULT 0,
|
blacklisted BIT DEFAULT 0,
|
||||||
@@ -49,8 +39,8 @@ CREATE TABLE IF NOT EXISTS LiveCharacters (
|
|||||||
uid INTEGER PRIMARY KEY AUTOINCREMENT,
|
uid INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
|
||||||
--metadata
|
--metadata
|
||||||
owner INTEGER REFERENCES UserAccounts(uid),
|
owner INTEGER REFERENCES Accounts(uid),
|
||||||
handle varchar(100),
|
handle varchar(100) UNIQUE,
|
||||||
avatar varchar(100),
|
avatar varchar(100),
|
||||||
birth timestamp NOT NULL DEFAULT (datetime()),
|
birth timestamp NOT NULL DEFAULT (datetime()),
|
||||||
|
|
||||||
@@ -58,8 +48,59 @@ CREATE TABLE IF NOT EXISTS LiveCharacters (
|
|||||||
roomIndex INTEGER DEFAULT 0,
|
roomIndex INTEGER DEFAULT 0,
|
||||||
originX INTEGER DEFAULT 0,
|
originX INTEGER DEFAULT 0,
|
||||||
originY 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,
|
level INTEGER DEFAULT 0,
|
||||||
exp INTEGER DEFAULT 0,
|
exp INTEGER DEFAULT 0,
|
||||||
maxHP INTEGER DEFAULT 0,
|
maxHP INTEGER DEFAULT 0,
|
||||||
@@ -70,53 +111,48 @@ CREATE TABLE IF NOT EXISTS LiveCharacters (
|
|||||||
defence INTEGER DEFAULT 0,
|
defence INTEGER DEFAULT 0,
|
||||||
intelligence INTEGER DEFAULT 0,
|
intelligence INTEGER DEFAULT 0,
|
||||||
resistance INTEGER DEFAULT 0,
|
resistance INTEGER DEFAULT 0,
|
||||||
accuracy INTEGER DEFAULT 0,
|
|
||||||
evasion INTEGER DEFAULT 0,
|
|
||||||
speed 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 (
|
CREATE TABLE IF NOT EXISTS InWorldItems (
|
||||||
uid INTEGER PRIMARY KEY,
|
|
||||||
|
|
||||||
--metadata
|
--metadata
|
||||||
owner INTEGER REFERENCES UserAccounts(uid),
|
uid INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
handle varchar(100),
|
itemType INTEGER,
|
||||||
avatar varchar(100),
|
|
||||||
birth timestamp NOT NULL,
|
|
||||||
death timestamp NOT NULL DEFAULT (datetime()),
|
|
||||||
|
|
||||||
--combat stats
|
--position in the world
|
||||||
level INTEGER DEFAULT 0,
|
roomIndex INTEGER DEFAULT 0,
|
||||||
exp INTEGER DEFAULT 0,
|
originX INTEGER DEFAULT 0,
|
||||||
maxHP INTEGER DEFAULT 0,
|
originY INTEGER DEFAULT 0,
|
||||||
maxMP INTEGER DEFAULT 0,
|
|
||||||
attack INTEGER DEFAULT 0,
|
--unique information
|
||||||
defence INTEGER DEFAULT 0,
|
stackSize INTEGER DEFAULT 0,
|
||||||
intelligence INTEGER DEFAULT 0,
|
durability INTEGER DEFAULT 0,
|
||||||
resistance INTEGER DEFAULT 0,
|
stats INTEGER REFERENCES StatisticSets(uid)
|
||||||
accuracy INTEGER DEFAULT 0,
|
|
||||||
evasion INTEGER DEFAULT 0,
|
|
||||||
speed INTEGER DEFAULT 0,
|
|
||||||
luck INTEGER DEFAULT 0
|
|
||||||
);
|
);
|
||||||
|
|
||||||
-------------------------
|
|
||||||
--global tables
|
|
||||||
-------------------------
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS InventoryItems (
|
CREATE TABLE IF NOT EXISTS InventoryItems (
|
||||||
--metadata
|
--metadata
|
||||||
uid INTEGER PRIMARY KEY AUTOINCREMENT,
|
uid INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
name varchar(100) UNIQUE,
|
owner INTEGER REFERENCES Characters(uid),
|
||||||
type varchar(100), --tmp type
|
itemType INTEGER,
|
||||||
|
|
||||||
--unique information
|
--unique information
|
||||||
durability INTEGER DEFAULT 0
|
stackSize INTEGER DEFAULT 0,
|
||||||
|
durability INTEGER DEFAULT 0,
|
||||||
|
stats INTEGER REFERENCES StatisticSets(uid)
|
||||||
);
|
);
|
||||||
|
|
||||||
-------------------------
|
CREATE TABLE IF NOT EXISTS WornEquipment (
|
||||||
--member tables
|
--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?
|
||||||
|
);
|
||||||
|
|||||||
@@ -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"
|
|
||||||
|
|
||||||
@@ -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;
|
|
||||||
};
|
|
||||||
@@ -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"
|
|
||||||
|
|
||||||
@@ -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:
|
|
||||||
//
|
|
||||||
};
|
|
||||||
@@ -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;
|
|
||||||
};
|
|
||||||
@@ -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 $@ $<
|
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
@@ -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 $@ $<
|
|
||||||
@@ -28,51 +28,53 @@
|
|||||||
#include "server_utilities.hpp"
|
#include "server_utilities.hpp"
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <iostream>
|
|
||||||
static int setRoom(lua_State* L) {
|
static int setRoom(lua_State* L) {
|
||||||
//variables
|
//reverse engineer the character index
|
||||||
|
int characterIndex = -1;
|
||||||
CharacterData* character = static_cast<CharacterData*>(lua_touserdata(L, 1));
|
CharacterData* character = static_cast<CharacterData*>(lua_touserdata(L, 1));
|
||||||
CharacterManager& characterMgr = CharacterManager::GetSingleton();
|
CharacterManager& characterMgr = CharacterManager::GetSingleton();
|
||||||
|
|
||||||
|
for (auto& it : *characterMgr.GetContainer()) {
|
||||||
|
if (character == &it.second) {
|
||||||
|
characterIndex = it.first;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//error checking
|
//error checking
|
||||||
if (characterMgr.Find(character->GetIndex()) != character) {
|
if (characterIndex == -1) {
|
||||||
throw(std::runtime_error("Lua Error: Failed to verify character index by reference"));
|
throw(std::runtime_error("Lua Error: Failed to find character index by reference"));
|
||||||
}
|
}
|
||||||
|
|
||||||
//get the room index, depending on the parameter type
|
//get the room index, depending on the parameter type
|
||||||
int roomIndex = -1;
|
int roomIndex = -1;
|
||||||
|
RoomManager& roomMgr = RoomManager::GetSingleton();
|
||||||
switch(lua_type(L, 2)) {
|
switch(lua_type(L, 2)) {
|
||||||
case LUA_TNUMBER:
|
case LUA_TNUMBER:
|
||||||
//simple integer
|
|
||||||
roomIndex = lua_tointeger(L, 2);
|
roomIndex = lua_tointeger(L, 2);
|
||||||
break;
|
break;
|
||||||
case LUA_TLIGHTUSERDATA: {
|
case LUA_TLIGHTUSERDATA:
|
||||||
//check that this is a room first
|
//reverse engineer the room index
|
||||||
RoomData* room = static_cast<RoomData*>(lua_touserdata(L, 2));
|
for (auto& it : *roomMgr.GetContainer()) {
|
||||||
RoomManager& roomMgr = RoomManager::GetSingleton();
|
if (lua_touserdata(L, 2) == &it.second) {
|
||||||
|
roomIndex = it.first;
|
||||||
if (roomMgr.Find(room->GetRoomIndex()) != room) {
|
break;
|
||||||
std::cout << room->GetRoomIndex() << std::endl;
|
|
||||||
throw(std::runtime_error("Lua Error: Failed to verify room index by reference"));
|
|
||||||
}
|
}
|
||||||
roomIndex = room->GetRoomIndex();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
}
|
||||||
|
|
||||||
|
//error checking
|
||||||
|
if (roomIndex == -1) {
|
||||||
throw(std::runtime_error("Lua Error: Failed to find room index by reference"));
|
throw(std::runtime_error("Lua Error: Failed to find room index by reference"));
|
||||||
}
|
}
|
||||||
|
|
||||||
//send the delete & create messages
|
//send the delete & create messages
|
||||||
pumpAndChangeRooms(character, roomIndex, character->GetIndex());
|
pumpAndChangeRooms(character, roomIndex, characterIndex);
|
||||||
return 0;
|
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) {
|
static int getOwner(lua_State* L) {
|
||||||
CharacterData* character = static_cast<CharacterData*>(lua_touserdata(L, 1));
|
CharacterData* character = static_cast<CharacterData*>(lua_touserdata(L, 1));
|
||||||
lua_pushinteger(L, character->GetOwner());
|
lua_pushinteger(L, character->GetOwner());
|
||||||
@@ -93,7 +95,6 @@ static int getAvatar(lua_State* L) {
|
|||||||
|
|
||||||
static const luaL_Reg characterLib[] = {
|
static const luaL_Reg characterLib[] = {
|
||||||
{"SetRoom", setRoom},
|
{"SetRoom", setRoom},
|
||||||
{"GetIndex", getIndex},
|
|
||||||
// {"GetOwner", getOwner}, //unusable without account API
|
// {"GetOwner", getOwner}, //unusable without account API
|
||||||
{"GetHandle", getHandle},
|
{"GetHandle", getHandle},
|
||||||
{"GetAvatar", getAvatar},
|
{"GetAvatar", getAvatar},
|
||||||
|
|||||||
@@ -30,14 +30,6 @@ CharacterData::CharacterData(): Entity("character") {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//database stuff
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
int CharacterData::GetIndex() {
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CharacterData::GetOwner() {
|
int CharacterData::GetOwner() {
|
||||||
return owner;
|
return owner;
|
||||||
}
|
}
|
||||||
@@ -49,7 +41,3 @@ std::string CharacterData::GetHandle() {
|
|||||||
std::string CharacterData::GetAvatar() {
|
std::string CharacterData::GetAvatar() {
|
||||||
return avatar;
|
return avatar;
|
||||||
}
|
}
|
||||||
|
|
||||||
Inventory* CharacterData::GetInventory() {
|
|
||||||
return &inventory;
|
|
||||||
}
|
|
||||||
@@ -24,7 +24,6 @@
|
|||||||
//components
|
//components
|
||||||
#include "character_defines.hpp"
|
#include "character_defines.hpp"
|
||||||
#include "entity.hpp"
|
#include "entity.hpp"
|
||||||
#include "inventory.hpp"
|
|
||||||
|
|
||||||
//std namespace
|
//std namespace
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -36,19 +35,14 @@ public:
|
|||||||
~CharacterData() = default;
|
~CharacterData() = default;
|
||||||
|
|
||||||
//database stuff
|
//database stuff
|
||||||
int GetIndex();
|
|
||||||
int GetOwner();
|
int GetOwner();
|
||||||
std::string GetHandle();
|
std::string GetHandle();
|
||||||
std::string GetAvatar();
|
std::string GetAvatar();
|
||||||
Inventory* GetInventory();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class CharacterManager;
|
friend class CharacterManager;
|
||||||
|
|
||||||
//database stuff
|
|
||||||
int index = -1;
|
|
||||||
int owner = -1;
|
int owner = -1;
|
||||||
std::string handle;
|
std::string handle;
|
||||||
std::string avatar;
|
std::string avatar;
|
||||||
Inventory inventory;
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -39,8 +39,12 @@
|
|||||||
static const char* CREATE_CHARACTER = "INSERT INTO LiveCharacters ("
|
static const char* CREATE_CHARACTER = "INSERT INTO LiveCharacters ("
|
||||||
"owner, "
|
"owner, "
|
||||||
"handle, "
|
"handle, "
|
||||||
"avatar "
|
"avatar, "
|
||||||
") VALUES (?1, ?2, ?3);";
|
"boundsX, "
|
||||||
|
"boundsY, "
|
||||||
|
"boundsW, "
|
||||||
|
"boundsH"
|
||||||
|
") VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7);";
|
||||||
|
|
||||||
static const char* LOAD_CHARACTER = "SELECT "
|
static const char* LOAD_CHARACTER = "SELECT "
|
||||||
"uid, "
|
"uid, "
|
||||||
@@ -49,13 +53,21 @@ static const char* LOAD_CHARACTER = "SELECT "
|
|||||||
"avatar, "
|
"avatar, "
|
||||||
"roomIndex, "
|
"roomIndex, "
|
||||||
"originX, "
|
"originX, "
|
||||||
"originY "
|
"originY, "
|
||||||
|
"boundsX, "
|
||||||
|
"boundsY, "
|
||||||
|
"boundsW, "
|
||||||
|
"boundsH "
|
||||||
"FROM LiveCharacters WHERE handle = ?;";
|
"FROM LiveCharacters WHERE handle = ?;";
|
||||||
|
|
||||||
static const char* SAVE_CHARACTER = "UPDATE OR FAIL LiveCharacters SET "
|
static const char* SAVE_CHARACTER = "UPDATE OR FAIL LiveCharacters SET "
|
||||||
"roomIndex = ?2, "
|
"roomIndex = ?2, "
|
||||||
"originX = ?3, "
|
"originX = ?3, "
|
||||||
"originY = ?4 "
|
"originY = ?4, "
|
||||||
|
"boundsX = ?5, "
|
||||||
|
"boundsY = ?6, "
|
||||||
|
"boundsW = ?7, "
|
||||||
|
"boundsH = ?8 "
|
||||||
"WHERE uid = ?1;";
|
"WHERE uid = ?1;";
|
||||||
|
|
||||||
static const char* DELETE_CHARACTER = "DELETE FROM LiveCharacters WHERE uid = ?;";
|
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_int(statement, 1, owner);
|
||||||
ret |= sqlite3_bind_text(statement, 2, handle.c_str(), handle.size() + 1, SQLITE_STATIC);
|
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_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
|
//check for binding errors
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@@ -141,7 +157,6 @@ int CharacterManager::Load(int owner, std::string handle, std::string avatar) {
|
|||||||
CharacterData& newChar = elementMap[uid];
|
CharacterData& newChar = elementMap[uid];
|
||||||
|
|
||||||
//metadata
|
//metadata
|
||||||
newChar.index = uid;
|
|
||||||
newChar.owner = owner;
|
newChar.owner = owner;
|
||||||
newChar.handle = reinterpret_cast<const char*>(sqlite3_column_text(statement, 2));
|
newChar.handle = reinterpret_cast<const char*>(sqlite3_column_text(statement, 2));
|
||||||
newChar.avatar = reinterpret_cast<const char*>(sqlite3_column_text(statement, 3));
|
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.x = (double)sqlite3_column_int(statement, 5);
|
||||||
newChar.origin.y = (double)sqlite3_column_int(statement, 6);
|
newChar.origin.y = (double)sqlite3_column_int(statement, 6);
|
||||||
//bounds
|
//bounds
|
||||||
newChar.bounds.x = CHARACTER_BOUNDS_X;
|
newChar.bounds.x = (int)sqlite3_column_int(statement, 7);
|
||||||
newChar.bounds.y = CHARACTER_BOUNDS_Y;
|
newChar.bounds.y = (int)sqlite3_column_int(statement, 8);
|
||||||
newChar.bounds.w = CHARACTER_BOUNDS_WIDTH;
|
newChar.bounds.w = (int)sqlite3_column_int(statement, 9);
|
||||||
newChar.bounds.h = CHARACTER_BOUNDS_HEIGHT;
|
newChar.bounds.h = (int)sqlite3_column_int(statement, 10);
|
||||||
|
|
||||||
//gameplay components: equipment, items, buffs, debuffs...
|
//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, 2, character.roomIndex) != SQLITE_OK;
|
||||||
ret |= sqlite3_bind_int(statement, 3, (int)character.origin.x) != 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, 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
|
//check for binding errors
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#config
|
#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+=
|
LIBS+=
|
||||||
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
|
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
|
||||||
|
|
||||||
|
|||||||
@@ -52,17 +52,15 @@ static int getTag(lua_State* L) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static int setInstance(lua_State* L) {
|
||||||
static int setBattleIndex(lua_State* L) {
|
|
||||||
BarrierData* barrier = static_cast<BarrierData*>(lua_touserdata(L, 1));
|
BarrierData* barrier = static_cast<BarrierData*>(lua_touserdata(L, 1));
|
||||||
barrier->SetBattleIndex(lua_tointeger(L, 2));
|
barrier->SetInstanceIndex(lua_tointeger(L, 2));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
static int getBattleIndex(lua_State* L) {
|
static int getInstance(lua_State* L) {
|
||||||
BarrierData* barrier = static_cast<BarrierData*>(lua_touserdata(L, 1));
|
BarrierData* barrier = static_cast<BarrierData*>(lua_touserdata(L, 1));
|
||||||
lua_pushinteger(L, barrier->GetBattleIndex());
|
lua_pushinteger(L, barrier->GetInstanceIndex());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,8 +81,8 @@ static const luaL_Reg barrierLib[] = {
|
|||||||
{"GetScript", getScript},
|
{"GetScript", getScript},
|
||||||
{"SetTag", setTag},
|
{"SetTag", setTag},
|
||||||
{"GetTag", getTag},
|
{"GetTag", getTag},
|
||||||
// {"SetBattleIndex", setBattleIndex},
|
{"SetInstance", setInstance},
|
||||||
{"GetBattleIndex", getBattleIndex},
|
{"GetInstance", getInstance},
|
||||||
{"SetStatus", setStatus},
|
{"SetStatus", setStatus},
|
||||||
{"GetStatus", getStatus},
|
{"GetStatus", getStatus},
|
||||||
{nullptr, nullptr}
|
{nullptr, nullptr}
|
||||||
@@ -28,15 +28,8 @@
|
|||||||
BarrierData::BarrierData(int i):
|
BarrierData::BarrierData(int i):
|
||||||
Entity::Entity("barrier")
|
Entity::Entity("barrier")
|
||||||
{
|
{
|
||||||
battleIndex = i;
|
instanceIndex = i;
|
||||||
memset(status, 0, sizeof(int) * 8);
|
memset(status, 0, sizeof(int) * 8);
|
||||||
|
|
||||||
SetBounds({
|
|
||||||
BARRIER_BOUNDS_X,
|
|
||||||
BARRIER_BOUNDS_Y,
|
|
||||||
BARRIER_BOUNDS_WIDTH,
|
|
||||||
BARRIER_BOUNDS_HEIGHT
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BarrierData::~BarrierData() {
|
BarrierData::~BarrierData() {
|
||||||
@@ -46,7 +39,6 @@ BarrierData::~BarrierData() {
|
|||||||
int BarrierData::Update(lua_State* L) {
|
int BarrierData::Update(lua_State* L) {
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
//NOTE: this is here mostly for the "barrier tick" effect
|
|
||||||
if (scriptRef != LUA_NOREF) {
|
if (scriptRef != LUA_NOREF) {
|
||||||
//Call the script reference
|
//Call the script reference
|
||||||
lua_pushinteger(L, scriptRef);
|
lua_pushinteger(L, scriptRef);
|
||||||
@@ -85,12 +77,12 @@ std::string BarrierData::GetTag(std::string key) {
|
|||||||
return tags[key];
|
return tags[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
int BarrierData::SetBattleIndex(int i) {
|
int BarrierData::SetInstanceIndex(int i) {
|
||||||
return battleIndex = i;
|
return instanceIndex = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
int BarrierData::GetBattleIndex() const {
|
int BarrierData::GetInstanceIndex() const {
|
||||||
return battleIndex;
|
return instanceIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
int BarrierData::SetStatus(int k, int v) {
|
int BarrierData::SetStatus(int k, int v) {
|
||||||
@@ -21,7 +21,6 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "barrier_defines.hpp"
|
|
||||||
#include "entity.hpp"
|
#include "entity.hpp"
|
||||||
|
|
||||||
#include "lua.hpp"
|
#include "lua.hpp"
|
||||||
@@ -31,7 +30,7 @@
|
|||||||
|
|
||||||
class BarrierData: public Entity {
|
class BarrierData: public Entity {
|
||||||
public:
|
public:
|
||||||
BarrierData(int battleIndex);
|
BarrierData(int instanceIndex);
|
||||||
~BarrierData();
|
~BarrierData();
|
||||||
|
|
||||||
int Update(lua_State*);
|
int Update(lua_State*);
|
||||||
@@ -39,12 +38,11 @@ public:
|
|||||||
int SetScriptReference(int);
|
int SetScriptReference(int);
|
||||||
int GetScriptReference();
|
int GetScriptReference();
|
||||||
|
|
||||||
//NOTE: Why does this have tags? Are the tags used?
|
|
||||||
std::string SetTag(std::string key, std::string value);
|
std::string SetTag(std::string key, std::string value);
|
||||||
std::string GetTag(std::string key);
|
std::string GetTag(std::string key);
|
||||||
|
|
||||||
int SetBattleIndex(int i);
|
int SetInstanceIndex(int i);
|
||||||
int GetBattleIndex() const;
|
int GetInstanceIndex() const;
|
||||||
|
|
||||||
int SetStatus(int k, int v);
|
int SetStatus(int k, int v);
|
||||||
int GetStatus(int k);
|
int GetStatus(int k);
|
||||||
@@ -55,7 +53,7 @@ private:
|
|||||||
int scriptRef = LUA_NOREF;
|
int scriptRef = LUA_NOREF;
|
||||||
std::map<std::string, std::string> tags;
|
std::map<std::string, std::string> tags;
|
||||||
|
|
||||||
int battleIndex;
|
int instanceIndex;
|
||||||
|
|
||||||
int status[8];
|
int status[8];
|
||||||
};
|
};
|
||||||
@@ -23,6 +23,8 @@
|
|||||||
|
|
||||||
#include "lua_utilities.hpp"
|
#include "lua_utilities.hpp"
|
||||||
|
|
||||||
|
#include "barrier_defines.hpp"
|
||||||
|
|
||||||
BarrierManager::BarrierManager() {
|
BarrierManager::BarrierManager() {
|
||||||
//EMPTY
|
//EMPTY
|
||||||
}
|
}
|
||||||
@@ -32,12 +34,57 @@ BarrierManager::~BarrierManager() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//arg: a list of barriers to be updated in the clients
|
//arg: a list of barriers to be updated in the clients
|
||||||
void BarrierManager::Update(std::list<std::pair<const int, BarrierData*>>* barrierList, bool updateAll) {
|
void BarrierManager::Update(
|
||||||
int ret;
|
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) {
|
for (auto& it : elementMap) {
|
||||||
ret = it.second.Update(lua);
|
//normal update
|
||||||
if (ret || updateAll) {
|
ret = it.second.Update(lua) ? 1 : 0;
|
||||||
barrierList->push_back(std::pair<const int, BarrierData*>(it.first, &it.second));
|
|
||||||
|
//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
|
#pragma once
|
||||||
|
|
||||||
#include "barrier_data.hpp"
|
#include "barrier_data.hpp"
|
||||||
|
#include "character_data.hpp"
|
||||||
|
#include "creature_data.hpp"
|
||||||
|
|
||||||
#include "lua.hpp"
|
#include "lua.hpp"
|
||||||
#include "sqlite3.h"
|
#include "sqlite3.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <functional>
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
class BarrierManager {
|
class BarrierManager {
|
||||||
public:
|
public:
|
||||||
@@ -37,7 +39,12 @@ public:
|
|||||||
~BarrierManager();
|
~BarrierManager();
|
||||||
|
|
||||||
//common public methods
|
//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);
|
int Create(int instanceIndex);
|
||||||
void Unload(int uid);
|
void Unload(int uid);
|
||||||
@@ -19,20 +19,33 @@
|
|||||||
* 3. This notice may not be removed or altered from any source
|
* 3. This notice may not be removed or altered from any source
|
||||||
* distribution.
|
* distribution.
|
||||||
*/
|
*/
|
||||||
#include "item_data.hpp"
|
#include "combat_instance.hpp"
|
||||||
|
|
||||||
ItemType ItemData::SetItemType(ItemType t) {
|
CombatInstance::CombatInstance() {
|
||||||
return type = t;
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemType ItemData::GetItemType() {
|
CombatInstance::~CombatInstance() {
|
||||||
return type;
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
int ItemData::SetQuantity(int i) {
|
void CombatInstance::Update() {
|
||||||
return quantity = i;
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
int ItemData::GetQuantity() {
|
//accessors and mutators
|
||||||
return quantity;
|
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 "character_data.hpp"
|
||||||
#include "creature_data.hpp"
|
#include "creature_data.hpp"
|
||||||
|
|
||||||
#include <functional>
|
class CombatInstance {
|
||||||
|
|
||||||
class BattleData {
|
|
||||||
public:
|
public:
|
||||||
constexpr static int BATTLE_SIZE = 8;
|
CombatInstance();
|
||||||
|
~CombatInstance();
|
||||||
BattleData();
|
|
||||||
~BattleData();
|
|
||||||
|
|
||||||
void Update();
|
void Update();
|
||||||
|
|
||||||
//accessors and mutators
|
//accessors and mutators
|
||||||
int PushCharacter(CharacterData* const characterData);
|
void PushCharacter(CharacterData* const characterData);
|
||||||
int PopCharacter(CharacterData const * const characterData);
|
void PopCharacter(CharacterData* const characterData);
|
||||||
|
|
||||||
int PushCreature(CreatureData* const creatureData);
|
void PushCreature(CreatureData* const creatureData);
|
||||||
int PopCreature(CreatureData const * const creatureData);
|
void PopCreature(CreatureData* const creatureData);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::array<CharacterData*, BATTLE_SIZE> characterArray;
|
std::array<CharacterData*, 8> characterArray;
|
||||||
std::array<CreatureData*, BATTLE_SIZE> creatureArray;
|
std::array<CreatureData*, 8> creatureArray;
|
||||||
};
|
};
|
||||||
@@ -19,26 +19,26 @@
|
|||||||
* 3. This notice may not be removed or altered from any source
|
* 3. This notice may not be removed or altered from any source
|
||||||
* distribution.
|
* distribution.
|
||||||
*/
|
*/
|
||||||
#include "battle_manager.hpp"
|
#include "combat_instance_manager.hpp"
|
||||||
|
|
||||||
BattleManager::BattleManager() {
|
CombatInstanceManager::CombatInstanceManager() {
|
||||||
//EMPTY
|
//EMPTY
|
||||||
}
|
}
|
||||||
|
|
||||||
BattleManager::~BattleManager() {
|
CombatInstanceManager::~CombatInstanceManager() {
|
||||||
UnloadAll();
|
UnloadAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
//arg: a list of combats to be updated in the clients
|
//arg: a list of combats to be updated in the clients
|
||||||
void BattleManager::Update() {
|
void CombatInstanceManager::Update() {
|
||||||
for (auto& it : elementMap) {
|
for (auto& it : elementMap) {
|
||||||
it.second.Update();
|
it.second.Update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int BattleManager::Create() {
|
int CombatInstanceManager::Create() {
|
||||||
//implicitly create the new object
|
//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
|
//TODO: do various things like saving to the database
|
||||||
return counter++;
|
return counter++;
|
||||||
@@ -46,16 +46,16 @@ int BattleManager::Create() {
|
|||||||
|
|
||||||
//TODO: (1) combat load, save
|
//TODO: (1) combat load, save
|
||||||
|
|
||||||
void BattleManager::Unload(int uid) {
|
void CombatInstanceManager::Unload(int uid) {
|
||||||
elementMap.erase(uid);
|
elementMap.erase(uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BattleManager::UnloadAll() {
|
void CombatInstanceManager::UnloadAll() {
|
||||||
elementMap.clear();
|
elementMap.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BattleManager::UnloadIf(std::function<bool(std::pair<const int, BattleData const&>)> fn) {
|
void CombatInstanceManager::UnloadIf(std::function<bool(std::pair<const int, CombatInstance const&>)> fn) {
|
||||||
std::map<int, BattleData>::iterator it = elementMap.begin();
|
std::map<int, CombatInstance>::iterator it = elementMap.begin();
|
||||||
while (it != elementMap.end()) {
|
while (it != elementMap.end()) {
|
||||||
if (fn(*it)) {
|
if (fn(*it)) {
|
||||||
it = elementMap.erase(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) {
|
CombatInstance* CombatInstanceManager::Find(int uid) {
|
||||||
std::map<int, BattleData>::iterator it = elementMap.find(uid);
|
std::map<int, CombatInstance>::iterator it = elementMap.find(uid);
|
||||||
|
|
||||||
if (it == elementMap.end()) {
|
if (it == elementMap.end()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -76,26 +76,26 @@ BattleData* BattleManager::Find(int uid) {
|
|||||||
return &it->second;
|
return &it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
int BattleManager::GetLoadedCount() {
|
int CombatInstanceManager::GetLoadedCount() {
|
||||||
return elementMap.size();
|
return elementMap.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<int, BattleData>* BattleManager::GetContainer() {
|
std::map<int, CombatInstance>* CombatInstanceManager::GetContainer() {
|
||||||
return &elementMap;
|
return &elementMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
lua_State* BattleManager::SetLuaState(lua_State* L) {
|
lua_State* CombatInstanceManager::SetLuaState(lua_State* L) {
|
||||||
return lua = L;
|
return lua = L;
|
||||||
}
|
}
|
||||||
|
|
||||||
lua_State* BattleManager::GetLuaState() {
|
lua_State* CombatInstanceManager::GetLuaState() {
|
||||||
return lua;
|
return lua;
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3* BattleManager::SetDatabase(sqlite3* db) {
|
sqlite3* CombatInstanceManager::SetDatabase(sqlite3* db) {
|
||||||
return database = db;
|
return database = db;
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3* BattleManager::GetDatabase() {
|
sqlite3* CombatInstanceManager::GetDatabase() {
|
||||||
return database;
|
return database;
|
||||||
}
|
}
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "battle_data.hpp"
|
#include "combat_instance.hpp"
|
||||||
|
|
||||||
#include "lua.hpp"
|
#include "lua.hpp"
|
||||||
#include "sqlite3.h"
|
#include "sqlite3.h"
|
||||||
@@ -29,10 +29,10 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
class BattleManager {
|
class CombatInstanceManager {
|
||||||
public:
|
public:
|
||||||
BattleManager();
|
CombatInstanceManager();
|
||||||
~BattleManager();
|
~CombatInstanceManager();
|
||||||
|
|
||||||
//common public methods
|
//common public methods
|
||||||
void Update();
|
void Update();
|
||||||
@@ -41,12 +41,12 @@ public:
|
|||||||
void Unload(int uid);
|
void Unload(int uid);
|
||||||
|
|
||||||
void UnloadAll();
|
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
|
//accessors & mutators
|
||||||
BattleData* Find(int uid);
|
CombatInstance* Find(int uid);
|
||||||
int GetLoadedCount();
|
int GetLoadedCount();
|
||||||
std::map<int, BattleData>* GetContainer();
|
std::map<int, CombatInstance>* GetContainer();
|
||||||
|
|
||||||
//hooks
|
//hooks
|
||||||
lua_State* SetLuaState(lua_State* L);
|
lua_State* SetLuaState(lua_State* L);
|
||||||
@@ -56,7 +56,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
//members
|
//members
|
||||||
std::map<int, BattleData> elementMap;
|
std::map<int, CombatInstance> elementMap;
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
lua_State* lua = nullptr;
|
lua_State* lua = nullptr;
|
||||||
sqlite3* database = nullptr;
|
sqlite3* database = nullptr;
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#config
|
#config
|
||||||
INCLUDES+=. ../../common/gameplay
|
INCLUDES+=. .. ../characters ../creatures ../entities ../../common/gameplay ../../common/utilities
|
||||||
LIBS+=
|
LIBS+=
|
||||||
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
|
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
|
||||||
|
|
||||||
@@ -32,12 +32,39 @@ CreatureManager::~CreatureManager() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//arg: a list of creatures to be updated in the clients
|
//arg: a list of creatures to be updated in the clients
|
||||||
void CreatureManager::Update(std::list<std::pair<const int, CreatureData*>>* creatureList, bool updateAll) {
|
void CreatureManager::Update(
|
||||||
int ret;
|
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) {
|
for (auto& it : elementMap) {
|
||||||
ret = it.second.Update(lua);
|
//normal update
|
||||||
if (ret || updateAll) {
|
ret = it.second.Update(lua) ? 1 : 0;
|
||||||
creatureList->push_back(std::pair<const int, CreatureData*>(it.first, &it.second));
|
|
||||||
|
//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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "character_data.hpp"
|
||||||
#include "creature_data.hpp"
|
#include "creature_data.hpp"
|
||||||
|
|
||||||
#include "lua.hpp"
|
#include "lua.hpp"
|
||||||
@@ -30,6 +31,7 @@
|
|||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
class CreatureManager {
|
class CreatureManager {
|
||||||
public:
|
public:
|
||||||
@@ -37,7 +39,11 @@ public:
|
|||||||
~CreatureManager();
|
~CreatureManager();
|
||||||
|
|
||||||
//common public methods
|
//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);
|
int Create(std::string avatar, int scriptRef);
|
||||||
void Unload(int uid);
|
void Unload(int uid);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#config
|
#config
|
||||||
INCLUDES+=. .. ../entities ../../common/gameplay ../../common/utilities
|
INCLUDES+=. .. ../characters ../entities ../../common/gameplay ../../common/utilities
|
||||||
LIBS+=
|
LIBS+=
|
||||||
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
|
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
|
||||||
|
|
||||||
|
|||||||
@@ -63,6 +63,10 @@ BoundingBox Entity::GetBounds() const {
|
|||||||
return bounds;
|
return bounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BoundingBox Entity::GetRealBounds() const {
|
||||||
|
return bounds + origin;
|
||||||
|
}
|
||||||
|
|
||||||
const char* Entity::GetType() const {
|
const char* Entity::GetType() const {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
@@ -41,6 +41,7 @@ public:
|
|||||||
Vector2 GetOrigin() const;
|
Vector2 GetOrigin() const;
|
||||||
Vector2 GetMotion() const;
|
Vector2 GetMotion() const;
|
||||||
BoundingBox GetBounds() const;
|
BoundingBox GetBounds() const;
|
||||||
|
BoundingBox GetRealBounds() const;
|
||||||
|
|
||||||
const char* GetType() const;
|
const char* GetType() const;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#include directories
|
#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
|
#libraries
|
||||||
#the order of the $(LIBS) is important, at least for MinGW
|
#the order of the $(LIBS) is important, at least for MinGW
|
||||||
@@ -30,13 +30,11 @@ OUT=$(addprefix $(OUTDIR)/,server)
|
|||||||
#targets
|
#targets
|
||||||
all: $(OBJ) $(OUT)
|
all: $(OBJ) $(OUT)
|
||||||
$(MAKE) -C accounts
|
$(MAKE) -C accounts
|
||||||
$(MAKE) -C barriers
|
|
||||||
$(MAKE) -C battles
|
|
||||||
$(MAKE) -C characters
|
$(MAKE) -C characters
|
||||||
$(MAKE) -C clients
|
$(MAKE) -C clients
|
||||||
|
$(MAKE) -C combat
|
||||||
$(MAKE) -C creatures
|
$(MAKE) -C creatures
|
||||||
$(MAKE) -C entities
|
$(MAKE) -C entities
|
||||||
$(MAKE) -C inventory
|
|
||||||
$(MAKE) -C rooms
|
$(MAKE) -C rooms
|
||||||
$(MAKE) -C triggers
|
$(MAKE) -C triggers
|
||||||
$(CXX) $(CXXFLAGS) -o $(OUT) $(OBJ) $(LIBS)
|
$(CXX) $(CXXFLAGS) -o $(OUT) $(OBJ) $(LIBS)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#config
|
#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+=
|
LIBS+=
|
||||||
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
|
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
|
||||||
|
|
||||||
|
|||||||
@@ -109,24 +109,6 @@ static int forEachCreature(lua_State* L) {
|
|||||||
return 0;
|
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) {
|
static int setOnTick(lua_State* L) {
|
||||||
RoomData* room = reinterpret_cast<RoomData*>(lua_touserdata(L, 1));
|
RoomData* room = reinterpret_cast<RoomData*>(lua_touserdata(L, 1));
|
||||||
luaL_unref(L, LUA_REGISTRYINDEX, room->GetTickReference());
|
luaL_unref(L, LUA_REGISTRYINDEX, room->GetTickReference());
|
||||||
@@ -140,19 +122,6 @@ static int getOnTick(lua_State* L) {
|
|||||||
return 1;
|
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) {
|
static int initialize(lua_State* L) {
|
||||||
RoomData* room = static_cast<RoomData*>(lua_touserdata(L, 1));
|
RoomData* room = static_cast<RoomData*>(lua_touserdata(L, 1));
|
||||||
|
|
||||||
@@ -179,14 +148,10 @@ static const luaL_Reg roomLib[] = {
|
|||||||
|
|
||||||
{"ForEachCharacter", forEachCharacter},
|
{"ForEachCharacter", forEachCharacter},
|
||||||
{"ForEachCreature", forEachCreature},
|
{"ForEachCreature", forEachCreature},
|
||||||
{"ForEachBarrier", forEachBarrier},
|
|
||||||
|
|
||||||
{"SetOnTick", setOnTick},
|
{"SetOnTick", setOnTick},
|
||||||
{"GetOnTick", getOnTick},
|
{"GetOnTick", getOnTick},
|
||||||
|
|
||||||
{"SetTag", setTag},
|
|
||||||
{"GetTag", getTag},
|
|
||||||
|
|
||||||
{"Initialize", initialize},
|
{"Initialize", initialize},
|
||||||
{nullptr, nullptr}
|
{nullptr, nullptr}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -30,115 +30,72 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
/* DOCS: this is the process for RoomData::RunFrame(), read more
|
//TODO: (9) character collisions should be preformed client-side
|
||||||
*
|
|
||||||
* 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
|
|
||||||
void RoomData::RunFrame() {
|
void RoomData::RunFrame() {
|
||||||
RunFrameUpdates(RunFrameLuaOnTick());
|
|
||||||
RunFrameTriggers();
|
|
||||||
RunFrameCharacterCreatureCollisions();
|
|
||||||
RunFrameCharacterBarrierCollisions();
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//hi-cohesion methods for one-time use
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
bool RoomData::RunFrameLuaOnTick() {
|
|
||||||
//get the hook
|
//get the hook
|
||||||
lua_rawgeti(lua, LUA_REGISTRYINDEX, tickRef);
|
lua_rawgeti(lua, LUA_REGISTRYINDEX, tickRef);
|
||||||
|
|
||||||
//returning 1 means pump all
|
|
||||||
bool updateAll = false;
|
|
||||||
if (!lua_isnil(lua, -1)) {
|
if (!lua_isnil(lua, -1)) {
|
||||||
//call the tick function, with this as a parameter
|
//call the tick function, with this as a parameter
|
||||||
lua_pushlightuserdata(lua, this);
|
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) ));
|
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 {
|
else {
|
||||||
lua_pop(lua, 1);
|
lua_pop(lua, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return updateAll;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RoomData::RunFrameUpdates(bool updateAll) {
|
|
||||||
//lists of non-character entities that need updating client-side
|
//lists of non-character entities that need updating client-side
|
||||||
std::list<std::pair<const int, CreatureData*>> creatureList;
|
//types are index, ptr, action (0 = update, 1 = unload)
|
||||||
std::list<std::pair<const int, BarrierData*>> barrierList;
|
std::list<std::tuple<const int, CreatureData*, int>> creatureList;
|
||||||
|
std::list<std::tuple<const int, BarrierData*, int>> barrierList;
|
||||||
|
|
||||||
//update the entities in the room
|
//update the entities in the room
|
||||||
for (auto& it : characterList) {
|
for (auto& it : characterList) {
|
||||||
it->Update();
|
it->Update();
|
||||||
}
|
}
|
||||||
creatureMgr.Update(&creatureList, updateAll);
|
creatureMgr.Update(&creatureList, &characterList);
|
||||||
barrierMgr.Update(&barrierList, updateAll);
|
barrierMgr.Update(&barrierList, &creatureList, &characterList);
|
||||||
|
|
||||||
//update the battles
|
|
||||||
battleMgr.Update();
|
|
||||||
|
|
||||||
//send the creature updates
|
//send the creature updates
|
||||||
for (auto& it : creatureList) {
|
for (auto& it : creatureList) {
|
||||||
CreaturePacket packet;
|
CreaturePacket packet;
|
||||||
copyCreatureToPacket(&packet, it.second, it.first);
|
copyCreatureToPacket(&packet, std::get<1>(it), std::get<0>(it));
|
||||||
|
|
||||||
|
//interpret the event
|
||||||
|
if (std::get<2>(it) & 1) {
|
||||||
packet.type = SerialPacketType::CREATURE_UPDATE;
|
packet.type = SerialPacketType::CREATURE_UPDATE;
|
||||||
|
}
|
||||||
|
if (std::get<2>(it) & 2) {
|
||||||
|
packet.type = SerialPacketType::CREATURE_UNLOAD;
|
||||||
|
}
|
||||||
|
|
||||||
packet.roomIndex = roomIndex;
|
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
|
//send the barrier updates
|
||||||
for (auto& it : barrierList) {
|
for (auto& it : barrierList) {
|
||||||
BarrierPacket packet;
|
BarrierPacket packet;
|
||||||
copyBarrierToPacket(&packet, it.second, it.first);
|
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.type = SerialPacketType::BARRIER_UPDATE;
|
||||||
|
}
|
||||||
|
|
||||||
packet.roomIndex = roomIndex;
|
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
|
//build a list of entities for use with the triggers
|
||||||
//currently, this only uses characters
|
|
||||||
std::stack<Entity*> entityStack;
|
std::stack<Entity*> entityStack;
|
||||||
for (auto& it : characterList) {
|
for (auto& it : characterList) {
|
||||||
entityStack.push(it);
|
entityStack.push(it);
|
||||||
@@ -148,101 +105,6 @@ void RoomData::RunFrameTriggers() {
|
|||||||
triggerMgr.Compare(entityStack);
|
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) {
|
std::string RoomData::SetName(std::string s) {
|
||||||
return roomName = s;
|
return roomName = s;
|
||||||
}
|
}
|
||||||
@@ -267,44 +129,6 @@ int RoomData::GetRoomIndex() {
|
|||||||
return roomIndex;
|
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() {
|
BarrierManager* RoomData::GetBarrierMgr() {
|
||||||
return &barrierMgr;
|
return &barrierMgr;
|
||||||
}
|
}
|
||||||
@@ -355,11 +179,3 @@ int RoomData::SetTickReference(int i) {
|
|||||||
int RoomData::GetTickReference() {
|
int RoomData::GetTickReference() {
|
||||||
return tickRef;
|
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];
|
|
||||||
}
|
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
#include "barrier_manager.hpp"
|
#include "barrier_manager.hpp"
|
||||||
#include "character_data.hpp"
|
#include "character_data.hpp"
|
||||||
#include "battle_manager.hpp"
|
#include "combat_instance_manager.hpp"
|
||||||
#include "creature_manager.hpp"
|
#include "creature_manager.hpp"
|
||||||
#include "region_pager_lua.hpp"
|
#include "region_pager_lua.hpp"
|
||||||
#include "trigger_manager.hpp"
|
#include "trigger_manager.hpp"
|
||||||
@@ -53,9 +53,6 @@ public:
|
|||||||
int SetRoomIndex(int i);
|
int SetRoomIndex(int i);
|
||||||
int GetRoomIndex();
|
int GetRoomIndex();
|
||||||
|
|
||||||
void PushCharacter(CharacterData* const character);
|
|
||||||
void PopCharacter(CharacterData const * const character);
|
|
||||||
|
|
||||||
BarrierManager* GetBarrierMgr();
|
BarrierManager* GetBarrierMgr();
|
||||||
std::list<CharacterData*>* GetCharacterList();
|
std::list<CharacterData*>* GetCharacterList();
|
||||||
CreatureManager* GetCreatureMgr();
|
CreatureManager* GetCreatureMgr();
|
||||||
@@ -73,17 +70,7 @@ public:
|
|||||||
int GetTickReference();
|
int GetTickReference();
|
||||||
//TODO: other triggers like player entry & exit, etc.
|
//TODO: other triggers like player entry & exit, etc.
|
||||||
|
|
||||||
std::string SetTag(std::string key, std::string value);
|
|
||||||
std::string GetTag(std::string key);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//hi-cohesion methods for one-time use
|
|
||||||
bool RunFrameLuaOnTick();
|
|
||||||
void RunFrameUpdates(bool updateAll);
|
|
||||||
void RunFrameTriggers();
|
|
||||||
void RunFrameCharacterCreatureCollisions();
|
|
||||||
void RunFrameCharacterBarrierCollisions();
|
|
||||||
|
|
||||||
//metadata
|
//metadata
|
||||||
std::string roomName;
|
std::string roomName;
|
||||||
std::string tilesetName;
|
std::string tilesetName;
|
||||||
@@ -92,7 +79,7 @@ private:
|
|||||||
int roomIndex = 0;
|
int roomIndex = 0;
|
||||||
BarrierManager barrierMgr;
|
BarrierManager barrierMgr;
|
||||||
std::list<CharacterData*> characterList;
|
std::list<CharacterData*> characterList;
|
||||||
BattleManager battleMgr;
|
CombatInstanceManager combatInstanceMgr;
|
||||||
CreatureManager creatureMgr;
|
CreatureManager creatureMgr;
|
||||||
RegionPagerLua pager;
|
RegionPagerLua pager;
|
||||||
TriggerManager triggerMgr;
|
TriggerManager triggerMgr;
|
||||||
@@ -103,5 +90,4 @@ private:
|
|||||||
|
|
||||||
//hooks
|
//hooks
|
||||||
int tickRef = LUA_NOREF;
|
int tickRef = LUA_NOREF;
|
||||||
std::map<std::string, std::string> tags;
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ void RoomManager::UnloadIf(std::function<bool(std::pair<const int, RoomData cons
|
|||||||
lua_pop(lua, 1);
|
lua_pop(lua, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RoomManager::PushCharacter(CharacterData* const character) {
|
void RoomManager::PushCharacter(CharacterData* character) {
|
||||||
if (!character) {
|
if (!character) {
|
||||||
throw(std::runtime_error("Failed to push a null character to a room"));
|
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());
|
RoomData* room = Find(character->GetRoomIndex());
|
||||||
|
|
||||||
if (!room) {
|
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
|
//NOTE: to pop an character from a room, the character must first exist
|
||||||
if (!character) {
|
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());
|
RoomData* room = Find(character->GetRoomIndex());
|
||||||
|
|
||||||
if (!room) {
|
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
|
//TODO: rename these functions from Get to Find
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ public:
|
|||||||
void UnloadAll();
|
void UnloadAll();
|
||||||
void UnloadIf(std::function<bool(std::pair<const int, RoomData const&>)> fn);
|
void UnloadIf(std::function<bool(std::pair<const int, RoomData const&>)> fn);
|
||||||
|
|
||||||
void PushCharacter(CharacterData* const character);
|
void PushCharacter(CharacterData* character);
|
||||||
void PopCharacter(CharacterData const * const character);
|
void PopCharacter(CharacterData const* character);
|
||||||
|
|
||||||
//accessors and mutators
|
//accessors and mutators
|
||||||
RoomData* Find(int uid);
|
RoomData* Find(int uid);
|
||||||
|
|||||||
@@ -596,36 +596,11 @@ void ServerApplication::hQueryCharacterExists(CharacterPacket* const argPacket)
|
|||||||
//respond with all character data
|
//respond with all character data
|
||||||
CharacterPacket newPacket;
|
CharacterPacket newPacket;
|
||||||
|
|
||||||
//retrieve all character data
|
|
||||||
if (argPacket->roomIndex == -1) {
|
|
||||||
for (auto& it : *characterMgr.GetContainer()) {
|
for (auto& it : *characterMgr.GetContainer()) {
|
||||||
copyCharacterToPacket(&newPacket, &it.second, it.first);
|
if (argPacket->roomIndex != -1 && it.second.GetRoomIndex() != argPacket->roomIndex) {
|
||||||
newPacket.type = SerialPacketType::QUERY_CHARACTER_EXISTS;
|
continue;
|
||||||
network.SendTo(argPacket->srcAddress, static_cast<SerialPacket*>(&newPacket));
|
|
||||||
}
|
}
|
||||||
return;
|
copyCharacterToPacket(&newPacket, it.first);
|
||||||
}
|
|
||||||
|
|
||||||
//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());
|
|
||||||
newPacket.type = SerialPacketType::QUERY_CHARACTER_EXISTS;
|
newPacket.type = SerialPacketType::QUERY_CHARACTER_EXISTS;
|
||||||
network.SendTo(argPacket->srcAddress, static_cast<SerialPacket*>(&newPacket));
|
network.SendTo(argPacket->srcAddress, static_cast<SerialPacket*>(&newPacket));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ void pumpAndChangeRooms(int characterIndex, int newRoomIndex) {
|
|||||||
pumpAndChangeRooms(character, newRoomIndex, characterIndex);
|
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) {
|
void pumpAndChangeRooms(CharacterData* const characterData, int newRoomIndex, int characterIndex) {
|
||||||
//delete the character from the old room
|
//delete the character from the old room
|
||||||
CharacterPacket newPacket;
|
CharacterPacket newPacket;
|
||||||
|
|||||||
@@ -1,25 +1,26 @@
|
|||||||
TODO: Resource manager
|
TODO: Resource manager
|
||||||
TODO: Add the TextureLoader
|
|
||||||
TODO: Consistency for bounds names
|
TODO: Consistency for bounds names
|
||||||
TODO: Cross compiler (to replace dead linux PC ;_;)
|
TODO: Cross compiler (to replace dead linux PC ;_;)
|
||||||
TODO: New button graphics?
|
TODO: New button graphics
|
||||||
TODO: New typeface
|
TODO: New typeface
|
||||||
TODO: Account passwords (list)
|
TODO: Account passwords (list)
|
||||||
TODO: backbone account server OR
|
* backbone account server OR
|
||||||
TODO: social network login OR
|
* social network login OR
|
||||||
TODO: salts & hashes
|
* ...
|
||||||
TODO: login screen prompting for username & password
|
* salts & hashes
|
||||||
|
* login screen prompting for username & password
|
||||||
|
|
||||||
TODO: Features
|
TODO: Features
|
||||||
TODO: Make sure login errors are sent to the client
|
* Make sure login errors are sent to the client
|
||||||
TODO: Add the "home" parameter to the server's config file
|
* Add the "home" parameter to the server's config file
|
||||||
TODO: Fix shoddy movement
|
* Waypoints, with positions and trigger zones (collision areas) for doors, monster spawns, etc. (trigger system)
|
||||||
TODO: Better UI system
|
* Fix shoddy movement
|
||||||
TODO: Make a way for the server owner to control the server directly
|
* Remove the big "Shut Down" button (currently broken...)
|
||||||
TODO: The TileSheet class should implement the surface itself
|
* Make a way for the server owner to control the server directly
|
||||||
TODO: Time delay for requesting region packets
|
* The TileSheet class should implement the surface itself
|
||||||
TODO: A proper logging system
|
* Time delay for requesting region packets
|
||||||
TODO: Fix the const-ness of accessors
|
* A proper logging system
|
||||||
TODO: Add a screenshot of the game to README.md
|
* Fix the const-ness of accessors
|
||||||
TODO: joystick/gamepad support
|
* Add a screenshot of the game to README.md
|
||||||
TODO: add the tilesheet to the map system
|
* joystick/gamepad support
|
||||||
TODO: Better collision logic
|
* add the tilesheet to the map system
|
||||||