Compare commits

..

3 Commits

Author SHA1 Message Date
Kayne Ruse ab6207d4f3 Barriers are working corretly, but are way too slow 2016-04-14 12:43:00 +10:00
Kayne Ruse 1267b30806 Creatures are replaced with barriers 2016-04-14 04:45:30 +10:00
Kayne Ruse 5d217d7cf9 CreatureManager now uses Tuples 2016-04-14 04:19:59 +10:00
146 changed files with 3128 additions and 1283 deletions
+1 -7
View File
@@ -1,9 +1,3 @@
[submodule "bin"]
path = bin
url = https://github.com/krgamestudios/bin.git
[submodule "TurtleGUI"]
path = TurtleGUI
url = https://github.com/krgamestudios/TurtleGUI.git
[submodule "TurtleMap"]
path = TurtleMap
url = https://github.com/krgamestudios/TurtleMap.git
url = https://github.com/Ratstail91/Tortuga.git
+3 -9
View File
@@ -6,14 +6,8 @@ This game is inspired by classic 2D RPGs (Final Fantasy, The Legend of Zelda), a
## Releases
* The most recent stable build for Windows can be found [here](https://www.dropbox.com/s/zm9hg11ywol7yyz/Tortuga-win.rar?dl=1).
* The most recent stable build for Linux can be found [here](https://www.dropbox.com/s/5z6ag9r88ovr5bb/Tortuga-linux.tar?dl=1).
## Patreon
If you would like to support the development of Tortuga, please consider becoming a patron below.
* [My Patreon Page](https://patreon.com/user?u=2811779)
* 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-linux.tar).
## Documentation
@@ -58,4 +52,4 @@ Permission is granted to anyone to use this software for any purpose, including
### Items not made by me
* [Coolvetica Font](http://typodermicfonts.com/coolvetica/)
* Creative Commons Artwork from [Artsader](http://www.moosader.com/artsader/)
* Creative Commons Artwork from [Artsader](http://www.moosader.com/artsader/)
Submodule TurtleGUI deleted from 13e810df0a
Submodule TurtleMap deleted from d6672e59d0
+1 -1
Submodule bin updated: 08e1382e66...c653980193
-4
View File
@@ -103,7 +103,3 @@ void BaseScene::KeyDown(SDL_KeyboardEvent const& event) {
void BaseScene::KeyUp(SDL_KeyboardEvent const& event) {
//EMPTY
}
void BaseScene::TextInput(SDL_TextInputEvent const& event) {
//EMPTY
}
+1 -2
View File
@@ -47,9 +47,8 @@ public:
virtual void MouseWheel(SDL_MouseWheelEvent const& event);
virtual void KeyDown(SDL_KeyboardEvent const& event);
virtual void KeyUp(SDL_KeyboardEvent const& event);
virtual void TextInput(SDL_TextInputEvent const& event);
//TODO: joystick and controller events
//TODO: (9) joystick and controller events
protected:
//control
-10
View File
@@ -188,12 +188,6 @@ void ClientApplication::Init(int argc, char* argv[]) {
DEBUG_INTERNAL_VAR(MAX_PACKET_SIZE);
DEBUG_INTERNAL_VAR(static_cast<int>(SerialPacketType::LAST));
//-------------------------
//BUGFIX
//-------------------------
SDL_StopTextInput();
//-------------------------
//finalize the startup
//-------------------------
@@ -304,10 +298,6 @@ void ClientApplication::ProcessEvents() {
activeScene->KeyUp(event.key);
break;
case SDL_TEXTINPUT:
activeScene->TextInput(event.text);
break;
//TODO: (9) joystick and controller events
//window events are handled internally
+9 -21
View File
@@ -22,7 +22,7 @@
#include "barrier_manager.hpp"
void BarrierManager::DrawTo(SDL_Renderer* const dest, Sint16 x, Sint16 y, double scaleX, double scaleY) {
for (auto& it : elementMap) {
for (auto& it : barrierMap) {
it.second.DrawTo(dest, x, y);
}
}
@@ -47,38 +47,26 @@ void BarrierManager::UnloadTemplateImages() {
}
BaseBarrier* BarrierManager::Create(int index) {
elementMap.emplace(index, BaseBarrier(baseImage, templateImages));
return &elementMap[index];
barrierMap.emplace(index, BaseBarrier(baseImage, templateImages));
return &barrierMap[index];
}
void BarrierManager::Unload(int i) {
elementMap.erase(i);
barrierMap.erase(i);
}
void BarrierManager::UnloadAll() {
elementMap.clear();
}
void BarrierManager::UnloadIf(std::function<bool(std::pair<const int, BaseBarrier const&>)> fn) {
std::map<int, BaseBarrier>::iterator it = elementMap.begin();
while (it != elementMap.end()) {
if (fn(*it)) {
it = elementMap.erase(it);
}
else {
++it;
}
}
barrierMap.clear();
}
int BarrierManager::Size() {
return elementMap.size();
return barrierMap.size();
}
BaseBarrier* BarrierManager::Find(int i) {
std::map<int, BaseBarrier>::iterator it = elementMap.find(i);
std::map<int, BaseBarrier>::iterator it = barrierMap.find(i);
if (it == elementMap.end()) {
if (it == barrierMap.end()) {
return nullptr;
}
@@ -86,7 +74,7 @@ BaseBarrier* BarrierManager::Find(int i) {
}
std::map<int, BaseBarrier>* BarrierManager::GetContainer() {
return &elementMap;
return &barrierMap;
}
std::map<std::string, Image>* BarrierManager::GetTemplateContainer() {
+1 -3
View File
@@ -23,7 +23,6 @@
#include "base_barrier.hpp"
#include <functional>
#include <list>
#include <string>
@@ -43,7 +42,6 @@ public:
BaseBarrier* Create(int index);
void Unload(int i);
void UnloadAll();
void UnloadIf(std::function<bool(std::pair<const int, BaseBarrier const&>)> fn);
int Size();
@@ -54,5 +52,5 @@ public:
private:
Image baseImage;
std::map<std::string, Image> templateImages;
std::map<int, BaseBarrier> elementMap;
std::map<int, BaseBarrier> barrierMap;
};
+1 -1
View File
@@ -1,5 +1,5 @@
#config
INCLUDES+=. .. ../../common/global_defines ../../common/utilities ../../TurtleGUI
INCLUDES+=. .. ../../common/gameplay ../../common/graphics ../../common/utilities
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
-58
View File
@@ -1,58 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013-2016
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "heartbeat_utility.hpp"
#include "channels.hpp"
#include "ip_operators.hpp"
//heartbeat system
void HeartbeatUtility::hPing(ServerPacket* const argPacket) {
ServerPacket newPacket;
newPacket.type = SerialPacketType::PONG;
network.SendTo(argPacket->srcAddress, &newPacket);
}
void HeartbeatUtility::hPong(ServerPacket* const argPacket) {
if (*network.GetIPAddress(Channels::SERVER) != argPacket->srcAddress) {
throw(std::runtime_error("Heartbeat message received from an unknown source"));
}
attemptedBeats = 0;
lastBeat = Clock::now();
}
int HeartbeatUtility::CheckHeartBeat() {
//check the connection (heartbeat)
if (Clock::now() - lastBeat > std::chrono::seconds(3)) {
if (attemptedBeats > 2) {
return 1;
}
else {
ServerPacket newPacket;
newPacket.type = SerialPacketType::PING;
network.SendTo(Channels::SERVER, &newPacket);
attemptedBeats++;
lastBeat = Clock::now();
}
}
return 0;
}
+2 -2
View File
@@ -1,9 +1,9 @@
#include directories
INCLUDES+=. entities scenes ../common/debugging ../common/global_defines ../common/network ../common/network/packet_types ../common/utilities ../TurtleGUI ../TurtleMap
INCLUDES+=. entities scenes ../common/debugging ../common/gameplay ../common/graphics ../common/map ../common/network ../common/network/packet_types ../common/ui ../common/utilities
#libraries
#the order of the $(LIBS) is important, at least for MinGW
LIBS+=client.a ../libcommon.a ../libturtlegui.a ../libturtlemap.a -lSDL2_net
LIBS+=client.a ../common/libcommon.a -lSDL2_net
ifeq ($(OS),Windows_NT)
LIBS+=-lwsock32 -liphlpapi -lmingw32
endif
+3 -7
View File
@@ -28,8 +28,6 @@
#include <sstream>
#include <stdexcept>
constexpr SDL_Color WHITE = {255, 255, 255, 255};
//-------------------------
//Public access members
//-------------------------
@@ -51,16 +49,14 @@ DisconnectedScreen::DisconnectedScreen() {
//setup the button
backButton.SetBackgroundTexture(GetRenderer(), image.GetTexture());
backButton.SetText(GetRenderer(), font, WHITE, "Back");
backButton.SetText(GetRenderer(), font, "Back", COLOR_WHITE);
//set the button positions
backButton.SetX(50);
backButton.SetY(50);
//set the disconnection message text
textLine.SetX(50);
textLine.SetY(30);
textLine.SetText(GetRenderer(), font, WHITE, config["client.disconnectMessage"]);
textLine.SetText(GetRenderer(), font, config["client.disconnectMessage"], {255, 255, 255, 255});
//full reset
UDPNetworkUtility::GetSingleton().Unbind(Channels::SERVER);
@@ -96,7 +92,7 @@ void DisconnectedScreen::FrameEnd() {
void DisconnectedScreen::RenderFrame(SDL_Renderer* renderer) {
backButton.DrawTo(renderer);
textLine.DrawTo(renderer);
textLine.DrawTo(renderer, 50, 30);
}
//-------------------------
+22 -132
View File
@@ -27,8 +27,6 @@
#include <stdexcept>
#include <sstream>
constexpr SDL_Color WHITE = {255, 255, 255, 255};
//-------------------------
//Public access members
//-------------------------
@@ -54,11 +52,11 @@ LobbyMenu::LobbyMenu(int* const argClientIndex, int* const argAccountIndex):
//setup the buttons
searchButton.SetBackgroundTexture(GetRenderer(), buttonImage.GetTexture());
searchButton.SetText(GetRenderer(), font, WHITE, "Search");
searchButton.SetText(GetRenderer(), font, "Search", COLOR_WHITE);
joinButton.SetBackgroundTexture(GetRenderer(), buttonImage.GetTexture());
joinButton.SetText(GetRenderer(), font, WHITE, "Join");
joinButton.SetText(GetRenderer(), font, "Join", COLOR_WHITE);
backButton.SetBackgroundTexture(GetRenderer(), buttonImage.GetTexture());
backButton.SetText(GetRenderer(), font, WHITE, "Back");
backButton.SetText(GetRenderer(), font, "Back", COLOR_WHITE);
//set the button positions (assumed)
searchButton.SetX(50);
@@ -68,28 +66,7 @@ LobbyMenu::LobbyMenu(int* const argClientIndex, int* const argAccountIndex):
backButton.SetX(50);
backButton.SetY(90);
//setup the text fields
username.SetText(GetRenderer(), font, WHITE, config["client.username"]);
password.SetText(GetRenderer(), font, WHITE, config["client.password"]);
handle.SetText(GetRenderer(), font, WHITE, config["client.handle"]);
avatar.SetText(GetRenderer(), font, WHITE, config["client.avatar"]);
username.SetBounds(BoundingBox{0, 0, 300, 20});
password.SetBounds(BoundingBox{0, 0, 300, 20});
handle.SetBounds(BoundingBox{0, 0, 300, 20});
avatar.SetBounds(BoundingBox{0, 0, 300, 20});
username.SetX(50);
username.SetY(110);
password.SetX(50);
password.SetY(130);
handle.SetX(50);
handle.SetY(150);
avatar.SetX(50);
avatar.SetY(170);
//pseudo-list selection
//TODO: move this into the UI library?
boundingBox = {300, 50, 200, 12};
//hacked together a highlight box
@@ -135,11 +112,6 @@ void LobbyMenu::RenderFrame(SDL_Renderer* renderer) {
joinButton.DrawTo(renderer);
backButton.DrawTo(renderer);
username.DrawTo(renderer);
password.DrawTo(renderer);
handle.DrawTo(renderer);
avatar.DrawTo(renderer);
//TODO: (3) draw headers for the server list
//TODO: (3) ping/delay displayed in the server list
for (int i = 0; i < serverVector.size(); i++) {
@@ -149,13 +121,8 @@ void LobbyMenu::RenderFrame(SDL_Renderer* renderer) {
}
//draw the server's info
serverVector[i].nameImage.SetX(boundingBox.x);
serverVector[i].nameImage.SetY(boundingBox.y + boundingBox.h * i);
serverVector[i].nameImage.DrawTo(renderer);
serverVector[i].playerCountImage.SetX(boundingBox.x+276);
serverVector[i].playerCountImage.SetY(boundingBox.y + boundingBox.h * i);
serverVector[i].playerCountImage.DrawTo(renderer);
serverVector[i].nameImage.DrawTo(renderer, boundingBox.x, boundingBox.y + boundingBox.h * i);
serverVector[i].playerCountImage.DrawTo(renderer, boundingBox.x+276, boundingBox.y + boundingBox.h * i);
}
}
@@ -173,35 +140,6 @@ void LobbyMenu::MouseButtonDown(SDL_MouseButtonEvent const& event) {
searchButton.MouseButtonDown(event);
joinButton.MouseButtonDown(event);
backButton.MouseButtonDown(event);
if (username.MouseButtonDown(event)) {
//GUI trick
if (!username.GetText().compare(config["client.username"])) {
username.SetText(GetRenderer(), font, WHITE, "");
}
SDL_StartTextInput();
}
if (password.MouseButtonDown(event)) {
//GUI trick
if (!password.GetText().compare(config["client.password"])) {
password.SetText(GetRenderer(), font, WHITE, "");
}
SDL_StartTextInput();
}
if (handle.MouseButtonDown(event)) {
//GUI trick
if (!handle.GetText().compare(config["client.handle"])) {
handle.SetText(GetRenderer(), font, WHITE, "");
}
SDL_StartTextInput();
}
if (avatar.MouseButtonDown(event)) {
//GUI trick
if (!avatar.GetText().compare(config["client.avatar"])) {
avatar.SetText(GetRenderer(), font, WHITE, "");
}
SDL_StartTextInput();
}
}
void LobbyMenu::MouseButtonUp(SDL_MouseButtonEvent const& event) {
@@ -236,22 +174,6 @@ void LobbyMenu::KeyDown(SDL_KeyboardEvent const& event) {
case SDLK_ESCAPE:
SetSceneSignal(SceneSignal::MAINMENU);
break;
case SDLK_BACKSPACE:
//easier than mucking about with SDL_TextEditEvent
if (username.GetFocus()) {
username.PopChars(GetRenderer(), font, WHITE, 1);
}
if (password.GetFocus()) {
password.PopChars(GetRenderer(), font, WHITE, 1);
}
if (handle.GetFocus()) {
handle.PopChars(GetRenderer(), font, WHITE, 1);
}
if (avatar.GetFocus()) {
avatar.PopChars(GetRenderer(), font, WHITE, 1);
}
break;
}
}
@@ -259,21 +181,6 @@ void LobbyMenu::KeyUp(SDL_KeyboardEvent const& event) {
//
}
void LobbyMenu::TextInput(SDL_TextInputEvent const& event) {
if (username.GetFocus()) {
username.PushText(GetRenderer(), font, WHITE, std::string(event.text));
}
if (password.GetFocus()) {
password.PushText(GetRenderer(), font, WHITE, std::string(event.text));
}
if (handle.GetFocus()) {
handle.PushText(GetRenderer(), font, WHITE, std::string(event.text));
}
if (avatar.GetFocus()) {
avatar.PushText(GetRenderer(), font, WHITE, std::string(event.text));
}
}
//-------------------------
//Network handlers
//-------------------------
@@ -341,8 +248,8 @@ void LobbyMenu::HandleBroadcastResponse(ServerPacket* const argPacket) {
};
//text graphics
serverVector.back().nameImage.SetText(GetRenderer(), font, color, newServer.name);
serverVector.back().playerCountImage.SetText(GetRenderer(), font, color, itoa_base10(newServer.playerCount));
serverVector.back().nameImage.SetText(GetRenderer(), font, newServer.name, color);
serverVector.back().playerCountImage.SetText(GetRenderer(), font, itoa_base10(newServer.playerCount), color);
}
void LobbyMenu::HandleJoinResponse(ClientPacket* const argPacket) {
@@ -363,19 +270,11 @@ void LobbyMenu::HandleLoginResponse(ClientPacket* const argPacket) {
}
void LobbyMenu::HandleJoinRejection(TextPacket* const argPacket) {
//NOTE: NEVER HAPPENS
throw(std::runtime_error("HandleJoinRejection"));
//TODO: (9) LobbyMenu::HandleJoinRejection()
}
void LobbyMenu::HandleLoginRejection(TextPacket* const argPacket) {
config["client.disconnectMessage"] = std::string() + "Join request rejected: " + argPacket->text;
SetSceneSignal(SceneSignal::DISCONNECTEDSCREEN);
//avoid crashes from the heartbeat system
ClientPacket newPacket;
newPacket.type = SerialPacketType::DISCONNECT_REQUEST;
newPacket.clientIndex = clientIndex;
network.SendTo(argPacket->srcAddress, &newPacket);
//TODO: (9) LobbyMenu::HandleLoginRejection
}
//-------------------------
@@ -383,27 +282,24 @@ void LobbyMenu::HandleLoginRejection(TextPacket* const argPacket) {
//-------------------------
void LobbyMenu::SendBroadcastRequest() {
//broadcast to the home server, and to the LAN
ClientPacket packet;
//broadcast to the network, or a specific server
ClientPacket packet;
packet.type = SerialPacketType::BROADCAST_REQUEST;
network.SendTo(config["server.host"].c_str(), config.Int("server.port"), &packet);
packet.type = SerialPacketType::BROADCAST_REQUEST;
network.SendTo(config["server.home"].c_str(), config.Int("server.port"), &packet);
network.SendTo(config["server.host"].c_str(), config.Int("server.port"), &packet);
//reset the server list
serverVector.clear();
selection = nullptr;
//reset the server list
serverVector.clear();
selection = nullptr;
}
void LobbyMenu::SendJoinRequest() {
//BUG: 101 received in LobbyMenu on failed join
//pack the packet
ClientPacket packet;
packet.type = SerialPacketType::JOIN_REQUEST;
ClientPacket packet;
packet.type = SerialPacketType::JOIN_REQUEST;
//join the selected server
network.SendTo(selection->address, &packet);
selection = nullptr;
//join the selected server
network.SendTo(selection->address, &packet);
selection = nullptr;
}
void LobbyMenu::SendLoginRequest() {
@@ -412,13 +308,7 @@ void LobbyMenu::SendLoginRequest() {
ClientPacket packet;
packet.type = SerialPacketType::LOGIN_REQUEST;
packet.clientIndex = clientIndex;
strncpy(packet.username, username.GetText().c_str(), PACKET_STRING_SIZE+1);
strncpy(packet.username, config["client.username"].c_str(), PACKET_STRING_SIZE+1);
network.SendTo(Channels::SERVER, &packet);
//TODO: remove
config["client.username"] = username.GetText();
config["client.password"] = password.GetText();
config["client.handle"] = handle.GetText();
config["client.avatar"] = avatar.GetText();
}
-6
View File
@@ -25,7 +25,6 @@
#include "image.hpp"
#include "button.hpp"
#include "bounding_box.hpp"
#include "text_field.hpp"
#include "text_line.hpp"
#include "SDL2/SDL_ttf.h"
@@ -62,7 +61,6 @@ protected:
void MouseWheel(SDL_MouseWheelEvent const& event) override;
void KeyDown(SDL_KeyboardEvent const& event) override;
void KeyUp(SDL_KeyboardEvent const& event) override;
void TextInput(SDL_TextInputEvent const& event) override;
//Network handlers
void HandlePacket(SerialPacket* const);
@@ -104,10 +102,6 @@ protected:
Button searchButton;
Button joinButton;
Button backButton;
TextField username;
TextField password;
TextField handle;
TextField avatar;
std::vector<ServerInfo> serverVector;
ServerInfo* selection = nullptr;
+11 -15
View File
@@ -26,8 +26,6 @@
#include <sstream>
#include <stdexcept>
constexpr SDL_Color WHITE = {255, 255, 255, 255};
//-------------------------
//Public access members
//-------------------------
@@ -48,11 +46,11 @@ MainMenu::MainMenu() {
//setup the buttons
startButton.SetBackgroundTexture(GetRenderer(), buttonImage.GetTexture());
startButton.SetText(GetRenderer(), font, WHITE, "Start");
startButton.SetText(GetRenderer(), font, "Start", COLOR_WHITE);
optionsButton.SetBackgroundTexture(GetRenderer(), buttonImage.GetTexture());
optionsButton.SetText(GetRenderer(), font, WHITE, "Options");
optionsButton.SetText(GetRenderer(), font, "Options", COLOR_WHITE);
quitButton.SetBackgroundTexture(GetRenderer(), buttonImage.GetTexture());
quitButton.SetText(GetRenderer(), font, WHITE, "Quit");
quitButton.SetText(GetRenderer(), font, "Quit", COLOR_WHITE);
//set the button positions
startButton.SetX(50);
@@ -63,15 +61,9 @@ MainMenu::MainMenu() {
quitButton.SetY(50 + 20 * 2);
//text box
int h = -1;
SDL_RenderGetLogicalSize(GetRenderer(), nullptr, &h);
textBox.SetX(50);
textBox.SetY(h-100);
textBox.PushLine(GetRenderer(), font, WHITE, "Thanks for playing!");
textBox.PushLine(GetRenderer(), font, WHITE, "You can get the latest version at: ");
textBox.PushLine(GetRenderer(), font, WHITE, "krgamestudios.com"); //TODO: (9) click to open the website/update
textBox.PushLine(GetRenderer(), font, "Thanks for playing!", {255, 255, 255, 255});
textBox.PushLine(GetRenderer(), font, "You can get the latest version at: ", {255, 255, 255, 255});
textBox.PushLine(GetRenderer(), font, "krgamestudios.com", {255, 255, 255, 255}); //TODO: (9) click to open the website/update
//debug
//
@@ -101,7 +93,11 @@ void MainMenu::RenderFrame(SDL_Renderer* renderer) {
startButton.DrawTo(renderer);
optionsButton.DrawTo(renderer);
quitButton.DrawTo(renderer);
textBox.DrawTo(renderer);
int h = -1;
SDL_RenderGetLogicalSize(GetRenderer(), nullptr, &h);
textBox.DrawTo(renderer, 50, h-50, -12);
}
//-------------------------
+1 -1
View File
@@ -1,5 +1,5 @@
#config
INCLUDES+=. .. ../entities ../../common/debugging ../../common/global_defines ../../common/network ../../common/network/packet_types ../../common/utilities ../../TurtleGUI ../../TurtleMap
INCLUDES+=. .. ../client_utilities ../entities ../../common/gameplay ../../common/graphics ../../common/map ../../common/network ../../common/network/packet_types ../../common/ui ../../common/utilities
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
+3 -7
View File
@@ -26,8 +26,6 @@
#include <sstream>
#include <stdexcept>
constexpr SDL_Color WHITE = {255, 255, 255, 255};
//-------------------------
//Public access members
//-------------------------
@@ -48,16 +46,14 @@ OptionsMenu::OptionsMenu() {
//setup the button
backButton.SetBackgroundTexture(GetRenderer(), buttonImage.GetTexture());
backButton.SetText(GetRenderer(), font, WHITE, "Back");
backButton.SetText(GetRenderer(), font, "Back", COLOR_WHITE);
//set the button positions
backButton.SetX(50);
backButton.SetY(50);
//text line
textLine.SetX(50);
textLine.SetY(30);
textLine.SetText(GetRenderer(), font, WHITE, "Am I making any progress?");
textLine.SetText(GetRenderer(), font, "This code is fucking hard to refactor.", {255, 255, 255, 255});
}
OptionsMenu::~OptionsMenu() {
@@ -82,7 +78,7 @@ void OptionsMenu::FrameEnd() {
void OptionsMenu::RenderFrame(SDL_Renderer* renderer) {
backButton.DrawTo(renderer);
textLine.DrawTo(renderer);
textLine.DrawTo(renderer, 50, 30);
}
//-------------------------
+79 -73
View File
@@ -34,8 +34,6 @@
#include <sstream>
#include <stdexcept>
constexpr SDL_Color WHITE = {255, 255, 255, 255};
//-------------------------
//static functions
//-------------------------
@@ -74,9 +72,9 @@ World::World(int* const argClientIndex, int* const argAccountIndex):
//setup the buttons
disconnectButton.SetBackgroundTexture(GetRenderer(), buttonImage.GetTexture());
disconnectButton.SetText(GetRenderer(), font, WHITE, "Disconnect");
disconnectButton.SetText(GetRenderer(), font, "Disconnect", COLOR_WHITE);
shutdownButton.SetBackgroundTexture(GetRenderer(), buttonImage.GetTexture());
shutdownButton.SetText(GetRenderer(), font, WHITE, "Shutdown");
shutdownButton.SetText(GetRenderer(), font, "Shutdown", COLOR_WHITE);
//set the button positions
disconnectButton.SetX(50);
@@ -118,8 +116,8 @@ World::World(int* const argClientIndex, int* const argAccountIndex):
"slot 7 red.png",
"slot 8 red.png"
};
barrierMgr.LoadBaseImage(GetRenderer(), config["dir.sprites"] + "barrier/base.png");
barrierMgr.LoadTemplateImages(GetRenderer(), config["dir.sprites"] + "barrier/", slotNames);
barrierMgr.LoadBaseImage(GetRenderer(), config["dir.sprites"] + "/barrier/base.png");
barrierMgr.LoadTemplateImages(GetRenderer(), config["dir.sprites"] + "/barrier/", slotNames);
std::cout << "Templates loaded: " << barrierMgr.GetTemplateContainer()->size() << std::endl;
}
@@ -154,19 +152,14 @@ void World::Update() {
throw(e);
}
catch(std::exception& e) {
std::cerr << "HandlePacket Error (" << (int)(reinterpret_cast<SerialPacket*>(packetBuffer)->type) << "): " << e.what() << std::endl;
std::cerr << "HandlePacket Error: " << e.what() << std::endl;
}
//free the buffer
delete reinterpret_cast<char*>(packetBuffer);
//heartbeat system
if (heartbeatUtility.CheckHeartBeat()) {
//escape to the disconnect screen
SendDisconnectRequest();
SetSceneSignal(SceneSignal::DISCONNECTEDSCREEN);
ConfigUtility::GetSingleton()["client.disconnectMessage"] = "Error: Lost connection to the server";
}
CheckHeartBeat();
//update all entities
for (auto& it : characterMap) {
@@ -192,27 +185,7 @@ void World::Update() {
return;
}
//TODO: (0) regular query interval
if (Clock::now() - queryTime > std::chrono::seconds(3)) {
queryTime = Clock::now();
//query the world state (room)
CharacterPacket characterPacket;
memset(&characterPacket, 0, MAX_PACKET_SIZE);
characterPacket.type = SerialPacketType::QUERY_CHARACTER_EXISTS;
characterPacket.roomIndex = roomIndex;
network.SendTo(Channels::SERVER, &characterPacket);
CreaturePacket creaturePacket;
creaturePacket.type = SerialPacketType::QUERY_CREATURE_EXISTS;
creaturePacket.roomIndex = roomIndex;
network.SendTo(Channels::SERVER, &creaturePacket);
BarrierPacket barrierPacket;
barrierPacket.type = SerialPacketType::QUERY_BARRIER_EXISTS;
barrierPacket.roomIndex = roomIndex;
network.SendTo(Channels::SERVER, &barrierPacket);
}
//TODO: (1) regular query interval
//cull creatures
for (std::map<int, BaseCreature>::iterator it = creatureMap.begin(); it != creatureMap.end(); /* */) {
if ( (localCharacter->GetOrigin() - it->second.GetOrigin()).Length() > INFLUENCE_RADIUS) {
@@ -223,10 +196,7 @@ void World::Update() {
}
}
//cull barriers
barrierMgr.UnloadIf([&](std::pair<const int, BaseBarrier const&> barrierIt) -> bool {
return (localCharacter->GetOrigin() - barrierIt.second.GetOrigin()).Length() > INFLUENCE_RADIUS;
});
//TODO: cull barriers
//get the collidable boxes
std::list<BoundingBox> boxList = GenerateCollisionGrid(localCharacter, tileSheet.GetTileW(), tileSheet.GetTileH());
@@ -268,12 +238,12 @@ void World::RenderFrame(SDL_Renderer* renderer) {
shutdownButton.DrawTo(renderer);
//FPS
fpsTextLine.DrawTo(renderer);
fpsTextLine.DrawTo(renderer, 0, 0);
int fpsRet = fps.Calculate();
if (fpsRet != -1) {
std::ostringstream msg;
msg << "FPS: " << fpsRet;
fpsTextLine.SetText(renderer, font, WHITE, msg.str());
fpsTextLine.SetText(renderer, font, msg.str(), {255, 255, 255, 255});
}
}
@@ -416,10 +386,10 @@ void World::HandlePacket(SerialPacket* const argPacket) {
switch(argPacket->type) {
//heartbeat system
case SerialPacketType::PING:
heartbeatUtility.hPing(static_cast<ServerPacket*>(argPacket));
hPing(static_cast<ServerPacket*>(argPacket));
break;
case SerialPacketType::PONG:
heartbeatUtility.hPong(static_cast<ServerPacket*>(argPacket));
hPong(static_cast<ServerPacket*>(argPacket));
break;
//game server connections
@@ -458,10 +428,6 @@ void World::HandlePacket(SerialPacket* const argPacket) {
hCharacterMovement(static_cast<CharacterPacket*>(argPacket));
break;
case SerialPacketType::CHARACTER_REJECTION:
hCharacterRejection(static_cast<TextPacket*>(argPacket));
break;
//creature management
case SerialPacketType::CREATURE_UPDATE:
hCreatureUpdate(static_cast<CreaturePacket*>(argPacket));
@@ -511,6 +477,7 @@ void World::HandlePacket(SerialPacket* const argPacket) {
//general rejection messages
case SerialPacketType::REGION_REJECTION:
case SerialPacketType::CHARACTER_REJECTION:
case SerialPacketType::QUERY_REJECTION:
throw(fatal_error(static_cast<TextPacket*>(argPacket)->text));
break;
@@ -528,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
//-------------------------
@@ -722,9 +727,6 @@ void World::hCharacterCreate(CharacterPacket* const argPacket) {
if (character->GetOwner() == accountIndex) {
localCharacter = static_cast<LocalCharacter*>(character);
//reset queries
queryTime = Clock::now() - std::chrono::seconds(4); //back 4 seconds to trigger automatically
//focus the camera on this character's sprite
camera.marginX = (camera.width / 2 - localCharacter->GetSprite()->GetClipW() / 2);
camera.marginY = (camera.height/ 2 - localCharacter->GetSprite()->GetClipH() / 2);
@@ -732,6 +734,26 @@ void World::hCharacterCreate(CharacterPacket* const argPacket) {
//focus on this character's info
characterIndex = argPacket->characterIndex;
roomIndex = argPacket->roomIndex;
//query the world state (room)
CharacterPacket characterPacket;
memset(&characterPacket, 0, MAX_PACKET_SIZE);
characterPacket.type = SerialPacketType::QUERY_CHARACTER_EXISTS;
characterPacket.roomIndex = roomIndex;
characterPacket.origin = localCharacter->GetOrigin();
network.SendTo(Channels::SERVER, &characterPacket);
CreaturePacket creaturePacket;
creaturePacket.type = SerialPacketType::QUERY_CREATURE_EXISTS;
creaturePacket.roomIndex = roomIndex;
creaturePacket.origin = localCharacter->GetOrigin();
network.SendTo(Channels::SERVER, &creaturePacket);
BarrierPacket barrierPacket;
barrierPacket.type = SerialPacketType::QUERY_BARRIER_EXISTS;
barrierPacket.roomIndex = roomIndex;
barrierPacket.origin = localCharacter->GetOrigin();
network.SendTo(Channels::SERVER, &barrierPacket);
}
//debug
@@ -772,12 +794,12 @@ void World::hCharacterUnload(CharacterPacket* const argPacket) {
void World::hQueryCharacterExists(CharacterPacket* const argPacket) {
//prevent a double message about this player's character
//TODO: why is this commented out?
if (argPacket->accountIndex == accountIndex) {
return;
}
// if (argPacket->accountIndex == accountIndex) {
// return;
// }
//ignore characters in a different room (sub-optimal)
if (argPacket->roomIndex != roomIndex || (localCharacter->GetOrigin() - argPacket->origin).Length() > INFLUENCE_RADIUS) {
if (argPacket->roomIndex != roomIndex) {
return;
}
@@ -813,18 +835,6 @@ void World::hCharacterMovement(CharacterPacket* const argPacket) {
}
}
void World::hCharacterRejection(TextPacket* const argPacket) {
//NOTE: simply crap out
config["client.disconnectMessage"] = std::string() + "Character rejected: " + argPacket->text;
SetSceneSignal(SceneSignal::DISCONNECTEDSCREEN);
//avoid crashes from the heartbeat system
ClientPacket newPacket;
newPacket.type = SerialPacketType::DISCONNECT_REQUEST;
newPacket.clientIndex = clientIndex;
network.SendTo(argPacket->srcAddress, &newPacket);
}
//-------------------------
//creature management
//-------------------------
@@ -906,12 +916,10 @@ void World::hCreatureUnload(CreaturePacket* const argPacket) {
}
void World::hQueryCreatureExists(CreaturePacket* const argPacket) {
if (!localCharacter) {
return;
}
std::cout << "Creature Query" << std::endl;
//ignore creatures in a different room (sub-optimal)
if (argPacket->roomIndex != roomIndex || (localCharacter->GetOrigin() - argPacket->origin).Length() > INFLUENCE_RADIUS) {
if (argPacket->roomIndex != roomIndex) {
return;
}
@@ -1016,12 +1024,10 @@ void World::hBarrierUnload(BarrierPacket* const argPacket) {
}
void World::hQueryBarrierExists(BarrierPacket* const argPacket) {
if (!localCharacter) {
return;
}
std::cout << "Barrier Query" << std::endl;
//ignore barriers in a different room (sub-optimal)
if (argPacket->roomIndex != roomIndex || (localCharacter->GetOrigin() - argPacket->origin).Length() > INFLUENCE_RADIUS) {
if (argPacket->roomIndex != roomIndex) {
return;
}
+9 -4
View File
@@ -43,7 +43,6 @@
#include "base_scene.hpp"
#include "base_barrier.hpp"
#include "base_creature.hpp"
#include "heartbeat_utility.hpp"
#include "local_character.hpp"
#include "SDL2/SDL.h"
@@ -81,6 +80,12 @@ private:
//handle incoming traffic
void HandlePacket(SerialPacket* const);
//heartbeat system
void hPing(ServerPacket* const);
void hPong(ServerPacket* const);
void CheckHeartBeat();
//basic connections
void SendLogoutRequest();
void SendDisconnectRequest();
@@ -102,7 +107,6 @@ private:
void hCharacterUnload(CharacterPacket* const);
void hQueryCharacterExists(CharacterPacket* const);
void hCharacterMovement(CharacterPacket* const);
void hCharacterRejection(TextPacket* const);
//creature management
void hCreatureUpdate(CreaturePacket* const);
@@ -161,9 +165,10 @@ private:
LocalCharacter* localCharacter = nullptr;
//heartbeat
HeartbeatUtility heartbeatUtility;
//TODO: (2) Heartbeat needs it's own utility
typedef std::chrono::steady_clock Clock;
Clock::time_point queryTime = Clock::now() - std::chrono::seconds(4); //back 4 seconds to trigger automatically
Clock::time_point lastBeat = Clock::now();
int attemptedBeats = 0;
//ugly references; I hate this
ConfigUtility& config = ConfigUtility::GetSingleton();
@@ -1,5 +1,5 @@
#config
INCLUDES+=. .. ../characters ../creatures ../entities ../inventory ../../common/global_defines ../../common/utilities ../../TurtleGUI
INCLUDES+=. packet_types ../gameplay ../map ../utilities
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
@@ -10,13 +10,10 @@ CXXSRC=$(wildcard *.cpp)
OBJDIR=obj
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
#output
OUTDIR=..
OUT=$(addprefix $(OUTDIR)/,server.a)
#targets
all: $(OBJ) $(OUT)
ar -crs $(OUT) $(OBJ)
$(MAKE) -C packet_types
$(OBJ): | $(OBJDIR)
+188
View File
@@ -0,0 +1,188 @@
/* 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 "application.hpp"
#include <chrono>
#include <sstream>
#include <stdexcept>
void Application::Init(int argc, char* argv[]) {
//create and check the window
window = SDL_CreateWindow(
"Example Caption",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
screenWidth,
screenHeight,
SDL_WINDOW_RESIZABLE);
if (!window) {
std::ostringstream msg;
msg << "Failed to create the window: " << SDL_GetError();
throw(std::runtime_error(msg.str()));
}
//create and check the renderer
renderer = SDL_CreateRenderer(window, -1, 0);
if (!renderer) {
std::ostringstream msg;
msg << "Failed to create the renderer: " << SDL_GetError();
throw(std::runtime_error(msg.str()));
}
//screen scaling
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "best");
SDL_RenderSetLogicalSize(renderer, screenWidth, screenHeight);
//set the hook for the renderer
BaseScene::SetRenderer(renderer);
}
void Application::Proc() {
//load the first scene
ProcessSceneSignal(SceneSignal::FIRST);
//fixed frame rate
typedef std::chrono::steady_clock Clock;
Clock::time_point simTime = Clock::now();
Clock::time_point realTime;
constexpr std::chrono::duration<int, std::milli> frameDelay(16); //~60FPS
//the game loop continues until the scenes signal QUIT
while(activeScene->GetSceneSignal() != SceneSignal::QUIT) {
//switch scenes if necessary
if(activeScene->GetSceneSignal() != SceneSignal::CONTINUE) {
ProcessSceneSignal(activeScene->GetSceneSignal());
continue;
}
//update the current time
realTime = Clock::now();
//simulate the game or give the machine a break
if (simTime < realTime) {
while(simTime < realTime) {
//call the user defined functions
activeScene->FrameStart();
ProcessEvents();
activeScene->Update();
activeScene->FrameEnd();
//step to the next frame
simTime += frameDelay;
}
}
else {
SDL_Delay(1);
}
SDL_RenderClear(renderer);
activeScene->RenderFrame(renderer);
SDL_RenderPresent(renderer);
}
//cleanup
ClearScene();
}
void Application::Quit() {
//clean up after the program
BaseScene::SetRenderer(nullptr);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
}
//-------------------------
//Scene management
//-------------------------
void Application::ProcessEvents() {
SDL_Event event;
while(SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_QUIT:
activeScene->QuitEvent();
break;
case SDL_MOUSEMOTION:
activeScene->MouseMotion(event.motion);
break;
case SDL_MOUSEBUTTONDOWN:
activeScene->MouseButtonDown(event.button);
break;
case SDL_MOUSEBUTTONUP:
activeScene->MouseButtonUp(event.button);
break;
case SDL_MOUSEWHEEL:
activeScene->MouseWheel(event.wheel);
break;
case SDL_KEYDOWN:
activeScene->KeyDown(event.key);
break;
case SDL_KEYUP:
activeScene->KeyUp(event.key);
break;
//TODO: joystick and controller events
//window events are handled internally
case SDL_WINDOWEVENT:
switch(event.window.event) {
case SDL_WINDOWEVENT_RESIZED:
SDL_RenderSetLogicalSize(renderer, event.window.data1, event.window.data2);
break;
}
break;
}
}
}
//Add the custom scene headers here
#include "example_scene.hpp"
void Application::ProcessSceneSignal(SceneSignal signal) {
ClearScene();
switch(signal) {
case SceneSignal::FIRST:
case SceneSignal::EXAMPLE_SCENE:
activeScene = new ExampleScene();
break;
default: {
std::ostringstream msg;
msg << "Failed to recognize the scene signal: " << signal;
throw(std::logic_error(msg.str()));
}
}
}
void Application::ClearScene() {
delete activeScene;
activeScene = nullptr;
}
@@ -21,21 +21,34 @@
*/
#pragma once
#include "item_type.hpp"
#include "base_scene.hpp"
#include "scene_signal.hpp"
class ItemData {
#include "SDL2/SDL.h"
//TODO: do something with these
constexpr int screenWidth = 800;
constexpr int screenHeight = 600;
//DOCS: The Application class handles scene switching, utilizing only one window
class Application {
public:
ItemData() = default;
~ItemData() = default;
Application() = default;
~Application() = default;
//accessors and mutators
ItemType SetItemType(ItemType);
ItemType GetItemType();
int SetQuantity(int);
int GetQuantity();
void Init(int argc, char* argv[]);
void Proc();
void Quit();
private:
ItemType type;
int quantity = 1;
//scene management
void ProcessEvents();
void ProcessSceneSignal(SceneSignal);
void ClearScene();
BaseScene* activeScene = nullptr;
//TODO: build a "window" class?
SDL_Window* window = nullptr;
SDL_Renderer* renderer = nullptr;
};
+105
View File
@@ -0,0 +1,105 @@
/* 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 "base_scene.hpp"
SDL_Renderer* BaseScene::rendererHandle = nullptr;
BaseScene::BaseScene() {
//EMPTY
}
BaseScene::~BaseScene() {
//EMPTY
}
void BaseScene::RenderFrame(SDL_Renderer* renderer) {
//EMPTY
}
void BaseScene::SetRenderer(SDL_Renderer* r) {
rendererHandle = r;
}
SDL_Renderer* BaseScene::GetRenderer() {
return rendererHandle;
}
void BaseScene::SetSceneSignal(SceneSignal signal) {
sceneSignal = signal;
}
SceneSignal BaseScene::GetSceneSignal() {
return sceneSignal;
}
//-------------------------
//frame phases
//-------------------------
void BaseScene::FrameStart() {
//EMPTY
}
void BaseScene::Update() {
//EMPTY
}
void BaseScene::FrameEnd() {
//EMPTY
}
//-------------------------
//input events
//-------------------------
void BaseScene::QuitEvent() {
sceneSignal = SceneSignal::QUIT;
}
void BaseScene::MouseMotion(SDL_MouseMotionEvent const& event) {
//EMPTY
}
void BaseScene::MouseButtonDown(SDL_MouseButtonEvent const& event) {
//EMPTY
}
void BaseScene::MouseButtonUp(SDL_MouseButtonEvent const& event) {
//EMPTY
}
void BaseScene::MouseWheel(SDL_MouseWheelEvent const& event) {
//EMPTY
}
void BaseScene::KeyDown(SDL_KeyboardEvent const& event) {
//preference as a default
switch(event.keysym.sym) {
case SDLK_ESCAPE:
QuitEvent();
break;
}
}
void BaseScene::KeyUp(SDL_KeyboardEvent const& event) {
//EMPTY
}
+61
View File
@@ -0,0 +1,61 @@
/* 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 "scene_signal.hpp"
#include "SDL2/SDL.h"
class BaseScene {
public:
BaseScene();
virtual ~BaseScene();
virtual void RenderFrame(SDL_Renderer*);
static void SetRenderer(SDL_Renderer*);
SceneSignal GetSceneSignal();
//frame phases
virtual void FrameStart();
virtual void Update();
virtual void FrameEnd();
//input events
virtual void QuitEvent();
virtual void MouseMotion(SDL_MouseMotionEvent const& event);
virtual void MouseButtonDown(SDL_MouseButtonEvent const& event);
virtual void MouseButtonUp(SDL_MouseButtonEvent const& event);
virtual void MouseWheel(SDL_MouseWheelEvent const& event);
virtual void KeyDown(SDL_KeyboardEvent const& event);
virtual void KeyUp(SDL_KeyboardEvent const& event);
//TODO: joystick and controller events
protected:
//control
static SDL_Renderer* GetRenderer();
void SetSceneSignal(SceneSignal);
private:
static SDL_Renderer* rendererHandle;
SceneSignal sceneSignal = SceneSignal::CONTINUE;
};
@@ -0,0 +1,83 @@
/* 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 "example_scene.hpp"
ExampleScene::ExampleScene() {
//
}
ExampleScene::~ExampleScene() {
//
}
//-------------------------
//frame phases
//-------------------------
void ExampleScene::FrameStart() {
//
}
void ExampleScene::Update() {
//
}
void ExampleScene::FrameEnd() {
//
}
void ExampleScene::RenderFrame(SDL_Renderer* renderer) {
//
}
//-------------------------
//input events
//-------------------------
void ExampleScene::MouseMotion(SDL_MouseMotionEvent const& event) {
//
}
void ExampleScene::MouseButtonDown(SDL_MouseButtonEvent const& event) {
//
}
void ExampleScene::MouseButtonUp(SDL_MouseButtonEvent const& event) {
//
}
void ExampleScene::MouseWheel(SDL_MouseWheelEvent const& event) {
//
}
void ExampleScene::KeyDown(SDL_KeyboardEvent const& event) {
//preference as a default
switch(event.keysym.sym) {
case SDLK_ESCAPE:
QuitEvent();
break;
}
}
void ExampleScene::KeyUp(SDL_KeyboardEvent const& event) {
//
}
@@ -0,0 +1,46 @@
/* 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 "base_scene.hpp"
class ExampleScene : public BaseScene {
public:
ExampleScene();
~ExampleScene();
void RenderFrame(SDL_Renderer* renderer) override;
private:
//frame phases
void FrameStart() override;
void Update() override;
void FrameEnd() override;
//input events
void MouseMotion(SDL_MouseMotionEvent const& event) override;
void MouseButtonDown(SDL_MouseButtonEvent const& event) override;
void MouseButtonUp(SDL_MouseButtonEvent const& event) override;
void MouseWheel(SDL_MouseWheelEvent const& event) override;
void KeyDown(SDL_KeyboardEvent const& event) override;
void KeyUp(SDL_KeyboardEvent const& event) override;
};
@@ -19,20 +19,25 @@
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "item_data.hpp"
#include "application.hpp"
ItemType ItemData::SetItemType(ItemType t) {
return type = t;
}
#include "SDL2/SDL.h"
ItemType ItemData::GetItemType() {
return type;
}
#include <iostream>
#include <stdexcept>
int ItemData::SetQuantity(int i) {
return quantity = i;
}
int ItemData::GetQuantity() {
return quantity;
}
int main(int argc, char** argv) {
std::cout << "Beginning " << argv[0] << std::endl;
try {
Application app;
app.Init(argc, argv);
app.Proc();
app.Quit();
}
catch(std::exception& e) {
std::cerr << "Fatal Error: " << e.what() << std::endl;
return 1;
}
std::cout << "Clean exit from " << argv[0] << std::endl;
return 0;
}
+56
View File
@@ -0,0 +1,56 @@
#include directories
INCLUDES+=.
#libraries
#the order of the $(LIBS) is important, at least for MinGW
LIBS+=
ifeq ($(OS),Windows_NT)
LIBS+=-lmingw32
endif
LIBS+=-lSDL2main -lSDL2
#flags
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
ifeq ($(shell uname), Linux)
#read data about the current install
CXXFLAGS+=$(shell sdl-config --cflags --static-libs)
endif
#source
CXXSRC=$(wildcard *.cpp)
#objects
OBJDIR=obj
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
#output
OUTDIR=out
OUT=$(addprefix $(OUTDIR)/,scenes)
#targets
all: $(OBJ) $(OUT)
$(CXX) $(CXXFLAGS) -o $(OUT) $(OBJ) $(LIBS)
$(OBJ): | $(OBJDIR)
$(OUT): | $(OUTDIR)
$(OBJDIR):
mkdir $(OBJDIR)
$(OUTDIR):
mkdir $(OUTDIR)
$(OBJDIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
clean:
ifeq ($(OS),Windows_NT)
$(RM) *.o *.a *.exe
else ifeq ($(shell uname), Linux)
find . -type f -name '*.o' -exec rm -f -r -v {} \;
find . -type f -name '*.a' -exec rm -f -r -v {} \;
rm -f -v $(OUT)
endif
rebuild: clean all
@@ -21,13 +21,12 @@
*/
#pragma once
#include "inventory.hpp"
enum SceneSignal {
//reserved members for internal use
QUIT = -1,
CONTINUE = 0,
FIRST = 1,
class InventoryManager {
public:
InventoryManager() = default;
~InventoryManager() = default;
private:
//
//custom scenes
EXAMPLE_SCENE
};
+167
View File
@@ -0,0 +1,167 @@
/* 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 "button.hpp"
#include <stdexcept>
void Button::DrawTo(SDL_Renderer* renderer) {
image.SetClipY(image.GetClipH() * state);
image.DrawTo(renderer, posX, posY);
}
void Button::SetBackgroundTexture(SDL_Renderer* renderer, SDL_Texture* texture) {
//copy the given texture
image.Free();
//a null texture can simply free the image
if (!texture) {
return;
}
//get the w & h, & create
int w = 0, h = 0;
SDL_QueryTexture(texture, nullptr, nullptr, &w, &h);
image.Create(renderer, w, h);
//copy
SDL_SetRenderTarget(renderer, image.GetTexture());
SDL_RenderCopy(renderer, texture, nullptr, nullptr);
SDL_SetRenderTarget(renderer, nullptr);
//prune
image.SetClipH(image.GetClipH() / 3);
}
void Button::SetText(SDL_Renderer* renderer, TTF_Font* font, std::string s, SDL_Color color) {
//make the surface (from SDL_ttf)
SDL_Surface* surf = TTF_RenderText_Solid(font, s.c_str(), color);
if (!surf) {
throw(std::runtime_error("Failed to create a TTF surface"));
}
//convert to texture
SDL_Texture* text = SDL_CreateTextureFromSurface(renderer, surf);
SDL_FreeSurface(surf);
if (!text) {
throw(std::runtime_error("Failed to create a TTF texture"));
}
//get the dimensions & rects
int x, y, w, h;
SDL_QueryTexture(text, nullptr, nullptr, &w, &h);
x = (image.GetClipW() - w) / 2;
y = (image.GetClipH() - h) / 2;
SDL_Rect src = {0, 0, w, h};
SDL_Rect dst;
//draw the text to the background
SDL_SetRenderTarget(renderer, image.GetTexture());
for (int i = 0; i < 3; i++) {
dst = {x, y + image.GetClipH() * i, w, h};
SDL_RenderCopy(renderer, text, &src, &dst);
}
SDL_SetRenderTarget(renderer, nullptr);
//free the texture
SDL_DestroyTexture(text);
}
void Button::SetX(int x) {
posX = x;
}
void Button::SetY(int y) {
posY = y;
}
Button::State Button::MouseMotion(SDL_MouseMotionEvent const& event) {
//if out of bounds, exit
if (!CheckBounds(event.x, event.y)) {
return state = State::IDLE;
}
//if in bounds, check button
if (event.state & SDL_BUTTON_LMASK && state == State::PRESSED) {
//stay pressed
// state = State::PRESSED;
}
else {
state = State::HOVER;
}
return state;
}
Button::State Button::MouseButtonDown(SDL_MouseButtonEvent const& event) {
//if out of bounds, exit
if (!CheckBounds(event.x, event.y)) {
return state = State::IDLE;
}
//if in bounds, check button
if (event.button == SDL_BUTTON_LEFT) {
return state = State::PRESSED;
}
//NOTE: if not left button down, ignore
return State::HOVER;
}
Button::State Button::MouseButtonUp(SDL_MouseButtonEvent const& event) {
//if out of bounds, exit
if (!CheckBounds(event.x, event.y)) {
return state = State::IDLE;
}
//if not left button up, ignore
if (event.button != SDL_BUTTON_LEFT) {
return state;
}
//if in bounds and left button up, send release signal
if (state == State::PRESSED) {
state = State::HOVER;
return State::RELEASED;
}
return state;
}
void Button::SetState(State s) {
state = s;
}
Button::State Button::GetState() {
return state;
}
bool Button::CheckBounds(int x, int y) {
//return if true (x, y) is within bounds, otherwise return false
return !(
x < posX ||
y < posY ||
x > posX + image.GetClipW() ||
y > posY + image.GetClipH()
);
}
+68
View File
@@ -0,0 +1,68 @@
/* 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 "image.hpp"
#include "SDL2/SDL_ttf.h"
#include <string>
constexpr SDL_Color COLOR_WHITE = {255, 255, 255, 255};
constexpr SDL_Color COLOR_RED = {255, 0, 0, 255};
constexpr SDL_Color COLOR_ORANGE = {255, 127, 0, 255};
constexpr SDL_Color COLOR_BLUE = {0, 0, 255, 255};
class Button {
public:
enum State {
IDLE = 0, HOVER = 1, PRESSED = 2, RELEASED = 3
};
//methods
Button() = default;
~Button() = default;
void DrawTo(SDL_Renderer*);
//setup
void SetBackgroundTexture(SDL_Renderer*, SDL_Texture*);
void SetText(SDL_Renderer*, TTF_Font*, std::string, SDL_Color);
void SetX(int x);
void SetY(int y);
//capture input
State MouseMotion(SDL_MouseMotionEvent const&);
State MouseButtonDown(SDL_MouseButtonEvent const&);
State MouseButtonUp(SDL_MouseButtonEvent const&);
//states
void SetState(State); //TODO: idle, busy or disabled
State GetState();
protected:
bool CheckBounds(int x, int y);
Image image;
int posX = 0, posY = 0;
State state = State::IDLE;
};
+211
View File
@@ -0,0 +1,211 @@
/* 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 "image.hpp"
#include "SDL2/SDL_image.h"
#include <sstream>
#include <stdexcept>
Image& Image::operator=(Image const& rhs) {
//don't screw yourself
if (this == &rhs) {
return *this;
}
Free();
//Copy the other Image's stuff
texture = rhs.texture;
clip = rhs.clip;
local = false;
}
Image& Image::operator=(Image&& rhs) {
//don't screw yourself
if (this == &rhs) {
return *this;
}
Free();
//Steal the other Image's stuff
texture = rhs.texture;
clip = rhs.clip;
local = rhs.local;
rhs.texture = nullptr;
rhs.clip = {0, 0, 0, 0};
rhs.local = false;
}
SDL_Texture* Image::Load(SDL_Renderer* renderer, std::string fname) {
Free();
//load the file into a surface
SDL_Surface* surface = IMG_Load(fname.c_str());
if (!surface) {
std::ostringstream msg;
msg << "Failed to load an image file: " << fname;
msg << "; " << IMG_GetError();
throw(std::runtime_error(msg.str()));
}
//create a texture from this surface
texture = SDL_CreateTextureFromSurface(renderer, surface);
if (!texture) {
std::ostringstream msg;
msg << "Failed to convert a newly loaded image file: " << fname;
msg << "; " << SDL_GetError();
throw(std::runtime_error(msg.str()));
}
//set the metadata
clip.x = 0;
clip.y = 0;
if (SDL_QueryTexture(texture, nullptr, nullptr, &clip.w, &clip.h)) {
std::ostringstream msg;
msg << "Failed to record metadata for a newly loaded image file: " << fname;
msg << "; " << SDL_GetError();
throw(std::runtime_error(msg.str()));
}
local = true;
//free the surface & return
SDL_FreeSurface(surface);
return texture;
}
SDL_Texture* Image::Create(SDL_Renderer* renderer, Uint16 w, Uint16 h, SDL_Color blank) {
Free();
//make the texture
texture = SDL_CreateTexture(renderer,
SDL_PIXELFORMAT_RGBA8888,
SDL_TEXTUREACCESS_TARGET,
w, h);
//check
if (!texture) {
std::ostringstream msg;
msg << "Failed to create a texture; " << SDL_GetError();
throw(std::runtime_error(msg.str()));
}
//set the metadata
clip.x = 0;
clip.y = 0;
if (SDL_QueryTexture(texture, nullptr, nullptr, &clip.w, &clip.h)) {
std::ostringstream msg;
msg << "Failed to record metadata for a newly created image";
msg << "; " << SDL_GetError();
throw(std::runtime_error(msg.str()));
}
local = true;
//blank (black) texture
SDL_SetRenderTarget(renderer, texture);
SDL_SetRenderDrawColor(renderer, blank.r, blank.g, blank.b, blank.a);
SDL_RenderFillRect(renderer, nullptr);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
SDL_SetRenderTarget(renderer, nullptr);
return texture;
}
SDL_Texture* Image::CopyTexture(SDL_Renderer* renderer, SDL_Texture* ptr) {
Free();
int w = 0, h = 0;
//get the info
SDL_QueryTexture(ptr, nullptr, nullptr, &w, &h);
//create a texture of (w, h) size (also sets the metadata)
Create(renderer, w, h);
//copy the argument texture to the local texture
SDL_SetRenderTarget(renderer, texture);
SDL_RenderCopy(renderer, ptr, nullptr, nullptr);
SDL_SetRenderTarget(renderer, nullptr);
//return the local texture
return texture;
}
SDL_Texture* Image::SetTexture(SDL_Texture* ptr) {
Free();
texture = ptr;
//set the metadata
clip.x = 0;
clip.y = 0;
if (SDL_QueryTexture(texture, nullptr, nullptr, &clip.w, &clip.h)) {
std::ostringstream msg;
msg << "Failed to record metadata for a newly set image";
msg << "; " << SDL_GetError();
throw(std::runtime_error(msg.str()));
}
local = false;
return texture;
}
SDL_Texture* Image::GetTexture() const {
return texture;
}
void Image::Free() {
if (local) {
SDL_DestroyTexture(texture);
local = false;
}
texture = nullptr;
clip = {0, 0, 0, 0};
}
void Image::DrawTo(SDL_Renderer* const renderer, Sint16 x, Sint16 y, double scaleX, double scaleY) {
if (!texture) {
throw(std::logic_error("No image texture to draw"));
}
SDL_Rect sclip = clip;
SDL_Rect dclip = {x, y, Uint16(clip.w * scaleX), Uint16(clip.h * scaleY)};
SDL_RenderCopy(renderer, texture, &sclip, &dclip);
}
void Image::SetAlpha(Uint8 a) {
if (SDL_SetTextureAlphaMod(texture, a)) {
std::ostringstream msg;
msg << "Failed to set alpha; " << SDL_GetError();
throw(std::runtime_error(msg.str()));
}
}
Uint8 Image::GetAlpha() {
Uint8 ret = 0;
if (SDL_GetTextureAlphaMod(texture, &ret)) {
std::ostringstream msg;
msg << "Failed to get alpha; " << SDL_GetError();
throw(std::runtime_error(msg.str()));
}
return ret;
}
+73
View File
@@ -0,0 +1,73 @@
/* 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 <string>
class Image {
public:
Image() = default;
Image(Image const& rhs) { *this = rhs; }
Image(Image&& rhs) { *this = std::move(rhs); }
Image(SDL_Renderer* r, std::string fname) { Load(r, fname); }
Image(SDL_Renderer* r, Uint16 w, Uint16 h) { Create(r, w, h); }
Image(SDL_Texture* p) { SetTexture(p); }
virtual ~Image() { Free(); }
Image& operator=(Image const&);
Image& operator=(Image&&);
SDL_Texture* Load(SDL_Renderer* renderer, std::string fname);
SDL_Texture* Create(SDL_Renderer* renderer, Uint16 w, Uint16 h, SDL_Color blank = {0, 0, 0, 255});
SDL_Texture* CopyTexture(SDL_Renderer* renderer, SDL_Texture* ptr);
SDL_Texture* SetTexture(SDL_Texture*);
SDL_Texture* GetTexture() const;
virtual void Free();
void DrawTo(SDL_Renderer* const, Sint16 x, Sint16 y, double scaleX = 1.0, double scaleY = 1.0);
void SetAlpha(Uint8 a);
Uint8 GetAlpha();
//Clip handlers
SDL_Rect SetClip(SDL_Rect r) { return clip = r; }
SDL_Rect GetClip() const { return clip; }
Sint16 SetClipX(Sint16 x) { return clip.x = x; }
Sint16 SetClipY(Sint16 y) { return clip.y = y; }
Uint16 SetClipW(Uint16 w) { return clip.w = w; }
Uint16 SetClipH(Uint16 h) { return clip.h = h; }
Sint16 GetClipX() const { return clip.x; }
Sint16 GetClipY() const { return clip.y; }
Uint16 GetClipW() const { return clip.w; }
Uint16 GetClipH() const { return clip.h; }
bool GetLocal() const { return local; }
protected:
SDL_Texture* texture = nullptr;
SDL_Rect clip = {0, 0, 0, 0};
bool local = false;
};
@@ -1,5 +1,5 @@
#config
INCLUDES+=. .. ../characters ../creatures ../entities ../inventory ../../common/global_defines ../../common/utilities ../../TurtleGUI
INCLUDES+=.
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
@@ -10,10 +10,6 @@ CXXSRC=$(wildcard *.cpp)
OBJDIR=obj
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
#output
OUTDIR=..
OUT=$(addprefix $(OUTDIR)/,server.a)
#targets
all: $(OBJ) $(OUT)
ar -crs $(OUT) $(OBJ)
+56
View File
@@ -0,0 +1,56 @@
/* 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_box.hpp"
#include <stdexcept>
TextBox::TextBox() {
//
}
TextBox::~TextBox() {
//
}
void TextBox::DrawTo(SDL_Renderer* renderer, int posX, int posY, int pointSize) {
for (std::list<TextLine>::iterator it = lineList.begin(); it != lineList.end(); it++) {
it->DrawTo(renderer, posX, posY);
posY += pointSize;
}
}
void TextBox::PushLine(SDL_Renderer* renderer, TTF_Font* font, std::string str, SDL_Color color) {
lineList.emplace_front(renderer, font, str, color);
}
void TextBox::PopLine(int num) {
//prevent underflow
num < lineList.size() ? num : lineList.size();
for (int i = 0; i < num; ++i) {
lineList.pop_back();
}
}
void TextBox::ClearLines() {
lineList.clear();
}
@@ -21,15 +21,25 @@
*/
#pragma once
#include "item_data.hpp"
#include "text_line.hpp"
#include "SDL2/SDL.h"
#include "SDL2/SDL_ttf.h"
#include <string>
#include <list>
class Inventory {
class TextBox {
public:
Inventory() = default;
~Inventory() = default;
TextBox();
~TextBox();
void DrawTo(SDL_Renderer*, int posX, int posY, int pointSize);
void PushLine(SDL_Renderer*, TTF_Font*, std::string, SDL_Color color);
void PopLine(int num = 1);
void ClearLines();
private:
std::list<ItemData> itemList;
std::list<TextLine> lineList;
};
+70
View File
@@ -0,0 +1,70 @@
/* 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_line.hpp"
#include <stdexcept>
SDL_Texture* renderTextTexture(SDL_Renderer* renderer, TTF_Font* font, std::string str, SDL_Color color) {
//make the surface (from SDL_ttf)
SDL_Surface* surface = TTF_RenderText_Solid(font, str.c_str(), color);
if (!surface) {
throw(std::runtime_error("Failed to create a TTF surface"));
}
//convert to texture
SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface);
//cleanup
SDL_FreeSurface(surface);
//check
if (!texture) {
throw(std::runtime_error("Failed to create a TTF texture"));
}
//NOTE: free the texture yourself
return texture;
}
TextLine::TextLine() {
//
}
TextLine::~TextLine() {
ClearText();
}
void TextLine::DrawTo(SDL_Renderer* renderer, int posX, int posY) {
SDL_Rect dclip = {posX, posY, 0, 0};
SDL_QueryTexture(texture, nullptr, nullptr, &dclip.w, &dclip.h);
SDL_RenderCopy(renderer, texture, nullptr, &dclip);
}
void TextLine::SetText(SDL_Renderer* renderer, TTF_Font* font, std::string str, SDL_Color color) {
//just use the above global function
SDL_DestroyTexture(texture);
texture = renderTextTexture(renderer, font, str, color);
}
void TextLine::ClearText() {
SDL_DestroyTexture(texture);
}
@@ -21,22 +21,25 @@
*/
#pragma once
#include "server_packet.hpp"
#include "udp_network_utility.hpp"
#include "SDL2/SDL.h"
#include "SDL2/SDL_ttf.h"
#include <chrono>
#include <string>
class HeartbeatUtility {
SDL_Texture* renderTextTexture(SDL_Renderer*, TTF_Font*, std::string, SDL_Color color);
class TextLine {
public:
//heartbeat system
void hPing(ServerPacket* const);
void hPong(ServerPacket* const);
TextLine();
TextLine(SDL_Renderer* r, TTF_Font* f, std::string s, SDL_Color c)
{ SetText(r, f, s, c); }
virtual ~TextLine();
int CheckHeartBeat();
void DrawTo(SDL_Renderer*, int posX, int posY);
private:
UDPNetworkUtility& network = UDPNetworkUtility::GetSingleton();
typedef std::chrono::steady_clock Clock;
Clock::time_point lastBeat = Clock::now();
int attemptedBeats = 0;
void SetText(SDL_Renderer*, TTF_Font*, std::string, SDL_Color color);
void ClearText();
protected:
SDL_Texture* texture = nullptr;
};
+4 -2
View File
@@ -1,10 +1,12 @@
#output
export OUTDIR=../..
export OUTDIR=..
export OUT=$(addprefix $(OUTDIR)/,libcommon.a)
all: $(OUTDIR)
$(MAKE) -C debugging
$(MAKE) -C global_defines
$(MAKE) -C gameplay
$(MAKE) -C graphics
$(MAKE) -C map
$(MAKE) -C network
$(MAKE) -C utilities
+28
View File
@@ -0,0 +1,28 @@
#config
INCLUDES+=. ../graphics
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
#source
CXXSRC=$(wildcard *.cpp)
#objects
OBJDIR=obj
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
#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 $@ $<
+82
View File
@@ -0,0 +1,82 @@
/* 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 "region.hpp"
#include <cmath>
#include <cstring>
#include <stdexcept>
int snapToBase(int base, int x) {
return floor((double)x / base) * base;
}
Region::Region(int argX, int argY): x(argX), y(argY) {
if (x != snapToBase(REGION_WIDTH, x) || y != snapToBase(REGION_HEIGHT, y)) {
throw(std::invalid_argument("Region location is off grid"));
}
memset(tiles, 0, REGION_WIDTH*REGION_HEIGHT*REGION_DEPTH*sizeof(type_t));
}
Region::Region(Region const& rhs): x(rhs.x), y(rhs.y) {
memcpy(tiles, rhs.tiles, REGION_WIDTH*REGION_HEIGHT*REGION_DEPTH*sizeof(type_t));
solid = rhs.solid;
}
Region::type_t Region::SetTile(int x, int y, int z, type_t v) {
if (x < 0 || y < 0 || z < 0 || x >= REGION_WIDTH || y >= REGION_HEIGHT || z >= REGION_DEPTH) {
throw(std::out_of_range("Region::SetTile() argument out of range"));
}
return tiles[x][y][z] = v;
}
Region::type_t Region::GetTile(int x, int y, int z) const {
if (x < 0 || y < 0 || z < 0 || x >= REGION_WIDTH || y >= REGION_HEIGHT || z >= REGION_DEPTH) {
throw(std::out_of_range("Region::GetTile() argument out of range"));
}
return tiles[x][y][z];
}
bool Region::SetSolid(int x, int y, bool b) {
if (x < 0 || y < 0 || x >= REGION_WIDTH || y >= REGION_HEIGHT) {
throw(std::out_of_range("Region::SetSolid() argument out of range"));
}
return solid[x * REGION_WIDTH + y] = b;
}
bool Region::GetSolid(int x, int y) const {
if (x < 0 || y < 0 || x >= REGION_WIDTH || y >= REGION_HEIGHT) {
throw(std::out_of_range("Region::GetSolid() argument out of range"));
}
return solid[x * REGION_WIDTH + y];
}
int Region::GetX() const {
return x;
}
int Region::GetY() const {
return y;
}
std::bitset<REGION_WIDTH*REGION_HEIGHT>* Region::GetSolidBitset() {
return &solid;
}
+62
View File
@@ -0,0 +1,62 @@
/* 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 <bitset>
//the region's storage format
constexpr int REGION_WIDTH = 20;
constexpr int REGION_HEIGHT = 20;
constexpr int REGION_DEPTH = 3;
//utility function
int snapToBase(int base, int x);
class Region {
public:
typedef unsigned char type_t;
Region() = delete;
Region(int x, int y);
Region(Region const&);
~Region() = default;
type_t SetTile(int x, int y, int z, type_t v);
type_t GetTile(int x, int y, int z) const;
bool SetSolid(int x, int y, bool b);
bool GetSolid(int x, int y) const;
//accessors
int GetX() const;
int GetY() const;
std::bitset<REGION_WIDTH*REGION_HEIGHT>* GetSolidBitset();
private:
friend class TileSheet;
const int x;
const int y;
type_t tiles[REGION_WIDTH][REGION_HEIGHT][REGION_DEPTH];
std::bitset<REGION_WIDTH*REGION_HEIGHT> solid;
};
+99
View File
@@ -0,0 +1,99 @@
/* 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 "region_api.hpp"
#include "region.hpp"
static int setTile(lua_State* L) {
Region* region = reinterpret_cast<Region*>(lua_touserdata(L, 1));
int ret = region->SetTile(lua_tointeger(L, 2)-1, lua_tointeger(L, 3)-1, lua_tointeger(L, 4)-1, lua_tointeger(L, 5));
lua_pushinteger(L, ret);
return 1;
}
static int getTile(lua_State* L) {
Region* region = reinterpret_cast<Region*>(lua_touserdata(L, 1));
int ret = region->GetTile(lua_tointeger(L, 2)-1, lua_tointeger(L, 3)-1, lua_tointeger(L, 4)-1);
lua_pushinteger(L, ret);
return 1;
}
static int setSolid(lua_State* L) {
Region* region = reinterpret_cast<Region*>(lua_touserdata(L, 1));
bool ret = region->SetSolid(lua_tointeger(L, 2)-1, lua_tointeger(L, 3)-1, lua_toboolean(L, 4));
lua_pushboolean(L, ret);
return 1;
}
static int getSolid(lua_State* L) {
Region* region = reinterpret_cast<Region*>(lua_touserdata(L, 1));
bool ret = region->GetSolid(lua_tointeger(L, 2)-1, lua_tointeger(L, 3)-1);
lua_pushboolean(L, ret);
return 1;
}
static int getX(lua_State* L) {
Region* region = reinterpret_cast<Region*>(lua_touserdata(L, 1));
lua_pushinteger(L, region->GetX());
return 1;
}
static int getY(lua_State* L) {
Region* region = reinterpret_cast<Region*>(lua_touserdata(L, 1));
lua_pushinteger(L, region->GetY());
return 1;
}
static int getWidth(lua_State* L) {
lua_pushinteger(L, REGION_WIDTH);
return 1;
}
static int getHeight(lua_State* L) {
lua_pushinteger(L, REGION_HEIGHT);
return 1;
}
static int getDepth(lua_State* L) {
lua_pushinteger(L, REGION_DEPTH);
return 1;
}
static const luaL_Reg regionLib[] = {
{"SetTile",setTile},
{"GetTile",getTile},
{"SetSolid",setSolid},
{"GetSolid",getSolid},
{"GetX",getX},
{"GetY",getY},
//the global macros
{"GetWidth",getWidth},
{"GetHeight",getHeight},
{"GetDepth",getDepth},
{nullptr, nullptr}
};
LUAMOD_API int openRegionAPI(lua_State* L) {
luaL_newlib(L, regionLib);
return 1;
}
@@ -21,12 +21,7 @@
*/
#pragma once
enum ItemType {
//basics
POTION = 101,
#include "lua.hpp"
//weapons
SWORD = 201,
DAGGER = 202,
STAFF = 203
};
#define TORTUGA_REGION_API "region"
LUAMOD_API int openRegionAPI(lua_State* L);
+172
View File
@@ -0,0 +1,172 @@
/* 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 "region_pager_api.hpp"
#include "region_pager_lua.hpp"
#include "region.hpp"
//DOCS: These glue functions simply wrap RegionPagerLua's methods
//NOTE: zero indexing is used here, but not in the region API
static int setTile(lua_State* L) {
RegionPagerLua* pager = reinterpret_cast<RegionPagerLua*>(lua_touserdata(L, 1));
int ret = pager->SetTile(lua_tointeger(L, 2), lua_tointeger(L, 3), lua_tointeger(L, 4), lua_tointeger(L, 5));
lua_pushinteger(L, ret);
return 1;
}
static int getTile(lua_State* L) {
RegionPagerLua* pager = reinterpret_cast<RegionPagerLua*>(lua_touserdata(L, 1));
int ret = pager->GetTile(lua_tointeger(L, 2), lua_tointeger(L, 3), lua_tointeger(L, 4));
lua_pushinteger(L, ret);
return 1;
}
static int setSolid(lua_State* L) {
RegionPagerLua* pager = reinterpret_cast<RegionPagerLua*>(lua_touserdata(L, 1));
bool ret = pager->SetSolid(lua_tointeger(L, 2), lua_tointeger(L, 3), lua_toboolean(L, 4));
lua_pushboolean(L, ret);
return 1;
}
static int getSolid(lua_State* L) {
RegionPagerLua* pager = reinterpret_cast<RegionPagerLua*>(lua_touserdata(L, 1));
bool ret = pager->GetSolid(lua_tointeger(L, 2), lua_tointeger(L, 3));
lua_pushboolean(L, ret);
return 1;
}
static int getRegion(lua_State* L) {
RegionPagerLua* pager = reinterpret_cast<RegionPagerLua*>(lua_touserdata(L, 1));
Region* region = pager->GetRegion(lua_tointeger(L, 2), lua_tointeger(L, 3));
lua_pushlightuserdata(L, region);
return 1;
}
static int loadRegion(lua_State* L) {
RegionPagerLua* pager = reinterpret_cast<RegionPagerLua*>(lua_touserdata(L, 1));
Region* region = pager->LoadRegion(lua_tointeger(L, 2), lua_tointeger(L, 3));
lua_pushlightuserdata(L, region);
return 1;
}
static int saveRegion(lua_State* L) {
RegionPagerLua* pager = reinterpret_cast<RegionPagerLua*>(lua_touserdata(L, 1));
Region* region = pager->SaveRegion(lua_tointeger(L, 2), lua_tointeger(L, 3));
lua_pushlightuserdata(L, region);
return 1;
}
static int createRegion(lua_State* L) {
RegionPagerLua* pager = reinterpret_cast<RegionPagerLua*>(lua_touserdata(L, 1));
Region* region = pager->CreateRegion(lua_tointeger(L, 2), lua_tointeger(L, 3));
lua_pushlightuserdata(L, region);
return 1;
}
static int unloadRegion(lua_State* L) {
RegionPagerLua* pager = reinterpret_cast<RegionPagerLua*>(lua_touserdata(L, 1));
//two argument types: coords & the region itself
switch(lua_type(L, 2)) {
case LUA_TNUMBER:
pager->UnloadIf([&](Region const& region) -> bool {
int x = lua_tointeger(L, 2);
int y = lua_tointeger(L, 3);
return region.GetX() == x && region.GetY() == y;
});
break;
case LUA_TLIGHTUSERDATA:
pager->UnloadIf([&](Region const& region) -> bool {
return (&region) == lua_touserdata(L, 2);
});
break;
}
return 0;
}
static int setOnLoad(lua_State* L) {
RegionPagerLua* pager = reinterpret_cast<RegionPagerLua*>(lua_touserdata(L, 1));
luaL_unref(L, LUA_REGISTRYINDEX, pager->GetLoadReference());
pager->SetLoadReference(luaL_ref(L, LUA_REGISTRYINDEX));
return 0;
}
static int setOnSave(lua_State* L) {
RegionPagerLua* pager = reinterpret_cast<RegionPagerLua*>(lua_touserdata(L, 1));
luaL_unref(L, LUA_REGISTRYINDEX, pager->GetSaveReference());
pager->SetSaveReference(luaL_ref(L, LUA_REGISTRYINDEX));
return 0;
}
static int setOnCreate(lua_State* L) {
RegionPagerLua* pager = reinterpret_cast<RegionPagerLua*>(lua_touserdata(L, 1));
luaL_unref(L, LUA_REGISTRYINDEX, pager->GetCreateReference());
pager->SetCreateReference(luaL_ref(L, LUA_REGISTRYINDEX));
return 0;
}
static int setOnUnload(lua_State* L) {
RegionPagerLua* pager = reinterpret_cast<RegionPagerLua*>(lua_touserdata(L, 1));
luaL_unref(L, LUA_REGISTRYINDEX, pager->GetUnloadReference());
pager->SetUnloadReference(luaL_ref(L, LUA_REGISTRYINDEX));
return 0;
}
//debugging
static int containerSize(lua_State* L) {
RegionPagerLua* pager = static_cast<RegionPagerLua*>(lua_touserdata(L, 1));
lua_pushinteger(L, pager->GetContainer()->size());
return 1;
}
static const luaL_Reg regionPagerLib[] = {
//curry
{"SetTile", setTile},
{"GetTile", getTile},
{"SetSolid", setSolid},
{"GetSolid", getSolid},
//access and control
{"GetRegion", getRegion},
{"LoadRegion", loadRegion},
{"SaveRegion", saveRegion},
{"CreateRegion", createRegion},
{"UnloadRegion", unloadRegion},
//triggers
{"SetOnLoad",setOnLoad},
{"SetOnSave",setOnSave},
{"SetOnCreate",setOnCreate},
{"SetOnUnload",setOnUnload},
//debugging
{"ContainerSize", containerSize},
//sentinel
{nullptr, nullptr}
};
LUAMOD_API int openRegionPagerAPI(lua_State* L) {
luaL_newlib(L, regionPagerLib);
return 1;
}
@@ -19,5 +19,9 @@
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "inventory.hpp"
#pragma once
#include "lua.hpp"
#define TORTUGA_REGION_PAGER_API "region_pager"
LUAMOD_API int openRegionPagerAPI(lua_State* L);
+106
View File
@@ -0,0 +1,106 @@
/* 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 "region_pager_base.hpp"
#include <stdexcept>
#include <algorithm>
RegionPagerBase::~RegionPagerBase() {
UnloadAll();
};
Region::type_t RegionPagerBase::SetTile(int x, int y, int z, Region::type_t v) {
Region* ptr = GetRegion(x, y);
return ptr->SetTile(x - ptr->GetX(), y - ptr->GetY(), z, v);
}
//Bug Origin?
Region::type_t RegionPagerBase::GetTile(int x, int y, int z) {
Region* ptr = GetRegion(x, y);
return ptr->GetTile(x - ptr->GetX(), y - ptr->GetY(), z);
}
bool RegionPagerBase::SetSolid(int x, int y, int b) {
Region* ptr = GetRegion(x, y);
return ptr->SetSolid(x - ptr->GetX(), y - ptr->GetY(), b);
}
bool RegionPagerBase::GetSolid(int x, int y) {
Region* ptr = GetRegion(x, y);
return ptr->GetSolid(x - ptr->GetX(), y - ptr->GetY());
}
Region* RegionPagerBase::GetRegion(int x, int y) {
x = snapToBase(REGION_WIDTH, x);
y = snapToBase(REGION_HEIGHT, y);
//get the region by various means
Region* ptr = nullptr;
ptr = FindRegion(x, y);
if (ptr) return ptr;
ptr = LoadRegion(x, y);
if (ptr) return ptr;
return CreateRegion(x, y);
}
Region* RegionPagerBase::FindRegion(int x, int y) {
//find the region
std::list<Region>::iterator it = find_if(regionList.begin(), regionList.end(), [x, y](Region& region) -> bool {
return region.GetX() == x && region.GetY() == y;
});
return it != regionList.end() ? &(*it) : nullptr;
}
Region* RegionPagerBase::PushRegion(Region* const ptr) {
regionList.push_front(*ptr);
return &regionList.front();
}
Region* RegionPagerBase::LoadRegion(int x, int y) {
//EMPTY, intended for override
return nullptr;
}
Region* RegionPagerBase::SaveRegion(int x, int y) {
//EMPTY, intended for override
return nullptr;
}
Region* RegionPagerBase::CreateRegion(int x, int y) {
if (FindRegion(x, y)) {
throw(std::logic_error("Cannot overwrite an existing region"));
}
regionList.emplace_front(x, y);
return &regionList.front();
}
void RegionPagerBase::UnloadIf(std::function<bool(Region const&)> fn) {
regionList.remove_if(fn);
}
void RegionPagerBase::UnloadAll() {
regionList.clear();
}
std::list<Region>* RegionPagerBase::GetContainer() {
return &regionList;
}
+58
View File
@@ -0,0 +1,58 @@
/* 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 "region.hpp"
#include <functional>
#include <list>
class RegionPagerBase {
public:
RegionPagerBase() = default;
virtual ~RegionPagerBase();
//tile manipulation
virtual Region::type_t SetTile(int x, int y, int z, Region::type_t v);
virtual Region::type_t GetTile(int x, int y, int z);
//solid manipulation
virtual bool SetSolid(int x, int y, int b);
virtual bool GetSolid(int x, int y);
//region manipulation
virtual Region* GetRegion(int x, int y);
virtual Region* FindRegion(int x, int y);
virtual Region* PushRegion(Region* const);
virtual Region* LoadRegion(int x, int y);
virtual Region* SaveRegion(int x, int y);
virtual Region* CreateRegion(int x, int y);
virtual void UnloadIf(std::function<bool(Region const&)> fn);
virtual void UnloadAll();
//accessors & mutators
std::list<Region>* GetContainer();
protected:
std::list<Region> regionList;
};
+208
View File
@@ -0,0 +1,208 @@
/* 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 "region_pager_lua.hpp"
#include <stdexcept>
RegionPagerLua::~RegionPagerLua() {
//unload all regions
UnloadAll();
//clear any stored functions
luaL_unref(lua, LUA_REGISTRYINDEX, loadRef);
luaL_unref(lua, LUA_REGISTRYINDEX, saveRef);
luaL_unref(lua, LUA_REGISTRYINDEX, createRef);
luaL_unref(lua, LUA_REGISTRYINDEX, unloadRef);
}
//return the loaded region, or nullptr on failure
Region* RegionPagerLua::LoadRegion(int x, int y) {
//get the pager's function from the registry
lua_rawgeti(lua, LUA_REGISTRYINDEX, loadRef);
//check if this function is available
if (lua_isnil(lua, -1)) {
lua_pop(lua, 1);
//signal that there is no load function
return nullptr;
}
//something to work on
Region tmpRegion(x, y);
lua_pushlightuserdata(lua, &tmpRegion);
//call the funtion, 1 arg, 1 return
if (lua_pcall(lua, 1, 1, 0) != LUA_OK) {
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) ));
}
//check the return value, success or failure
if (lua_isboolean(lua, -1) && lua_toboolean(lua, -1)) {
lua_pop(lua, 1);
//push and return the loaded region
regionList.push_front(tmpRegion);
return &regionList.front();
}
else {
lua_pop(lua, 1);
//signal a failure
return nullptr;
}
}
//NOTE: this return value seems strange; could replace it with a boolean
//return the saved region, or nullptr on failure
Region* RegionPagerLua::SaveRegion(int x, int y) {
//get the pager's function from the registry
lua_rawgeti(lua, LUA_REGISTRYINDEX, saveRef);
//check if this function is available
if (lua_isnil(lua, -1)) {
lua_pop(lua, 1);
//signal that the region wasn't saved
return nullptr;
}
//find the specified region
Region* ptr = FindRegion(x, y);
if (!ptr) {
lua_pop(lua, 1);
//signal that there is no save function
return nullptr;
}
lua_pushlightuserdata(lua, ptr);
//call the function, 1 arg, 1 return
if (lua_pcall(lua, 1, 1, 0) != LUA_OK) {
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) ));
}
//check the return value, success or failure
if (lua_isboolean(lua, -1) && lua_toboolean(lua, -1)) {
lua_pop(lua, 1);
//return the specified region that was saved
return ptr;
}
else {
lua_pop(lua, 1);
//signal a failure
return nullptr;
}
}
//DOCS: since this method is the last ditch call from GetRegion, it must return a valid region object, even if the create function hasn't been set.
//return a new region, throwing an error on failure
Region* RegionPagerLua::CreateRegion(int x, int y) {
if (FindRegion(x, y)) {
throw(std::logic_error("Cannot overwrite an existing region"));
}
//get the pager's function from the registry
lua_rawgeti(lua, LUA_REGISTRYINDEX, createRef);
//check if this function is available
if (lua_isnil(lua, -1)) {
lua_pop(lua, 1);
//return an empty region object
regionList.emplace_front(x, y);
return &regionList.front();
}
//something to work on
Region tmpRegion(x, y);
lua_pushlightuserdata(lua, &tmpRegion);
//call the function, 1 arg, 0 return
if (lua_pcall(lua, 1, 0, 0) != LUA_OK) {
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) ));
}
//return the new region
regionList.push_front(tmpRegion);
return &regionList.front();
}
//no return
void RegionPagerLua::UnloadIf(std::function<bool(Region const&)> fn) {
//get the pager's function from the registry
lua_rawgeti(lua, LUA_REGISTRYINDEX, unloadRef);
//check if this function is available
if (lua_isnil(lua, -1)) {
lua_pop(lua, 1);
//remove the regions anyway
regionList.remove_if(fn);
return;
}
//run each region through this lambda
regionList.remove_if([&](Region& region) -> bool {
if (fn(region)) {
//push a copy of the function onto the stack with the region
lua_pushvalue(lua, -1);
lua_pushlightuserdata(lua, static_cast<void*>(&region));
//call the function, 1 arg, 0 return
if (lua_pcall(lua, 1, 0, 0) != LUA_OK) {
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) ));
}
//signal to the container
return true;
}
//signal to the container
return false;
});
//pop the base copy of the function
lua_pop(lua, 1);
}
void RegionPagerLua::UnloadAll() {
//get the pager's function from the registry
lua_rawgeti(lua, LUA_REGISTRYINDEX, unloadRef);
//check if this function is available
if (lua_isnil(lua, -1)) {
lua_pop(lua, 1);
//remove the regions anyway
regionList.clear();
return;
}
for (auto& it : regionList) {
//push a copy of the function onto the stack with the region
lua_pushvalue(lua, -1);
lua_pushlightuserdata(lua, &it);
//call the function, 1 arg, 0 return
if (lua_pcall(lua, 1, 0, 0) != LUA_OK) {
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) ));
}
}
//pop the base copy of the function
lua_pop(lua, 1);
//remove from memory
regionList.clear();
}
+68
View File
@@ -0,0 +1,68 @@
/* 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 "region_pager_base.hpp"
#include "lua.hpp"
#include <functional>
#include <string>
//DOCS: set the lua hook before use
class RegionPagerLua : public RegionPagerBase {
public:
RegionPagerLua() = default;
~RegionPagerLua();
//region manipulation
Region* LoadRegion(int x, int y) override;
Region* SaveRegion(int x, int y) override;
Region* CreateRegion(int x, int y) override;
void UnloadIf(std::function<bool(Region const&)> fn) override;
void UnloadAll() override;
//accessors & mutators
lua_State* SetLuaState(lua_State* L) { return lua = L; }
lua_State* GetLuaState() { return lua; }
//utilities for the API
int SetLoadReference(int i) { return loadRef = i; }
int SetSaveReference(int i) { return saveRef = i; }
int SetCreateReference(int i) { return createRef = i; }
int SetUnloadReference(int i) { return unloadRef = i; }
int GetLoadReference() { return loadRef; }
int GetSaveReference() { return saveRef; }
int GetCreateReference() { return createRef; }
int GetUnloadReference() { return unloadRef; }
protected:
lua_State* lua = nullptr;
int loadRef = LUA_NOREF;
int saveRef = LUA_NOREF;
int createRef = LUA_NOREF;
int unloadRef = LUA_NOREF;
};
+124
View File
@@ -0,0 +1,124 @@
/* 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 "tile_sheet.hpp"
#include <stdexcept>
TileSheet& TileSheet::operator=(TileSheet const& rhs) {
//don't screw yourself
if (this == &rhs) {
return *this;
}
Free();
//Copy the other TileSheet's stuff
texture = rhs.texture;
clip = rhs.clip;
local = false;
countX = rhs.countX;
countY = rhs.countY;
}
TileSheet& TileSheet::operator=(TileSheet&& rhs) {
//don't screw yourself
if (this == &rhs) {
return *this;
}
Free();
//Copy the other TileSheet's stuff
texture = rhs.texture;
clip = rhs.clip;
local = false;
countX = rhs.countX;
countY = rhs.countY;
rhs.texture = nullptr;
rhs.clip = {0, 0, 0, 0};
rhs.local = false;
rhs.countX = 0;
rhs.countY = 0;
}
void TileSheet::Load(SDL_Renderer* renderer, std::string fname, int tileWidth, int tileHeight) {
Image::Load(renderer, fname);
countX = clip.w / tileWidth;
countY = clip.h / tileHeight;
clip.w = tileWidth;
clip.h = tileHeight;
}
SDL_Texture* TileSheet::SetTexture(SDL_Texture* ptr, int tileWidth, int tileHeight) {
Image::SetTexture(ptr);
countX = clip.w / tileWidth;
countY = clip.h / tileHeight;
clip.w = tileWidth;
clip.h = tileHeight;
}
void TileSheet::Free() {
Image::Free();
countX = countY = 0;
}
void TileSheet::DrawLayerTo(SDL_Renderer* const renderer, Region* const region, int layer, int camX, int camY, double scaleX, double scaleY) {
//TODO: (2) empty
}
void TileSheet::DrawRegionTo(SDL_Renderer* const renderer, Region* const region, int camX, int camY, double scaleX, double scaleY) {
//NOTE: TileSheet is a friend class of Region
//reimplementing DrawTo() to improve performance (less indirection)
if (!texture) {
throw(std::logic_error("No image texture to draw"));
}
//the local variables
SDL_Rect sclip = {0, 0, clip.w, clip.h};
SDL_Rect dclip = {0, 0, Uint16(clip.w * scaleX), Uint16(clip.h * scaleY)};
Region::type_t tile = 0;
//for each tile
for (register int i = 0; i < REGION_WIDTH; ++i) {
for (register int j = 0; j < REGION_HEIGHT; ++j) {
for (register int k = 0; k < REGION_DEPTH; ++k) {
//get the value to skip expensive lookups
tile = region->tiles[i][j][k];
//0 is invisible
if (tile == 0) continue;
//set the sclip
sclip.x = (tile-1) % countX * clip.h;
sclip.y = (tile-1) / countX * clip.w;
//set the dclip
dclip.x = ((region->x + i) * clip.w - camX) * scaleX;
dclip.y = ((region->y + j) * clip.h - camY) * scaleY;
//draw
SDL_RenderCopy(renderer, texture, &sclip, &dclip);
}
}
}
}
+67
View File
@@ -0,0 +1,67 @@
/* 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 "region.hpp"
#include "image.hpp"
#include <string>
class TileSheet : public Image {
public:
TileSheet() = default;
TileSheet(TileSheet const& rhs) { *this = rhs; }
TileSheet(TileSheet&& rhs) { *this = std::move(rhs); }
TileSheet(SDL_Renderer* r, std::string fn, int tw, int th) { Load(r, fn, tw, th); }
TileSheet(SDL_Texture* p, int tw, int th) { SetTexture(p, tw, th); }
~TileSheet() = default;
TileSheet& operator=(TileSheet const&);
TileSheet& operator=(TileSheet&&);
void Load(SDL_Renderer*, std::string fname, int tileWidth, int tileHeight);
SDL_Texture* SetTexture(SDL_Texture*, int tileWidth, int tileHeight);
void Free() override;
void DrawLayerTo(SDL_Renderer* const renderer, Region* const region, int layer, int camX, int camY, double scaleX = 1.0, double scaleY = 1.0);
void DrawRegionTo(SDL_Renderer* const renderer, Region* const region, int camX, int camY, double scaleX = 1.0, double scaleY = 1.0);
//accessors
//DOCS: Reuse Image::clip for tile sizes
int GetCountX() { return countX; }
int GetCountY() { return countY; }
int GetTileW() { return clip.w; }
int GetTileH() { return clip.h; }
protected:
int countX = 0, countY = 0;
using Image::Load;
using Image::Create;
using Image::SetTexture;
using Image::SetClip;
using Image::SetClipX;
using Image::SetClipY;
using Image::SetClipW;
using Image::SetClipH;
};
+1 -1
View File
@@ -1,5 +1,5 @@
#config
INCLUDES+=. packet_types ../global_defines ../utilities ../../TurtleGUI ../../TurtleMap
INCLUDES+=. packet_types ../gameplay ../map ../utilities
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
+1 -1
View File
@@ -1,5 +1,5 @@
#config
INCLUDES+=. .. ../../global_defines ../../utilities ../../../TurtleGUI ../../../TurtleMap
INCLUDES+=. .. ../../gameplay ../../map ../../utilities
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
+7 -8
View File
@@ -34,16 +34,15 @@
typedef SerialPacketBase SerialPacket;
//DOCS: NETWORK_VERSION is used to discern compatible servers and clients
constexpr int NETWORK_VERSION = 20161209;
constexpr int NETWORK_VERSION = 20160404;
union MaxPacket {
BarrierPacket a;
CharacterPacket b;
ClientPacket c;
CreaturePacket d;
RegionPacket e;
ServerPacket f;
TextPacket g;
CharacterPacket a;
ClientPacket b;
CreaturePacket c;
RegionPacket d;
ServerPacket e;
TextPacket f;
};
constexpr int MAX_PACKET_SIZE = sizeof(MaxPacket);
+19 -22
View File
@@ -142,6 +142,25 @@ enum class SerialPacketType {
FORMAT_END_CREATURE = 599,
//-------------------------
//BarrierPacket
// barrier index,
// bounds,
// roomIndex, origin, motion
// status
//-------------------------
FORMAT_COMBAT = 700,
BARRIER_UPDATE = 701,
BARRIER_CREATE = 702,
BARRIER_UNLOAD = 703,
QUERY_BARRIER_EXISTS = 704,
FORMAT_END_COMBAT = 799,
//-------------------------
//TextPacket
// name, text
@@ -165,28 +184,6 @@ enum class SerialPacketType {
FORMAT_END_TEXT = 699,
//-------------------------
//BarrierPacket
// barrier index,
// bounds,
// roomIndex, origin, motion
// status
//-------------------------
FORMAT_BARRIER = 700,
BARRIER_UPDATE = 701,
BARRIER_CREATE = 702,
BARRIER_UNLOAD = 703,
QUERY_BARRIER_EXISTS = 704,
BARRIER_ENTRY = 705,
BARRIER_EXIT = 706,
FORMAT_END_BARRIER = 799,
//-------------------------
//not used
//-------------------------
+8 -8
View File
@@ -70,12 +70,12 @@ void serializePacket(void* buffer, SerialPacketBase* packet) {
serializeCreature(buffer, static_cast<CreaturePacket*>(packet));
}
if (BOUNDS(packet->type, SerialPacketType::FORMAT_TEXT, SerialPacketType::FORMAT_END_TEXT)) {
serializeText(buffer, static_cast<TextPacket*>(packet));
if (BOUNDS(packet->type, SerialPacketType::FORMAT_COMBAT, SerialPacketType::FORMAT_END_COMBAT)) {
serializeBarrier(buffer, static_cast<BarrierPacket*>(packet));
}
if (BOUNDS(packet->type, SerialPacketType::FORMAT_BARRIER, SerialPacketType::FORMAT_END_BARRIER)) {
serializeBarrier(buffer, static_cast<BarrierPacket*>(packet));
if (BOUNDS(packet->type, SerialPacketType::FORMAT_TEXT, SerialPacketType::FORMAT_END_TEXT)) {
serializeText(buffer, static_cast<TextPacket*>(packet));
}
}
@@ -104,11 +104,11 @@ void deserializePacket(void* buffer, SerialPacketBase* packet) {
deserializeCreature(buffer, static_cast<CreaturePacket*>(packet));
}
if (BOUNDS(type, SerialPacketType::FORMAT_COMBAT, SerialPacketType::FORMAT_END_COMBAT)) {
deserializeBarrier(buffer, static_cast<BarrierPacket*>(packet));
}
if (BOUNDS(type, SerialPacketType::FORMAT_TEXT, SerialPacketType::FORMAT_END_TEXT)) {
deserializeText(buffer, static_cast<TextPacket*>(packet));
}
if (BOUNDS(type, SerialPacketType::FORMAT_BARRIER, SerialPacketType::FORMAT_END_BARRIER)) {
deserializeBarrier(buffer, static_cast<BarrierPacket*>(packet));
}
}
+75
View File
@@ -0,0 +1,75 @@
/* 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 <type_traits>
#include <algorithm>
class BoundingBox {
public:
//This is explicitly a POD
int x, y;
int w, h;
BoundingBox() = default;
BoundingBox(int i, int j): x(i), y(j), w(0), h(0) {};
BoundingBox(int i, int j, int k, int l): x(i), y(j), w(k), h(l) {};
~BoundingBox() = default;
BoundingBox& operator=(BoundingBox const&) = default;
int Size() {
return std::max(w*h,0);
}
bool CheckOverlap(BoundingBox rhs) {
return !(
x >= rhs.x + rhs.w ||
y >= rhs.y + rhs.h ||
rhs.x >= x + w ||
rhs.y >= y + h);
}
BoundingBox CalcOverlap(BoundingBox rhs) {
if (!CheckOverlap(rhs)) {
return {0, 0, 0, 0};
}
BoundingBox ret;
ret.x = std::max(x, rhs.x);
ret.y = std::max(y, rhs.y);
ret.w = std::min(x+w, rhs.x+rhs.w) - ret.x;
ret.h = std::min(y+h, rhs.y+rhs.h) - ret.y;
return ret;
}
};
//This is explicitly a POD
static_assert(std::is_pod<BoundingBox>::value, "BoundingBox is not a POD");
#include "vector2.hpp"
//operators
inline BoundingBox operator+(BoundingBox b, Vector2 v) {
return {b.x + (int)v.x, b.y + (int)v.y, b.w, b.h};
}
inline BoundingBox operator+(Vector2 v, BoundingBox b) {
return b + v;
}
-125
View File
@@ -1,125 +0,0 @@
/* Copyright: (c) Kayne Ruse 2015
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#pragma once
//DOCS: this is a generic CSV reading tool
//DOCS: empty lines and comment lines begining with '#' are ignored
//DOCS: whitespace characters are valid field values
//DOCS: if the file is invalid, then the behavior is undefined
#include <array>
#include <cstring>
#include <fstream>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>
//define the container types
template<int N>
using CSVElement = std::array<std::string, N>;
template<int N>
using CSVObject = std::vector<CSVElement<N>>;
//read a file into an object
template<int N>
CSVObject<N> readCSV(std::string fname, char delim = ',') {
//open the file
std::ifstream is(fname);
if (!is.is_open()) {
std::ostringstream msg;
msg << "Failed to open file: " << fname;
throw(std::runtime_error(msg.str()));
}
//build the scanf format
std::ostringstream format;
format << "%[^\0" << delim << "]";
//read and store each record (one per line)
CSVObject<N> object;
while(!is.eof()) {
//get a line
std::string tmpLine;
getline(is, tmpLine);
//skip blank and comment lines
if (tmpLine.size() == 0 || tmpLine[0] == '#') {
continue;
}
//read and store each field
CSVElement<N> record;
for (int i = 0; i < N; ++i) {
//get a field
char tmpField[256];
memset(tmpField, 0, 256);
sscanf(tmpLine.c_str(), format.str().c_str(), tmpField);
//prune the input
int len = std::min(strlen(tmpField)+1, tmpLine.size());
tmpLine = tmpLine.substr(len);
//store the field
record[i] = tmpField;
}
object.push_back(record);
}
//finally, close the file
is.close();
return object;
}
template<int N>
void writeCSV(std::string fname, CSVObject<N> const& object, char delim = ',') {
//open the file
std::ofstream os(fname);
if (!os.is_open()) {
std::ostringstream msg;
msg << "Failed to open file: " << fname;
throw(std::runtime_error(msg.str()));
}
//write each record, one at a time
for(auto& record : object) {
//write each field, one at a time
for (int i = 0; i < N; i++) {
os << record[i];
//print delimiter
if (i != N -1) {
os << delim;
}
}
os << std::endl;
}
//finish
os.close();
}
-60
View File
@@ -1,60 +0,0 @@
/* Copyright: (c) Kayne Ruse 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 "file_hash.hpp"
#include <fstream>
//hash a byte array into a 32-bit integer
unsigned fnv_hash_1a_32(void *key, int len) {
unsigned char *p = static_cast<unsigned char*>(key);
unsigned h = 0x811c9dc5;
for (int i = 0; i < len; i++) {
h = ( h ^ p[i] ) * 0x01000193;
}
return h;
}
int getFileHash(std::string fname) {
std::ifstream is(fname, std::ios::in | std::ios::binary);
//if the file doesn't exist, return a hash of -1
if (!is.is_open()) {
return -1;
}
//get the file size
is.seekg(0, std::ios_base::end);
int size = is.tellg();
is.seekg(0);
//create a buffer of that size
char buffer[size];
//load the data
is.read(buffer, size);
//cleanup
is.close();
//finally, return the hash value
return fnv_hash_1a_32(buffer, size);
}
-26
View File
@@ -1,26 +0,0 @@
/* Copyright: (c) Kayne Ruse 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 <string>
int getFileHash(std::string fname);
+111
View File
@@ -0,0 +1,111 @@
/* 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 <type_traits>
#include <stdexcept>
#include <cmath>
class Vector2 {
public:
double x, y;
Vector2() = default;
Vector2(double i, double j): x(i), y(j) {};
~Vector2() = default;
Vector2& operator=(Vector2 const&) = default;
double Length() const {
return sqrt(x*x+y*y);
}
double SquaredLength() const {
return x*x+y*y;
}
void Normalize() {
double l = Length();
if (l == 0)
throw(std::domain_error("Divide by zero"));
x /= l;
y /= l;
}
//Arithmetic operators
Vector2 operator+(Vector2 v) const {
Vector2 ret;
ret.x = x + v.x;
ret.y = y + v.y;
return ret;
}
Vector2 operator-(Vector2 v) const {
Vector2 ret;
ret.x = x - v.x;
ret.y = y - v.y;
return ret;
}
Vector2 operator*(Vector2 v) const {
Vector2 ret;
ret.x = x * v.x;
ret.y = y * v.y;
return ret;
}
Vector2 operator*(double d) const {
Vector2 ret;
ret.x = x * d;
ret.y = y * d;
return ret;
}
Vector2 operator/(Vector2 v) {
if (!v.x || !v.y)
throw(std::domain_error("Divide by zero"));
Vector2 ret;
ret.x = x / v.x;
ret.y = y / v.y;
return ret;
}
Vector2 operator/(double d) {
if (!d)
throw(std::domain_error("Divide by zero"));
Vector2 ret;
ret.x = x / d;
ret.y = y / d;
return ret;
}
//unary operators
Vector2 operator-() { return {-x, -y}; }
//comparison operators
bool operator==(Vector2 v) { return (x == v.x && y == v.y); }
bool operator!=(Vector2 v) { return (x != v.x || y != v.y); }
//member templates (curry the above operators)
template<typename T> Vector2 operator+=(T t) { return *this = *this + t; }
template<typename T> Vector2 operator-=(T t) { return *this = *this - t; }
template<typename T> Vector2 operator*=(T t) { return *this = *this * t; }
template<typename T> Vector2 operator/=(T t) { return *this = *this / t; }
template<typename T> bool operator==(T t) { return (x == t && y == t); }
template<typename T> bool operator!=(T t) { return (x != t || y != t); }
};
//This is explicitly a POD
static_assert(std::is_pod<Vector2>::value, "Vector2 is not a POD");
+14 -18
View File
@@ -15,25 +15,21 @@ Instructions For Setup
-------------------------
1. To create a server, simply run server.exe
(a public server "Island Home" is provided by default)
2. To play, run client.exe
3. Your unique information should be inputted into the lobby screen, replacing
the default values.
4. There are currently two options for avatars:
(a public server is provided by default)
2. To join a server, your player information must be input into rsc/config.cfg
(NOTE: This process will be streamlined later)
3. To change the config settings, open rsc/config.cfg
4. These settings must be unique for each player:
* character1.png #male
* character2.png #female
* client.username
* client.handle
5. Select a server, and click join.
-------------------------
Linux Users
-------------------------
Before running this on linux, you may need to run the following commands:
sudo apt-get install libsdl2-net-2.0-0
sudo apt-get install libsdl2-image-2.0-0
sudo apt-get install libsdl2-ttf-2.0-0
5. There are currently two options for 'client.avatar':
* client.avatar = character1.png #male
* client.avatar = character2.png #female
6. When you've correctly set these values, run client.exe, and select 'Start'
from the main menu; this displays the list of available servers.
7. Select the name of a server (default is 'Public') and select 'Join'.
8. Welcome to Tortuga, enjoy your stay.
+2 -6
View File
@@ -7,9 +7,7 @@
OUTDIR=out
BINDIR=bin
all: $(OUTDIR) dll
$(MAKE) -C TurtleGUI
$(MAKE) -C TurtleMap
all: $(OUTDIR) binary
$(MAKE) -C common
$(MAKE) -C server
$(MAKE) -C client
@@ -17,9 +15,7 @@ all: $(OUTDIR) dll
debug: export CXXFLAGS+=-g
debug: clean all
ifeq ($(OS),Windows_NT)
release: export CXXFLAGS+=-static-libgcc -static-libstdc++
endif
release: clean all package
#For use on my machine ONLY
@@ -31,7 +27,7 @@ else ifeq ($(shell uname), Linux)
tar -C $(OUTDIR) -zcvf Tortuga-linux.tar client server ../rsc ../copyright.txt ../instructions.txt
endif
dll: $(OUTDIR)
binary: $(OUTDIR)
ifeq ($(OS),Windows_NT)
xcopy /Y $(BINDIR)\\*.dll $(OUTDIR)
endif
-2
View File
@@ -2,7 +2,6 @@
#TODO: (9) split this file in two, one for each program
#server specific settings
server.home = island.krgamestudios.com
server.host = 255.255.255.255
server.port = 21795
server.name = local
@@ -15,7 +14,6 @@ server.dbname = database.db
#client.screen.f = false #NOTE: fullscreen option is currently disabled
client.username = username
client.password = password
client.handle = handle
client.avatar = character2.png
-5
View File
@@ -1,5 +0,0 @@
#Format (4 columns): "name", type, "sprite.png", stackable
"Sword",weapon,"sword.png",false
"Staff",weapon,"staff.png",false
"Dagger",weapon,"dagger.png",false
"Potion",consumable,"potion.png",true
Can't render this file because it contains an unexpected character in line 1 and column 22.
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1009 B

Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 316 B

Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 738 B

After

Width:  |  Height:  |  Size: 738 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 763 B

After

Width:  |  Height:  |  Size: 763 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 273 B

After

Width:  |  Height:  |  Size: 273 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 270 B

After

Width:  |  Height:  |  Size: 270 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 305 B

After

Width:  |  Height:  |  Size: 305 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 302 B

After

Width:  |  Height:  |  Size: 302 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 423 B

After

Width:  |  Height:  |  Size: 423 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 422 B

After

Width:  |  Height:  |  Size: 422 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 301 B

After

Width:  |  Height:  |  Size: 301 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 299 B

After

Width:  |  Height:  |  Size: 299 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 385 B

After

Width:  |  Height:  |  Size: 385 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 383 B

After

Width:  |  Height:  |  Size: 383 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 412 B

After

Width:  |  Height:  |  Size: 412 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 402 B

After

Width:  |  Height:  |  Size: 402 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 431 B

After

Width:  |  Height:  |  Size: 431 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 429 B

After

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 407 B

After

Width:  |  Height:  |  Size: 407 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 400 B

After

Width:  |  Height:  |  Size: 400 B

Some files were not shown because too many files have changed in this diff Show More