Compare commits

..

5 Commits

Author SHA1 Message Date
Kayne Ruse 3b1841f6b7 Wrote a simple passive timer for debugging 2014-07-30 20:53:32 +10:00
Kayne Ruse b6e8b13d1b Added error checking to Vector2::Normalize() 2014-07-17 17:01:18 +10:00
Kayne Ruse a13c7cc053 Cleaned up the collision code 2014-07-10 07:10:59 +10:00
Kayne Ruse 876510bc52 The collision check is working 2014-07-09 01:01:39 +10:00
Kayne Ruse 48bf0f549d Initial commit, read more
After a few days of work, I'm committing what i've done so far. Mostly
I've cherry picked the best parts of the multiplayer branch's modules, and
adapted them for use here. I've written a few new components, and I've
learnt a few things along the way. I may continue with this branch for a
while, before moving the changes into the main branch. Alternatively, it
might turn out that this single player version is more fun. We'll see.

I've swapped the config system for a pure lua version instead. This is
actually fairly flexible. I've also changed the map system and it's API a
great deal. The tile sheet can be loaded from lua, and the save directory
isn't hard coded anymore. I think this would be a good testbed for a lot
of different systems, including the collision system, however the current
system (using vectors) is inadequate. I'll have to dig up the old BBox,
possilby.

This branch will piggy back on the main repo for a while.
2014-07-08 17:02:28 +10:00
130 changed files with 1040 additions and 6153 deletions
-21
View File
@@ -1,21 +0,0 @@
#Editor generated files
*.sln
*.vcproj
*.suo
*.ncb
*.user
#Directories
Release/
Debug/
Out/
#Project generated files
*.db
*.o
*.a
*.exe
#Shell files
*.bat
*.sh
-33
View File
@@ -1,33 +0,0 @@
The most recent stable build for Windows can be found [here](https://dl.dropboxusercontent.com/u/46669050/Tortuga.rar).
Tortuga is a 2D multiplayer JRPG featuring permadeath (deletion of a character upon death). The emphasis of this game is on multiplayer cooperation, exploration and customization. The game runs on customizable server software that can support up to 150 simultaneous players or more.
This game is inspired by classic 2D RPGs, as well as more modern sandbox MMOs. This project is currently independently created and funded, with the goal of creating a game that will engage user's imagination and inspire a large modding community.
## Documentation
Tortuga's full documentation can be found in a separate branch, see [Tortuga/docs](https://github.com/Ratstail91/Tortuga/tree/docs).
For Tortuga's primary documentation, please read the [Tortuga Game Design Document](https://github.com/Ratstail91/Tortuga/blob/docs/Tortuga%20Game%20Design%20Document.docx?raw=true).
## External Dependencies
* [SDL 1.2](http://www.libsdl.org/) - Simple DirectMedia Layer API
* [SDL_net 1.2](http://www.libsdl.org/projects/SDL_net/) - SDL's networking extension
* [lua 5.2](http://www.lua.org/) - The lua programming language
* [SQLite3](http://www.sqlite.org/) - A lightweight SQL database engine
## Copyright
(Future versions (to be determined) may be released under a modified version of the [Uplink Developer's License](http://www.introversion.co.uk/uplink/developer/license.html).)
The current version of Tortuga is released under the [zlib license](http://en.wikipedia.org/wiki/Zlib_License).
Copyright (c) 2013, 2014 Kayne Ruse
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.
-29
View File
@@ -1,29 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* 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.
*/
#ifndef CHANNELS_HPP_
#define CHANNELS_HPP_
enum Channels {
SERVER = 0
};
#endif
-64
View File
@@ -1,64 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* 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.
*/
#ifndef CLIENTAPPLICATION_HPP_
#define CLIENTAPPLICATION_HPP_
#include "scene_list.hpp"
#include "base_scene.hpp"
#include "config_utility.hpp"
#include "udp_network_utility.hpp"
#include "character_data.hpp"
#include "combat_data.hpp"
#include "enemy_data.hpp"
#include <map>
class ClientApplication {
public:
ClientApplication() = default;
~ClientApplication() = default;
void Init(int argc, char** argv);
void Proc();
void Quit();
private:
//Private access members
void LoadScene(SceneList sceneIndex);
void UnloadScene();
BaseScene* activeScene = nullptr;
//shared parameters
ConfigUtility config;
UDPNetworkUtility network;
int clientIndex = -1;
int accountIndex = -1;
int characterIndex = -1;
std::map<int, CombatData> combatMap;
std::map<int, CharacterData> characterMap;
std::map<int, EnemyData> enemyMap;
};
#endif
-232
View File
@@ -1,232 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* 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 "in_combat.hpp"
#include "channels.hpp"
#include "utility.hpp"
#include <stdexcept>
//-------------------------
//Public access members
//-------------------------
InCombat::InCombat(
ConfigUtility* const argConfig,
UDPNetworkUtility* const argNetwork,
int* const argClientIndex,
int* const argAccountIndex,
int* const argCharacterIndex,
std::map<int, CombatData>* argCombatMap,
std::map<int, CharacterData>* argCharacterMap,
std::map<int, EnemyData>* argEnemyMap
):
config(*argConfig),
network(*argNetwork),
clientIndex(*argClientIndex),
accountIndex(*argAccountIndex),
characterIndex(*argCharacterIndex),
combatMap(*argCombatMap),
characterMap(*argCharacterMap),
enemyMap(*argEnemyMap)
{
/* //setup the utility objects
buttonImage.LoadSurface(config["dir.interface"] + "button_menu.bmp");
buttonImage.SetClipH(buttonImage.GetClipH()/3);
font.LoadSurface(config["dir.fonts"] + "pk_white_8.bmp");
//pass the utility objects
backButton.SetImage(&buttonImage);
backButton.SetFont(&font);
//set the button positions
backButton.SetX(50);
backButton.SetY(50 + buttonImage.GetClipH() * 0);
//set the button texts
backButton.SetText("Back");
//request a sync
RequestSynchronize();
*/
//debug
//
}
InCombat::~InCombat() {
//
}
//-------------------------
//Frame loop
//-------------------------
void InCombat::FrameStart() {
//
}
void InCombat::Update(double delta) {
//suck in and process all waiting packets
SerialPacket* packetBuffer = static_cast<SerialPacket*>(malloc(MAX_PACKET_SIZE));
while(network.Receive(packetBuffer)) {
HandlePacket(packetBuffer);
}
free(static_cast<void*>(packetBuffer));
//TODO: more
}
void InCombat::FrameEnd() {
//
}
void InCombat::RenderFrame() {
SDL_FillRect(GetScreen(), 0, 0);
Render(GetScreen());
SDL_Flip(GetScreen());
fps.Calculate();
}
void InCombat::Render(SDL_Surface* const screen) {
//TODO: draw the background
//TODO: draw the characters
//TODO: draw the enemies
//TODO: draw the UI
}
//-------------------------
//Event handlers
//-------------------------
void InCombat::QuitEvent() {
//exit the game AND the server
RequestDisconnect();
SetNextScene(SceneList::MAINMENU);
}
void InCombat::MouseMotion(SDL_MouseMotionEvent const& motion) {
//
}
void InCombat::MouseButtonDown(SDL_MouseButtonEvent const& button) {
//
}
void InCombat::MouseButtonUp(SDL_MouseButtonEvent const& button) {
//
}
void InCombat::KeyDown(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) {
case SDLK_ESCAPE:
QuitEvent();
break;
}
}
void InCombat::KeyUp(SDL_KeyboardEvent const& key) {
//
}
//-------------------------
//Network handlers
//-------------------------
void InCombat::HandlePacket(SerialPacket* const argPacket) {
switch(argPacket->type) {
case SerialPacketType::DISCONNECT:
HandleDisconnect(argPacket);
break;
//handle errors
default:
throw(std::runtime_error(std::string() + "Unknown SerialPacketType encountered in InCombat: " + to_string_custom(static_cast<int>(argPacket->type)) ));
break;
}
}
void InCombat::HandleDisconnect(SerialPacket* const) {
SetNextScene(SceneList::RESTART);
}
//TODO: more network handlers
//-------------------------
//Server control
//-------------------------
void InCombat::RequestSynchronize() {
ClientPacket newPacket;
//request a sync
newPacket.type = SerialPacketType::SYNCHRONIZE;
newPacket.clientIndex = clientIndex;
newPacket.accountIndex = accountIndex;
network.SendTo(Channels::SERVER, &newPacket);
}
void InCombat::SendPlayerUpdate() {
CharacterPacket newPacket;
//pack the packet
newPacket.type = SerialPacketType::CHARACTER_UPDATE;
newPacket.characterIndex = characterIndex;
//handle, avatar
newPacket.accountIndex = accountIndex;
// newPacket.roomIndex = localCharacter->roomIndex;
// newPacket.origin = localCharacter->origin;
// newPacket.motion = localCharacter->motion;
// newPacket.stats = localCharacter->stats;
//TODO: equipment
//TODO: items
//TODO: buffs
//TODO: debuffs
network.SendTo(Channels::SERVER, &newPacket);
}
void InCombat::RequestDisconnect() {
ClientPacket newPacket;
//send a disconnect request
newPacket.type = SerialPacketType::DISCONNECT;
newPacket.clientIndex = clientIndex;
newPacket.accountIndex = accountIndex;
network.SendTo(Channels::SERVER, &newPacket);
}
void InCombat::RequestShutdown() {
ClientPacket newPacket;
//send a shutdown request
newPacket.type = SerialPacketType::SHUTDOWN;
newPacket.clientIndex = clientIndex;
newPacket.accountIndex = accountIndex;
network.SendTo(Channels::SERVER, &newPacket);
}
-105
View File
@@ -1,105 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* 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.
*/
#ifndef INCOMBAT_HPP_
#define INCOMBAT_HPP_
//network
#include "udp_network_utility.hpp"
//graphics
#include "image.hpp"
#include "raster_font.hpp"
#include "button.hpp"
//common
#include "config_utility.hpp"
#include "frame_rate.hpp"
#include "combat_data.hpp"
#include "character_data.hpp"
#include "enemy_data.hpp"
//client
#include "base_scene.hpp"
class InCombat : public BaseScene {
public:
//Public access members
InCombat(
ConfigUtility* const argConfig,
UDPNetworkUtility* const argNetwork,
int* const argClientIndex,
int* const argAccountIndex,
int* const argCharacterIndex,
std::map<int, CombatData>* argCombatMap,
std::map<int, CharacterData>* argCharacterMap,
std::map<int, EnemyData>* argEnemyMap
);
~InCombat();
protected:
//Frame loop
void FrameStart();
void Update(double delta);
void FrameEnd();
void RenderFrame();
void Render(SDL_Surface* const);
//Event handlers
void QuitEvent();
void MouseMotion(SDL_MouseMotionEvent const&);
void MouseButtonDown(SDL_MouseButtonEvent const&);
void MouseButtonUp(SDL_MouseButtonEvent const&);
void KeyDown(SDL_KeyboardEvent const&);
void KeyUp(SDL_KeyboardEvent const&);
//Network handlers
void HandlePacket(SerialPacket* const);
void HandleDisconnect(SerialPacket* const);
//TODO: more network handlers
//Server control
void RequestSynchronize();
void SendPlayerUpdate();
void RequestDisconnect();
void RequestShutdown();
//TODO: more
//shared parameters
ConfigUtility& config;
UDPNetworkUtility& network;
int& clientIndex;
int& accountIndex;
int& characterIndex;
std::map<int, CombatData>& combatMap;
std::map<int, CharacterData>& characterMap;
std::map<int, EnemyData>& enemyMap;
//graphics
//TODO: graphics
//UI
//TODO: UI
FrameRate fps;
};
#endif
-468
View File
@@ -1,468 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* 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 "in_world.hpp"
#include "channels.hpp"
#include "utility.hpp"
#include <algorithm>
#include <cmath>
#include <stdexcept>
//-------------------------
//Public access members
//-------------------------
InWorld::InWorld(
ConfigUtility* const argConfig,
UDPNetworkUtility* const argNetwork,
int* const argClientIndex,
int* const argAccountIndex,
int* const argCharacterIndex,
std::map<int, CombatData>* argCombatMap,
std::map<int, CharacterData>* argCharacterMap
):
config(*argConfig),
network(*argNetwork),
clientIndex(*argClientIndex),
accountIndex(*argAccountIndex),
characterIndex(*argCharacterIndex),
combatMap(*argCombatMap),
characterMap(*argCharacterMap)
{
//setup the utility objects
buttonImage.LoadSurface(config["dir.interface"] + "button_menu.bmp");
buttonImage.SetClipH(buttonImage.GetClipH()/3);
font.LoadSurface(config["dir.fonts"] + "pk_white_8.bmp");
//pass the utility objects
disconnectButton.SetImage(&buttonImage);
disconnectButton.SetFont(&font);
shutDownButton.SetImage(&buttonImage);
shutDownButton.SetFont(&font);
//set the button positions
disconnectButton.SetX(50);
disconnectButton.SetY(50 + buttonImage.GetClipH() * 0);
shutDownButton.SetX(50);
shutDownButton.SetY(50 + buttonImage.GetClipH() * 1);
//set the button texts
disconnectButton.SetText("Disconnect");
shutDownButton.SetText("Shut Down");
//load the tilesheet
//TODO: add the tilesheet to the map system?
tileSheet.Load(config["dir.tilesets"] + "terrain.bmp", 12, 15);
//request a sync
RequestSynchronize();
//debug
//
}
InWorld::~InWorld() {
//
}
//-------------------------
//Frame loop
//-------------------------
void InWorld::FrameStart() {
//
}
void InWorld::Update(double delta) {
//suck in and process all waiting packets
SerialPacket* packetBuffer = static_cast<SerialPacket*>(malloc(MAX_PACKET_SIZE));
while(network.Receive(packetBuffer)) {
HandlePacket(packetBuffer);
}
free(static_cast<void*>(packetBuffer));
//update the characters
for (auto& it : characterMap) {
it.second.Update(delta);
}
//update the camera
if(localCharacter) {
camera.x = localCharacter->origin.x - camera.marginX;
camera.y = localCharacter->origin.y - camera.marginY;
}
//check the map
UpdateMap();
}
void InWorld::FrameEnd() {
//
}
void InWorld::RenderFrame() {
// SDL_FillRect(GetScreen(), 0, 0);
Render(GetScreen());
SDL_Flip(GetScreen());
fps.Calculate();
}
void InWorld::Render(SDL_Surface* const screen) {
//draw the map
for (std::list<Region>::iterator it = regionPager.GetContainer()->begin(); it != regionPager.GetContainer()->end(); it++) {
tileSheet.DrawRegionTo(screen, &(*it), camera.x, camera.y);
}
//draw characters
for (auto& it : characterMap) {
//TODO: drawing order according to Y origin
it.second.DrawTo(screen, camera.x, camera.y);
}
//draw UI
disconnectButton.DrawTo(screen);
shutDownButton.DrawTo(screen);
font.DrawStringTo(to_string_custom(fps.GetFrameRate()), screen, 0, 0);
}
//-------------------------
//Event handlers
//-------------------------
void InWorld::QuitEvent() {
//exit the game AND the server
RequestDisconnect();
SetNextScene(SceneList::MAINMENU);
}
void InWorld::MouseMotion(SDL_MouseMotionEvent const& motion) {
disconnectButton.MouseMotion(motion);
shutDownButton.MouseMotion(motion);
}
void InWorld::MouseButtonDown(SDL_MouseButtonEvent const& button) {
disconnectButton.MouseButtonDown(button);
shutDownButton.MouseButtonDown(button);
}
void InWorld::MouseButtonUp(SDL_MouseButtonEvent const& button) {
if (disconnectButton.MouseButtonUp(button) == Button::State::HOVER) {
RequestDisconnect();
}
if (shutDownButton.MouseButtonUp(button) == Button::State::HOVER) {
RequestShutDown();
}
}
void InWorld::KeyDown(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) {
case SDLK_ESCAPE: {
QuitEvent();
}
break;
//player movement
case SDLK_LEFT:
if (localCharacter) {
localCharacter->motion.x -= CHARACTER_WALKING_SPEED;
localCharacter->CorrectSprite();
SendPlayerUpdate();
}
break;
case SDLK_RIGHT:
if (localCharacter) {
localCharacter->motion.x += CHARACTER_WALKING_SPEED;
localCharacter->CorrectSprite();
SendPlayerUpdate();
}
break;
case SDLK_UP:
if (localCharacter) {
localCharacter->motion.y -= CHARACTER_WALKING_SPEED;
localCharacter->CorrectSprite();
SendPlayerUpdate();
}
break;
case SDLK_DOWN:
if (localCharacter) {
localCharacter->motion.y += CHARACTER_WALKING_SPEED;
localCharacter->CorrectSprite();
SendPlayerUpdate();
}
break;
}
}
void InWorld::KeyUp(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) {
//player movement
case SDLK_LEFT:
if (localCharacter) {
localCharacter->motion.x += CHARACTER_WALKING_SPEED;
localCharacter->CorrectSprite();
SendPlayerUpdate();
}
break;
case SDLK_RIGHT:
if (localCharacter) {
localCharacter->motion.x -= CHARACTER_WALKING_SPEED;
localCharacter->CorrectSprite();
SendPlayerUpdate();
}
break;
case SDLK_UP:
if (localCharacter) {
localCharacter->motion.y += CHARACTER_WALKING_SPEED;
localCharacter->CorrectSprite();
SendPlayerUpdate();
}
break;
case SDLK_DOWN:
if (localCharacter) {
localCharacter->motion.y -= CHARACTER_WALKING_SPEED;
localCharacter->CorrectSprite();
SendPlayerUpdate();
}
break;
}
}
//-------------------------
//Network handlers
//-------------------------
void InWorld::HandlePacket(SerialPacket* const argPacket) {
switch(argPacket->type) {
case SerialPacketType::DISCONNECT:
HandleDisconnect(argPacket);
break;
case SerialPacketType::CHARACTER_NEW:
HandleCharacterNew(static_cast<CharacterPacket*>(argPacket));
break;
case SerialPacketType::CHARACTER_DELETE:
HandleCharacterDelete(static_cast<CharacterPacket*>(argPacket));
break;
case SerialPacketType::CHARACTER_UPDATE:
HandleCharacterUpdate(static_cast<CharacterPacket*>(argPacket));
break;
case SerialPacketType::REGION_CONTENT:
HandleRegionContent(static_cast<RegionPacket*>(argPacket));
break;
//handle errors
default:
throw(std::runtime_error(std::string() + "Unknown SerialPacketType encountered in InWorld: " + to_string_custom(static_cast<int>(argPacket->type)) ));
break;
}
}
void InWorld::HandleDisconnect(SerialPacket* const argPacket) {
SetNextScene(SceneList::RESTART);
}
void InWorld::HandleCharacterNew(CharacterPacket* const argPacket) {
if (characterMap.find(argPacket->characterIndex) != characterMap.end()) {
throw(std::runtime_error("Cannot create duplicate characters"));
}
//create the character object
CharacterData& character = characterMap[argPacket->characterIndex];
//set the members
character.handle = argPacket->handle;
character.avatar = argPacket->avatar;
character.sprite.LoadSurface(config["dir.sprites"] + character.avatar, 4, 4);
character.roomIndex = argPacket->roomIndex;
character.origin = argPacket->origin;
character.motion = argPacket->motion;
character.stats = argPacket->stats;
character.CorrectSprite();
//catch this client's player object
if (argPacket->accountIndex == accountIndex && !localCharacter) {
characterIndex = argPacket->characterIndex;
localCharacter = &character;
//setup the camera
camera.width = GetScreen()->w;
camera.height = GetScreen()->h;
//center on the player's character
camera.marginX = (GetScreen()->w / 2 - localCharacter->sprite.GetImage()->GetClipW() / 2);
camera.marginY = (GetScreen()->h / 2 - localCharacter->sprite.GetImage()->GetClipH() / 2);
}
}
void InWorld::HandleCharacterDelete(CharacterPacket* const argPacket) {
//TODO: authenticate when own character is being deleted (linked to a TODO in the server)
//catch this client's player object
if (argPacket->characterIndex == characterIndex) {
characterIndex = -1;
localCharacter = nullptr;
}
characterMap.erase(argPacket->characterIndex);
}
void InWorld::HandleCharacterUpdate(CharacterPacket* const argPacket) {
if (characterMap.find(argPacket->characterIndex) == characterMap.end()) {
HandleCharacterNew(argPacket);
return;
}
CharacterData& character = characterMap[argPacket->characterIndex];
//other characters moving
if (argPacket->characterIndex != characterIndex) {
character.roomIndex = argPacket->roomIndex;
character.origin = argPacket->origin;
character.motion = argPacket->motion;
character.CorrectSprite();
}
}
void InWorld::HandleRegionContent(RegionPacket* const argPacket) {
//replace existing regions
regionPager.UnloadRegion(argPacket->x, argPacket->y);
regionPager.PushRegion(argPacket->region);
//clean up after the serial code
delete argPacket->region;
argPacket->region = nullptr;
}
//-------------------------
//Server control
//-------------------------
void InWorld::RequestSynchronize() {
ClientPacket newPacket;
//request a sync
newPacket.type = SerialPacketType::SYNCHRONIZE;
newPacket.clientIndex = clientIndex;
newPacket.accountIndex = accountIndex;
network.SendTo(Channels::SERVER, &newPacket);
}
void InWorld::SendPlayerUpdate() {
CharacterPacket newPacket;
//pack the packet
newPacket.type = SerialPacketType::CHARACTER_UPDATE;
newPacket.characterIndex = characterIndex;
//handle, avatar
newPacket.accountIndex = accountIndex;
newPacket.roomIndex = localCharacter->roomIndex;
newPacket.origin = localCharacter->origin;
newPacket.motion = localCharacter->motion;
newPacket.stats = localCharacter->stats;
//TODO: equipment
//TODO: items
//TODO: buffs
//TODO: debuffs
network.SendTo(Channels::SERVER, &newPacket);
}
void InWorld::RequestDisconnect() {
ClientPacket newPacket;
//send a disconnect request
newPacket.type = SerialPacketType::DISCONNECT;
newPacket.clientIndex = clientIndex;
newPacket.accountIndex = accountIndex;
network.SendTo(Channels::SERVER, &newPacket);
}
void InWorld::RequestShutDown() {
ClientPacket newPacket;
//send a shutdown request
newPacket.type = SerialPacketType::SHUTDOWN;
newPacket.clientIndex = clientIndex;
newPacket.accountIndex = accountIndex;
network.SendTo(Channels::SERVER, &newPacket);
}
void InWorld::RequestRegion(int roomIndex, int x, int y) {
RegionPacket packet;
//pack the region's data
packet.type = SerialPacketType::REGION_REQUEST;
packet.roomIndex = roomIndex;
packet.x = x;
packet.y = y;
network.SendTo(Channels::SERVER, &packet);
}
//-------------------------
//Utilities
//-------------------------
//TODO: convert this into a more generic function?; using parameters for the bounds
void InWorld::UpdateMap() {
//these represent the zone of regions that the client needs loaded, including the mandatory buffers (+1/-1)
int xStart = snapToBase(REGION_WIDTH, camera.x/tileSheet.GetTileW()) - REGION_WIDTH;
int xEnd = snapToBase(REGION_WIDTH, (camera.x+camera.width)/tileSheet.GetTileW()) + REGION_WIDTH;
int yStart = snapToBase(REGION_HEIGHT, camera.y/tileSheet.GetTileH()) - REGION_HEIGHT;
int yEnd = snapToBase(REGION_HEIGHT, (camera.y+camera.height)/tileSheet.GetTileH()) + REGION_HEIGHT;
//prune distant regions
for (std::list<Region>::iterator it = regionPager.GetContainer()->begin(); it != regionPager.GetContainer()->end(); /* EMPTY */) {
//check if the region is outside off this area
if (it->GetX() < xStart || it->GetX() > xEnd || it->GetY() < yStart || it->GetY() > yEnd) {
//clunky, but the alternative was time consuming
int tmpX = it->GetX();
int tmpY = it->GetY();
++it;
regionPager.UnloadRegion(tmpX, tmpY);
continue;
}
++it;
}
//request empty regions within this zone
for (int i = xStart; i <= xEnd; i += REGION_WIDTH) {
for (int j = yStart; j <= yEnd; j += REGION_HEIGHT) {
if (!regionPager.FindRegion(i, j)) {
RequestRegion(0, i, j);
}
}
}
}
-130
View File
@@ -1,130 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* 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.
*/
#ifndef INWORLD_HPP_
#define INWORLD_HPP_
//maps
#include "region_pager_base.hpp"
//networking
#include "udp_network_utility.hpp"
//graphics
#include "image.hpp"
#include "raster_font.hpp"
#include "button.hpp"
#include "tile_sheet.hpp"
//common
#include "config_utility.hpp"
#include "frame_rate.hpp"
#include "combat_data.hpp"
#include "character_data.hpp"
//client
#include "base_scene.hpp"
//STL
#include <map>
class InWorld : public BaseScene {
public:
//Public access members
InWorld(
ConfigUtility* const argConfig,
UDPNetworkUtility* const argNetwork,
int* const argClientIndex,
int* const argAccountIndex,
int* const argCharacterIndex,
std::map<int, CombatData>* argCombatMap,
std::map<int, CharacterData>* argCharacterMap
);
~InWorld();
protected:
//Frame loop
void FrameStart();
void Update(double delta);
void FrameEnd();
void RenderFrame();
void Render(SDL_Surface* const);
//Event handlers
void QuitEvent();
void MouseMotion(SDL_MouseMotionEvent const&);
void MouseButtonDown(SDL_MouseButtonEvent const&);
void MouseButtonUp(SDL_MouseButtonEvent const&);
void KeyDown(SDL_KeyboardEvent const&);
void KeyUp(SDL_KeyboardEvent const&);
//Network handlers
void HandlePacket(SerialPacket* const);
void HandleDisconnect(SerialPacket* const);
void HandleCharacterNew(CharacterPacket* const);
void HandleCharacterDelete(CharacterPacket* const);
void HandleCharacterUpdate(CharacterPacket* const);
void HandleRegionContent(RegionPacket* const);
//Server control
void RequestSynchronize();
void SendPlayerUpdate();
void RequestDisconnect();
void RequestShutDown();
void RequestRegion(int roomIndex, int x, int y);
//utilities
void UpdateMap();
//shared parameters
ConfigUtility& config;
UDPNetworkUtility& network;
int& clientIndex;
int& accountIndex;
int& characterIndex;
std::map<int, CombatData>& combatMap;
std::map<int, CharacterData>& characterMap;
//graphics
Image buttonImage;
RasterFont font;
TileSheet tileSheet;
//map
RegionPagerBase regionPager;
//UI
Button disconnectButton;
Button shutDownButton;
//TODO: Review the camera
struct {
int x = 0, y = 0;
int width = 0, height = 0;
int marginX = 0, marginY = 0;
} camera;
FrameRate fps;
//game
CharacterData* localCharacter = nullptr;
};
#endif
-248
View File
@@ -1,248 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* 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 "lobby_menu.hpp"
#include "channels.hpp"
#include "utility.hpp"
#include <stdexcept>
//-------------------------
//Public access members
//-------------------------
LobbyMenu::LobbyMenu(
ConfigUtility* const argConfig,
UDPNetworkUtility* const argNetwork,
int* const argClientIndex,
int* const argAccountIndex
):
config(*argConfig),
network(*argNetwork),
clientIndex(*argClientIndex),
accountIndex(*argAccountIndex)
{
//setup the utility objects
image.LoadSurface(config["dir.interface"] + "button_menu.bmp");
image.SetClipH(image.GetClipH()/3);
font.LoadSurface(config["dir.fonts"] + "pk_white_8.bmp");
//pass the utility objects
search.SetImage(&image);
search.SetFont(&font);
join.SetImage(&image);
join.SetFont(&font);
back.SetImage(&image);
back.SetFont(&font);
//set the button positions
search.SetX(50);
search.SetY(50 + image.GetClipH() * 0);
join.SetX(50);
join.SetY(50 + image.GetClipH() * 1);
back.SetX(50);
back.SetY(50 + image.GetClipH() * 2);
//set the button texts
search.SetText("Search");
join.SetText("Join");
back.SetText("Back");
//set the server list's position
listBox = {300, 50, 200, font.GetCharH()};
}
LobbyMenu::~LobbyMenu() {
//
}
//-------------------------
//Frame loop
//-------------------------
void LobbyMenu::FrameStart() {
//
}
void LobbyMenu::Update(double delta) {
//suck in and process all waiting packets
SerialPacket* packetBuffer = static_cast<SerialPacket*>(malloc(MAX_PACKET_SIZE));
while(network.Receive(packetBuffer)) {
HandlePacket(packetBuffer);
}
free(static_cast<void*>(packetBuffer));
}
void LobbyMenu::FrameEnd() {
//
}
void LobbyMenu::Render(SDL_Surface* const screen) {
//TODO: I need a proper UI system for the entire client and the editor
//UI
search.DrawTo(screen);
join.DrawTo(screen);
back.DrawTo(screen);
//TODO: draw headers for the server list
for (int i = 0; i < serverInfo.size(); i++) {
//draw the selected server's highlight
if (selection == &serverInfo[i]) {
SDL_Rect r = listBox;
r.y += i * listBox.h;
SDL_FillRect(screen, &r, SDL_MapRGB(screen->format, 255, 127, 39));
}
//draw the server name
font.DrawStringTo(serverInfo[i].name, screen, listBox.x, listBox.y + i*listBox.h);
//draw the player count
font.DrawStringTo(to_string_custom(serverInfo[i].playerCount), screen, listBox.x + listBox.w, listBox.y + i*listBox.h);
//compatible?
if (!serverInfo[i].compatible) {
font.DrawStringTo("?", screen, listBox.x - font.GetCharW(), listBox.y + i*listBox.h);
}
//TODO: ping/delay?
}
}
//-------------------------
//Event handlers
//-------------------------
void LobbyMenu::MouseMotion(SDL_MouseMotionEvent const& motion) {
search.MouseMotion(motion);
join.MouseMotion(motion);
back.MouseMotion(motion);
}
void LobbyMenu::MouseButtonDown(SDL_MouseButtonEvent const& button) {
search.MouseButtonDown(button);
join.MouseButtonDown(button);
back.MouseButtonDown(button);
}
void LobbyMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) {
if (search.MouseButtonUp(button) == Button::State::HOVER) {
//broadcast to the network, or a specific server
SerialPacket packet;
packet.type = SerialPacketType::BROADCAST_REQUEST;
network.SendTo(config["server.host"].c_str(), config.Int("server.port"), &packet);
//reset the server list
serverInfo.clear();
selection = nullptr;
}
else if (join.MouseButtonUp(button) == Button::State::HOVER && selection != nullptr && selection->compatible) {
//pack the packet
ClientPacket packet;
packet.type = SerialPacketType::JOIN_REQUEST;
strncpy(packet.username, config["client.username"].c_str(), PACKET_STRING_SIZE);
//join the selected server
network.SendTo(&selection->address, &packet);
selection = nullptr;
}
else if (back.MouseButtonUp(button) == Button::State::HOVER) {
SetNextScene(SceneList::MAINMENU);
}
else if (
//has the user selected a server on the list?
//TODO: replace with regular collision checker
button.x > listBox.x &&
button.x < listBox.x + listBox.w &&
button.y > listBox.y &&
button.y < listBox.y + listBox.h * serverInfo.size()
) {
selection = &serverInfo[(button.y - listBox.y)/listBox.h];
}
else {
selection = nullptr;
}
}
void LobbyMenu::KeyDown(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) {
case SDLK_ESCAPE:
SetNextScene(SceneList::MAINMENU);
break;
}
}
void LobbyMenu::KeyUp(SDL_KeyboardEvent const& key) {
//
}
//-------------------------
//Network handlers
//-------------------------
void LobbyMenu::HandlePacket(SerialPacket* const argPacket) {
switch(argPacket->type) {
case SerialPacketType::BROADCAST_RESPONSE:
HandleBroadcastResponse(static_cast<ServerPacket*>(argPacket));
break;
case SerialPacketType::JOIN_RESPONSE:
HandleJoinResponse(static_cast<ClientPacket*>(argPacket));
break;
//handle errors
default:
throw(std::runtime_error(std::string() + "Unknown SerialPacketType encountered in LobbyMenu: " + to_string_custom(static_cast<int>(argPacket->type)) ));
break;
}
}
void LobbyMenu::HandleBroadcastResponse(ServerPacket* const argPacket) {
//extract the data
ServerInformation server;
server.address = argPacket->srcAddress;
server.name = argPacket->name;
server.playerCount = argPacket->playerCount;
server.version = argPacket->version;
//NOTE: Check compatibility here
server.compatible = server.version == NETWORK_VERSION;
//push
serverInfo.push_back(server);
}
void LobbyMenu::HandleJoinResponse(ClientPacket* const argPacket) {
clientIndex = argPacket->clientIndex;
accountIndex = argPacket->accountIndex;
network.Bind(&argPacket->srcAddress, Channels::SERVER);
SetNextScene(SceneList::INWORLD);
//send this player's character info
CharacterPacket newPacket;
newPacket.type = SerialPacketType::CHARACTER_NEW;
strncpy(newPacket.handle, config["client.handle"].c_str(), PACKET_STRING_SIZE);
strncpy(newPacket.avatar, config["client.avatar"].c_str(), PACKET_STRING_SIZE);
newPacket.accountIndex = accountIndex;
network.SendTo(Channels::SERVER, &newPacket);
}
-100
View File
@@ -1,100 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* 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.
*/
#ifndef LOBBYMENU_HPP_
#define LOBBYMENU_HPP_
//graphics & ui
#include "image.hpp"
#include "raster_font.hpp"
#include "button.hpp"
//utilities
#include "config_utility.hpp"
#include "udp_network_utility.hpp"
//client
#include "base_scene.hpp"
//STL
#include <vector>
class LobbyMenu : public BaseScene {
public:
//Public access members
LobbyMenu(
ConfigUtility* const argConfig,
UDPNetworkUtility* const argNetwork,
int* const argClientIndex,
int* const argAccountIndex
);
~LobbyMenu();
protected:
//Frame loop
void FrameStart();
void Update(double delta);
void FrameEnd();
void Render(SDL_Surface* const);
//Event handlers
void MouseMotion(SDL_MouseMotionEvent const&);
void MouseButtonDown(SDL_MouseButtonEvent const&);
void MouseButtonUp(SDL_MouseButtonEvent const&);
void KeyDown(SDL_KeyboardEvent const&);
void KeyUp(SDL_KeyboardEvent const&);
//Network handlers
void HandlePacket(SerialPacket* const);
void HandleBroadcastResponse(ServerPacket* const);
void HandleJoinResponse(ClientPacket* const);
//shared parameters
ConfigUtility& config;
UDPNetworkUtility& network;
int& clientIndex;
int& accountIndex;
//members
Image image;
RasterFont font;
Button search;
Button join;
Button back;
//server list
struct ServerInformation {
IPaddress address;
std::string name;
int playerCount;
int version;
bool compatible;
};
std::vector<ServerInformation> serverInfo;
//a terrible hack, forgive me
//I'd love a proper gui system for this
SDL_Rect listBox;
ServerInformation* selection = nullptr;
};
#endif
-37
View File
@@ -1,37 +0,0 @@
#config
INCLUDES+=. ../common/gameplay ../common/graphics ../common/map ../common/network ../common/network/packet ../common/network/serial ../common/ui ../common/utilities
LIBS+=../libcommon.a -lSDL_net -lwsock32 -liphlpapi -lmingw32 -lSDLmain -lSDL -llua
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) -DGRAPHICS
#source
CXXSRC=$(wildcard *.cpp)
#objects
OBJDIR=obj
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
#output
OUTDIR=../out
OUT=$(addprefix $(OUTDIR)/,client)
#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:
$(RM) *.o *.a *.exe
rebuild: clean all
-142
View File
@@ -1,142 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* 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 "restart.hpp"
#include "channels.hpp"
#include <stdexcept>
//-------------------------
//Public access members
//-------------------------
Restart::Restart(
ConfigUtility* const argConfig,
UDPNetworkUtility* const argNetwork,
int* const argClientIndex,
int* const argAccountIndex,
int* const argCharacterIndex,
std::map<int, CombatData>* argCombatMap,
std::map<int, CharacterData>* argCharacterMap,
std::map<int, EnemyData>* argEnemyMap
):
config(*argConfig),
network(*argNetwork),
clientIndex(*argClientIndex),
accountIndex(*argAccountIndex),
characterIndex(*argCharacterIndex),
combatMap(*argCombatMap),
characterMap(*argCharacterMap),
enemyMap(*argEnemyMap)
{
//setup the utility objects
image.LoadSurface(config["dir.interface"] + "button_menu.bmp");
image.SetClipH(image.GetClipH()/3);
font.LoadSurface(config["dir.fonts"] + "pk_white_8.bmp");
//pass the utility objects
backButton.SetImage(&image);
backButton.SetFont(&font);
//set the button positions
backButton.SetX(50);
backButton.SetY(50 + image.GetClipH() * 0);
//set the button texts
backButton.SetText("Back");
//full reset
network.Unbind(Channels::SERVER);
clientIndex = -1;
accountIndex = -1;
characterIndex = -1;
combatMap.clear();
characterMap.clear();
enemyMap.clear();
//auto return
startTick = std::chrono::steady_clock::now();
}
Restart::~Restart() {
//
}
//-------------------------
//Frame loop
//-------------------------
void Restart::Update(double delta) {
if (std::chrono::steady_clock::now() - startTick > std::chrono::duration<int>(10)) {
QuitEvent();
}
while(network.Receive()) {
//EAT INCOMING PACKETS
}
}
void Restart::RenderFrame() {
SDL_FillRect(GetScreen(), 0, 0);
Render(GetScreen());
SDL_Flip(GetScreen());
fps.Calculate();
}
void Restart::Render(SDL_Surface* const screen) {
backButton.DrawTo(screen);
font.DrawStringTo("You have been disconnected.", screen, 50, 30);
}
//-------------------------
//Event handlers
//-------------------------
void Restart::QuitEvent() {
SetNextScene(SceneList::MAINMENU);
}
void Restart::MouseMotion(SDL_MouseMotionEvent const& motion) {
backButton.MouseMotion(motion);
}
void Restart::MouseButtonDown(SDL_MouseButtonEvent const& button) {
backButton.MouseButtonDown(button);
}
void Restart::MouseButtonUp(SDL_MouseButtonEvent const& button) {
if (backButton.MouseButtonUp(button) == Button::State::HOVER) {
QuitEvent();
}
}
void Restart::KeyDown(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) {
case SDLK_ESCAPE:
QuitEvent();
break;
}
}
void Restart::KeyUp(SDL_KeyboardEvent const& key) {
//
}
-70
View File
@@ -1,70 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* 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.
*/
#ifndef COMBATDATA_HPP_
#define COMBATDATA_HPP_
#include "vector2.hpp"
//gameplay members
#include "character_data.hpp"
#include "enemy_data.hpp"
//graphics
#ifdef GRAPHICS
#include "sprite_sheet.hpp"
#endif
//std namespace
#include <chrono>
#include <array>
#include <utility>
#define COMBAT_MAX_CHARACTERS 12
#define COMBAT_MAX_ENEMIES 12
struct CombatData {
enum class Terrain {
//TODO: types of combat terrains
NONE = 0,
GRASSLANDS,
};
typedef std::chrono::steady_clock Clock;
std::array<CharacterData, COMBAT_MAX_CHARACTERS> characterArray;
std::array<EnemyData, COMBAT_MAX_ENEMIES> enemyArray;
//world interaction
int mapIndex = 0;
Vector2 origin = {0.0,0.0};
Vector2 bounds = {0.0,0.0};
//time interval
Clock::time_point lastTick = Clock::now();
//graphics
#ifdef GRAPHICS
SpriteSheet sprite;
#endif
};
#endif
-62
View File
@@ -1,62 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* 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.
*/
#ifndef ENEMYDATA_HPP_
#define ENEMYDATA_HPP_
#include "vector2.hpp"
#include "statistics.hpp"
//graphics
#ifdef GRAPHICS
#include "sprite_sheet.hpp"
#endif
//std namespace
#include <string>
struct EnemyData {
//metadata
std::string handle;
std::string avatar;
//gameplay
Statistics stats;
//TODO: equipment
//TODO: items
//TODO: buffs
//TODO: debuffs
//TODO: rewards
//active gameplay members
//NOTE: these are lost when unloaded
#ifdef GRAPHICS
SpriteSheet sprite;
Vector2 origin = {0.0,0.0};
Vector2 bounds = {0.0,0.0};
#endif
int tableIndex;
int atbGauge = 0;
};
#endif
-37
View File
@@ -1,37 +0,0 @@
#config
INCLUDES+=. ../utilities ../graphics
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) -DGRAPHICS
#source
CXXSRC=$(wildcard *.cpp)
#objects
OBJDIR=obj
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
#output
OUTDIR=../..
OUT=$(addprefix $(OUTDIR)/,libcommon.a)
#targets
all: $(OBJ) $(OUT)
ar -crs $(OUT) $(OBJ)
$(OBJ): | $(OBJDIR)
$(OUT): | $(OUTDIR)
$(OBJDIR):
mkdir $(OBJDIR)
$(OUTDIR):
mkdir $(OUTDIR)
$(OBJDIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
clean:
$(RM) *.o *.a *.exe
rebuild: clean all
-31
View File
@@ -1,31 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* 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 "character_data.hpp"
#include "combat_data.hpp"
#include "enemy_data.hpp"
#include "statistics.hpp"
/* DOCS: Sanity check, read more
* Since most/all of the files in this directory are header files, I've created
* this source file as a "sanity check", to ensure that the above header files
* are written correctly via make.
*/
-42
View File
@@ -1,42 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* 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.
*/
#ifndef STATISTICS_HPP_
#define STATISTICS_HPP_
struct Statistics {
int level = 0;
int exp = 0;
int maxHP = 0;
int health = 0;
int maxMP = 0;
int mana = 0;
int attack = 0;
int defence = 0;
int intelligence = 0;
int resistance = 0;
int speed = 0;
float accuracy = 0.0;
float evasion = 0.0;
float luck = 0.0;
};
#endif
-12
View File
@@ -1,12 +0,0 @@
all:
$(MAKE) -C gameplay
$(MAKE) -C graphics
$(MAKE) -C map
$(MAKE) -C network
$(MAKE) -C ui
$(MAKE) -C utilities
clean:
$(RM) *.o *.a *.exe
rebuild: clean all
-39
View File
@@ -1,39 +0,0 @@
#config
INCLUDES+=. packet serial ../gameplay ../map ../utilities
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
#source
CXXSRC=$(wildcard *.cpp)
#objects
OBJDIR=obj
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
#output
OUTDIR=../..
OUT=$(addprefix $(OUTDIR)/,libcommon.a)
#targets
all: $(OBJ) $(OUT)
ar -crs $(OUT) $(OBJ)
$(MAKE) -C packet
$(MAKE) -C serial
$(OBJ): | $(OBJDIR)
$(OUT): | $(OUTDIR)
$(OBJDIR):
mkdir $(OBJDIR)
$(OUTDIR):
mkdir $(OUTDIR)
$(OBJDIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
clean:
$(RM) *.o *.a *.exe
rebuild: clean all
@@ -1,53 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* 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.
*/
#ifndef CHARACTERPACKET_HPP_
#define CHARACTERPACKET_HPP_
#include "serial_packet_base.hpp"
#include "vector2.hpp"
#include "statistics.hpp"
struct CharacterPacket : SerialPacketBase {
//identify the character
int characterIndex;
char handle[PACKET_STRING_SIZE];
char avatar[PACKET_STRING_SIZE];
//the owner
int accountIndex;
//location
int roomIndex;
Vector2 origin;
Vector2 motion;
//gameplay
Statistics stats;
//TODO: equipment
//TODO: items
//TODO: buffs
//TODO: debuffs
};
#endif
-34
View File
@@ -1,34 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* 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.
*/
#ifndef CLIENTPACKET_HPP_
#define CLIENTPACKET_HPP_
#include "serial_packet_base.hpp"
struct ClientPacket : SerialPacketBase {
int clientIndex;
int accountIndex;
char username[PACKET_STRING_SIZE];
// char password[PACKET_STRING_SIZE]; //hashed, not currently used
};
#endif
-44
View File
@@ -1,44 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* 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.
*/
#ifndef ENEMYPACKET_HPP_
#define ENEMYPACKET_HPP_
#include "serial_packet_base.hpp"
struct EnemyPacket : SerialPacketBase {
//identify the enemy
int enemyIndex;
char handle[PACKET_STRING_SIZE];
char avatar[PACKET_STRING_SIZE];
//gameplay
Statistics stats;
//TODO: equipment
//TODO: items
//TODO: buffs
//TODO: debuffs
//TODO: rewards
};
#endif
-37
View File
@@ -1,37 +0,0 @@
#config
INCLUDES+=. ../../gameplay ../../map ../../utilities
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
#source
CXXSRC=$(wildcard *.cpp)
#objects
OBJDIR=obj
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
#output
OUTDIR=../../..
OUT=$(addprefix $(OUTDIR)/,libcommon.a)
#targets
all: $(OBJ) $(OUT)
ar -crs $(OUT) $(OBJ)
$(OBJ): | $(OBJDIR)
$(OUT): | $(OUTDIR)
$(OBJDIR):
mkdir $(OBJDIR)
$(OUTDIR):
mkdir $(OUTDIR)
$(OBJDIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
clean:
$(RM) *.o *.a *.exe
rebuild: clean all
-38
View File
@@ -1,38 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* 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.
*/
#ifndef REGIONPACKET_HPP_
#define REGIONPACKET_HPP_
#include "serial_packet_base.hpp"
#include "region.hpp"
struct RegionPacket : SerialPacketBase {
//location/identify the region
int roomIndex;
int x, y;
//the data
Region* region;
};
#endif
-28
View File
@@ -1,28 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* 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 "serial_packet.hpp"
/* DOCS: Sanity check, read more
* Since most/all of the files in this directory are header files, I've created
* this source file as a "sanity check", to ensure that the above header files
* are written correctly via make.
*/
-44
View File
@@ -1,44 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* 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.
*/
#ifndef SERIALPACKET_HPP_
#define SERIALPACKET_HPP_
#include "character_packet.hpp"
#include "client_packet.hpp"
#include "combat_packet.hpp"
#include "enemy_packet.hpp"
#include "region_packet.hpp"
#include "server_packet.hpp"
//NOTE: SerialPacket is defined in serial_packet_base.hpp
union MaxPacket {
CharacterPacket a;
ClientPacket b;
CombatPacket c;
EnemyPacket d;
RegionPacket e;
ServerPacket f;
};
constexpr int MAX_PACKET_SIZE = sizeof(MaxPacket);
#endif
@@ -1,46 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* 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.
*/
#ifndef SERIALPACKETBASE_HPP_
#define SERIALPACKETBASE_HPP_
#ifndef SERIALPACKET_HPP_
#error Cannot include this file without 'serial_packet.hpp'
#endif
#include "serial_packet_type.hpp"
#include "SDL/SDL_net.h"
constexpr int NETWORK_VERSION = 20140607;
constexpr int PACKET_STRING_SIZE = 100;
struct SerialPacketBase {
//members
SerialPacketType type;
IPaddress srcAddress;
virtual ~SerialPacketBase() {};
};
typedef SerialPacketBase SerialPacket;
#endif
@@ -1,113 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* 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.
*/
#ifndef SERIALPACKETTYPE_HPP_
#define SERIALPACKETTYPE_HPP_
/* Key for the comments:
* request => response
*/
enum class SerialPacketType {
//default: there is something wrong
NONE = 0,
//keep alive
//ping => pong
PING = 1,
PONG = 2,
//search for the server list
//none => server name, player count, version info (and source address)
BROADCAST_REQUEST = 3,
BROADCAST_RESPONSE = 4,
//try to join the server
//username, and password => client index, account index
JOIN_REQUEST = 5,
JOIN_RESPONSE = 6,
JOIN_REJECTION = 7,
//mass update of all surrounding content
//character.x, character.y => packet barrage
SYNCHRONIZE = 8,
//disconnect from the server
//autentication, account index => disconnect that account
DISCONNECT = 9,
//shut down the server
//autentication => disconnect, shutdown
SHUTDOWN = 10,
//map data
//room index, region.x, region.y => room index, region.x, region.y, region content
REGION_REQUEST = 11,
REGION_CONTENT = 12,
//combat data
//TODO: system incomplete
COMBAT_NEW = 13,
COMBAT_DELETE = 14,
COMBAT_UPDATE = 15,
COMBAT_ENTER_REQUEST = 16,
COMBAT_ENTER_RESPONSE = 17,
COMBAT_EXIT_REQUEST = 18,
COMBAT_EXIT_RESPONSE = 19,
//TODO: COMBAT info
COMBAT_REJECTION = 20,
//character data
//character data => etc.
CHARACTER_NEW = 21,
CHARACTER_DELETE = 22,
CHARACTER_UPDATE = 23,
//authentication, character index => character stats
CHARACTER_STATS_REQUEST= 24,
CHARACTER_STATS_RESPONSE = 25,
//character new => character rejection, disconnect?
CHARACTER_REJECTION = 26,
//enemy data
//enemy data => etc.
ENEMY_NEW = 27,
ENEMY_DELETE = 28,
ENEMY_UPDATE = 29,
ENEMY_STATS_REQUEST = 30,
ENEMY_STATS_RESPONSE = 31,
//enemy index => enemy doens't exist
ENEMY_REJECTION= 32,
//NOTE: more packet types go here
//not used
LAST
};
#endif
-34
View File
@@ -1,34 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* 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.
*/
#ifndef SERVERPACKET_HPP_
#define SERVERPACKET_HPP_
#include "serial_packet_base.hpp"
struct ServerPacket : SerialPacketBase {
//identify the server
char name[PACKET_STRING_SIZE];
int playerCount;
int version;
};
#endif
-37
View File
@@ -1,37 +0,0 @@
#config
INCLUDES+=. ../packet ../../gameplay ../../map ../../utilities
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
#source
CXXSRC=$(wildcard *.cpp)
#objects
OBJDIR=obj
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
#output
OUTDIR=../../..
OUT=$(addprefix $(OUTDIR)/,libcommon.a)
#targets
all: $(OBJ) $(OUT)
ar -crs $(OUT) $(OBJ)
$(OBJ): | $(OBJDIR)
$(OUT): | $(OUTDIR)
$(OBJDIR):
mkdir $(OBJDIR)
$(OUTDIR):
mkdir $(OUTDIR)
$(OBJDIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
clean:
$(RM) *.o *.a *.exe
rebuild: clean all
-183
View File
@@ -1,183 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* 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 "serial.hpp"
#include "serial_util.hpp"
//simple type functions
void serializeType(SerialPacketBase* packet, void* buffer) {
SERIALIZE(buffer, &packet->type, sizeof(SerialPacketType));
}
void deserializeType(SerialPacketBase* packet, void* buffer) {
DESERIALIZE(buffer, &packet->type, sizeof(SerialPacketType));
}
//main switch functions
void serializePacket(SerialPacketBase* packet, void* buffer) {
switch(packet->type) {
//no extra data
case SerialPacketType::NONE:
case SerialPacketType::PING:
case SerialPacketType::PONG:
case SerialPacketType::BROADCAST_REQUEST:
//all rejections
case SerialPacketType::JOIN_REJECTION:
case SerialPacketType::CHARACTER_REJECTION:
case SerialPacketType::ENEMY_REJECTION:
case SerialPacketType::COMBAT_REJECTION:
serializeType(packet, buffer);
break;
//character info
case SerialPacketType::CHARACTER_NEW:
case SerialPacketType::CHARACTER_DELETE:
case SerialPacketType::CHARACTER_UPDATE:
case SerialPacketType::CHARACTER_STATS_REQUEST:
case SerialPacketType::CHARACTER_STATS_RESPONSE:
serializeCharacter(static_cast<CharacterPacket*>(packet), buffer);
break;
//client info
case SerialPacketType::JOIN_REQUEST:
case SerialPacketType::JOIN_RESPONSE:
case SerialPacketType::SYNCHRONIZE:
case SerialPacketType::DISCONNECT:
case SerialPacketType::SHUTDOWN:
serializeClient(static_cast<ClientPacket*>(packet), buffer);
break;
//combat info
case SerialPacketType::COMBAT_NEW:
case SerialPacketType::COMBAT_DELETE:
case SerialPacketType::COMBAT_UPDATE:
case SerialPacketType::COMBAT_ENTER_REQUEST:
case SerialPacketType::COMBAT_ENTER_RESPONSE:
case SerialPacketType::COMBAT_EXIT_REQUEST:
case SerialPacketType::COMBAT_EXIT_RESPONSE:
serializeCombat(static_cast<CombatPacket*>(packet), buffer);
break;
//enemy info
case SerialPacketType::ENEMY_NEW:
case SerialPacketType::ENEMY_DELETE:
case SerialPacketType::ENEMY_UPDATE:
case SerialPacketType::ENEMY_STATS_REQUEST:
case SerialPacketType::ENEMY_STATS_RESPONSE:
serializeEnemy(static_cast<EnemyPacket*>(packet), buffer);
break;
//region info
case SerialPacketType::REGION_REQUEST:
serializeRegionFormat(static_cast<RegionPacket*>(packet), buffer);
break;
case SerialPacketType::REGION_CONTENT:
serializeRegionContent(static_cast<RegionPacket*>(packet), buffer);
break;
//server info
case SerialPacketType::BROADCAST_RESPONSE:
serializeServer(static_cast<ServerPacket*>(packet), buffer);
break;
}
}
void deserializePacket(SerialPacketBase* packet, void* buffer) {
//find the type, so that you can actually deserialize the packet!
deserializeType(packet, buffer);
switch(packet->type) {
//no extra data
case SerialPacketType::NONE:
case SerialPacketType::PING:
case SerialPacketType::PONG:
case SerialPacketType::BROADCAST_REQUEST:
//all rejections
case SerialPacketType::JOIN_REJECTION:
case SerialPacketType::CHARACTER_REJECTION:
case SerialPacketType::ENEMY_REJECTION:
case SerialPacketType::COMBAT_REJECTION:
//NOTHING
break;
//character info
case SerialPacketType::CHARACTER_NEW:
case SerialPacketType::CHARACTER_DELETE:
case SerialPacketType::CHARACTER_UPDATE:
case SerialPacketType::CHARACTER_STATS_REQUEST:
case SerialPacketType::CHARACTER_STATS_RESPONSE:
deserializeCharacter(static_cast<CharacterPacket*>(packet), buffer);
break;
//client info
case SerialPacketType::JOIN_REQUEST:
case SerialPacketType::JOIN_RESPONSE:
case SerialPacketType::SYNCHRONIZE:
case SerialPacketType::DISCONNECT:
case SerialPacketType::SHUTDOWN:
deserializeClient(static_cast<ClientPacket*>(packet), buffer);
break;
//combat info
case SerialPacketType::COMBAT_NEW:
case SerialPacketType::COMBAT_DELETE:
case SerialPacketType::COMBAT_UPDATE:
//TODO: is this the best fit?
case SerialPacketType::COMBAT_ENTER_REQUEST:
case SerialPacketType::COMBAT_ENTER_RESPONSE:
case SerialPacketType::COMBAT_EXIT_REQUEST:
case SerialPacketType::COMBAT_EXIT_RESPONSE:
serializeCombat(static_cast<CombatPacket*>(packet), buffer);
break;
//enemy info
case SerialPacketType::ENEMY_NEW:
case SerialPacketType::ENEMY_DELETE:
case SerialPacketType::ENEMY_UPDATE:
case SerialPacketType::ENEMY_STATS_REQUEST:
case SerialPacketType::ENEMY_STATS_RESPONSE:
serializeEnemy(static_cast<EnemyPacket*>(packet), buffer);
break;
//region info
case SerialPacketType::REGION_REQUEST:
deserializeRegionFormat(static_cast<RegionPacket*>(packet), buffer);
break;
case SerialPacketType::REGION_CONTENT:
deserializeRegionContent(static_cast<RegionPacket*>(packet), buffer);
break;
//server info
case SerialPacketType::BROADCAST_RESPONSE:
deserializeServer(static_cast<ServerPacket*>(packet), buffer);
break;
}
}
-65
View File
@@ -1,65 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* 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.
*/
#ifndef SERIALIZE_HPP_
#define SERIALIZE_HPP_
#include "serial_packet.hpp"
#include "region.hpp"
#include "statistics.hpp"
//Primary interface functions
void serializePacket(SerialPacketBase*, void* dest);
void deserializePacket(SerialPacketBase*, void* src);
void serializeType(SerialPacketBase*, void*);
void deserializeType(SerialPacketBase*, void*);
//utility functions, exposed
void serializeCharacter(CharacterPacket*, void*);
void serializeClient(ClientPacket*, void*);
void serializeCombat(CombatPacket*, void*);
void serializeEnemy(EnemyPacket*, void*);
void serializeRegionFormat(RegionPacket*, void*);
void serializeRegionContent(RegionPacket*, void*);
void serializeServer(ServerPacket*, void*);
void serializeStatistics(Statistics*, void*);
void deserializeCharacter(CharacterPacket*, void*);
void deserializeClient(ClientPacket*, void*);
void deserializeCombat(CombatPacket*, void*);
void deserializeEnemy(EnemyPacket*, void*);
void deserializeRegionFormat(RegionPacket*, void*);
void deserializeRegionContent(RegionPacket*, void*);
void deserializeServer(ServerPacket*, void*);
void deserializeStatistics(Statistics*, void*);
/* DOCS: Keep the PACKET_BUFFER_SIZE up to date
* DOCS: REGION_CONTENT is currently the largest type of packet, read more
* map content: REGION_WIDTH * REGION_HEIGHT * REGION_DEPTH * sizoeof(region::type_t)
* map format: sizeof(int) * 3
* metadata: sizeof(SerialPacket::Type)
*/
constexpr int PACKET_BUFFER_SIZE = REGION_WIDTH * REGION_HEIGHT * REGION_DEPTH * sizeof(Region::type_t) + sizeof(int) * 3 + sizeof(SerialPacketType);
#endif
@@ -1,80 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* 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 "serial.hpp"
#include "serial_util.hpp"
void serializeCharacter(CharacterPacket* packet, void* buffer) {
SERIALIZE(buffer, &packet->type, sizeof(SerialPacketType));
//identify the character
SERIALIZE(buffer, &packet->characterIndex, sizeof(int));
SERIALIZE(buffer, &packet->handle, PACKET_STRING_SIZE);
SERIALIZE(buffer, &packet->avatar, PACKET_STRING_SIZE);
//the owner
SERIALIZE(buffer, &packet->accountIndex, sizeof(int));
//location
SERIALIZE(buffer, &packet->roomIndex, sizeof(int));
SERIALIZE(buffer, &packet->origin.x, sizeof(double));
SERIALIZE(buffer, &packet->origin.y, sizeof(double));
SERIALIZE(buffer, &packet->motion.x, sizeof(double));
SERIALIZE(buffer, &packet->motion.y, sizeof(double));
//stats structure
serializeStatistics(&packet->stats, buffer);
buffer = reinterpret_cast<char*>(buffer) + sizeof(Statistics);
//TODO: equipment
//TODO: items
//TODO: buffs
//TODO: debuffs
}
void deserializeCharacter(CharacterPacket* packet, void* buffer) {
DESERIALIZE(buffer, &packet->type, sizeof(SerialPacketType));
//identify the character
DESERIALIZE(buffer, &packet->characterIndex, sizeof(int));
DESERIALIZE(buffer, &packet->handle, PACKET_STRING_SIZE);
DESERIALIZE(buffer, &packet->avatar, PACKET_STRING_SIZE);
//the owner
DESERIALIZE(buffer, &packet->accountIndex, sizeof(int));
//location
DESERIALIZE(buffer, &packet->roomIndex, sizeof(int));
DESERIALIZE(buffer, &packet->origin.x, sizeof(double));
DESERIALIZE(buffer, &packet->origin.y, sizeof(double));
DESERIALIZE(buffer, &packet->motion.x, sizeof(double));
DESERIALIZE(buffer, &packet->motion.y, sizeof(double));
//stats structure
deserializeStatistics(&packet->stats, buffer);
buffer = reinterpret_cast<char*>(buffer) + sizeof(Statistics);
//TODO: equipment
//TODO: items
//TODO: buffs
//TODO: debuffs
}
-42
View File
@@ -1,42 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* 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 "serial.hpp"
#include "serial_util.hpp"
void serializeClient(ClientPacket* packet, void* buffer) {
SERIALIZE(buffer, &packet->type, sizeof(SerialPacketType));
SERIALIZE(buffer, &packet->clientIndex, sizeof(int));
SERIALIZE(buffer, &packet->accountIndex, sizeof(int));
SERIALIZE(buffer, &packet->username, PACKET_STRING_SIZE);
// SERIALIZE(buffer, &packet->password, PACKET_STRING_SIZE);
}
void deserializeClient(ClientPacket* packet, void* buffer) {
DESERIALIZE(buffer, &packet->type, sizeof(SerialPacketType));
DESERIALIZE(buffer, &packet->clientIndex, sizeof(int));
DESERIALIZE(buffer, &packet->accountIndex, sizeof(int));
DESERIALIZE(buffer, &packet->username, PACKET_STRING_SIZE);
// DESERIALIZE(buffer, &packet->password, PACKET_STRING_SIZE);
}
-64
View File
@@ -1,64 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* 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 "serial.hpp"
#include "serial_util.hpp"
void serializeCombat(CombatPacket* packet, void* buffer) {
SERIALIZE(buffer, &packet->type, sizeof(SerialPacketType));
//identify the combat instance
SERIALIZE(buffer, &packet->combatIndex, sizeof(int));
SERIALIZE(buffer, &packet->difficulty, sizeof(int));
SERIALIZE(buffer, &packet->terrainType, sizeof(CombatData::Terrain));
//combatants
SERIALIZE(buffer, &packet->characterArray, sizeof(int) * COMBAT_MAX_CHARACTERS);
SERIALIZE(buffer, &packet->enemyArray, sizeof(int) * COMBAT_MAX_ENEMIES);
//location
SERIALIZE(buffer, &packet->mapIndex, sizeof(int));
SERIALIZE(buffer, &packet->origin.x, sizeof(double));
SERIALIZE(buffer, &packet->origin.y, sizeof(double));
//TODO: rewards
}
void deserializeCombat(CombatPacket* packet, void* buffer) {
DESERIALIZE(buffer, &packet->type, sizeof(SerialPacketType));
//identify the combat instance
DESERIALIZE(buffer, &packet->combatIndex, sizeof(int));
DESERIALIZE(buffer, &packet->difficulty, sizeof(int));
DESERIALIZE(buffer, &packet->terrainType, sizeof(CombatData::Terrain));
//combatants
DESERIALIZE(buffer, &packet->characterArray, sizeof(int) * COMBAT_MAX_CHARACTERS);
DESERIALIZE(buffer, &packet->enemyArray, sizeof(int) * COMBAT_MAX_ENEMIES);
//location
DESERIALIZE(buffer, &packet->mapIndex, sizeof(int));
DESERIALIZE(buffer, &packet->origin.x, sizeof(double));
DESERIALIZE(buffer, &packet->origin.y, sizeof(double));
//TODO: rewards
}
-66
View File
@@ -1,66 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* 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 "serial.hpp"
#include "serial_util.hpp"
void serializeEnemy(EnemyPacket* packet, void* buffer) {
SERIALIZE(buffer, &packet->type, sizeof(SerialPacketType));
//identify the enemy
SERIALIZE(buffer, &packet->enemyIndex, sizeof(int));
SERIALIZE(buffer, &packet->handle, PACKET_STRING_SIZE);
SERIALIZE(buffer, &packet->avatar, PACKET_STRING_SIZE);
//gameplay
//stats structure
serializeStatistics(&packet->stats, buffer);
buffer = reinterpret_cast<char*>(buffer) + sizeof(Statistics);
//TODO: equipment
//TODO: items
//TODO: buffs
//TODO: debuffs
//TODO: rewards
}
void deserializeEnemy(EnemyPacket* packet, void* buffer) {
DESERIALIZE(buffer, &packet->type, sizeof(SerialPacketType));
//identify the enemy
DESERIALIZE(buffer, &packet->enemyIndex, sizeof(int));
DESERIALIZE(buffer, &packet->handle, PACKET_STRING_SIZE);
DESERIALIZE(buffer, &packet->avatar, PACKET_STRING_SIZE);
//stats structure
deserializeStatistics(&packet->stats, buffer);
buffer = reinterpret_cast<char*>(buffer) + sizeof(Statistics);
//TODO: equipment
//TODO: items
//TODO: buffs
//TODO: debuffs
//TODO: rewards
}
-83
View File
@@ -1,83 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* 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 "serial.hpp"
#include "serial_util.hpp"
void serializeRegionFormat(RegionPacket* packet, void* buffer) {
SERIALIZE(buffer, &packet->type, sizeof(SerialPacketType));
//format
SERIALIZE(buffer, &packet->roomIndex, sizeof(int));
SERIALIZE(buffer, &packet->x, sizeof(int));
SERIALIZE(buffer, &packet->y, sizeof(int));
}
void serializeRegionContent(RegionPacket* packet, void* buffer) {
SERIALIZE(buffer, &packet->type, sizeof(SerialPacketType));
//format
SERIALIZE(buffer, &packet->roomIndex, sizeof(int));
SERIALIZE(buffer, &packet->x, sizeof(int));
SERIALIZE(buffer, &packet->y, sizeof(int));
//content
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++) {
*reinterpret_cast<Region::type_t*>(buffer) = packet->region->GetTile(i, j, k);
buffer = reinterpret_cast<char*>(buffer) + sizeof(Region::type_t);
}
}
}
}
void deserializeRegionFormat(RegionPacket* packet, void* buffer) {
DESERIALIZE(buffer, &packet->type, sizeof(SerialPacketType));
//format
DESERIALIZE(buffer, &packet->roomIndex, sizeof(int));
DESERIALIZE(buffer, &packet->x, sizeof(int));
DESERIALIZE(buffer, &packet->y, sizeof(int));
}
void deserializeRegionContent(RegionPacket* packet, void* buffer) {
DESERIALIZE(buffer, &packet->type, sizeof(SerialPacketType));
//format
DESERIALIZE(buffer, &packet->roomIndex, sizeof(int));
DESERIALIZE(buffer, &packet->x, sizeof(int));
DESERIALIZE(buffer, &packet->y, sizeof(int));
//an object to work on
packet->region = new Region(packet->x, packet->y);
//content
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++) {
packet->region->SetTile(i, j, k, *reinterpret_cast<Region::type_t*>(buffer));
buffer = reinterpret_cast<char*>(buffer) + sizeof(Region::type_t);
}
}
}
}
-42
View File
@@ -1,42 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* 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 "serial.hpp"
#include "serial_util.hpp"
void serializeServer(ServerPacket* packet, void* buffer) {
SERIALIZE(buffer, &packet->type, sizeof(SerialPacketType));
//identify the server
SERIALIZE(buffer, &packet->name, PACKET_STRING_SIZE);
SERIALIZE(buffer, &packet->playerCount, sizeof(int));
SERIALIZE(buffer, &packet->version, sizeof(int));
}
void deserializeServer(ServerPacket* packet, void* buffer) {
DESERIALIZE(buffer, &packet->type, sizeof(SerialPacketType));
//identify the server
DESERIALIZE(buffer, &packet->name, PACKET_STRING_SIZE);
DESERIALIZE(buffer, &packet->playerCount, sizeof(int));
DESERIALIZE(buffer, &packet->version, sizeof(int));
}
@@ -1,65 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* 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 "serial.hpp"
#include "serial_util.hpp"
void serializeStatistics(Statistics* stats, void* buffer) {
//integers
SERIALIZE(buffer, &stats->level, sizeof(int));
SERIALIZE(buffer, &stats->exp, sizeof(int));
SERIALIZE(buffer, &stats->maxHP, sizeof(int));
SERIALIZE(buffer, &stats->health, sizeof(int));
SERIALIZE(buffer, &stats->maxMP, sizeof(int));
SERIALIZE(buffer, &stats->mana, sizeof(int));
SERIALIZE(buffer, &stats->attack, sizeof(int));
SERIALIZE(buffer, &stats->defence, sizeof(int));
SERIALIZE(buffer, &stats->intelligence, sizeof(int));
SERIALIZE(buffer, &stats->resistance, sizeof(int));
SERIALIZE(buffer, &stats->speed, sizeof(int));
//floats
SERIALIZE(buffer, &stats->accuracy, sizeof(float));
SERIALIZE(buffer, &stats->evasion, sizeof(float));
SERIALIZE(buffer, &stats->luck, sizeof(float));
}
void deserializeStatistics(Statistics* stats, void* buffer) {
//integers
DESERIALIZE(buffer, &stats->level, sizeof(int));
DESERIALIZE(buffer, &stats->exp, sizeof(int));
DESERIALIZE(buffer, &stats->maxHP, sizeof(int));
DESERIALIZE(buffer, &stats->health, sizeof(int));
DESERIALIZE(buffer, &stats->maxMP, sizeof(int));
DESERIALIZE(buffer, &stats->mana, sizeof(int));
DESERIALIZE(buffer, &stats->attack, sizeof(int));
DESERIALIZE(buffer, &stats->defence, sizeof(int));
DESERIALIZE(buffer, &stats->intelligence, sizeof(int));
DESERIALIZE(buffer, &stats->resistance, sizeof(int));
DESERIALIZE(buffer, &stats->speed, sizeof(int));
//floats
DESERIALIZE(buffer, &stats->accuracy, sizeof(float));
DESERIALIZE(buffer, &stats->evasion, sizeof(float));
DESERIALIZE(buffer, &stats->luck, sizeof(float));
}
-31
View File
@@ -1,31 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* 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.
*/
#ifndef SERIALIZEUTIL_HPP_
#define SERIALIZEUTIL_HPP_
#include <cstring>
//NOTE: The strange assignments here used in order to move the void* parameter
#define SERIALIZE(buffer, data, size) memcpy(buffer, data, size); buffer = reinterpret_cast<char*>(buffer) + size;
#define DESERIALIZE(buffer, data, size) memcpy(data, buffer, size); buffer = reinterpret_cast<char*>(buffer) + size;
#endif
-224
View File
@@ -1,224 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* 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 "udp_network_utility.hpp"
#include "serial.hpp"
#include <stdexcept>
//DOCS: memset() is used before sending a packet to remove old data; you don't want to send sensitive data over the network
//NOTE: don't confuse SerialPacket with UDPpacket
void UDPNetworkUtility::Open(int port) {
socket = SDLNet_UDP_Open(port);
packet = SDLNet_AllocPacket(PACKET_BUFFER_SIZE);
if (!socket || !packet) {
Close();
throw(std::runtime_error("Failed to open UDPNetworkUtility"));
}
}
void UDPNetworkUtility::Close() {
SDLNet_UDP_Close(socket);
SDLNet_FreePacket(packet);
socket = nullptr;
packet = nullptr;
}
//-------------------------
//bind to a channel
//-------------------------
int UDPNetworkUtility::Bind(const char* ip, int port, int channel) {
IPaddress add;
if (SDLNet_ResolveHost(&add, ip, port) == -1) {
throw(std::runtime_error("Failed to resolve a host"));
}
return Bind(&add, channel);
}
int UDPNetworkUtility::Bind(IPaddress* add, int channel) {
int ret = SDLNet_UDP_Bind(socket, channel, add);
if (ret < 0) {
throw(std::runtime_error("Failed to bind to a channel"));
}
return ret;
}
void UDPNetworkUtility::Unbind(int channel) {
SDLNet_UDP_Unbind(socket, channel);
}
//-------------------------
//send a buffer
//-------------------------
int UDPNetworkUtility::SendTo(const char* ip, int port, void* data, int len) {
IPaddress add;
if (SDLNet_ResolveHost(&add, ip, port) == -1) {
throw(std::runtime_error("Failed to resolve a host"));
}
SendTo(&add, data, len);
}
int UDPNetworkUtility::SendTo(IPaddress* add, void* data, int len) {
if (len > packet->maxlen) {
throw(std::runtime_error("The buffer is to large for the UDPpacket"));
}
memset(packet->data, 0, packet->maxlen);
memcpy(packet->data, data, len);
packet->len = len;
packet->address = *add;
int ret = SDLNet_UDP_Send(socket, -1, packet);
if (ret <= 0) {
throw(std::runtime_error("Failed to send a packet"));
}
return ret;
}
int UDPNetworkUtility::SendTo(int channel, void* data, int len) {
if (len > packet->maxlen) {
throw(std::runtime_error("The buffer is to large for the UDPpacket"));
}
memset(packet->data, 0, packet->maxlen);
memcpy(packet->data, data, len);
packet->len = len;
int ret = SDLNet_UDP_Send(socket, channel, packet);
if (ret <= 0) {
throw(std::runtime_error("Failed to send a packet"));
}
return ret;
}
int UDPNetworkUtility::SendToAllChannels(void* data, int len) {
if (len > packet->maxlen) {
throw(std::runtime_error("The buffer is to large for the UDPpacket"));
}
memset(packet->data, 0, packet->maxlen);
memcpy(packet->data, data, len);
packet->len = len;
int sent = 0;
//send to all bound channels
for (int i = 0; i < SDLNET_MAX_UDPCHANNELS; i++) {
if (SDLNet_UDP_GetPeerAddress(socket, i)) {
sent += SDLNet_UDP_Send(socket, i, packet);
}
}
return sent;
}
//TODO: put a void* and int* parameter list here
int UDPNetworkUtility::Receive() {
memset(packet->data, 0, packet->maxlen);
int ret = SDLNet_UDP_Recv(socket, packet);
if (ret < 0) {
throw(std::runtime_error("Unknown network error occured"));
}
return ret;
}
//-------------------------
//send a SerialPacket
//-------------------------
int UDPNetworkUtility::SendTo(const char* ip, int port, SerialPacket* serialPacket) {
IPaddress add;
if (SDLNet_ResolveHost(&add, ip, port) == -1) {
throw(std::runtime_error("Failed to resolve a host"));
}
SendTo(&add, serialPacket);
}
int UDPNetworkUtility::SendTo(IPaddress* add, SerialPacket* serialPacket) {
memset(packet->data, 0, packet->maxlen);
serializePacket(serialPacket, packet->data);
packet->len = PACKET_BUFFER_SIZE;
packet->address = *add;
int ret = SDLNet_UDP_Send(socket, -1, packet);
if (ret <= 0) {
throw(std::runtime_error("Failed to send a packet"));
}
return ret;
}
int UDPNetworkUtility::SendTo(int channel, SerialPacket* serialPacket) {
memset(packet->data, 0, packet->maxlen);
serializePacket(serialPacket, packet->data);
packet->len = PACKET_BUFFER_SIZE;
int ret = SDLNet_UDP_Send(socket, channel, packet);
if (ret <= 0) {
throw(std::runtime_error("Failed to send a packet"));
}
return ret;
}
int UDPNetworkUtility::SendToAllChannels(SerialPacket* serialPacket) {
memset(packet->data, 0, packet->maxlen);
serializePacket(serialPacket, packet->data);
packet->len = PACKET_BUFFER_SIZE;
int sent = 0;
//send to all bound channels
for (int i = 0; i < SDLNET_MAX_UDPCHANNELS; i++) {
if (SDLNet_UDP_GetPeerAddress(socket, i)) {
sent += SDLNet_UDP_Send(socket, i, packet);
}
}
return sent;
}
int UDPNetworkUtility::Receive(SerialPacket* serialPacket) {
memset(packet->data, 0, packet->maxlen);
int ret = SDLNet_UDP_Recv(socket, packet);
deserializePacket(serialPacket, packet->data);
serialPacket->srcAddress = packet->address;
if (ret < 0) {
throw(std::runtime_error("Unknown network error occured"));
}
return ret;
}
-72
View File
@@ -1,72 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* 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.
*/
#ifndef UDPNETWORKUTILITY_HPP_
#define UDPNETWORKUTILITY_HPP_
#include "SDL/SDL_net.h"
#include "serial_packet.hpp"
class UDPNetworkUtility {
public:
UDPNetworkUtility() = default;
~UDPNetworkUtility() = default;
void Open(int port);
void Close();
//bind to a channel
int Bind(const char* ip, int port, int channel = -1);
int Bind(IPaddress* add, int channel = -1);
void Unbind(int channel);
IPaddress* GetIPAddress(int channel) {
return SDLNet_UDP_GetPeerAddress(socket, channel);
}
//send a buffer
int SendTo(const char* ip, int port, void* data, int len);
int SendTo(IPaddress* add, void* data, int len);
int SendTo(int channel, void* data, int len);
int SendToAllChannels(void* data, int len);
int Receive();
//send a SerialPacket
int SendTo(const char* ip, int port, SerialPacket* serialPacket);
int SendTo(IPaddress* add, SerialPacket* serialPacket);
int SendTo(int channel, SerialPacket* serialPacket);
int SendToAllChannels(SerialPacket* serialPacket);
int Receive(SerialPacket* serialPacket);
//accessors
UDPpacket* GetPacket() const {
return packet;
}
UDPsocket GetSocket() const {
return socket;
}
private:
UDPsocket socket = nullptr;
UDPpacket* packet = nullptr;
};
#endif
-40
View File
@@ -1,40 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* 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 "check_bounds.hpp"
bool checkPoint(Vector2 const& origin, Vector2 const& bound, Vector2 const& point) {
return !(
point.x < origin.x ||
point.y < origin.y ||
point.x >= origin.x + bound.x ||
point.y >= origin.y + bound.y
);
}
bool checkOverlap(Vector2 const& originOne, Vector2 const& boundOne, Vector2 const& originTwo, Vector2 const& boundTwo) {
return !(
originOne.x >= originTwo.x + boundTwo.x ||
originOne.x + boundOne.x >= originTwo.x ||
originOne.y >= originTwo.y + boundTwo.y ||
originOne.y + boundOne.y >= originTwo.y
);
}
-30
View File
@@ -1,30 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* 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.
*/
#ifndef CHECKBOUNDS_HPP_
#define CHECKBOUNDS_HPP_
#include "vector2.hpp"
bool checkPoint(Vector2 const& origin, Vector2 const& bound, Vector2 const& point);
bool checkOverlap(Vector2 const& originOne, Vector2 const& boundOne, Vector2 const& originTwo, Vector2 const& boundTwo);
#endif
-105
View File
@@ -1,105 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* 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 "config_utility.hpp"
#include <cstdlib>
#include <fstream>
#include <stdexcept>
using namespace std;
void ConfigUtility::Load(string fname) {
ifstream is(fname);
if (!is.is_open()) {
throw(runtime_error("Failed to open config file"));
}
string key, val;
for (;;) { //forever
//eat whitespace
while(isspace(is.peek()))
is.ignore();
//end of file
if (is.eof())
break;
//skip comment lines
if (is.peek() == '#') {
while(is.peek() != '\n' && !is.eof()) {
is.ignore();
}
continue;
}
//read in the pair
getline(is, key,'=');
getline(is, val);
//trim the strings at the start & end
while(key.size() && isspace(*key.begin())) key.erase(0, 1);
while(val.size() && isspace(*val.begin())) val.erase(0, 1);
while(key.size() && isspace(*(key.end()-1))) key.erase(key.end() - 1);
while(val.size() && isspace(*(val.end()-1))) val.erase(val.end() - 1);
//allow empty/wiped values
if (key.size() == 0) {
continue;
}
//save the pair
table[key] = val;
}
is.close();
}
std::string& ConfigUtility::String(std::string s) {
return table[s];
}
int ConfigUtility::Integer(std::string s) {
std::map<std::string, std::string>::iterator it = table.find(s);
if (it == table.end()) {
return 0;
}
return atoi(it->second.c_str());
}
double ConfigUtility::Double(std::string s) {
std::map<std::string, std::string>::iterator it = table.find(s);
if (it == table.end()) {
return 0.0;
}
return atof(it->second.c_str());
}
bool ConfigUtility::Boolean(std::string s) {
std::map<std::string, std::string>::iterator it = table.find(s);
if (it == table.end()) {
return false;
}
return it->second == "true";
}
-60
View File
@@ -1,60 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* 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.
*/
#ifndef CONFIGUTILITY_HPP_
#define CONFIGUTILITY_HPP_
#include <map>
#include <string>
class ConfigUtility {
public:
ConfigUtility() = default;
ConfigUtility(std::string s) { Load(s); }
void Load(std::string fname);
//convert to a type
std::string& String(std::string);
int Integer(std::string);
double Double(std::string);
bool Boolean(std::string);
//shorthand
std::string& operator[](std::string s) {
return String(s);
}
int Int(std::string s) {
return Integer(s);
}
bool Bool(std::string s) {
return Boolean(s);
}
//OO breaker
std::map<std::string, std::string>* GetMap() {
return &table;
}
private:
std::map<std::string, std::string> table;
};
#endif
-50
View File
@@ -1,50 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* 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 "sql_utility.hpp"
#include "utility.hpp"
#include <stdexcept>
#include <fstream>
#include <cstdlib>
int runSQLScript(sqlite3* db, std::string fname, int (*callback)(void*,int,char**,char**), void* argPtr) {
//load the file into a string
std::ifstream is(fname);
if (!is.is_open()) {
return -1;
}
std::string script;
getline(is, script, '\0');
is.close();
//run the SQL loaded from the file
char* errmsg = nullptr;
int ret = sqlite3_exec(db, script.c_str(), callback, argPtr, &errmsg);
if (ret != SQLITE_OK) {
//handle any errors received from the SQL
std::runtime_error e(std::string() + "SQL Script Error " + to_string_custom(ret) + ": " + errmsg);
free(errmsg);
throw(e);
}
return ret;
}
-31
View File
@@ -1,31 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* 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.
*/
#ifndef SERVERUTILITY_HPP_
#define SERVERUTILITY_HPP_
#include "sqlite3/sqlite3.h"
#include <string>
int runSQLScript(sqlite3* db, std::string fname, int (*callback)(void*,int,char**,char**) = nullptr, void* argPtr = nullptr);
#endif
+4 -5
View File
@@ -3,16 +3,15 @@
#MKDIR=mkdir
#RM=del /y
CXXFLAGS+=-static-libgcc -static-libstdc++
#CXXFLAGS+=-static-libgcc -static-libstdc++ -g -fno-inline-functions -Wall
#CXXFLAGS+=-static-libgcc -static-libstdc++
export
#export
OUTDIR=out
all: $(OUTDIR)
$(MAKE) -C common
$(MAKE) -C server
$(MAKE) -C client
$(MAKE) -C src
$(OUTDIR):
mkdir $(OUTDIR)
+3
View File
@@ -0,0 +1,3 @@
--reroute the program while in development
config = {debug = true}
dofile("../rsc/setup.lua")
-29
View File
@@ -1,29 +0,0 @@
#configuration of the programs
#server specific settings
server.host = 255.255.255.255
server.port = 21795
server.name = local
server.dbname = database.db
#client specific settings
client.screen.f = false
client.username = Kayne Ruse
client.handle = Ratstail91
client.avatar = elliot2.bmp
#directories
dir.fonts = rsc/graphics/fonts/
dir.logos = rsc/graphics/logos/
dir.sprites = rsc/graphics/sprites/
dir.tilesets = rsc/graphics/tilesets/
dir.interface = rsc/graphics/interface/
dir.scripts = rsc/scripts/
dir.maps = rsc/maps/
#map system
map.savename = servermap
#debugging
+9
View File
@@ -0,0 +1,9 @@
--overwriting the existing hard coded methods
function Region.Load(region)
--the return value signals if this succeeded or failed
return false
end
function Region.Save(region)
--
end
+16
View File
@@ -0,0 +1,16 @@
--uber lazy declarations
function math.sqr(x) return x*x end
function math.dist(x, y, i, j) return math.sqrt(math.sqr(x-i) + math.sqr(y-j)) end
--define these
function Region.Create(region)
for i = 1, Region.GetWidth() do
for j = 1, Region.GetHeight() do
Region.SetTile(region, i, j, 1, 1) --to show the basics are working
end
end
end
function Region.Unload(region)
--
end
+33
View File
@@ -0,0 +1,33 @@
local sheet = TileSheet.GetTileSheet()
local pager = RegionPager.GetRegionPager()
--the selected tilesheet
TileSheet.Load(sheet, config.dir.tilesets .. "terrain.bmp", 32, 32)
--tile macros, mapped to this tilesheet
local base = 14
local shift = 36
tiles = {
plains = base + shift * 0,
grass = base + shift * 1,
dirt = base + shift * 2,
sand = base + shift * 3,
water = base + shift * 4
}
--could set custom generation systems here, that differ from the global generators, etc.
function Region.Create(region)
for i = 1, Region.GetWidth() do
for j = 1, Region.GetHeight() do
local dist = math.dist(0, 0, i + Region.GetX(region) -1, j + Region.GetY(region) -1)
if dist < 10 then
Region.SetTile(region, i, j, 1, tiles.plains)
elseif dist < 12 then
Region.SetTile(region, i, j, 1, tiles.sand)
else
Region.SetTile(region, i, j, 1, tiles.water)
Region.SetSolid(region, i, j, true)
end
end
end
end
-20
View File
@@ -1,20 +0,0 @@
print("Lua script check (./rsc)")
-------------------------
--Map API overrides
-------------------------
function region.create(r)
for i = 1, region.getwidth() do
for j = 1, region.getheight() do
if math.abs(region.getx(r) + i -1) == math.abs(region.gety(r) + j -1) then
region.settile(r, i, j, 1, 50)
else
region.settile(r, i, j, 1, 14)
end
end
end
--signal
region.settile(r, 4, 5, 2, 86)
end
-68
View File
@@ -1,68 +0,0 @@
--TODO: why is the database setup script scripted, while accessing, etc. hardcoded?
--there should be a way to control the database more directly
--TODO: move this script into a hardocded Init() method?
CREATE TABLE IF NOT EXISTS Accounts (
uid INTEGER PRIMARY KEY AUTOINCREMENT,
username varchar(100) UNIQUE,
--TODO: server-client security
-- password varchar(100),
blacklisted BIT DEFAULT 0,
whitelisted BIT DEFAULT 1,
mod BIT DEFAULT 0,
admin BIT DEFAULT 0
);
CREATE TABLE IF NOT EXISTS Characters (
uid INTEGER PRIMARY KEY AUTOINCREMENT,
--metadata
owner INTEGER REFERENCES Accounts(uid),
handle varchar(100) UNIQUE,
avatar varchar(100),
birth timestamp NOT NULL DEFAULT (datetime()),
--position
roomIndex INTEGER DEFAULT 0,
originX INTEGER DEFAULT 0,
originY INTEGER DEFAULT 0,
--statistics
level INTEGER DEFAULT 0,
exp INTEGER DEFAULT 0,
maxHP INTEGER DEFAULT 0,
health INTEGER DEFAULT 0,
maxMP INTEGER DEFAULT 0,
mana INTEGER DEFAULT 0,
attack INTEGER DEFAULT 0,
defence INTEGER DEFAULT 0,
intelligence INTEGER DEFAULT 0,
resistance INTEGER DEFAULT 0,
speed INTEGER DEFAULT 0,
accuracy REAL DEFAULT 0.0,
evasion REAL DEFAULT 0.0,
luck REAL DEFAULT 0.0,
--equipment
weapon INTEGER REFERENCES WornEquipment(uid),
helmet INTEGER REFERENCES WornEquipment(uid),
armour INTEGER REFERENCES WornEquipment(uid)
--etc.
);
CREATE TABLE IF NOT EXISTS InventoryItems (
--metadata
uid INTEGER PRIMARY KEY AUTOINCREMENT,
itemID INTEGER, --type
stackSize INTEGER DEFAULT 0,
owner INTEGER REFERENCES Characters(uid)
);
CREATE TABLE IF NOT EXISTS WornEquipment (
--metadata
uid INTEGER PRIMARY KEY AUTOINCREMENT,
itemID INTEGER, --type
owner INTEGER REFERENCES Characters(uid)
--hold all equipment info
--stat mods, special effects, etc.
);
+42
View File
@@ -0,0 +1,42 @@
--[[
--reroute the program while in development
config = {debug = true}
dofile("../rsc/setup.lua")
--]]
--catch the debug signal if the program was rerouted
local debug = false
if config ~= nil then
debug = config.debug
end
--the program's configuration
config = {
debug = debug,
screen = {
width = 800,
height = 600,
fullscreen = false
},
dir = {
fonts = "rsc/graphics/fonts/",
logos = "rsc/graphics/logos/",
sprites = "rsc/graphics/sprites/",
tilesets = "rsc/graphics/tilesets/",
interface = "rsc/graphics/interface/",
scripts = "rsc/scripts/",
maps = "rsc/maps/"
},
mapname = "mapname"
}
--development environment
if config.debug then
for k, v in pairs(config.dir) do
config.dir[k] = string.format("../%s", v)
end
end
--"load" the scripted systems
dofile(config.dir.scripts .. "file_format.lua")
dofile(config.dir.scripts .. "generator.lua")
-38
View File
@@ -1,38 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* 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.
*/
#ifndef ACCOUNTDATA_HPP_
#define ACCOUNTDATA_HPP_
#include <string>
struct AccountData {
std::string username;
//TODO: password
bool blackListed = false;
bool whiteListed = true;
bool mod = false;
bool admin = false;
int clientIndex;
};
#endif
-226
View File
@@ -1,226 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* 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 "account_manager.hpp"
#include <stdexcept>
//-------------------------
//Define the queries
//-------------------------
static const char* CREATE_USER_ACCOUNT = "INSERT INTO Accounts (username) VALUES (?);";
static const char* LOAD_USER_ACCOUNT = "SELECT * FROM Accounts WHERE username = ?;";
static const char* SAVE_USER_ACCOUNT = "UPDATE OR FAIL Accounts SET blacklisted = ?2, whitelisted = ?3, mod = ?4, admin = ?5 WHERE uid = ?1;";
static const char* DELETE_USER_ACCOUNT = "DELETE FROM Accounts WHERE uid = ?;";
//-------------------------
//Define the public methods
//-------------------------
int AccountManager::CreateAccount(std::string username, int clientIndex) {
//create this user account, failing if it exists, leave this account in memory
sqlite3_stmt* statement = nullptr;
//prep
if (sqlite3_prepare_v2(database, CREATE_USER_ACCOUNT, -1, &statement, nullptr) != SQLITE_OK) {
throw( std::runtime_error(std::string() + "Failed to prepare an SQL statement: " + sqlite3_errmsg(database)) );
}
//parameter
if (sqlite3_bind_text(statement, 1, username.c_str(), username.size() + 1, SQLITE_STATIC) != SQLITE_OK) {
throw( std::runtime_error(std::string() + "Failed to replace a prepared statement's parameter: " + sqlite3_errmsg(database)) );
}
//execute
if (sqlite3_step(statement) != SQLITE_DONE) {
//if this fails, than this account exists
sqlite3_finalize(statement);
return -1;
}
sqlite3_finalize(statement);
//load this account into memory
return LoadAccount(username, clientIndex);
}
int AccountManager::LoadAccount(std::string username, int clientIndex) {
//load this user account, failing if it is in memory, creating it if it doesn't exist
sqlite3_stmt* statement = nullptr;
//prep
if (sqlite3_prepare_v2(database, LOAD_USER_ACCOUNT, -1, &statement, nullptr) != SQLITE_OK) {
throw( std::runtime_error(std::string() + "Failed to prepare an SQL statement: " + sqlite3_errmsg(database)) );
}
//parameter
if (sqlite3_bind_text(statement, 1, username.c_str(), username.size() + 1, SQLITE_STATIC) != SQLITE_OK) {
throw( std::runtime_error(std::string() + "Failed to replace a prepared statement's parameter: " + sqlite3_errmsg(database)) );
}
//execute
int ret = sqlite3_step(statement);
//process the result
if (ret == SQLITE_ROW) {
//get the index
int uid = sqlite3_column_int(statement, 0);
//check to see if this account is already loaded
if (accountMap.find(uid) != accountMap.end()) {
sqlite3_finalize(statement);
return -1;
}
//extract the data into memory
AccountData& newAccount = accountMap[uid];
newAccount.username = reinterpret_cast<const char*>(sqlite3_column_text(statement, 1));
newAccount.blackListed = sqlite3_column_int(statement, 2);
newAccount.whiteListed = sqlite3_column_int(statement, 3);
newAccount.mod = sqlite3_column_int(statement, 4);
newAccount.admin = sqlite3_column_int(statement, 5);
newAccount.clientIndex = clientIndex;
//finish the routine
sqlite3_finalize(statement);
return uid;
}
sqlite3_finalize(statement);
if (ret == SQLITE_DONE) {
//create the non-existant account instead
return CreateAccount(username, clientIndex);
}
throw(std::runtime_error(std::string() + "Unknown SQL error in LoadAccount: " + sqlite3_errmsg(database) ));
}
int AccountManager::SaveAccount(int uid) {
//save this user account from memory, replacing it if it exists in the database
//DOCS: To use this method, change the in-memory copy, and then call this function using that object's UID.
//this method fails if this account is not loaded
if (accountMap.find(uid) == accountMap.end()) {
return -1;
}
AccountData& account = accountMap[uid];
sqlite3_stmt* statement = nullptr;
//prep
if (sqlite3_prepare_v2(database, SAVE_USER_ACCOUNT, -1, &statement, nullptr) != SQLITE_OK) {
throw( std::runtime_error(std::string() + "Failed to prepare an SQL statement: " + sqlite3_errmsg(database)) );
}
//parameters
bool ret = false;
ret |= sqlite3_bind_int(statement, 1, uid) != SQLITE_OK;
ret |= sqlite3_bind_int(statement, 2, account.blackListed) != SQLITE_OK;
ret |= sqlite3_bind_int(statement, 3, account.whiteListed) != SQLITE_OK;
ret |= sqlite3_bind_int(statement, 4, account.mod) != SQLITE_OK;
ret |= sqlite3_bind_int(statement, 5, account.admin) != SQLITE_OK;
//check for binding errors
if (ret) {
throw( std::runtime_error(std::string() + "Failed to replace a prepared statement's parameter: " + sqlite3_errmsg(database)) );
}
//execute
if (sqlite3_step(statement) != SQLITE_DONE) {
//if this fails, than something went horribly wrong
sqlite3_finalize(statement);
throw( std::runtime_error(std::string() + "Unknown SQL error when saving an account: " + sqlite3_errmsg(database)) );
}
sqlite3_finalize(statement);
//successful execution
return 0;
}
void AccountManager::UnloadAccount(int uid) {
//save this user account, and then unload it
//NOTE: the associated characters are unloaded externally
SaveAccount(uid);
accountMap.erase(uid);
}
void AccountManager::DeleteAccount(int uid) {
//delete a user account from the database, and remove it from memory
//NOTE: the associated characters should be deleted externally
sqlite3_stmt* statement = nullptr;
//prep
if (sqlite3_prepare_v2(database, DELETE_USER_ACCOUNT, -1, &statement, nullptr) != SQLITE_OK) {
throw( std::runtime_error(std::string() + "Failed to prepare an SQL statement: " + sqlite3_errmsg(database)) );
}
//parameter
if (sqlite3_bind_int(statement, 1, uid) != SQLITE_OK) {
throw( std::runtime_error(std::string() + "Failed to replace a prepared statement's parameter: " + sqlite3_errmsg(database)) );
}
//execute
if (sqlite3_step(statement) != SQLITE_DONE) {
//if this fails, than something went horribly wrong
sqlite3_finalize(statement);
throw( std::runtime_error(std::string() + "Unknown SQL error when deleting an account: " + sqlite3_errmsg(database)) );
}
//finish the routine
sqlite3_finalize(statement);
accountMap.erase(uid);
}
void AccountManager::UnloadAll() {
for (auto& it : accountMap) {
SaveAccount(it.first);
}
accountMap.clear();
}
//-------------------------
//Define the accessors and mutators
//-------------------------
AccountData* AccountManager::GetAccount(int uid) {
std::map<int, AccountData>::iterator it = accountMap.find(uid);
if (it == accountMap.end()) {
return nullptr;
}
return &it->second;
}
std::map<int, AccountData>* AccountManager::GetContainer() {
return &accountMap;
}
sqlite3* AccountManager::SetDatabase(sqlite3* db) {
return database = db;
}
sqlite3* AccountManager::GetDatabase() {
return database;
}
-57
View File
@@ -1,57 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* 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.
*/
#ifndef ACCOUNTMANAGER_HPP_
#define ACCOUNTMANAGER_HPP_
#include "account_data.hpp"
#include "sqlite3/sqlite3.h"
#include <map>
class AccountManager {
public:
AccountManager() = default;
~AccountManager() { UnloadAll(); };
//public access methods
int CreateAccount(std::string username, int clientIndex);
int LoadAccount(std::string username, int clientIndex);
int SaveAccount(int uid);
void UnloadAccount(int uid);
void DeleteAccount(int uid);
void UnloadAll();
//accessors and mutators
AccountData* GetAccount(int uid);
std::map<int, AccountData>* GetContainer();
sqlite3* SetDatabase(sqlite3* db);
sqlite3* GetDatabase();
private:
std::map<int, AccountData> accountMap;
sqlite3* database = nullptr;
};
#endif
-318
View File
@@ -1,318 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* 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 "character_manager.hpp"
#include "sqlite3/sqlite3.h"
#include <stdexcept>
//-------------------------
//Define the queries
//-------------------------
static const char* CREATE_CHARACTER = "INSERT INTO Characters (owner, handle, avatar) VALUES (?, ?, ?);";
static const char* LOAD_CHARACTER = "SELECT * FROM Characters WHERE handle = ?;";
static const char* SAVE_CHARACTER = "UPDATE OR FAIL Characters SET "
"roomIndex = ?2,"
"originX = ?3,"
"originY = ?4,"
"level = ?5,"
"exp = ?6,"
"maxHP = ?7,"
"health = ?8,"
"maxMP = ?9,"
"mana = ?10,"
"attack = ?11,"
"defence = ?12,"
"intelligence = ?13,"
"resistance = ?14,"
"speed = ?15,"
"accuracy = ?16,"
"evasion = ?17,"
"luck = ?18"
" WHERE uid = ?1;";
static const char* DELETE_CHARACTER = "DELETE FROM Characters WHERE uid = ?;";
//-------------------------
//Define the methods
//-------------------------
//TODO: default stats as a parameter? This would be good for differing beggining states or multiple classes
int CharacterManager::CreateCharacter(int owner, std::string handle, std::string avatar) {
//Create the character, failing if it exists
sqlite3_stmt* statement = nullptr;
//prep
if (sqlite3_prepare_v2(database, CREATE_CHARACTER, -1, &statement, nullptr) != SQLITE_OK) {
throw( std::runtime_error(std::string() + "Failed to prepare an SQL statement: " + sqlite3_errmsg(database)) );
}
//parameters
bool ret = false;
ret |= sqlite3_bind_int(statement, 1, owner);
ret |= sqlite3_bind_text(statement, 2, handle.c_str(), handle.size() + 1, SQLITE_STATIC);
ret |= sqlite3_bind_text(statement, 3, avatar.c_str(), avatar.size() + 1, SQLITE_STATIC);
//check for binding errors
if (ret) {
throw( std::runtime_error(std::string() + "Failed to replace a prepared statement's parameter: " + sqlite3_errmsg(database)) );
}
//execute
if (sqlite3_step(statement) != SQLITE_DONE) {
//if this fails, than this character exists
sqlite3_finalize(statement);
return -1;
}
sqlite3_finalize(statement);
//load this character into memory
return LoadCharacter(owner, handle, avatar);
}
int CharacterManager::LoadCharacter(int owner, std::string handle, std::string avatar) {
//load the specified character, creating it if it doesn't exist
//fail if it is already loaded, or does not belong to this account
sqlite3_stmt* statement = nullptr;
//prep
if (sqlite3_prepare_v2(database, LOAD_CHARACTER, -1, &statement, nullptr) != SQLITE_OK) {
throw( std::runtime_error(std::string() + "Failed to prepare an SQL statement: " + sqlite3_errmsg(database)) );
}
//parameter
if (sqlite3_bind_text(statement, 1, handle.c_str(), handle.size() + 1, SQLITE_STATIC) != SQLITE_OK) {
throw( std::runtime_error(std::string() + "Failed to replace a prepared statement's parameter: " + sqlite3_errmsg(database)) );
}
//execute
int ret = sqlite3_step(statement);
//process the result
if (ret == SQLITE_ROW) {
//get the index
int uid = sqlite3_column_int(statement, 0);
//check to see if this character is already loaded
if (characterMap.find(uid) != characterMap.end()) {
sqlite3_finalize(statement);
return -1;
}
//check the owner
if (owner != sqlite3_column_int(statement, 1)) {
sqlite3_finalize(statement);
return -2;
}
//extract the data into memory
CharacterData& newChar = characterMap[uid];
//metadata
newChar.owner = owner;
newChar.handle = reinterpret_cast<const char*>(sqlite3_column_text(statement, 2));
newChar.avatar = reinterpret_cast<const char*>(sqlite3_column_text(statement, 3));
//Don't cache the birth
//world origin
newChar.roomIndex = sqlite3_column_int(statement, 5);
newChar.origin.x = (double)sqlite3_column_int(statement, 6);
newChar.origin.y = (double)sqlite3_column_int(statement, 7);
//statistics
newChar.stats.level = sqlite3_column_int(statement, 8);
newChar.stats.exp = sqlite3_column_int(statement, 9);
newChar.stats.maxHP = sqlite3_column_int(statement, 10);
newChar.stats.health = sqlite3_column_int(statement, 11);
newChar.stats.maxMP = sqlite3_column_int(statement, 12);
newChar.stats.mana = sqlite3_column_int(statement, 13);
newChar.stats.attack = sqlite3_column_int(statement, 14);
newChar.stats.defence = sqlite3_column_int(statement, 15);
newChar.stats.intelligence = sqlite3_column_int(statement, 16);
newChar.stats.resistance = sqlite3_column_int(statement, 17);
newChar.stats.speed = sqlite3_column_int(statement, 18);
newChar.stats.accuracy = sqlite3_column_double(statement, 19);
newChar.stats.evasion = sqlite3_column_double(statement, 20);
newChar.stats.luck = sqlite3_column_double(statement, 21);
//TODO: equipment
//TODO: items
//TODO: buffs
//TODO: debuffs
//finish the routine
sqlite3_finalize(statement);
return uid;
}
sqlite3_finalize(statement);
if (ret == SQLITE_DONE) {
//create the non-existant character instead
return CreateCharacter(owner, handle, avatar);
}
throw(std::runtime_error(std::string() + "Unknown SQL error in LoadCharacter: " + sqlite3_errmsg(database) ));
}
int CharacterManager::SaveCharacter(int uid) {
//save this character from memory, replacing it if it exists in the database
//DOCS: To use this method, change the in-memory copy, and then call this function using that object's UID.
//this method fails if this character is not loaded
if (characterMap.find(uid) == characterMap.end()) {
return -1;
}
CharacterData& character = characterMap[uid];
sqlite3_stmt* statement = nullptr;
//prep
if (sqlite3_prepare_v2(database, SAVE_CHARACTER, -1, &statement, nullptr) != SQLITE_OK) {
throw( std::runtime_error(std::string() + "Failed to prepare an SQL statement: " + sqlite3_errmsg(database)) );
}
//parameters
bool ret = false;
ret |= sqlite3_bind_int(statement, 1, uid) != SQLITE_OK;
ret |= sqlite3_bind_int(statement, 2, character.roomIndex) != SQLITE_OK;
ret |= sqlite3_bind_int(statement, 3, (int)character.origin.x) != SQLITE_OK;
ret |= sqlite3_bind_int(statement, 4, (int)character.origin.y) != SQLITE_OK;
//statistics
ret |= sqlite3_bind_int(statement, 5, character.stats.level) != SQLITE_OK;
ret |= sqlite3_bind_int(statement, 6, character.stats.exp) != SQLITE_OK;
ret |= sqlite3_bind_int(statement, 7, character.stats.maxHP) != SQLITE_OK;
ret |= sqlite3_bind_int(statement, 8, character.stats.health) != SQLITE_OK;
ret |= sqlite3_bind_int(statement, 9, character.stats.maxMP) != SQLITE_OK;
ret |= sqlite3_bind_int(statement, 10, character.stats.mana) != SQLITE_OK;
ret |= sqlite3_bind_int(statement, 11, character.stats.attack) != SQLITE_OK;
ret |= sqlite3_bind_int(statement, 12, character.stats.defence) != SQLITE_OK;
ret |= sqlite3_bind_int(statement, 13, character.stats.intelligence) != SQLITE_OK;
ret |= sqlite3_bind_int(statement, 14, character.stats.resistance) != SQLITE_OK;
ret |= sqlite3_bind_int(statement, 15, character.stats.speed) != SQLITE_OK;
ret |= sqlite3_bind_double(statement, 16, character.stats.accuracy) != SQLITE_OK;
ret |= sqlite3_bind_double(statement, 17, character.stats.evasion) != SQLITE_OK;
ret |= sqlite3_bind_double(statement, 18, character.stats.luck) != SQLITE_OK;
//TODO: equipment
//TODO: items
//TODO: buffs
//TODO: debuffs
//check for binding errors
if (ret) {
throw( std::runtime_error(std::string() + "Failed to replace a prepared statement's parameter: " + sqlite3_errmsg(database)) );
}
//execute
if (sqlite3_step(statement) != SQLITE_DONE) {
//if this fails, than something went horribly wrong
sqlite3_finalize(statement);
throw( std::runtime_error(std::string() + "Unknown SQL error when saving an account: " + sqlite3_errmsg(database)) );
}
sqlite3_finalize(statement);
//successful execution
return 0;
}
void CharacterManager::UnloadCharacter(int uid) {
//save this character, then unload it
SaveCharacter(uid);
characterMap.erase(uid);
}
void CharacterManager::DeleteCharacter(int uid) {
//delete this character from the database, then remove it from memory
sqlite3_stmt* statement = nullptr;
//prep
if (sqlite3_prepare_v2(database, DELETE_CHARACTER, -1, &statement, nullptr) != SQLITE_OK) {
throw( std::runtime_error(std::string() + "Failed to prepare an SQL statement: " + sqlite3_errmsg(database)) );
}
//parameter
if (sqlite3_bind_int(statement, 1, uid) != SQLITE_OK) {
throw( std::runtime_error(std::string() + "Failed to replace a prepared statement's parameter: " + sqlite3_errmsg(database)) );
}
//execute
if (sqlite3_step(statement) != SQLITE_DONE) {
//if this fails, than something went horribly wrong
sqlite3_finalize(statement);
throw( std::runtime_error(std::string() + "Unknown SQL error when deleting an account: " + sqlite3_errmsg(database)) );
}
//finish the routine
sqlite3_finalize(statement);
characterMap.erase(uid);
}
void CharacterManager::UnloadCharacterIf(std::function<bool(std::map<int, CharacterData>::iterator)> f) {
//save this character, then unload it if the parameter returns true
for (std::map<int, CharacterData>::iterator it = characterMap.begin(); it != characterMap.end(); /* EMPTY */ ) {
if (f(it)) {
SaveCharacter(it->first);
it = characterMap.erase(it);
continue;
}
it++;
}
}
void CharacterManager::UnloadAll() {
for (auto& it : characterMap) {
SaveCharacter(it.first);
}
characterMap.clear();
}
//-------------------------
//Define the accessors and mutators
//-------------------------
CharacterData* CharacterManager::GetCharacter(int uid) {
std::map<int, CharacterData>::iterator it = characterMap.find(uid);
if (it == characterMap.end()) {
return nullptr;
}
return &it->second;
}
std::map<int, CharacterData>* CharacterManager::GetContainer() {
return &characterMap;
}
sqlite3* CharacterManager::SetDatabase(sqlite3* db) {
return database = db;
}
sqlite3* CharacterManager::GetDatabase() {
return database;
}
-60
View File
@@ -1,60 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* 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.
*/
#ifndef CHARACTERMANAGER_HPP_
#define CHARACTERMANAGER_HPP_
#include "character_data.hpp"
#include "sqlite3/sqlite3.h"
#include <map>
#include <functional>
class CharacterManager {
public:
CharacterManager() = default;
~CharacterManager() { UnloadAll(); };
//public access methods
int CreateCharacter(int owner, std::string handle, std::string avatar);
int LoadCharacter(int owner, std::string handle, std::string avatar);
int SaveCharacter(int uid);
void UnloadCharacter(int uid);
void DeleteCharacter(int uid);
void UnloadCharacterIf(std::function<bool(std::map<int, CharacterData>::iterator)> f);
void UnloadAll();
//accessors and mutators
CharacterData* GetCharacter(int uid);
std::map<int, CharacterData>* GetContainer();
sqlite3* SetDatabase(sqlite3* db);
sqlite3* GetDatabase();
private:
std::map<int, CharacterData> characterMap;
sqlite3* database = nullptr;
};
#endif
-54
View File
@@ -1,54 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* 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 "combat_manager.hpp"
//-------------------------
//public access methods
//-------------------------
//TODO
//-------------------------
//accessors and mutators
//-------------------------
CombatData* CombatManager::GetCombat(int uid) {
std::map<int, CombatData>::iterator it = combatMap.find(uid);
if (it == combatMap.end()) {
return nullptr;
}
return &it->second;
}
std::map<int, CombatData>* CombatManager::GetContainer() {
return &combatMap;
}
lua_State* CombatManager::SetLuaState(lua_State* L) {
return luaState = L;
}
lua_State* CombatManager::GetLuaState() {
return luaState;
}
-34
View File
@@ -1,34 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* 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 "enemy_factory_generic.hpp"
EnemyFactoryGeneric::EnemyFactoryGeneric() : EnemyFactoryInterface() {
//EMPTY
}
EnemyFactoryGeneric::~EnemyFactoryGeneric() noexcept {
//EMPTY
}
void EnemyFactoryGeneric::Generate(std::list<EnemyData>* container) {
//TODO: fill this out
}
-42
View File
@@ -1,42 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* 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.
*/
#ifndef ENEMYFACTORYGENERIC_HPP_
#define ENEMYFACTORYGENERIC_HPP_
#include "enemy_factory_interface.hpp"
#include "enemy_data.hpp"
#include <list>
//DOCS: Not really intended for use, but rather for copying and tweaking
class EnemyFactoryGeneric : public EnemyFactoryInterface {
public:
EnemyFactoryGeneric();
~EnemyFactoryGeneric() noexcept override;
void Generate(std::list<EnemyData>* container) override;
private:
//TODO: hold the parameters specified by the room
};
#endif
-48
View File
@@ -1,48 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* 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.
*/
#ifndef ENEMYFACTORYINTERFACE_HPP_
#define ENEMYFACTORYINTERFACE_HPP_
#include "enemy_data.hpp"
#include "room_data.hpp"
#include <list>
//NOTE: Based on biome, world difficulty, etc.
class EnemyFactoryInterface {
public:
EnemyFactoryInterface() = default;
virtual ~EnemyFactoryInterface() = default;
virtual void Generate(std::list<EnemyData>* container) = 0;
//control the difficulty of the room
RoomData::RoomType SetType(RoomData::RoomType t) { return type = t; }
int SetDifficulty(int d) { return difficulty = d; }
RoomData::RoomType GetType() { return type; }
int GetDifficulty() { return difficulty; }
protected:
RoomData::RoomType type;
int difficulty;
};
#endif
-54
View File
@@ -1,54 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* 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 "enemy_manager.hpp"
//-------------------------
//public access methods
//-------------------------
//TODO
//-------------------------
//accessors and mutators
//-------------------------
EnemyData* EnemyManager::GetEnemy(int uid) {
std::map<int, EnemyData>::iterator it = enemyMap.find(uid);
if (it == enemyMap.end()) {
return nullptr;
}
return &it->second;
}
std::map<int, EnemyData>* EnemyManager::GetContainer() {
return &enemyMap;
}
lua_State* EnemyManager::SetLuaState(lua_State* L) {
return luaState = L;
}
lua_State* EnemyManager::GetLuaState() {
return luaState;
}
-51
View File
@@ -1,51 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* 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.
*/
#ifndef ENEMYMANAGER_HPP_
#define ENEMYMANAGER_HPP_
#include "enemy_data.hpp"
#include "lua/lua.hpp"
#include <map>
class EnemyManager {
public:
EnemyManager() = default;
~EnemyManager() = default;
//public access methods
//TODO
//accessors and mutators
EnemyData* GetEnemy(int uid);
std::map<int, EnemyData>* GetContainer();
lua_State* SetLuaState(lua_State*);
lua_State* GetLuaState();
private:
std::map<int, EnemyData> enemyMap;
lua_State* luaState = nullptr;
};
#endif
-45
View File
@@ -1,45 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* 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 "server_application.hpp"
#include "SDL/SDL.h"
#include <stdexcept>
#include <iostream>
using namespace std;
int main(int argc, char** argv) {
cout << "Beginning server" << endl;
try {
ServerApplication app;
app.Init(argc, argv);
app.Proc();
app.Quit();
}
catch(exception& e) {
cerr << "Fatal error: " << e.what() << endl;
return 1;
}
cout << "Clean exit" << endl;
return 0;
}
-63
View File
@@ -1,63 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* 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 "room_api.hpp"
#include "room_manager.hpp"
#include "room_data.hpp"
static int getType(lua_State* L) {
RoomData* room = reinterpret_cast<RoomData*>(lua_touserdata(L, 1));
lua_pushinteger(L, static_cast<int>(room->type));
return 1;
}
//TODO: parameters
static int getRegionPager(lua_State* L) {
RoomData* room = reinterpret_cast<RoomData*>(lua_touserdata(L, 1));
lua_pushlightuserdata(L, reinterpret_cast<void*>(&room->pager));
return 1;
}
//RoomManager only
static int getRoom(lua_State* L) {
//get the room manager
lua_pushstring(L, ROOM_MANAGER_PSEUDOINDEX);
lua_gettable(L, LUA_REGISTRYINDEX);
RoomManager* roomMgr = reinterpret_cast<RoomManager*>(lua_touserdata(L, -1));
//push the room and return it
lua_pushlightuserdata(L, reinterpret_cast<void*>( roomMgr->GetRoom(lua_tointeger(L, -2)) ));
return 1;
}
static const luaL_Reg roomlib[] = {
{"gettype",getType},
{"getregionpager",getRegionPager},
{"getroom",getRoom},
{nullptr, nullptr}
};
LUAMOD_API int luaopen_roomapi(lua_State* L) {
luaL_newlib(L, roomlib);
return 1;
}
-72
View File
@@ -1,72 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* 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 "room_manager.hpp"
#include <stdexcept>
//-------------------------
//public access methods
//-------------------------
RoomData* RoomManager::CreateRoom(int uid) {
//don't overwrite existing rooms
std::map<int, RoomData*>::iterator it = roomMap.find(uid);
if (it != roomMap.end()) {
throw(std::runtime_error("Cannot overwrite an existing room"));
}
roomMap[uid] = new RoomData();
//TODO: create room in the API
if (luaState) {
roomMap[uid]->pager.SetLuaState(luaState);
}
return roomMap[uid];
}
RoomData* RoomManager::UnloadRoom(int uid) {
//TODO: unload room in the API
delete roomMap[uid];
roomMap.erase(uid);
}
RoomData* RoomManager::GetRoom(int uid) {
RoomData* ptr = FindRoom(uid);
if (ptr) return ptr;
ptr = CreateRoom(uid);
return ptr;
}
RoomData* RoomManager::FindRoom(int uid) {
std::map<int, RoomData*>::iterator it = roomMap.find(uid);
if (it == roomMap.end()) {
return nullptr;
}
return it->second;
}
RoomData* RoomManager::PushRoom(int uid, RoomData* room) {
//unload existing rooms with this index
std::map<int, RoomData*>::iterator it = roomMap.find(uid);
if (it != roomMap.end()) {
UnloadRoom(uid);
}
roomMap[uid] = room;
}
-57
View File
@@ -1,57 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* 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.
*/
#ifndef ROOMMANAGER_HPP_
#define ROOMMANAGER_HPP_
#include "room_data.hpp"
#include "lua/lua.hpp"
#include <map>
#define ROOM_MANAGER_PSEUDOINDEX "RoomManager"
class RoomManager {
public:
RoomManager() = default;
~RoomManager() = default;
//public access methods
RoomData* CreateRoom(int uid);
RoomData* UnloadRoom(int uid);
RoomData* GetRoom(int uid);
RoomData* FindRoom(int uid);
RoomData* PushRoom(int uid, RoomData*);
//accessors and mutators
std::map<int, RoomData*>* GetContainer() { return &roomMap; }
lua_State* SetLuaState(lua_State* L) { return luaState = L; }
lua_State* GetLuaState() { return luaState; }
private:
std::map<int, RoomData*> roomMap;
lua_State* luaState = nullptr;
};
#endif
-489
View File
@@ -1,489 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* 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 "server_application.hpp"
#include "sql_utility.hpp"
#include "serial.hpp"
#include "utility.hpp"
#include <stdexcept>
#include <iostream>
#include <string>
//-------------------------
//public methods
//-------------------------
void ServerApplication::Init(int argc, char** argv) {
//NOTE: I might need to rearrange the init process so that lua & SQL can interact with the map system as needed.
std::cout << "Beginning startup" << std::endl;
//initial setup
config.Load("rsc\\config.cfg");
//-------------------------
//Initialize the APIs
//-------------------------
//Init SDL
if (SDL_Init(0)) {
throw(std::runtime_error("Failed to initialize SDL"));
}
std::cout << "Initialized SDL" << std::endl;
//Init SDL_net
if (SDLNet_Init()) {
throw(std::runtime_error("Failed to initialize SDL_net"));
}
network.Open(config.Int("server.port"));
std::cout << "Initialized SDL_net" << std::endl;
//Init SQL
int ret = sqlite3_open_v2(config["server.dbname"].c_str(), &database, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, nullptr);
if (ret != SQLITE_OK || !database) {
throw(std::runtime_error(std::string() + "Failed to initialize SQL: " + sqlite3_errmsg(database) ));
}
std::cout << "Initialized SQL" << std::endl;
//Init lua
luaState = luaL_newstate();
if (!luaState) {
throw(std::runtime_error("Failed to initialize lua"));
}
luaL_openlibs(luaState);
std::cout << "Initialized lua" << std::endl;
//-------------------------
//Setup the objects
//-------------------------
//set the hooks
accountMgr.SetDatabase(database);
characterMgr.SetDatabase(database);
combatMgr.SetLuaState(luaState);
roomMgr.SetLuaState(luaState);
enemyMgr.SetLuaState(luaState);
std::cout << "Internal managers set" << std::endl;
//register the "globals"
lua_pushstring(luaState, ROOM_MANAGER_PSEUDOINDEX);
lua_pushlightuserdata(luaState, &roomMgr);
lua_settable(luaState, LUA_REGISTRYINDEX);
std::cout << "Internal managers registered with lua" << std::endl;
//-------------------------
//Run the startup scripts
//-------------------------
//setup the database
if (runSQLScript(database, config["dir.scripts"] + "setup_server.sql")) {
throw(std::runtime_error("Failed to initialize SQL's setup script"));
}
std::cout << "Completed SQL's setup script" << std::endl;
//run lua's startup script
if (luaL_dofile(luaState, (config["dir.scripts"] + "setup_server.lua").c_str())) {
throw(std::runtime_error(std::string() + "Failed to initialize lua's setup script: " + lua_tostring(luaState, -1) ));
}
std::cout << "Completed lua's setup script" << std::endl;
//-------------------------
//debug output
//-------------------------
std::cout << "Internal sizes:" << std::endl;
std::cout << "\tTile Size: " << sizeof(Region::type_t) << std::endl;
std::cout << "\tRegion Format: " << REGION_WIDTH << ", " << REGION_HEIGHT << ", " << REGION_DEPTH << std::endl;
std::cout << "\tRegion Content Footprint: " << REGION_WIDTH * REGION_HEIGHT * REGION_DEPTH * sizeof(Region::type_t) << std::endl;
std::cout << "\tPACKET_BUFFER_SIZE: " << PACKET_BUFFER_SIZE << std::endl;
std::cout << "\tMAX_PACKET_SIZE: " << MAX_PACKET_SIZE << std::endl;
//-------------------------
//finalize the startup
//-------------------------
std::cout << "Startup completed successfully" << std::endl;
//-------------------------
//debugging
//-------------------------
//...
}
void ServerApplication::Proc() {
SerialPacket* packetBuffer = static_cast<SerialPacket*>(malloc(MAX_PACKET_SIZE));
while(running) {
//suck in the waiting packets & process them
while(network.Receive(packetBuffer)) {
HandlePacket(packetBuffer);
}
//update the internals
//TODO: update the internals i.e. player positions
//give the computer a break
SDL_Delay(10);
}
free(static_cast<void*>(packetBuffer));
}
void ServerApplication::Quit() {
std::cout << "Shutting down" << std::endl;
//close the managers
clientMap.clear();
accountMgr.UnloadAll();
characterMgr.UnloadAll();
//TODO: unload combats
//TODO: unload enemies
//TODO: unload rooms
//APIs
lua_close(luaState);
sqlite3_close_v2(database);
network.Close();
SDLNet_Quit();
SDL_Quit();
std::cout << "Shutdown finished" << std::endl;
}
//-------------------------
//handle incoming traffic
//-------------------------
void ServerApplication::HandlePacket(SerialPacket* const argPacket) {
switch(argPacket->type) {
//basic connections
case SerialPacketType::BROADCAST_REQUEST:
HandleBroadcastRequest(static_cast<SerialPacket*>(argPacket));
break;
case SerialPacketType::JOIN_REQUEST:
HandleJoinRequest(static_cast<ClientPacket*>(argPacket));
break;
case SerialPacketType::DISCONNECT:
HandleDisconnect(static_cast<ClientPacket*>(argPacket));
break;
case SerialPacketType::SHUTDOWN:
HandleShutdown(static_cast<SerialPacket*>(argPacket));
break;
//map management
case SerialPacketType::REGION_REQUEST:
HandleRegionRequest(static_cast<RegionPacket*>(argPacket));
break;
//combat management
//TODO: combat management
//character management
case SerialPacketType::CHARACTER_NEW:
HandleCharacterNew(static_cast<CharacterPacket*>(argPacket));
break;
case SerialPacketType::CHARACTER_DELETE:
HandleCharacterDelete(static_cast<CharacterPacket*>(argPacket));
break;
case SerialPacketType::CHARACTER_UPDATE:
case SerialPacketType::CHARACTER_STATS_REQUEST:
HandleCharacterUpdate(static_cast<CharacterPacket*>(argPacket));
break;
//enemy management
//TODO: enemy management
//mismanagement
case SerialPacketType::SYNCHRONIZE:
HandleSynchronize(static_cast<ClientPacket*>(argPacket));
break;
//handle errors
default:
throw(std::runtime_error(std::string() + "Unknown SerialPacketType encountered in the server: " + to_string_custom(static_cast<int>(argPacket->type)) ));
break;
}
}
//-------------------------
//basic connections
//-------------------------
void ServerApplication::HandleBroadcastRequest(SerialPacket* const argPacket) {
//send the server's data
ServerPacket newPacket;
newPacket.type = SerialPacketType::BROADCAST_RESPONSE;
strncpy(newPacket.name, config["server.name"].c_str(), PACKET_STRING_SIZE);
newPacket.playerCount = characterMgr.GetContainer()->size();
newPacket.version = NETWORK_VERSION;
network.SendTo(&argPacket->srcAddress, static_cast<SerialPacket*>(&newPacket));
}
void ServerApplication::HandleJoinRequest(ClientPacket* const argPacket) {
//create the new client
ClientData newClient;
newClient.address = argPacket->srcAddress;
//load the user account
//TODO: handle passwords
int accountIndex = accountMgr.LoadAccount(argPacket->username, clientUID);
if (accountIndex < 0) {
//TODO: send rejection packet
std::cerr << "Error: Account already loaded: " << accountIndex << std::endl;
return;
}
//send the client their info
ClientPacket newPacket;
newPacket.type = SerialPacketType::JOIN_RESPONSE;
newPacket.clientIndex = clientUID;
newPacket.accountIndex = accountIndex;
network.SendTo(&newClient.address, static_cast<SerialPacket*>(&newPacket));
//finished this routine
clientMap[clientUID++] = newClient;
std::cout << "New connection, " << clientMap.size() << " clients and " << accountMgr.GetContainer()->size() << " accounts total" << std::endl;
}
void ServerApplication::HandleDisconnect(ClientPacket* const argPacket) {
//TODO: authenticate who is disconnecting/kicking
//forward to the specified client
network.SendTo(
&clientMap[ accountMgr.GetAccount(argPacket->accountIndex)->clientIndex ].address,
static_cast<SerialPacket*>(argPacket)
);
//save and unload this account's characters
//pump the unload message to all remaining clients
characterMgr.UnloadCharacterIf([&](std::map<int, CharacterData>::iterator it) -> bool {
if (argPacket->accountIndex == it->second.owner) {
PumpCharacterUnload(it->first);
return true;
}
return false;
});
//erase the in-memory stuff
clientMap.erase(accountMgr.GetAccount(argPacket->accountIndex)->clientIndex);
accountMgr.UnloadAccount(argPacket->accountIndex);
//finished this routine
std::cout << "Disconnection, " << clientMap.size() << " clients and " << accountMgr.GetContainer()->size() << " accounts total" << std::endl;
}
void ServerApplication::HandleShutdown(SerialPacket* const argPacket) {
//TODO: authenticate who is shutting the server down
//end the server
running = false;
//disconnect all clients
SerialPacket newPacket;
newPacket.type = SerialPacketType::DISCONNECT;
PumpPacket(&newPacket);
//finished this routine
std::cout << "Shutdown signal accepted" << std::endl;
}
//-------------------------
//map management
//-------------------------
void ServerApplication::HandleRegionRequest(RegionPacket* const argPacket) {
RegionPacket newPacket;
newPacket.type = SerialPacketType::REGION_CONTENT;
newPacket.roomIndex = argPacket->roomIndex;
newPacket.x = argPacket->x;
newPacket.y = argPacket->y;
newPacket.region = roomMgr.GetRoom(argPacket->roomIndex)->pager.GetRegion(argPacket->x, argPacket->y);
//send the content
network.SendTo(&argPacket->srcAddress, static_cast<SerialPacket*>(&newPacket));
}
//-------------------------
//combat management
//-------------------------
//TODO: combat management
//-------------------------
//Character Management
//-------------------------
void ServerApplication::HandleCharacterNew(CharacterPacket* const argPacket) {
//NOTE: misnomer, try to load the character first
int characterIndex = characterMgr.LoadCharacter(argPacket->accountIndex, argPacket->handle, argPacket->avatar);
if (characterIndex == -1) {
//TODO: rejection packet
std::cerr << "Warning: Character already loaded" << std::endl;
return;
}
if (characterIndex == -2) {
//TODO: rejection packet
std::cerr << "Warning: Character already exists" << std::endl;
return;
}
//send this new character to all clients
CharacterPacket newPacket;
newPacket.type = SerialPacketType::CHARACTER_NEW;
CopyCharacterToPacket(&newPacket, characterIndex);
PumpPacket(&newPacket);
}
void ServerApplication::HandleCharacterDelete(CharacterPacket* const argPacket) {
//NOTE: Disconnecting only unloads a character, this explicitly deletes it
//Authenticate the owner is doing this
int characterIndex = characterMgr.LoadCharacter(argPacket->accountIndex, argPacket->handle, argPacket->avatar);
//if this is not your character
if (characterIndex == -2) {
//TODO: rejection packet
std::cerr << "Warning: Character cannot be deleted" << std::endl;
//unload an unneeded character
if (characterIndex != -1) {
characterMgr.UnloadCharacter(characterIndex);
}
return;
}
//delete it
characterMgr.DeleteCharacter(characterIndex);
//TODO: success packet
//Unload this character from all clients
PumpCharacterUnload(characterIndex);
}
void ServerApplication::HandleCharacterUpdate(CharacterPacket* const argPacket) {
CharacterData* character = characterMgr.GetCharacter(argPacket->characterIndex);
//make a new character if this one doesn't exist
if (!character) {
//this isn't normal
std::cerr << "Warning: HandleCharacterUpdate() is passing to HandleCharacterNew()" << std::endl;
HandleCharacterNew(argPacket);
return;
}
/* TODO: rewrite this design flaw, read more
* Slaving the client to the server here is a terrible idea, instead there
* needs to be a utility function to update and send the server-side character
* to the clients.
*
* Other things to consider include functionality to reequip the character,
* apply status effects and to change the stats as well. These should all be
* handled server-side.
*/
character->roomIndex = argPacket->roomIndex;
character->origin = argPacket->origin;
character->motion = argPacket->motion;
character->stats = argPacket->stats;
//TODO: equipment
//TODO: items
//TODO: buffs
//TODO: debuffs
PumpPacket(argPacket);
}
//-------------------------
//enemy management
//-------------------------
//TODO: enemy management
//-------------------------
//mismanagement
//-------------------------
void ServerApplication::HandleSynchronize(ClientPacket* const argPacket) {
//TODO: compensate for large distances
//NOTE: I quite dislike this function
//send all of the server's data to this client
ClientData& client = clientMap[argPacket->clientIndex];
//send all characters
CharacterPacket newPacket;
newPacket.type = SerialPacketType::CHARACTER_UPDATE;
for (auto& it : *characterMgr.GetContainer()) {
newPacket.characterIndex = it.first;
CopyCharacterToPacket(&newPacket, it.first);
network.SendTo(&client.address, static_cast<SerialPacket*>(&newPacket));
}
//TODO: more in HandleSynchronize()
}
//-------------------------
//utility methods
//-------------------------
//TODO: a function that only sends to characters in a certain proximity
void ServerApplication::PumpPacket(SerialPacket* const argPacket) {
for (auto& it : clientMap) {
network.SendTo(&it.second.address, argPacket);
}
}
void ServerApplication::PumpCharacterUnload(int uid) {
//delete the client-side character(s)
CharacterPacket newPacket;
newPacket.type = SerialPacketType::CHARACTER_DELETE;
newPacket.characterIndex = uid;
PumpPacket(static_cast<SerialPacket*>(&newPacket));
}
void ServerApplication::CopyCharacterToPacket(CharacterPacket* const packet, int characterIndex) {
CharacterData* character = characterMgr.GetCharacter(characterIndex);
if (!character) {
throw(std::runtime_error("Failed to copy a character to a packet"));
}
//TODO: keep this up to date when the character changes
packet->characterIndex = characterIndex;
strncpy(packet->handle, character->handle.c_str(), PACKET_STRING_SIZE);
strncpy(packet->avatar, character->avatar.c_str(), PACKET_STRING_SIZE);
packet->accountIndex = character->owner;
packet->roomIndex = character->roomIndex;
packet->origin = character->origin;
packet->motion = character->motion;
packet->stats = character->stats;
}
-111
View File
@@ -1,111 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* 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.
*/
#ifndef SERVERAPPLICATION_HPP_
#define SERVERAPPLICATION_HPP_
//server specific stuff
#include "account_manager.hpp"
#include "character_manager.hpp"
#include "client_data.hpp"
#include "combat_manager.hpp"
#include "enemy_manager.hpp"
#include "room_manager.hpp"
//common utilities
#include "udp_network_utility.hpp"
#include "config_utility.hpp"
//APIs
#include "lua/lua.hpp"
#include "sqlite3/sqlite3.h"
#include "SDL/SDL.h"
//STL
#include <map>
#include <string>
//The main application class
class ServerApplication {
public:
//public methods
ServerApplication() = default;
~ServerApplication() = default;
void Init(int argc, char** argv);
void Proc();
void Quit();
private:
//handle incoming traffic
void HandlePacket(SerialPacket* const);
//basic connections
void HandleBroadcastRequest(SerialPacket* const);
void HandleJoinRequest(ClientPacket* const);
void HandleDisconnect(ClientPacket* const);
void HandleShutdown(SerialPacket* const);
//map management
void HandleRegionRequest(RegionPacket* const);
//combat management
//TODO: combat management
//character management
void HandleCharacterNew(CharacterPacket* const);
void HandleCharacterDelete(CharacterPacket* const);
void HandleCharacterUpdate(CharacterPacket* const);
//enemy management
//TODO: enemy management
//mismanagement
void HandleSynchronize(ClientPacket* const);
//utility methods
//TODO: a function that only sends to characters in a certain proximity
void PumpPacket(SerialPacket* const);
void PumpCharacterUnload(int uid);
void CopyCharacterToPacket(CharacterPacket* const packet, int characterIndex);
//APIs and utilities
sqlite3* database = nullptr;
lua_State* luaState = nullptr;
UDPNetworkUtility network;
ConfigUtility config;
//simple tables
std::map<int, ClientData> clientMap;
//managers
AccountManager accountMgr;
CharacterManager characterMgr;
CombatManager combatMgr;
EnemyManager enemyMgr;
RoomManager roomMgr;
//misc
bool running = true;
int clientUID = 0;
};
#endif
@@ -5,7 +5,7 @@
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial ClientApplications, and to alter it and redistribute it
* 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
@@ -19,12 +19,13 @@
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "client_application.hpp"
#include "application.hpp"
#include "serial.hpp"
#include "timer.hpp"
#include <stdexcept>
#include <chrono>
#include <iostream>
//-------------------------
//Scene headers
@@ -34,37 +35,71 @@
#include "splash_screen.hpp"
#include "main_menu.hpp"
#include "options_menu.hpp"
#include "lobby_menu.hpp"
#include "in_world.hpp"
#include "in_combat.hpp"
#include "restart.hpp"
//-------------------------
//Public access members
//-------------------------
void ClientApplication::Init(int argc, char** argv) {
//load the prerequisites
config.Load("rsc\\config.cfg");
void Application::Init(int argc, char** argv) {
std::cout << "Beginning " << argv[0] << std::endl;
//-------------------------
//Initialize the APIs
//-------------------------
//initialize SDL
if (SDL_Init(SDL_INIT_VIDEO)) {
throw(std::runtime_error("Failed to initialize SDL"));
}
int w = config.Int("client.screen.w");
int h = config.Int("client.screen.h");
int f = config.Bool("client.screen.f") ? SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_FULLSCREEN : SDL_HWSURFACE|SDL_DOUBLEBUF;
std::cout << "Initialized SDL" << std::endl;
BaseScene::SetScreen(w ? w : 800, h ? h : 600, 0, f);
//initialize SDL_net
if (SDLNet_Init()) {
throw(std::runtime_error("Failed to initialize SDL_net"));
//initialize lua
lua = luaL_newstate();
if (!lua) {
throw(std::runtime_error("Failed to initialize lua"));
}
network.Open(0);
luaL_openlibs(lua);
std::cout << "Initialized lua" << std::endl;
if (luaL_dofile(lua, "rsc\\setup.lua")) {
throw(std::runtime_error("Failed to initialize lua's startup script"));
}
std::cout << "Initialized lua's setup script" << std::endl;
//-------------------------
//Setup the screen
//-------------------------
lua_getglobal(lua, "config");
lua_getfield(lua, 1, "screen");
lua_getfield(lua, 2, "width");
lua_getfield(lua, 2, "height");
lua_getfield(lua, 2, "fullscreen");
int w = lua_tointeger(lua, 3);
int h = lua_tointeger(lua, 4);
int f = lua_toboolean(lua, 5);
lua_pop(lua, 5);
BaseScene::SetScreen(w ? w : 800, h ? h : 600, 0, f ? SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_FULLSCREEN : SDL_HWSURFACE|SDL_DOUBLEBUF);
std::cout << "Initialized the screen" << std::endl;
//-------------------------
//finalize the startup
//-------------------------
std::cout << "Startup completed successfully" << std::endl;
//-------------------------
//debugging
//-------------------------
//...
}
void ClientApplication::Proc() {
void Application::Proc() {
LoadScene(SceneList::FIRST);
//prepare the time system
@@ -85,6 +120,8 @@ void ClientApplication::Proc() {
//update the current time
realTime = Clock::now();
Timer runTimer("run");
//simulate game time
while (simTime < realTime) {
//call each user defined function
@@ -92,55 +129,57 @@ void ClientApplication::Proc() {
simTime += delta;
}
runTimer.Stop();
Timer renderTimer("render");
//draw the game to the screen
activeScene->RenderFrame();
renderTimer.Stop();
//debugging output
// std::cout << runTimer << std::endl;
// std::cout << renderTimer << std::endl;
}
UnloadScene();
}
void ClientApplication::Quit() {
network.Close();
SDLNet_Quit();
void Application::Quit() {
std::cout << "Shutting down" << std::endl;
lua_close(lua);
SDL_Quit();
std::cout << "Clean exit" << std::endl;
}
//-------------------------
//Private access members
//-------------------------
void ClientApplication::LoadScene(SceneList sceneIndex) {
void Application::LoadScene(SceneList sceneIndex) {
UnloadScene();
switch(sceneIndex) {
//add scene creation calls here
case SceneList::FIRST:
case SceneList::SPLASHSCREEN:
activeScene = new SplashScreen(&config);
activeScene = new SplashScreen(lua);
break;
case SceneList::MAINMENU:
activeScene = new MainMenu(&config);
activeScene = new MainMenu(lua);
break;
case SceneList::OPTIONSMENU:
activeScene = new OptionsMenu(&config);
break;
case SceneList::LOBBYMENU:
activeScene = new LobbyMenu(&config, &network, &clientIndex, &accountIndex);
activeScene = new OptionsMenu(lua);
break;
case SceneList::INWORLD:
activeScene = new InWorld(&config, &network, &clientIndex, &accountIndex, &characterIndex, &combatMap, &characterMap);
break;
case SceneList::INCOMBAT:
activeScene = new InCombat(&config, &network, &clientIndex, &accountIndex, &characterIndex, &combatMap, &characterMap, &enemyMap);
break;
case SceneList::RESTART:
activeScene = new Restart(&config, &network, &clientIndex, &accountIndex, &characterIndex, &combatMap, &characterMap, &enemyMap);
activeScene = new InWorld(lua);
break;
default:
throw(std::logic_error("Failed to recognize the scene index"));
}
}
void ClientApplication::UnloadScene() {
void Application::UnloadScene() {
delete activeScene;
activeScene = nullptr;
}
@@ -19,28 +19,31 @@
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef COMBATPACKET_HPP_
#define COMBATPACKET_HPP_
#ifndef APPLICATION_HPP_
#define APPLICATION_HPP_
#include "serial_packet_base.hpp"
#include "scene_list.hpp"
#include "base_scene.hpp"
#include "combat_data.hpp"
#include "lua/lua.hpp"
struct CombatPacket : SerialPacketBase {
//identify the combat instance
int combatIndex;
int difficulty;
CombatData::Terrain terrainType;
class Application {
public:
Application() = default;
~Application() = default;
//combatants
int characterArray[COMBAT_MAX_CHARACTERS];
int enemyArray[COMBAT_MAX_ENEMIES];
void Init(int argc, char** argv);
void Proc();
void Quit();
//location
int mapIndex;
Vector2 origin;
private:
//Private access members
void LoadScene(SceneList sceneIndex);
void UnloadScene();
//TODO: rewards
BaseScene* activeScene = nullptr;
lua_State* lua = nullptr;
};
#endif
@@ -19,27 +19,23 @@
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "character_data.hpp"
#include "character.hpp"
void CharacterData::Update(double delta) {
void Character::Update(double delta) {
if (motion.x && motion.y) {
origin += motion * delta * CHARACTER_WALKING_MOD;
}
else if (motion != 0) {
origin += motion * delta;
}
#ifdef GRAPHICS
sprite.Update(delta);
#endif
}
#ifdef GRAPHICS
void CharacterData::DrawTo(SDL_Surface* const dest, int camX, int camY) {
void Character::DrawTo(SDL_Surface* const dest, int camX, int camY) {
sprite.DrawTo(dest, origin.x - camX, origin.y - camY);
}
void CharacterData::CorrectSprite() {
void Character::CorrectSprite() {
//NOTE: These must correspond to the sprite sheet in use
if (motion.y > 0) {
sprite.SetYIndex(0);
@@ -63,5 +59,3 @@ void CharacterData::CorrectSprite() {
sprite.SetXIndex(0);
}
}
#endif
@@ -19,60 +19,51 @@
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef CHARACTERDATA_HPP_
#define CHARACTERDATA_HPP_
#ifndef CHARACTER_HPP_
#define CHARACTER_HPP_
//components
#include "vector2.hpp"
#include "statistics.hpp"
#include "bounding_box.hpp"
//graphics
#ifdef GRAPHICS
#include "sprite_sheet.hpp"
#endif
#include "sprite_sheet.hpp"
//std namespace
#include <string>
#include <cmath>
//the speeds that the characters move
constexpr double CHARACTER_WALKING_SPEED = 140.0;
constexpr double CHARACTER_WALKING_MOD = 1.0/sqrt(2.0);
struct CharacterData {
//metadata
int owner;
std::string handle;
std::string avatar;
class Character {
public:
Character() = default;
~Character() = default;
//world position
int roomIndex = 0;
Vector2 origin = {0.0,0.0};
Vector2 motion = {0.0,0.0};
Vector2 bounds = {0.0,0.0};
//base statistics
Statistics stats;
//TODO: equipment
//TODO: items
//TODO: buffs
//TODO: debuffs
//methods
void Update(double delta);
#ifdef GRAPHICS
//graphics
void DrawTo(SDL_Surface* const, int camX, int camY);
void CorrectSprite();
#endif
SpriteSheet* GetSprite() { return &sprite; }
//active gameplay members
//NOTE: these are lost when unloaded
#ifdef GRAPHICS
//accessors and mutators
Vector2 SetOrigin(Vector2 v) { return origin = v; }
Vector2 GetOrigin() const { return origin; }
Vector2 SetMotion(Vector2 v) { return motion = v; }
Vector2 GetMotion() const { return motion; }
BoundingBox SetBoundingBox(BoundingBox b) { return bounds = b; }
BoundingBox GetBoundingBox() const { return bounds; }
private:
//graphics
SpriteSheet sprite;
#endif
bool inCombat = false;
int atbGauge = 0;
//TODO: stored command
//position
Vector2 origin = {0.0,0.0};
Vector2 motion = {0.0,0.0};
BoundingBox bounds;
};
#endif
@@ -11,7 +11,7 @@ OBJDIR=obj
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
#output
OUTDIR=../..
OUTDIR=..
OUT=$(addprefix $(OUTDIR)/,libcommon.a)
#targets
@@ -19,13 +19,11 @@
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef CLIENTDATA_HPP_
#define CLIENTDATA_HPP_
#include "timer.hpp"
#include "SDL/SDL_net.h"
struct ClientData {
IPaddress address = {0,0};
};
#endif
std::ostream& operator<<(std::ostream& os, Timer& t) {
os << t.GetName() << ": ";
os << std::chrono::duration_cast<std::chrono::nanoseconds>(t.GetTime()).count();
os << "ns";
return os;
}
@@ -19,33 +19,36 @@
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef COMBATMANAGER_HPP_
#define COMBATMANAGER_HPP_
#ifndef TIMER_HPP_
#define TIMER_HPP_
#include "combat_data.hpp"
#include <chrono>
#include <string>
#include <ostream>
#include "lua/lua.hpp"
#include <map>
class CombatManager {
class Timer {
public:
CombatManager() = default;
~CombatManager() = default;
typedef std::chrono::high_resolution_clock Clock;
//public access methods
//TODO
Timer() = default;
Timer(std::string s) : name(s), start(Clock::now()) {};
~Timer() = default;
inline void Start() { start = Clock::now(); }
inline void Stop() { time = Clock::now() - start; }
//accessors and mutators
CombatData* GetCombat(int uid);
std::map<int, CombatData>* GetContainer();
Clock::duration GetTime() { return time; }
lua_State* SetLuaState(lua_State*);
lua_State* GetLuaState();
std::string SetName(std::string s) { return name = s; }
std::string GetName() { return name; }
private:
std::map<int, CombatData> combatMap;
lua_State* luaState = nullptr;
std::string name;
Clock::time_point start;
Clock::duration time;
};
#endif
std::ostream& operator<<(std::ostream& os, Timer& t);
#endif
@@ -1,5 +1,5 @@
#config
INCLUDES+=. ../map
INCLUDES+=.
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
@@ -11,7 +11,7 @@ OBJDIR=obj
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
#output
OUTDIR=../..
OUTDIR=..
OUT=$(addprefix $(OUTDIR)/,libcommon.a)
#targets
+257
View File
@@ -0,0 +1,257 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* 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 "in_world.hpp"
#include "timer.hpp"
#include "utility.hpp"
#include "region_pager_api.hpp"
#include "tile_sheet_api.hpp"
#include <iostream>
//-------------------------
//Public access members
//-------------------------
InWorld::InWorld(lua_State* L): lua(L) {
//register the pager
lua_pushstring(lua, TORTUGA_REGION_PAGER_PSEUDO_INDEX);
lua_pushlightuserdata(lua, &pager);
lua_settable(L, LUA_REGISTRYINDEX);
//register the tilesheet
lua_pushstring(lua, TORTUGA_TILE_SHEET_PSEUDO_INDEX);
lua_pushlightuserdata(lua, &tileSheet);
lua_settable(L, LUA_REGISTRYINDEX);
//setup the component objecrs
pager.SetLuaState(lua);
//get the config info
lua_getglobal(lua, "config");
lua_getfield(lua, -1, "dir");
lua_getfield(lua, -1, "fonts");
std::string fonts = lua_tostring(lua, -1);
lua_getfield(lua, -2, "interface");
std::string interface = lua_tostring(lua, -1);
lua_getfield(lua, -3, "sprites");
std::string sprites = lua_tostring(lua, -1);
lua_getfield(lua, -4, "scripts");
std::string scripts = lua_tostring(lua, -1);
lua_pop(lua, 6);
//run the additional scripts
if (luaL_dofile(lua, (scripts + "in_world.lua").c_str())) {
throw(std::runtime_error(std::string() + "Failed to run in_world.lua: " + lua_tostring(lua, -1) ));
}
//setup the utility objects
buttonImage.LoadSurface(interface + "button_menu.bmp");
buttonImage.SetClipH(buttonImage.GetClipH()/3);
font.LoadSurface(fonts + "pk_white_8.bmp");
//pass the utility objects
backButton.SetImage(&buttonImage);
backButton.SetFont(&font);
//set the button positions
backButton.SetX(50);
backButton.SetY(50 + buttonImage.GetClipH() * 0);
//set the button texts
backButton.SetText("Back");
//entities
character.GetSprite()->LoadSurface(sprites + "elliot2.bmp", 4, 4);
character.SetBoundingBox({0, 0,
character.GetSprite()->GetImage()->GetClipW(),
character.GetSprite()->GetImage()->GetClipH()
});
//setup the camera
camera.margin.x = GetScreen()->w / 2 - character.GetSprite()->GetImage()->GetClipW() / 2;
camera.margin.y = GetScreen()->h / 2 - character.GetSprite()->GetImage()->GetClipH() / 2;
//debug
//
}
InWorld::~InWorld() {
//unregister the map components
lua_pushstring(lua, TORTUGA_REGION_PAGER_PSEUDO_INDEX);
lua_pushstring(lua, TORTUGA_TILE_SHEET_PSEUDO_INDEX);
lua_pushnil(lua);
lua_settable(lua, LUA_REGISTRYINDEX);
lua_pushnil(lua);
lua_settable(lua, LUA_REGISTRYINDEX);
}
//-------------------------
//Frame loop
//-------------------------
void InWorld::FrameStart() {
//
}
void InWorld::Update(double delta) {
//update the entities
character.Update(delta);
//check for collisions with the map
BoundingBox wallBounds = {0, 0, tileSheet.GetTileW(), tileSheet.GetTileH()};
const int xCount = character.GetBoundingBox().w / wallBounds.w + 1;
const int yCount = character.GetBoundingBox().h / wallBounds.h + 1;
for (int i = -1; i <= xCount; ++i) {
for (int j = -1; j <= yCount; ++j) {
//set the wall's position
wallBounds.x = wallBounds.w * i + snapToBase((double)wallBounds.w, character.GetOrigin().x);
wallBounds.y = wallBounds.h * j + snapToBase((double)wallBounds.h, character.GetOrigin().y);
if (!pager.GetSolid(wallBounds.x / wallBounds.w, wallBounds.y / wallBounds.h)) {
continue;
}
if ((character.GetOrigin() + character.GetBoundingBox()).CheckOverlap(wallBounds)) {
character.SetOrigin(character.GetOrigin() - (character.GetMotion() * delta));
character.SetMotion({0,0});
character.CorrectSprite();
}
}
}
//update the camera
camera.origin.x = character.GetOrigin().x - camera.margin.x;
camera.origin.y = character.GetOrigin().y - camera.margin.y;
//TODO: prune distant regions
//summon nearby unloaded regions
const int left = snapToBase(REGION_WIDTH, camera.origin.x / tileSheet.GetTileW());
const int top = snapToBase(REGION_HEIGHT, camera.origin.y / tileSheet.GetTileH());
const int right = snapToBase(REGION_WIDTH, (camera.origin.x + GetScreen()->w) / tileSheet.GetTileW());
const int bottom = snapToBase(REGION_HEIGHT, (camera.origin.y + GetScreen()->h) / tileSheet.GetTileH());
for (int i = left - REGION_WIDTH; i <= right + REGION_WIDTH; i += REGION_WIDTH) {
for (int j = top - REGION_HEIGHT; j <= bottom + REGION_HEIGHT; j += REGION_HEIGHT) {
pager.GetRegion(i, j);
}
}
}
void InWorld::FrameEnd() {
//
}
void InWorld::RenderFrame() {
// SDL_FillRect(GetScreen(), 0, 0);
Render(GetScreen());
SDL_Flip(GetScreen());
fps.Calculate();
}
void InWorld::Render(SDL_Surface* const screen) {
//draw all regions
for (std::list<Region>::iterator it = pager.GetContainer()->begin(); it != pager.GetContainer()->end(); it++) {
tileSheet.DrawRegionTo(screen, &(*it), camera.origin.x, camera.origin.y);
}
//draw the characters
character.DrawTo(screen, camera.origin.x, camera.origin.y);
//draw the UI
backButton.DrawTo(screen);
font.DrawStringTo(to_string_custom(fps.GetFrameRate()), screen, 0, 0);
}
//-------------------------
//Event handlers
//-------------------------
void InWorld::QuitEvent() {
//exit the game
SetNextScene(SceneList::QUIT);
}
void InWorld::MouseMotion(SDL_MouseMotionEvent const& motion) {
backButton.MouseMotion(motion);
}
void InWorld::MouseButtonDown(SDL_MouseButtonEvent const& button) {
backButton.MouseButtonDown(button);
}
void InWorld::MouseButtonUp(SDL_MouseButtonEvent const& button) {
if (backButton.MouseButtonUp(button) == Button::State::HOVER) {
SetNextScene(SceneList::MAINMENU);
}
}
void InWorld::KeyDown(SDL_KeyboardEvent const& key) {
//player movement
Vector2 motion = character.GetMotion();
switch(key.keysym.sym) {
case SDLK_LEFT:
motion.x -= CHARACTER_WALKING_SPEED;
break;
case SDLK_RIGHT:
motion.x += CHARACTER_WALKING_SPEED;
break;
case SDLK_UP:
motion.y -= CHARACTER_WALKING_SPEED;
break;
case SDLK_DOWN:
motion.y += CHARACTER_WALKING_SPEED;
break;
}
if (character.GetMotion() != motion) {
character.SetMotion(motion);
character.CorrectSprite();
}
}
void InWorld::KeyUp(SDL_KeyboardEvent const& key) {
//player movement
Vector2 motion = character.GetMotion();
switch(key.keysym.sym) {
//NOTE: The use of min/max here are to prevent awkward movements
case SDLK_LEFT:
motion.x = std::min(motion.x + CHARACTER_WALKING_SPEED, 0.0);
break;
case SDLK_RIGHT:
motion.x = std::max(motion.x - CHARACTER_WALKING_SPEED, 0.0);
break;
case SDLK_UP:
motion.y = std::min(motion.y + CHARACTER_WALKING_SPEED, 0.0);
break;
case SDLK_DOWN:
motion.y = std::max(motion.y - CHARACTER_WALKING_SPEED, 0.0);
break;
}
if (character.GetMotion() != motion) {
character.SetMotion(motion);
character.CorrectSprite();
}
}
+35 -40
View File
@@ -1,4 +1,4 @@
/* Copyright: (c) Kayne Ruse 2014
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
@@ -19,49 +19,41 @@
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef RESTART_HPP_
#define RESTART_HPP_
#ifndef INWORLD_HPP_
#define INWORLD_HPP_
//network
#include "udp_network_utility.hpp"
//graphics
//graphics & ui
#include "image.hpp"
#include "raster_font.hpp"
#include "button.hpp"
//common
#include "config_utility.hpp"
//map stuff
#include "tile_sheet.hpp"
#include "region_pager_lua.hpp"
//entities
#include "character.hpp"
//utilities
#include "frame_rate.hpp"
#include "combat_data.hpp"
#include "character_data.hpp"
#include "enemy_data.hpp"
//client
//framework
#include "base_scene.hpp"
//std namespace
#include <chrono>
//APIs
#include "lua/lua.hpp"
class Restart : public BaseScene {
class InWorld : public BaseScene {
public:
//Public access members
Restart(
ConfigUtility* const argConfig,
UDPNetworkUtility* const argNetwork,
int* const argClientIndex,
int* const argAccountIndex,
int* const argCharacterIndex,
std::map<int, CombatData>* argCombatMap,
std::map<int, CharacterData>* argCharacterMap,
std::map<int, EnemyData>* argEnemyMap
);
~Restart();
InWorld(lua_State* L);
~InWorld();
protected:
//Frame loop
void FrameStart();
void Update(double delta);
void FrameEnd();
void RenderFrame();
void Render(SDL_Surface* const);
@@ -73,26 +65,29 @@ protected:
void KeyDown(SDL_KeyboardEvent const&);
void KeyUp(SDL_KeyboardEvent const&);
struct {
struct {
int x, y;
}origin, margin;
}camera;
//shared parameters
ConfigUtility& config;
UDPNetworkUtility& network;
int& clientIndex;
int& accountIndex;
int& characterIndex;
std::map<int, CombatData>& combatMap;
std::map<int, CharacterData>& characterMap;
std::map<int, EnemyData>& enemyMap;
lua_State* lua = nullptr;
//graphics
Image image;
Image buttonImage;
RasterFont font;
//map stuff
TileSheet tileSheet;
RegionPagerLua pager;
//entities
Character character;
//UI
Button backButton;
FrameRate fps;
//auto return
std::chrono::steady_clock::time_point startTick;
};
#endif
+6 -4
View File
@@ -37,7 +37,8 @@
#include "lua/lua.hpp"
#include "region_api.hpp"
#include "pager_api.hpp"
#include "region_pager_api.hpp"
#include "tile_sheet_api.hpp"
//these libs are loaded by lua.c and are readily available to any Lua program
static const luaL_Reg loadedlibs[] = {
@@ -53,9 +54,10 @@ static const luaL_Reg loadedlibs[] = {
{LUA_MATHLIBNAME, luaopen_math},
{LUA_DBLIBNAME, luaopen_debug},
//custom libs
{LUA_REGIONLIBNAME, luaopen_regionapi},
{LUA_PAGERLIBNAME, luaopen_pagerapi},
//Tortuga's API
{TORTUGA_REGION_NAME, openRegionAPI},
{TORTUGA_REGION_PAGER_NAME, openRegionPagerAPI},
{TORTUGA_TILE_SHEET_NAME, openTileSheetAPI},
{NULL, NULL}
};
+2 -4
View File
@@ -19,7 +19,7 @@
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "client_application.hpp"
#include "application.hpp"
#include <stdexcept>
#include <iostream>
@@ -27,9 +27,8 @@
using namespace std;
int main(int argc, char** argv) {
cout << "Beginning client" << endl;
try {
ClientApplication app;
Application app;
app.Init(argc, argv);
app.Proc();
app.Quit();
@@ -38,6 +37,5 @@ int main(int argc, char** argv) {
cerr << "Fatal exception thrown: " << e.what() << endl;
return 1;
}
cout << "Clean exit" << endl;
return 0;
}
+14 -11
View File
@@ -25,13 +25,20 @@
//Public access members
//-------------------------
MainMenu::MainMenu(ConfigUtility* const argConfig):
config(*argConfig)
{
MainMenu::MainMenu(lua_State* L): lua(L) {
//get the config info
lua_getglobal(lua, "config");
lua_getfield(lua, -1, "dir");
lua_getfield(lua, -1, "interface");
std::string interface = lua_tostring(lua, -1);
lua_getfield(lua, -2, "fonts");
std::string fonts = lua_tostring(lua, -1);
lua_pop(lua, 4);
//setup the utility objects
image.LoadSurface(config["dir.interface"] + "button_menu.bmp");
image.LoadSurface(interface + "button_menu.bmp");
image.SetClipH(image.GetClipH()/3);
font.LoadSurface(config["dir.fonts"] + "pk_white_8.bmp");
font.LoadSurface(fonts + "pk_white_8.bmp");
//pass the utility objects
startButton.SetImage(&image);
@@ -102,7 +109,7 @@ void MainMenu::MouseButtonDown(SDL_MouseButtonEvent const& button) {
void MainMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) {
if (startButton.MouseButtonUp(button) == Button::State::HOVER) {
SetNextScene(SceneList::LOBBYMENU);
SetNextScene(SceneList::INWORLD);
}
if (optionsButton.MouseButtonUp(button) == Button::State::HOVER) {
SetNextScene(SceneList::OPTIONSMENU);
@@ -113,11 +120,7 @@ void MainMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) {
}
void MainMenu::KeyDown(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) {
case SDLK_ESCAPE:
QuitEvent();
break;
}
//
}
void MainMenu::KeyUp(SDL_KeyboardEvent const& key) {
+4 -3
View File
@@ -24,15 +24,16 @@
#include "base_scene.hpp"
#include "config_utility.hpp"
#include "image.hpp"
#include "raster_font.hpp"
#include "button.hpp"
#include "lua/lua.hpp"
class MainMenu : public BaseScene {
public:
//Public access members
MainMenu(ConfigUtility* const);
MainMenu(lua_State* L);
~MainMenu();
protected:
@@ -50,7 +51,7 @@ protected:
void KeyUp(SDL_KeyboardEvent const&);
//shared parameters
ConfigUtility& config;
lua_State* lua = nullptr;
//members
Image image;
+8 -3
View File
@@ -1,6 +1,6 @@
#config
INCLUDES+=. ../common/gameplay ../common/map ../common/network ../common/network/packet ../common/network/serial ../common/utilities
LIBS+=../libcommon.a -lSDL_net -lwsock32 -liphlpapi -lmingw32 -lSDLmain -lSDL -llua -lsqlite3
INCLUDES+=. debugging graphics map ui utilities
LIBS+=libcommon.a -lmingw32 -lSDLmain -lSDL -llua
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
#source
@@ -12,10 +12,15 @@ OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
#output
OUTDIR=../out
OUT=$(addprefix $(OUTDIR)/,server)
OUT=$(addprefix $(OUTDIR)/,jam)
#targets
all: $(OBJ) $(OUT)
$(MAKE) -C debugging
$(MAKE) -C graphics
$(MAKE) -C map
$(MAKE) -C ui
$(MAKE) -C utilities
$(CXX) $(CXXFLAGS) -o $(OUT) $(OBJ) $(LIBS)
$(OBJ): | $(OBJDIR)
+37
View File
@@ -0,0 +1,37 @@
#config
INCLUDES+=. ../graphics ../utilities
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
#source
CXXSRC=$(wildcard *.cpp)
#objects
OBJDIR=obj
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
#output
OUTDIR=..
OUT=$(addprefix $(OUTDIR)/,libcommon.a)
#targets
all: $(OBJ) $(OUT)
ar -crs $(OUT) $(OBJ)
$(OBJ): | $(OBJDIR)
$(OUT): | $(OUTDIR)
$(OBJDIR):
mkdir $(OBJDIR)
$(OUTDIR):
mkdir $(OUTDIR)
$(OBJDIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
clean:
$(RM) *.o *.a *.exe
rebuild: clean all
@@ -35,6 +35,7 @@ Region::Region(int argX, int argY): x(argX), y(argY) {
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) {
@@ -44,3 +45,11 @@ Region::type_t Region::SetTile(int x, int y, int z, type_t v) {
Region::type_t Region::GetTile(int x, int y, int z) {
return tiles[x][y][z];
}
bool Region::SetSolid(int x, int y, bool b) {
return solid[x * REGION_WIDTH + y] = b;
}
bool Region::GetSolid(int x, int y) {
return solid[x * REGION_WIDTH + y];
}
@@ -22,10 +22,17 @@
#ifndef REGION_HPP_
#define REGION_HPP_
#include <bitset>
#include <cmath>
//the region's storage format
constexpr int REGION_WIDTH = 20;
constexpr int REGION_HEIGHT = 20;
constexpr int REGION_DEPTH = 3;
//the size of the solid map
constexpr int REGION_SOLID_FOOTPRINT = ceil(REGION_WIDTH * REGION_HEIGHT / 8.0);
class Region {
public:
typedef unsigned char type_t;
@@ -38,14 +45,23 @@ public:
type_t SetTile(int x, int y, int z, type_t v);
type_t GetTile(int x, int y, int z);
bool SetSolid(int x, int y, bool b);
bool GetSolid(int x, int y);
//accessors
int GetX() const { return x; }
int GetY() const { return y; }
std::bitset<REGION_WIDTH*REGION_HEIGHT>* GetSolidBitset() { return &solid; }
private:
const int x;
const int y;
type_t tiles[REGION_WIDTH][REGION_HEIGHT][REGION_DEPTH];
std::bitset<REGION_WIDTH*REGION_HEIGHT> solid;
};
//the memory footprint of the tile and solid data; not including any metadata
constexpr int REGION_FOOTPRINT = REGION_WIDTH * REGION_HEIGHT * REGION_DEPTH * sizeof(Region::type_t) + REGION_SOLID_FOOTPRINT;
#endif
@@ -37,6 +37,20 @@ static int getTile(lua_State* L) {
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());
@@ -65,42 +79,44 @@ static int getDepth(lua_State* L) {
}
static int load(lua_State* L) {
//TODO: fill this
//EMPTY
lua_pushboolean(L, false);
return 1;
}
static int save(lua_State* L) {
//TODO: fill this
//EMPTY
return 0;
}
static int create(lua_State* L) {
//TODO: fill this
//EMPTY
return 0;
}
static int unload(lua_State* L) {
//TODO: fill this
//EMPTY
return 0;
}
static const luaL_Reg regionlib[] = {
{"settile",setTile},
{"gettile",getTile},
{"getx",getX},
{"gety",getY},
{"getwidth",getWidth},
{"getheight",getHeight},
{"getdepth",getDepth},
{"load",load},
{"save",save},
{"create",create},
{"unload",unload},
static const luaL_Reg regionLib[] = {
{"SetTile",setTile},
{"GetTile",getTile},
{"SetSolid",setSolid},
{"GetSolid",getSolid},
{"GetX",getX},
{"GetY",getY},
{"GetWidth",getWidth},
{"GetHeight",getHeight},
{"GetDepth",getDepth},
{"Load",load},
{"Save",save},
{"Create",create},
{"Unload",unload},
{nullptr, nullptr}
};
LUAMOD_API int luaopen_regionapi(lua_State* L) {
luaL_newlib(L, regionlib);
LUAMOD_API int openRegionAPI(lua_State* L) {
luaL_newlib(L, regionLib);
return 1;
}
@@ -24,7 +24,7 @@
#include "lua/lua.hpp"
#define LUA_REGIONLIBNAME "region"
LUAMOD_API int luaopen_regionapi(lua_State* L);
#define TORTUGA_REGION_NAME "Region"
LUAMOD_API int openRegionAPI(lua_State* L);
#endif

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