Compare commits
71 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 93c41bb19c | |||
| bf922ec598 | |||
| de902d2d3d | |||
| 7b3bf24e5d | |||
| de7da81102 | |||
| 6428b02d85 | |||
| 519b8a1e36 | |||
| 967f0653a1 | |||
| b86d393571 | |||
| 6b38501c27 | |||
| 5893342ad8 | |||
| ac4a264f12 | |||
| 43895a462a | |||
| 1bde0ed3f7 | |||
| d903c0df30 | |||
| 9620826d65 | |||
| 0a71f43ef3 | |||
| a47e76845f | |||
| c2eb08bd5e | |||
| 7b76e07231 | |||
| 1dd8042d3d | |||
| c575ee9ce1 | |||
| 1befc76b70 | |||
| 6a6e7f7125 | |||
| bb6e248583 | |||
| f7df4fba6c | |||
| e7403be508 | |||
| 873715b28c | |||
| b1d6e5a314 | |||
| f0453375c4 | |||
| e5a98efd7d | |||
| 14b330009b | |||
| 288b62d3f8 | |||
| c5e8f1b3af | |||
| 980717f9fd | |||
| 68475eee0f | |||
| eeb2400e79 | |||
| 01244005e9 | |||
| c5005b9b07 | |||
| 80a26341b1 | |||
| b7877962f1 | |||
| 688d064085 | |||
| 1c4d53e3ef | |||
| a53a134163 | |||
| 4d12788c53 | |||
| 1beb7cbd5d | |||
| 8358d72a98 | |||
| 4ebff4a25a | |||
| 0ff787abda | |||
| 9b5b48a8ab | |||
| 5dd0fb9e23 | |||
| 7c210e04a5 | |||
| 9236e02101 | |||
| 8f4ebf20da | |||
| 910e51f637 | |||
| 92fc9b4e25 | |||
| 2b8e7241c9 | |||
| 124cb3ad13 | |||
| 6d3400d948 | |||
| 5031352fe3 | |||
| 624369f147 | |||
| 9a7f7b8684 | |||
| fa9487c2f2 | |||
| 9ec1ddab99 | |||
| 6f1c2d0555 | |||
| 01b50d5590 | |||
| 9c673928e6 | |||
| d55dfb90e4 | |||
| 235a05d006 | |||
| dabb7b3b2e | |||
| e756289c2b |
@@ -1,23 +1,25 @@
|
|||||||
The most recent stable windows build can be found [here](https://dl.dropboxusercontent.com/u/46669050/Tortuga.rar).
|
The most recent stable build for Windows can be found [here](https://dl.dropboxusercontent.com/u/46669050/Tortuga.rar).
|
||||||
|
|
||||||
Tortuga is an open source 2D multiplayer role playing game featuring permadeath (deletion of a character upon death). The emphasis of this game is on multiplayer cooperation, competition, exploration and customization. The game runs on customizable server software that can support up to 150 simultaneous players or more.
|
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.
|
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
|
## External Dependencies
|
||||||
|
|
||||||
* [SDL 1.6](http://www.libsdl.org/) - Simple DirectMedia Layer API
|
* [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
|
* [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
|
* [lua 5.2](http://www.lua.org/) - The lua programming language
|
||||||
* [SQLite3](http://www.sqlite.org/) - A lightweight SQL database engine
|
* [SQLite3](http://www.sqlite.org/) - A lightweight SQL database engine
|
||||||
|
|
||||||
## Documentation
|
|
||||||
|
|
||||||
[Tortuga Game Design Document](https://github.com/Ratstail91/Tortuga/blob/docs/design%20doc.docx?raw=true)
|
|
||||||
[Tortuga Technical Document](https://github.com/Ratstail91/Tortuga/blob/docs/technical%20doc.docx?raw=true)
|
|
||||||
|
|
||||||
## Copyright
|
## 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).
|
The current version of Tortuga is released under the [zlib license](http://en.wikipedia.org/wiki/Zlib_License).
|
||||||
|
|
||||||
Copyright (c) 2013, 2014 Kayne Ruse
|
Copyright (c) 2013, 2014 Kayne Ruse
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2013, 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2013, 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
@@ -1,3 +1,24 @@
|
|||||||
|
/* 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_
|
#ifndef CHANNELS_HPP_
|
||||||
#define CHANNELS_HPP_
|
#define CHANNELS_HPP_
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2013, 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
@@ -56,7 +56,7 @@ void ClientApplication::Init(int argc, char** argv) {
|
|||||||
if (SDLNet_Init()) {
|
if (SDLNet_Init()) {
|
||||||
throw(std::runtime_error("Failed to initialize SDL_net"));
|
throw(std::runtime_error("Failed to initialize SDL_net"));
|
||||||
}
|
}
|
||||||
network.Open(0, PACKET_BUFFER_SIZE);
|
network.Open(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientApplication::Proc() {
|
void ClientApplication::Proc() {
|
||||||
@@ -119,13 +119,13 @@ void ClientApplication::LoadScene(SceneList sceneIndex) {
|
|||||||
activeScene = new OptionsMenu(&config);
|
activeScene = new OptionsMenu(&config);
|
||||||
break;
|
break;
|
||||||
case SceneList::LOBBYMENU:
|
case SceneList::LOBBYMENU:
|
||||||
activeScene = new LobbyMenu(&config, &network, &clientIndex);
|
activeScene = new LobbyMenu(&config, &network, &clientIndex, &accountIndex, &characterIndex);
|
||||||
break;
|
break;
|
||||||
case SceneList::INWORLD:
|
case SceneList::INWORLD:
|
||||||
activeScene = new InWorld(&config, &network, &clientIndex);
|
activeScene = new InWorld(&config, &network, &clientIndex, &accountIndex, &characterIndex, &combatMap, &characterMap);
|
||||||
break;
|
break;
|
||||||
case SceneList::INCOMBAT:
|
case SceneList::INCOMBAT:
|
||||||
activeScene = new InCombat();
|
activeScene = new InCombat(&config, &network, &clientIndex, &accountIndex, &characterIndex, &combatMap, &characterMap, &enemyMap);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw(std::logic_error("Failed to recognize the scene index"));
|
throw(std::logic_error("Failed to recognize the scene index"));
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2013, 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
@@ -27,6 +27,11 @@
|
|||||||
|
|
||||||
#include "config_utility.hpp"
|
#include "config_utility.hpp"
|
||||||
#include "udp_network_utility.hpp"
|
#include "udp_network_utility.hpp"
|
||||||
|
#include "character_data.hpp"
|
||||||
|
#include "combat_data.hpp"
|
||||||
|
#include "enemy_data.hpp"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
class ClientApplication {
|
class ClientApplication {
|
||||||
public:
|
public:
|
||||||
@@ -44,9 +49,16 @@ private:
|
|||||||
|
|
||||||
BaseScene* activeScene = nullptr;
|
BaseScene* activeScene = nullptr;
|
||||||
|
|
||||||
|
//shared parameters
|
||||||
ConfigUtility config;
|
ConfigUtility config;
|
||||||
UDPNetworkUtility network;
|
UDPNetworkUtility network;
|
||||||
int clientIndex = -1; //replace with a struct?
|
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
|
#endif
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2013, 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
@@ -25,7 +25,25 @@
|
|||||||
//Public access members
|
//Public access members
|
||||||
//-------------------------
|
//-------------------------
|
||||||
|
|
||||||
InCombat::InCombat() {
|
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)
|
||||||
|
{
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,6 +67,13 @@ 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) {
|
void InCombat::Render(SDL_Surface* const screen) {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
@@ -57,6 +82,12 @@ void InCombat::Render(SDL_Surface* const screen) {
|
|||||||
//Event handlers
|
//Event handlers
|
||||||
//-------------------------
|
//-------------------------
|
||||||
|
|
||||||
|
void InCombat::QuitEvent() {
|
||||||
|
//exit the game AND the server
|
||||||
|
// RequestDisconnect();
|
||||||
|
SetNextScene(SceneList::MAINMENU);
|
||||||
|
}
|
||||||
|
|
||||||
void InCombat::MouseMotion(SDL_MouseMotionEvent const& motion) {
|
void InCombat::MouseMotion(SDL_MouseMotionEvent const& motion) {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
@@ -80,3 +111,15 @@ void InCombat::KeyDown(SDL_KeyboardEvent const& key) {
|
|||||||
void InCombat::KeyUp(SDL_KeyboardEvent const& key) {
|
void InCombat::KeyUp(SDL_KeyboardEvent const& key) {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
//Network handlers
|
||||||
|
//-------------------------
|
||||||
|
|
||||||
|
//TODO: network handlers
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
//Server control
|
||||||
|
//-------------------------
|
||||||
|
|
||||||
|
//TODO: server control
|
||||||
@@ -19,62 +19,86 @@
|
|||||||
* 3. This notice may not be removed or altered from any source
|
* 3. This notice may not be removed or altered from any source
|
||||||
* distribution.
|
* distribution.
|
||||||
*/
|
*/
|
||||||
#ifndef EDITORSCENE_HPP_
|
#ifndef INCOMBAT_HPP_
|
||||||
#define EDITORSCENE_HPP_
|
#define INCOMBAT_HPP_
|
||||||
|
|
||||||
#include "base_scene.hpp"
|
//network
|
||||||
|
#include "udp_network_utility.hpp"
|
||||||
|
|
||||||
#include "config_utility.hpp"
|
//graphics
|
||||||
#include "image.hpp"
|
#include "image.hpp"
|
||||||
#include "raster_font.hpp"
|
#include "raster_font.hpp"
|
||||||
#include "menu_bar.hpp"
|
#include "button.hpp"
|
||||||
|
|
||||||
#include "region_pager.hpp"
|
//common
|
||||||
#include "map_allocator.hpp"
|
#include "config_utility.hpp"
|
||||||
#include "map_file_format.hpp"
|
#include "frame_rate.hpp"
|
||||||
#include "tile_sheet.hpp"
|
|
||||||
|
|
||||||
class EditorScene : public BaseScene {
|
#include "combat_data.hpp"
|
||||||
|
#include "character_data.hpp"
|
||||||
|
#include "enemy_data.hpp"
|
||||||
|
|
||||||
|
//client
|
||||||
|
#include "base_scene.hpp"
|
||||||
|
|
||||||
|
class InCombat : public BaseScene {
|
||||||
public:
|
public:
|
||||||
//Public access members
|
//Public access members
|
||||||
EditorScene(ConfigUtility* const);
|
InCombat(
|
||||||
~EditorScene();
|
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:
|
protected:
|
||||||
//Frame loop
|
//Frame loop
|
||||||
void FrameStart();
|
void FrameStart();
|
||||||
void Update(double delta);
|
void Update(double delta);
|
||||||
void FrameEnd();
|
void FrameEnd();
|
||||||
|
void RenderFrame();
|
||||||
void Render(SDL_Surface* const);
|
void Render(SDL_Surface* const);
|
||||||
|
|
||||||
//Event handlers
|
//Event handlers
|
||||||
|
void QuitEvent();
|
||||||
void MouseMotion(SDL_MouseMotionEvent const&);
|
void MouseMotion(SDL_MouseMotionEvent const&);
|
||||||
void MouseButtonDown(SDL_MouseButtonEvent const&);
|
void MouseButtonDown(SDL_MouseButtonEvent const&);
|
||||||
void MouseButtonUp(SDL_MouseButtonEvent const&);
|
void MouseButtonUp(SDL_MouseButtonEvent const&);
|
||||||
void KeyDown(SDL_KeyboardEvent const&);
|
void KeyDown(SDL_KeyboardEvent const&);
|
||||||
void KeyUp(SDL_KeyboardEvent const&);
|
void KeyUp(SDL_KeyboardEvent const&);
|
||||||
|
|
||||||
//members
|
//Network handlers
|
||||||
void HandleMenuOption(int entry, int drop);
|
void HandlePacket(SerialPacket);
|
||||||
|
void HandleDisconnect(SerialPacket);
|
||||||
|
//TODO: more
|
||||||
|
|
||||||
//globals
|
//Server control
|
||||||
|
void SendPlayerUpdate();
|
||||||
|
void RequestDisconnect();
|
||||||
|
void RequestShutdown();
|
||||||
|
//TODO: more
|
||||||
|
|
||||||
|
//shared parameters
|
||||||
ConfigUtility& config;
|
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;
|
||||||
|
|
||||||
//debugging tools
|
//graphics
|
||||||
void DrawToDebugInfo(std::string, int line);
|
//TODO: graphics
|
||||||
Image debugInfo;
|
|
||||||
bool debugOpen = true;
|
|
||||||
|
|
||||||
RasterFont font;
|
//UI
|
||||||
Image buttonImage;
|
//TODO: UI
|
||||||
MenuBar menuBar;
|
FrameRate fps;
|
||||||
|
|
||||||
struct {
|
|
||||||
int x = 0, y = 0;
|
|
||||||
} camera;
|
|
||||||
|
|
||||||
RegionPager<BlankAllocator, DummyFormat> pager;
|
|
||||||
TileSheet tsheet;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2013, 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
@@ -31,10 +31,22 @@
|
|||||||
//Public access members
|
//Public access members
|
||||||
//-------------------------
|
//-------------------------
|
||||||
|
|
||||||
InWorld::InWorld(ConfigUtility* const argConfig, UDPNetworkUtility* const argNetwork, int* const argClientIndex):
|
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),
|
config(*argConfig),
|
||||||
network(*argNetwork),
|
network(*argNetwork),
|
||||||
clientIndex(*argClientIndex)
|
clientIndex(*argClientIndex),
|
||||||
|
accountIndex(*argAccountIndex),
|
||||||
|
characterIndex(*argCharacterIndex),
|
||||||
|
combatMap(*argCombatMap),
|
||||||
|
characterMap(*argCharacterMap)
|
||||||
{
|
{
|
||||||
//setup the utility objects
|
//setup the utility objects
|
||||||
buttonImage.LoadSurface(config["dir.interface"] + "button_menu.bmp");
|
buttonImage.LoadSurface(config["dir.interface"] + "button_menu.bmp");
|
||||||
@@ -61,25 +73,8 @@ InWorld::InWorld(ConfigUtility* const argConfig, UDPNetworkUtility* const argNet
|
|||||||
//TODO: add the tilesheet to the map system?
|
//TODO: add the tilesheet to the map system?
|
||||||
tileSheet.Load(config["dir.tilesets"] + "terrain.bmp", 12, 15);
|
tileSheet.Load(config["dir.tilesets"] + "terrain.bmp", 12, 15);
|
||||||
|
|
||||||
//create the server-side player object
|
|
||||||
//TODO: the login system needs an overhaul
|
|
||||||
SerialPacket packet;
|
|
||||||
packet.meta.type = SerialPacket::Type::PLAYER_NEW;
|
|
||||||
packet.playerInfo.clientIndex = clientIndex;
|
|
||||||
snprintf(packet.playerInfo.handle, PACKET_STRING_SIZE, "%s", config["player.handle"].c_str());
|
|
||||||
snprintf(packet.playerInfo.avatar, PACKET_STRING_SIZE, "%s", config["player.avatar"].c_str());
|
|
||||||
packet.playerInfo.position = {0,0};
|
|
||||||
packet.playerInfo.motion = {0,0};
|
|
||||||
|
|
||||||
//send it
|
|
||||||
char buffer[PACKET_BUFFER_SIZE];
|
|
||||||
serialize(&packet, buffer);
|
|
||||||
network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE);
|
|
||||||
|
|
||||||
//request a sync
|
//request a sync
|
||||||
packet.meta.type = SerialPacket::Type::SYNCHRONIZE;
|
RequestSynchronize();
|
||||||
serialize(&packet, buffer);
|
|
||||||
network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE);
|
|
||||||
|
|
||||||
//debug
|
//debug
|
||||||
// RequestRegion(0, 0);
|
// RequestRegion(0, 0);
|
||||||
@@ -101,22 +96,19 @@ void InWorld::Update(double delta) {
|
|||||||
SerialPacket packet;
|
SerialPacket packet;
|
||||||
|
|
||||||
//suck in all waiting packets
|
//suck in all waiting packets
|
||||||
while(network.Receive()) {
|
while(network.Receive(&packet)) {
|
||||||
deserialize(&packet, network.GetInData());
|
|
||||||
packet.meta.srcAddress = network.GetInPacket()->address;
|
|
||||||
HandlePacket(packet);
|
HandlePacket(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
//update the characters
|
//update the characters
|
||||||
for (auto& it : playerCharacters) {
|
for (auto& it : characterMap) {
|
||||||
it.second.Update(delta);
|
it.second.Update(delta);
|
||||||
}
|
}
|
||||||
//TODO: sort the players and entities by Y position
|
|
||||||
|
|
||||||
//update the camera
|
//update the camera
|
||||||
if(localCharacter) {
|
if(localCharacter) {
|
||||||
camera.x = localCharacter->GetPosition().x - camera.marginX;
|
camera.x = localCharacter->position.x - camera.marginX;
|
||||||
camera.y = localCharacter->GetPosition().y - camera.marginY;
|
camera.y = localCharacter->position.y - camera.marginY;
|
||||||
}
|
}
|
||||||
|
|
||||||
//check the map
|
//check the map
|
||||||
@@ -131,27 +123,25 @@ void InWorld::RenderFrame() {
|
|||||||
// SDL_FillRect(GetScreen(), 0, 0);
|
// SDL_FillRect(GetScreen(), 0, 0);
|
||||||
Render(GetScreen());
|
Render(GetScreen());
|
||||||
SDL_Flip(GetScreen());
|
SDL_Flip(GetScreen());
|
||||||
|
fps.Calculate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InWorld::Render(SDL_Surface* const screen) {
|
void InWorld::Render(SDL_Surface* const screen) {
|
||||||
//draw the map
|
//draw the map
|
||||||
//TODO: figure out something to fix the region container access
|
|
||||||
for (auto it = regionPager.GetContainer()->begin(); it != regionPager.GetContainer()->end(); it++) {
|
for (auto it = regionPager.GetContainer()->begin(); it != regionPager.GetContainer()->end(); it++) {
|
||||||
tileSheet.DrawRegionTo(screen, *it, camera.x, camera.y);
|
tileSheet.DrawRegionTo(screen, *it, camera.x, camera.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
//draw characters
|
//draw characters
|
||||||
for (auto& it : playerCharacters) {
|
for (auto& it : characterMap) {
|
||||||
|
//TODO: drawing order according to Y position
|
||||||
it.second.DrawTo(screen, camera.x, camera.y);
|
it.second.DrawTo(screen, camera.x, camera.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
//draw UI
|
//draw UI
|
||||||
disconnectButton.DrawTo(screen);
|
disconnectButton.DrawTo(screen);
|
||||||
shutDownButton.DrawTo(screen);
|
shutDownButton.DrawTo(screen);
|
||||||
|
|
||||||
font.DrawStringTo(to_string_custom(fps.GetFrameRate()), screen, 0, 0);
|
font.DrawStringTo(to_string_custom(fps.GetFrameRate()), screen, 0, 0);
|
||||||
|
|
||||||
fps.Calculate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
@@ -161,6 +151,7 @@ void InWorld::Render(SDL_Surface* const screen) {
|
|||||||
void InWorld::QuitEvent() {
|
void InWorld::QuitEvent() {
|
||||||
//exit the game AND the server
|
//exit the game AND the server
|
||||||
RequestDisconnect();
|
RequestDisconnect();
|
||||||
|
SetNextScene(SceneList::MAINMENU);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InWorld::MouseMotion(SDL_MouseMotionEvent const& motion) {
|
void InWorld::MouseMotion(SDL_MouseMotionEvent const& motion) {
|
||||||
@@ -192,29 +183,29 @@ void InWorld::KeyDown(SDL_KeyboardEvent const& key) {
|
|||||||
//player movement
|
//player movement
|
||||||
case SDLK_LEFT:
|
case SDLK_LEFT:
|
||||||
if (localCharacter) {
|
if (localCharacter) {
|
||||||
localCharacter->AdjustDirection(PlayerCharacter::Direction::WEST);
|
localCharacter->motion.x -= CHARACTER_WALKING_SPEED;
|
||||||
SendState();
|
SendPlayerUpdate();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDLK_RIGHT:
|
case SDLK_RIGHT:
|
||||||
if (localCharacter) {
|
if (localCharacter) {
|
||||||
localCharacter->AdjustDirection(PlayerCharacter::Direction::EAST);
|
localCharacter->motion.x += CHARACTER_WALKING_SPEED;
|
||||||
SendState();
|
SendPlayerUpdate();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDLK_UP:
|
case SDLK_UP:
|
||||||
if (localCharacter) {
|
if (localCharacter) {
|
||||||
localCharacter->AdjustDirection(PlayerCharacter::Direction::NORTH);
|
localCharacter->motion.y -= CHARACTER_WALKING_SPEED;
|
||||||
SendState();
|
SendPlayerUpdate();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDLK_DOWN:
|
case SDLK_DOWN:
|
||||||
if (localCharacter) {
|
if (localCharacter) {
|
||||||
localCharacter->AdjustDirection(PlayerCharacter::Direction::SOUTH);
|
localCharacter->motion.y += CHARACTER_WALKING_SPEED;
|
||||||
SendState();
|
SendPlayerUpdate();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -225,29 +216,29 @@ void InWorld::KeyUp(SDL_KeyboardEvent const& key) {
|
|||||||
//player movement
|
//player movement
|
||||||
case SDLK_LEFT:
|
case SDLK_LEFT:
|
||||||
if (localCharacter) {
|
if (localCharacter) {
|
||||||
localCharacter->AdjustDirection(PlayerCharacter::Direction::EAST);
|
localCharacter->motion.x += CHARACTER_WALKING_SPEED;
|
||||||
SendState();
|
SendPlayerUpdate();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDLK_RIGHT:
|
case SDLK_RIGHT:
|
||||||
if (localCharacter) {
|
if (localCharacter) {
|
||||||
localCharacter->AdjustDirection(PlayerCharacter::Direction::WEST);
|
localCharacter->motion.x -= CHARACTER_WALKING_SPEED;
|
||||||
SendState();
|
SendPlayerUpdate();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDLK_UP:
|
case SDLK_UP:
|
||||||
if (localCharacter) {
|
if (localCharacter) {
|
||||||
localCharacter->AdjustDirection(PlayerCharacter::Direction::SOUTH);
|
localCharacter->motion.y += CHARACTER_WALKING_SPEED;
|
||||||
SendState();
|
SendPlayerUpdate();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDLK_DOWN:
|
case SDLK_DOWN:
|
||||||
if (localCharacter) {
|
if (localCharacter) {
|
||||||
localCharacter->AdjustDirection(PlayerCharacter::Direction::NORTH);
|
localCharacter->motion.y -= CHARACTER_WALKING_SPEED;
|
||||||
SendState();
|
SendPlayerUpdate();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -262,21 +253,21 @@ void InWorld::HandlePacket(SerialPacket packet) {
|
|||||||
case SerialPacket::Type::DISCONNECT:
|
case SerialPacket::Type::DISCONNECT:
|
||||||
HandleDisconnect(packet);
|
HandleDisconnect(packet);
|
||||||
break;
|
break;
|
||||||
case SerialPacket::Type::PLAYER_NEW:
|
|
||||||
HandlePlayerNew(packet);
|
|
||||||
break;
|
|
||||||
case SerialPacket::Type::PLAYER_DELETE:
|
|
||||||
HandlePlayerDelete(packet);
|
|
||||||
break;
|
|
||||||
case SerialPacket::Type::PLAYER_UPDATE:
|
|
||||||
HandlePlayerUpdate(packet);
|
|
||||||
break;
|
|
||||||
case SerialPacket::Type::REGION_CONTENT:
|
case SerialPacket::Type::REGION_CONTENT:
|
||||||
HandleRegionContent(packet);
|
HandleRegionContent(packet);
|
||||||
break;
|
break;
|
||||||
|
case SerialPacket::Type::CHARACTER_UPDATE:
|
||||||
|
HandleCharacterUpdate(packet);
|
||||||
|
break;
|
||||||
|
case SerialPacket::Type::CHARACTER_NEW:
|
||||||
|
HandleCharacterNew(packet);
|
||||||
|
break;
|
||||||
|
case SerialPacket::Type::CHARACTER_DELETE:
|
||||||
|
HandleCharacterDelete(packet);
|
||||||
|
break;
|
||||||
//handle errors
|
//handle errors
|
||||||
default:
|
default:
|
||||||
throw(std::runtime_error("Unknown SerialPacket::Type encountered"));
|
throw(std::runtime_error(std::string() + "Unknown SerialPacket::Type encountered in InWorld: " + to_string_custom(int(packet.meta.type))));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -284,120 +275,141 @@ void InWorld::HandlePacket(SerialPacket packet) {
|
|||||||
void InWorld::HandleDisconnect(SerialPacket packet) {
|
void InWorld::HandleDisconnect(SerialPacket packet) {
|
||||||
network.Unbind(Channels::SERVER);
|
network.Unbind(Channels::SERVER);
|
||||||
clientIndex = -1;
|
clientIndex = -1;
|
||||||
|
accountIndex = -1;
|
||||||
|
characterIndex = -1;
|
||||||
SetNextScene(SceneList::MAINMENU);
|
SetNextScene(SceneList::MAINMENU);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InWorld::HandlePlayerNew(SerialPacket packet) {
|
|
||||||
if (playerCharacters.find(packet.playerInfo.playerIndex) != playerCharacters.end()) {
|
|
||||||
throw(std::runtime_error("Cannot create duplicate players"));
|
|
||||||
}
|
|
||||||
|
|
||||||
playerCharacters[packet.playerInfo.playerIndex].GetSprite()->LoadSurface(config["dir.sprites"] + packet.playerInfo.avatar, 4, 4);
|
|
||||||
playerCharacters[packet.playerInfo.playerIndex].SetPosition(packet.playerInfo.position);
|
|
||||||
playerCharacters[packet.playerInfo.playerIndex].SetMotion(packet.playerInfo.motion);
|
|
||||||
playerCharacters[packet.playerInfo.playerIndex].ResetDirection();
|
|
||||||
|
|
||||||
//catch this client's player object
|
|
||||||
if (packet.playerInfo.clientIndex == clientIndex && !localCharacter) {
|
|
||||||
playerIndex = packet.playerInfo.playerIndex;
|
|
||||||
localCharacter = &playerCharacters[playerIndex];
|
|
||||||
//setup the camera
|
|
||||||
camera.width = GetScreen()->w;
|
|
||||||
camera.height = GetScreen()->h;
|
|
||||||
//center on the player's character
|
|
||||||
camera.marginX = (GetScreen()->w / 2 - localCharacter->GetSprite()->GetImage()->GetClipW() / 2);
|
|
||||||
camera.marginY = (GetScreen()->h / 2 - localCharacter->GetSprite()->GetImage()->GetClipH() / 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void InWorld::HandlePlayerDelete(SerialPacket packet) {
|
|
||||||
if (playerCharacters.find(packet.playerInfo.playerIndex) == playerCharacters.end()) {
|
|
||||||
throw(std::runtime_error("Cannot delete non-existant players"));
|
|
||||||
}
|
|
||||||
|
|
||||||
playerCharacters.erase(packet.playerInfo.playerIndex);
|
|
||||||
|
|
||||||
//catch this client's player object
|
|
||||||
if (packet.playerInfo.clientIndex == clientIndex) {
|
|
||||||
playerIndex = -1;
|
|
||||||
localCharacter = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void InWorld::HandlePlayerUpdate(SerialPacket packet) {
|
|
||||||
if (playerCharacters.find(packet.playerInfo.playerIndex) == playerCharacters.end()) {
|
|
||||||
HandlePlayerNew(packet);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//update only if the message didn't originate from here
|
|
||||||
if (packet.playerInfo.clientIndex != clientIndex) {
|
|
||||||
playerCharacters[packet.playerInfo.playerIndex].SetPosition(packet.playerInfo.position);
|
|
||||||
playerCharacters[packet.playerInfo.playerIndex].SetMotion(packet.playerInfo.motion);
|
|
||||||
}
|
|
||||||
playerCharacters[packet.playerInfo.playerIndex].ResetDirection();
|
|
||||||
}
|
|
||||||
|
|
||||||
void InWorld::HandleRegionContent(SerialPacket packet) {
|
void InWorld::HandleRegionContent(SerialPacket packet) {
|
||||||
//replace existing regions
|
//replace existing regions
|
||||||
if (regionPager.FindRegion(packet.regionInfo.x, packet.regionInfo.y)) {
|
regionPager.UnloadRegion(packet.regionInfo.x, packet.regionInfo.y);
|
||||||
regionPager.UnloadRegion(packet.regionInfo.x, packet.regionInfo.y);
|
|
||||||
}
|
|
||||||
regionPager.PushRegion(packet.regionInfo.region);
|
regionPager.PushRegion(packet.regionInfo.region);
|
||||||
packet.regionInfo.region = nullptr;
|
packet.regionInfo.region = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InWorld::HandleCharacterUpdate(SerialPacket packet) {
|
||||||
|
if (characterMap.find(packet.characterInfo.characterIndex) == characterMap.end()) {
|
||||||
|
HandleCharacterNew(packet);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//update only if the message didn't originate from here
|
||||||
|
if (packet.characterInfo.clientIndex != clientIndex) {
|
||||||
|
characterMap[packet.characterInfo.characterIndex].position = packet.characterInfo.position;
|
||||||
|
characterMap[packet.characterInfo.characterIndex].motion = packet.characterInfo.motion;
|
||||||
|
}
|
||||||
|
characterMap[packet.characterInfo.characterIndex].CorrectSprite();
|
||||||
|
}
|
||||||
|
|
||||||
|
void InWorld::HandleCharacterNew(SerialPacket packet) {
|
||||||
|
if (characterMap.find(packet.characterInfo.characterIndex) != characterMap.end()) {
|
||||||
|
throw(std::runtime_error("Cannot create duplicate characters"));
|
||||||
|
}
|
||||||
|
|
||||||
|
//create the character object
|
||||||
|
CharacterData& character = characterMap[packet.characterInfo.characterIndex];
|
||||||
|
|
||||||
|
//set the members
|
||||||
|
character.handle = packet.characterInfo.handle;
|
||||||
|
character.avatar = packet.characterInfo.avatar;
|
||||||
|
character.sprite.LoadSurface(config["dir.sprites"] + character.avatar, 4, 4);
|
||||||
|
character.mapIndex = packet.characterInfo.mapIndex;
|
||||||
|
character.position = packet.characterInfo.position;
|
||||||
|
character.motion = packet.characterInfo.motion;
|
||||||
|
character.stats = packet.characterInfo.stats;
|
||||||
|
|
||||||
|
character.CorrectSprite();
|
||||||
|
|
||||||
|
//catch this client's player object
|
||||||
|
if (packet.characterInfo.characterIndex == characterIndex && !localCharacter) {
|
||||||
|
localCharacter = &character;
|
||||||
|
|
||||||
|
//setup the camera
|
||||||
|
//TODO: can't change the screen size?
|
||||||
|
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(SerialPacket packet) {
|
||||||
|
//TODO: authenticate when own character is being deleted (linked to a TODO in the server)
|
||||||
|
//catch this client's player object
|
||||||
|
if (packet.characterInfo.characterIndex == characterIndex) {
|
||||||
|
characterIndex = -1;
|
||||||
|
localCharacter = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
characterMap.erase(packet.characterInfo.characterIndex);
|
||||||
|
}
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
//Server control
|
//Server control
|
||||||
//-------------------------
|
//-------------------------
|
||||||
|
|
||||||
void InWorld::SendState() {
|
void InWorld::RequestSynchronize() {
|
||||||
|
SerialPacket packet;
|
||||||
|
|
||||||
|
//request a sync
|
||||||
|
packet.meta.type = SerialPacket::Type::SYNCHRONIZE;
|
||||||
|
packet.clientInfo.clientIndex = clientIndex;
|
||||||
|
packet.clientInfo.accountIndex = accountIndex;
|
||||||
|
packet.clientInfo.characterIndex = characterIndex;
|
||||||
|
|
||||||
|
network.SendTo(Channels::SERVER, &packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InWorld::SendPlayerUpdate() {
|
||||||
SerialPacket packet;
|
SerialPacket packet;
|
||||||
char buffer[PACKET_BUFFER_SIZE];
|
|
||||||
|
|
||||||
//pack the packet
|
//pack the packet
|
||||||
packet.meta.type = SerialPacket::Type::PLAYER_UPDATE;
|
packet.meta.type = SerialPacket::Type::CHARACTER_UPDATE;
|
||||||
packet.playerInfo.clientIndex = clientIndex;
|
packet.characterInfo.clientIndex = clientIndex;
|
||||||
packet.playerInfo.playerIndex = playerIndex;
|
packet.characterInfo.accountIndex = accountIndex;
|
||||||
packet.playerInfo.position = localCharacter->GetPosition();
|
packet.characterInfo.characterIndex = characterIndex;
|
||||||
packet.playerInfo.motion = localCharacter->GetMotion();
|
packet.characterInfo.position = localCharacter->position;
|
||||||
|
packet.characterInfo.motion = localCharacter->motion;
|
||||||
|
|
||||||
serialize(&packet, buffer);
|
network.SendTo(Channels::SERVER, &packet);
|
||||||
network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InWorld::RequestDisconnect() {
|
void InWorld::RequestDisconnect() {
|
||||||
SerialPacket packet;
|
SerialPacket packet;
|
||||||
char buffer[PACKET_BUFFER_SIZE];
|
|
||||||
|
|
||||||
//send a disconnect request
|
//send a disconnect request
|
||||||
packet.meta.type = SerialPacket::Type::DISCONNECT;
|
packet.meta.type = SerialPacket::Type::DISCONNECT;
|
||||||
packet.clientInfo.index = clientIndex;
|
packet.clientInfo.clientIndex = clientIndex;
|
||||||
serialize(&packet, buffer);
|
packet.clientInfo.accountIndex = accountIndex;
|
||||||
network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE);
|
packet.clientInfo.characterIndex = characterIndex;
|
||||||
|
|
||||||
|
network.SendTo(Channels::SERVER, &packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InWorld::RequestShutDown() {
|
void InWorld::RequestShutDown() {
|
||||||
SerialPacket packet;
|
SerialPacket packet;
|
||||||
char buffer[PACKET_BUFFER_SIZE];
|
|
||||||
|
|
||||||
//send a shutdown request
|
//send a shutdown request
|
||||||
packet.meta.type = SerialPacket::Type::SHUTDOWN;
|
packet.meta.type = SerialPacket::Type::SHUTDOWN;
|
||||||
packet.clientInfo.index = clientIndex;
|
packet.clientInfo.clientIndex = clientIndex;
|
||||||
serialize(&packet, buffer);
|
packet.clientInfo.accountIndex = accountIndex;
|
||||||
network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE);
|
packet.clientInfo.characterIndex = characterIndex;
|
||||||
|
|
||||||
|
network.SendTo(Channels::SERVER, &packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InWorld::RequestRegion(int x, int y) {
|
void InWorld::RequestRegion(int mapIndex, int x, int y) {
|
||||||
SerialPacket packet;
|
SerialPacket packet;
|
||||||
char buffer[PACKET_BUFFER_SIZE];
|
|
||||||
|
|
||||||
//pack the region's data
|
//pack the region's data
|
||||||
packet.meta.type = SerialPacket::Type::REGION_REQUEST;
|
packet.meta.type = SerialPacket::Type::REGION_REQUEST;
|
||||||
|
packet.regionInfo.mapIndex = mapIndex;
|
||||||
packet.regionInfo.x = x;
|
packet.regionInfo.x = x;
|
||||||
packet.regionInfo.y = y;
|
packet.regionInfo.y = y;
|
||||||
serialize(&packet, buffer);
|
|
||||||
network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE);
|
network.SendTo(Channels::SERVER, &packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
@@ -433,7 +445,7 @@ void InWorld::UpdateMap() {
|
|||||||
for (int i = xStart; i <= xEnd; i += REGION_WIDTH) {
|
for (int i = xStart; i <= xEnd; i += REGION_WIDTH) {
|
||||||
for (int j = yStart; j <= yEnd; j += REGION_HEIGHT) {
|
for (int j = yStart; j <= yEnd; j += REGION_HEIGHT) {
|
||||||
if (!regionPager.FindRegion(i, j)) {
|
if (!regionPager.FindRegion(i, j)) {
|
||||||
RequestRegion(i, j);
|
RequestRegion(0, i, j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2013, 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
@@ -29,8 +29,6 @@
|
|||||||
|
|
||||||
//networking
|
//networking
|
||||||
#include "udp_network_utility.hpp"
|
#include "udp_network_utility.hpp"
|
||||||
#include "serial_packet.hpp"
|
|
||||||
#include "serial.hpp"
|
|
||||||
|
|
||||||
//graphics
|
//graphics
|
||||||
#include "image.hpp"
|
#include "image.hpp"
|
||||||
@@ -42,9 +40,11 @@
|
|||||||
#include "config_utility.hpp"
|
#include "config_utility.hpp"
|
||||||
#include "frame_rate.hpp"
|
#include "frame_rate.hpp"
|
||||||
|
|
||||||
|
#include "combat_data.hpp"
|
||||||
|
#include "character_data.hpp"
|
||||||
|
|
||||||
//client
|
//client
|
||||||
#include "base_scene.hpp"
|
#include "base_scene.hpp"
|
||||||
#include "player_character.hpp"
|
|
||||||
|
|
||||||
//STL
|
//STL
|
||||||
#include <map>
|
#include <map>
|
||||||
@@ -52,7 +52,15 @@
|
|||||||
class InWorld : public BaseScene {
|
class InWorld : public BaseScene {
|
||||||
public:
|
public:
|
||||||
//Public access members
|
//Public access members
|
||||||
InWorld(ConfigUtility* const, UDPNetworkUtility* const, int* const);
|
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();
|
~InWorld();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -74,25 +82,29 @@ protected:
|
|||||||
//Network handlers
|
//Network handlers
|
||||||
void HandlePacket(SerialPacket);
|
void HandlePacket(SerialPacket);
|
||||||
void HandleDisconnect(SerialPacket);
|
void HandleDisconnect(SerialPacket);
|
||||||
void HandlePlayerNew(SerialPacket);
|
void HandleCharacterNew(SerialPacket);
|
||||||
void HandlePlayerDelete(SerialPacket);
|
void HandleCharacterDelete(SerialPacket);
|
||||||
void HandlePlayerUpdate(SerialPacket);
|
void HandleCharacterUpdate(SerialPacket);
|
||||||
void HandleRegionContent(SerialPacket);
|
void HandleRegionContent(SerialPacket);
|
||||||
|
|
||||||
//Server control
|
//Server control
|
||||||
void SendState();
|
void RequestSynchronize();
|
||||||
|
void SendPlayerUpdate();
|
||||||
void RequestDisconnect();
|
void RequestDisconnect();
|
||||||
void RequestShutDown();
|
void RequestShutDown();
|
||||||
void RequestRegion(int x, int y);
|
void RequestRegion(int mapIndex, int x, int y);
|
||||||
|
|
||||||
//utilities
|
//utilities
|
||||||
void UpdateMap();
|
void UpdateMap();
|
||||||
|
|
||||||
//globals
|
//shared parameters
|
||||||
ConfigUtility& config;
|
ConfigUtility& config;
|
||||||
FrameRate fps;
|
|
||||||
UDPNetworkUtility& network;
|
UDPNetworkUtility& network;
|
||||||
int& clientIndex;
|
int& clientIndex;
|
||||||
|
int& accountIndex;
|
||||||
|
int& characterIndex;
|
||||||
|
std::map<int, CombatData>& combatMap;
|
||||||
|
std::map<int, CharacterData>& characterMap;
|
||||||
|
|
||||||
//graphics
|
//graphics
|
||||||
Image buttonImage;
|
Image buttonImage;
|
||||||
@@ -105,17 +117,16 @@ protected:
|
|||||||
//UI
|
//UI
|
||||||
Button disconnectButton;
|
Button disconnectButton;
|
||||||
Button shutDownButton;
|
Button shutDownButton;
|
||||||
//TODO: Fix the camera
|
//TODO: Review the camera
|
||||||
struct {
|
struct {
|
||||||
int x = 0, y = 0;
|
int x = 0, y = 0;
|
||||||
int width = 0, height = 0;
|
int width = 0, height = 0;
|
||||||
int marginX = 0, marginY = 0;
|
int marginX = 0, marginY = 0;
|
||||||
} camera;
|
} camera;
|
||||||
|
FrameRate fps;
|
||||||
|
|
||||||
//game
|
//game
|
||||||
std::map<int, PlayerCharacter> playerCharacters;
|
CharacterData* localCharacter = nullptr;
|
||||||
PlayerCharacter* localCharacter = nullptr;
|
|
||||||
int playerIndex = -1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2013, 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
@@ -30,10 +30,18 @@
|
|||||||
//Public access members
|
//Public access members
|
||||||
//-------------------------
|
//-------------------------
|
||||||
|
|
||||||
LobbyMenu::LobbyMenu(ConfigUtility* const argConfig, UDPNetworkUtility* const argNetwork, int* const argClientIndex):
|
LobbyMenu::LobbyMenu(
|
||||||
|
ConfigUtility* const argConfig,
|
||||||
|
UDPNetworkUtility* const argNetwork,
|
||||||
|
int* const argClientIndex,
|
||||||
|
int* const argAccountIndex,
|
||||||
|
int* const argCharacterIndex
|
||||||
|
):
|
||||||
config(*argConfig),
|
config(*argConfig),
|
||||||
network(*argNetwork),
|
network(*argNetwork),
|
||||||
clientIndex(*argClientIndex)
|
clientIndex(*argClientIndex),
|
||||||
|
accountIndex(*argAccountIndex),
|
||||||
|
characterIndex(*argCharacterIndex)
|
||||||
{
|
{
|
||||||
//setup the utility objects
|
//setup the utility objects
|
||||||
image.LoadSurface(config["dir.interface"] + "button_menu.bmp");
|
image.LoadSurface(config["dir.interface"] + "button_menu.bmp");
|
||||||
@@ -78,11 +86,9 @@ void LobbyMenu::FrameStart() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LobbyMenu::Update(double delta) {
|
void LobbyMenu::Update(double delta) {
|
||||||
//suck in all waiting packets
|
//suck in and process all waiting packets
|
||||||
SerialPacket packet;
|
SerialPacket packet;
|
||||||
while(network.Receive()) {
|
while(network.Receive(&packet)) {
|
||||||
deserialize(&packet, network.GetInData());
|
|
||||||
packet.meta.srcAddress = network.GetInPacket()->address;
|
|
||||||
HandlePacket(packet);
|
HandlePacket(packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -93,6 +99,7 @@ void LobbyMenu::FrameEnd() {
|
|||||||
|
|
||||||
void LobbyMenu::Render(SDL_Surface* const screen) {
|
void LobbyMenu::Render(SDL_Surface* const screen) {
|
||||||
//TODO: I need a proper UI system for the entire client and the editor
|
//TODO: I need a proper UI system for the entire client and the editor
|
||||||
|
|
||||||
//UI
|
//UI
|
||||||
search.DrawTo(screen);
|
search.DrawTo(screen);
|
||||||
join.DrawTo(screen);
|
join.DrawTo(screen);
|
||||||
@@ -118,7 +125,7 @@ void LobbyMenu::Render(SDL_Surface* const screen) {
|
|||||||
font.DrawStringTo("?", screen, listBox.x - font.GetCharW(), listBox.y + i*listBox.h);
|
font.DrawStringTo("?", screen, listBox.x - font.GetCharW(), listBox.y + i*listBox.h);
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: ping?
|
//TODO: ping/delay?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,14 +147,10 @@ void LobbyMenu::MouseButtonDown(SDL_MouseButtonEvent const& button) {
|
|||||||
|
|
||||||
void LobbyMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) {
|
void LobbyMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) {
|
||||||
if (search.MouseButtonUp(button) == Button::State::HOVER) {
|
if (search.MouseButtonUp(button) == Button::State::HOVER) {
|
||||||
//the vars
|
|
||||||
SerialPacket packet;
|
|
||||||
char buffer[PACKET_BUFFER_SIZE];
|
|
||||||
|
|
||||||
//broadcast to the network, or a specific server
|
//broadcast to the network, or a specific server
|
||||||
|
SerialPacket packet;
|
||||||
packet.meta.type = SerialPacket::Type::BROADCAST_REQUEST;
|
packet.meta.type = SerialPacket::Type::BROADCAST_REQUEST;
|
||||||
serialize(&packet, buffer);
|
network.SendTo(config["server.host"].c_str(), config.Int("server.port"), &packet);
|
||||||
network.Send(config["server.host"].c_str(), config.Int("server.port"), buffer, PACKET_BUFFER_SIZE);
|
|
||||||
|
|
||||||
//reset the server list
|
//reset the server list
|
||||||
serverInfo.clear();
|
serverInfo.clear();
|
||||||
@@ -155,15 +158,15 @@ void LobbyMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
else if (join.MouseButtonUp(button) == Button::State::HOVER && selection != nullptr && selection->compatible) {
|
else if (join.MouseButtonUp(button) == Button::State::HOVER && selection != nullptr && selection->compatible) {
|
||||||
//TODO: The player login information should be collected by the lobby screen
|
//pack the packet
|
||||||
//the vars
|
|
||||||
SerialPacket packet;
|
SerialPacket packet;
|
||||||
char buffer[PACKET_BUFFER_SIZE];
|
packet.meta.type = SerialPacket::Type::JOIN_REQUEST;
|
||||||
|
strncpy(packet.clientInfo.username, config["client.username"].c_str(), PACKET_STRING_SIZE);
|
||||||
|
strncpy(packet.clientInfo.handle, config["client.handle"].c_str(), PACKET_STRING_SIZE);
|
||||||
|
strncpy(packet.clientInfo.avatar, config["client.avatar"].c_str(), PACKET_STRING_SIZE);
|
||||||
|
|
||||||
//join the selected server
|
//join the selected server
|
||||||
packet.meta.type = SerialPacket::Type::JOIN_REQUEST;
|
network.SendTo(&selection->address, &packet);
|
||||||
serialize(&packet, buffer);
|
|
||||||
network.Send(&selection->address, buffer, PACKET_BUFFER_SIZE);
|
|
||||||
selection = nullptr;
|
selection = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,33 +200,38 @@ void LobbyMenu::KeyUp(SDL_KeyboardEvent const& key) {
|
|||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
//Network handlers
|
||||||
|
//-------------------------
|
||||||
|
|
||||||
void LobbyMenu::HandlePacket(SerialPacket packet) {
|
void LobbyMenu::HandlePacket(SerialPacket packet) {
|
||||||
switch(packet.meta.type) {
|
switch(packet.meta.type) {
|
||||||
case SerialPacket::Type::BROADCAST_RESPONSE: {
|
case SerialPacket::Type::BROADCAST_RESPONSE: {
|
||||||
//extract the data
|
//extract the data
|
||||||
ServerInformation server;
|
ServerInformation server;
|
||||||
server.address = packet.meta.srcAddress;
|
server.address = packet.meta.srcAddress;
|
||||||
|
server.networkVersion = packet.serverInfo.networkVersion;
|
||||||
server.name = packet.serverInfo.name;
|
server.name = packet.serverInfo.name;
|
||||||
server.playerCount = packet.serverInfo.playerCount;
|
server.playerCount = packet.serverInfo.playerCount;
|
||||||
|
|
||||||
//NOTE: Check compatibility here
|
//NOTE: Check compatibility here
|
||||||
server.compatible = packet.serverInfo.regionWidth == REGION_WIDTH &&
|
server.compatible = server.networkVersion == NETWORK_VERSION;
|
||||||
packet.serverInfo.regionHeight == REGION_HEIGHT &&
|
|
||||||
packet.serverInfo.regionDepth == REGION_DEPTH;
|
|
||||||
|
|
||||||
//push
|
//push
|
||||||
serverInfo.push_back(server);
|
serverInfo.push_back(server);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SerialPacket::Type::JOIN_RESPONSE:
|
case SerialPacket::Type::JOIN_RESPONSE:
|
||||||
clientIndex = packet.clientInfo.index;
|
clientIndex = packet.clientInfo.clientIndex;
|
||||||
|
accountIndex = packet.clientInfo.accountIndex;
|
||||||
|
characterIndex = packet.clientInfo.characterIndex;
|
||||||
network.Bind(&packet.meta.srcAddress, Channels::SERVER);
|
network.Bind(&packet.meta.srcAddress, Channels::SERVER);
|
||||||
SetNextScene(SceneList::INWORLD);
|
SetNextScene(SceneList::INWORLD);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//handle errors
|
//handle errors
|
||||||
default:
|
default:
|
||||||
throw(std::runtime_error("Unknown SerialPacket::Type encountered"));
|
throw(std::runtime_error(std::string() + "Unknown SerialPacket::Type encountered in LobbyMenu: " + to_string_custom(int(packet.meta.type))));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2013, 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
@@ -28,13 +28,8 @@
|
|||||||
#include "button.hpp"
|
#include "button.hpp"
|
||||||
#include "config_utility.hpp"
|
#include "config_utility.hpp"
|
||||||
|
|
||||||
//map
|
|
||||||
#include "region.hpp"
|
|
||||||
|
|
||||||
//network
|
//network
|
||||||
#include "udp_network_utility.hpp"
|
#include "udp_network_utility.hpp"
|
||||||
#include "serial_packet.hpp"
|
|
||||||
#include "serial.hpp"
|
|
||||||
|
|
||||||
//client
|
//client
|
||||||
#include "base_scene.hpp"
|
#include "base_scene.hpp"
|
||||||
@@ -45,7 +40,13 @@
|
|||||||
class LobbyMenu : public BaseScene {
|
class LobbyMenu : public BaseScene {
|
||||||
public:
|
public:
|
||||||
//Public access members
|
//Public access members
|
||||||
LobbyMenu(ConfigUtility* const, UDPNetworkUtility* const, int* const);
|
LobbyMenu(
|
||||||
|
ConfigUtility* const argConfig,
|
||||||
|
UDPNetworkUtility* const argNetwork,
|
||||||
|
int* const argClientIndex,
|
||||||
|
int* const argAccountIndex,
|
||||||
|
int* const argCharacterIndex
|
||||||
|
);
|
||||||
~LobbyMenu();
|
~LobbyMenu();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -62,12 +63,15 @@ protected:
|
|||||||
void KeyDown(SDL_KeyboardEvent const&);
|
void KeyDown(SDL_KeyboardEvent const&);
|
||||||
void KeyUp(SDL_KeyboardEvent const&);
|
void KeyUp(SDL_KeyboardEvent const&);
|
||||||
|
|
||||||
|
//Network handlers
|
||||||
void HandlePacket(SerialPacket);
|
void HandlePacket(SerialPacket);
|
||||||
|
|
||||||
//global
|
//shared parameters
|
||||||
ConfigUtility& config;
|
ConfigUtility& config;
|
||||||
UDPNetworkUtility& network;
|
UDPNetworkUtility& network;
|
||||||
int& clientIndex;
|
int& clientIndex;
|
||||||
|
int& accountIndex;
|
||||||
|
int& characterIndex;
|
||||||
|
|
||||||
//members
|
//members
|
||||||
Image image;
|
Image image;
|
||||||
@@ -79,7 +83,7 @@ protected:
|
|||||||
//server list
|
//server list
|
||||||
struct ServerInformation {
|
struct ServerInformation {
|
||||||
IPaddress address;
|
IPaddress address;
|
||||||
//TODO: version info
|
int networkVersion;
|
||||||
std::string name;
|
std::string name;
|
||||||
int playerCount;
|
int playerCount;
|
||||||
bool compatible;
|
bool compatible;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2013, 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2013, 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2013, 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
@@ -49,7 +49,7 @@ protected:
|
|||||||
void KeyDown(SDL_KeyboardEvent const&);
|
void KeyDown(SDL_KeyboardEvent const&);
|
||||||
void KeyUp(SDL_KeyboardEvent const&);
|
void KeyUp(SDL_KeyboardEvent const&);
|
||||||
|
|
||||||
//globals
|
//shared parameters
|
||||||
ConfigUtility& config;
|
ConfigUtility& config;
|
||||||
|
|
||||||
//members
|
//members
|
||||||
+3
-10
@@ -1,17 +1,14 @@
|
|||||||
#config
|
#config
|
||||||
INCLUDES+=. scenes ../common ../common/graphics ../common/map ../common/network ../common/ui
|
INCLUDES+=. ../common/gameplay ../common/graphics ../common/map ../common/network ../common/ui ../common/utilities
|
||||||
LIBS+=libclient.a ../libcommon.a -lSDL_net -lwsock32 -liphlpapi -lmingw32 -lSDLmain -lSDL -llua -lsqlite3
|
LIBS+=../libcommon.a -lSDL_net -lwsock32 -liphlpapi -lmingw32 -lSDLmain -lSDL -llua
|
||||||
CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES))
|
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) -DGRAPHICS
|
||||||
CFLAGS+=-DDEBUG $(addprefix -I,$(INCLUDES))
|
|
||||||
|
|
||||||
#source
|
#source
|
||||||
CXXSRC=$(wildcard *.cpp)
|
CXXSRC=$(wildcard *.cpp)
|
||||||
CSRC=$(wildcard *.c)
|
|
||||||
|
|
||||||
#objects
|
#objects
|
||||||
OBJDIR=obj
|
OBJDIR=obj
|
||||||
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
|
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
|
||||||
OBJ+=$(addprefix $(OBJDIR)/,$(CSRC:.c=.o))
|
|
||||||
|
|
||||||
#output
|
#output
|
||||||
OUTDIR=../out
|
OUTDIR=../out
|
||||||
@@ -19,7 +16,6 @@ OUT=$(addprefix $(OUTDIR)/,client)
|
|||||||
|
|
||||||
#targets
|
#targets
|
||||||
all: $(OBJ) $(OUT)
|
all: $(OBJ) $(OUT)
|
||||||
$(MAKE) -C scenes
|
|
||||||
$(CXX) $(CXXFLAGS) -o $(OUT) $(OBJ) $(LIBS)
|
$(CXX) $(CXXFLAGS) -o $(OUT) $(OBJ) $(LIBS)
|
||||||
|
|
||||||
$(OBJ): | $(OBJDIR)
|
$(OBJ): | $(OBJDIR)
|
||||||
@@ -35,9 +31,6 @@ $(OUTDIR):
|
|||||||
$(OBJDIR)/%.o: %.cpp
|
$(OBJDIR)/%.o: %.cpp
|
||||||
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
$(OBJDIR)/%.o: %.c
|
|
||||||
$(CC) $(CFLAGS) -c -o $@ $<
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) *.o *.a *.exe
|
$(RM) *.o *.a *.exe
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2013, 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2013, 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
@@ -49,7 +49,7 @@ protected:
|
|||||||
void KeyDown(SDL_KeyboardEvent const&);
|
void KeyDown(SDL_KeyboardEvent const&);
|
||||||
void KeyUp(SDL_KeyboardEvent const&);
|
void KeyUp(SDL_KeyboardEvent const&);
|
||||||
|
|
||||||
//globals
|
//shared parameters
|
||||||
ConfigUtility& config;
|
ConfigUtility& config;
|
||||||
|
|
||||||
//members
|
//members
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
|
||||||
*
|
|
||||||
* 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 "player_character.hpp"
|
|
||||||
|
|
||||||
#define WALKING_SPEED 140
|
|
||||||
|
|
||||||
void PlayerCharacter::Update(double delta) {
|
|
||||||
if (diagonal) {
|
|
||||||
constexpr double d = 1.0/sqrt(2);
|
|
||||||
position += motion * delta * d;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
position += motion * delta;
|
|
||||||
}
|
|
||||||
sprite.Update(delta);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlayerCharacter::AdjustDirection(Direction direction) {
|
|
||||||
//shift the movement in this direction
|
|
||||||
switch(direction) {
|
|
||||||
case Direction::NORTH:
|
|
||||||
if (motion.y >= 0) {
|
|
||||||
motion.y -= WALKING_SPEED;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Direction::SOUTH:
|
|
||||||
if (motion.y <= 0) {
|
|
||||||
motion.y += WALKING_SPEED;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Direction::WEST:
|
|
||||||
if (motion.x >= 0) {
|
|
||||||
motion.x -= WALKING_SPEED;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Direction::EAST:
|
|
||||||
if (motion.x <= 0) {
|
|
||||||
motion.x += WALKING_SPEED;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
//face the correct direction
|
|
||||||
ResetDirection();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlayerCharacter::FaceDirection(Direction direction) {
|
|
||||||
//this function depends on the format of the sprite sheets
|
|
||||||
switch(direction) {
|
|
||||||
case Direction::NORTH:
|
|
||||||
sprite.SetYIndex(1);
|
|
||||||
break;
|
|
||||||
case Direction::SOUTH:
|
|
||||||
sprite.SetYIndex(0);
|
|
||||||
break;
|
|
||||||
case Direction::WEST:
|
|
||||||
sprite.SetYIndex(2);
|
|
||||||
break;
|
|
||||||
case Direction::EAST:
|
|
||||||
sprite.SetYIndex(3);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlayerCharacter::ResetDirection() {
|
|
||||||
//base the direction on the character's movement
|
|
||||||
if (motion.y > 0) {
|
|
||||||
FaceDirection(Direction::SOUTH);
|
|
||||||
}
|
|
||||||
else if (motion.y < 0) {
|
|
||||||
FaceDirection(Direction::NORTH);
|
|
||||||
}
|
|
||||||
else if (motion.x > 0) {
|
|
||||||
FaceDirection(Direction::EAST);
|
|
||||||
}
|
|
||||||
else if (motion.x < 0) {
|
|
||||||
FaceDirection(Direction::WEST);
|
|
||||||
}
|
|
||||||
ResetSpeed();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlayerCharacter::ResetSpeed() {
|
|
||||||
//diagonal
|
|
||||||
if (motion.x != 0 && motion.y != 0) {
|
|
||||||
sprite.SetDelay(0.1);
|
|
||||||
diagonal = true;
|
|
||||||
}
|
|
||||||
//cardinal
|
|
||||||
else if (motion != 0) {
|
|
||||||
sprite.SetDelay(0.1);
|
|
||||||
diagonal = false;
|
|
||||||
}
|
|
||||||
//not moving
|
|
||||||
else {
|
|
||||||
sprite.SetDelay(0);
|
|
||||||
sprite.SetXIndex(0);
|
|
||||||
diagonal = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
|
||||||
*
|
|
||||||
* 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 PLAYERCHARACTER_HPP_
|
|
||||||
#define PLAYERCHARACTER_HPP_
|
|
||||||
|
|
||||||
#include "vector2.hpp"
|
|
||||||
#include "sprite_sheet.hpp"
|
|
||||||
|
|
||||||
//TODO: correct the PlayerCharacter class and it's movement system
|
|
||||||
class PlayerCharacter {
|
|
||||||
public:
|
|
||||||
enum class Direction {
|
|
||||||
NORTH, SOUTH, EAST, WEST
|
|
||||||
};
|
|
||||||
|
|
||||||
PlayerCharacter() = default;
|
|
||||||
~PlayerCharacter() = default;
|
|
||||||
|
|
||||||
void Update(double delta);
|
|
||||||
|
|
||||||
void DrawTo(SDL_Surface* const dest, int camX, int camY) { sprite.DrawTo(dest, position.x - camX, position.y - camY); }
|
|
||||||
|
|
||||||
//clunky code results in smooth movement and controls
|
|
||||||
void AdjustDirection(Direction);
|
|
||||||
void FaceDirection(Direction);
|
|
||||||
void ResetDirection();
|
|
||||||
void ResetSpeed();
|
|
||||||
|
|
||||||
//accessors and mutators
|
|
||||||
Vector2 SetPosition(Vector2 v) { return position = v; }
|
|
||||||
Vector2 ShiftPosition(Vector2 v) { return position += v; }
|
|
||||||
Vector2 GetPosition() { return position; }
|
|
||||||
|
|
||||||
Vector2 SetMotion(Vector2 v) { return motion = v; }
|
|
||||||
Vector2 ShiftMotion(Vector2 v) { return motion += v; }
|
|
||||||
Vector2 GetMotion() { return motion; }
|
|
||||||
|
|
||||||
SpriteSheet* GetSprite() { return &sprite; }
|
|
||||||
private:
|
|
||||||
Vector2 position;
|
|
||||||
Vector2 motion;
|
|
||||||
SpriteSheet sprite;
|
|
||||||
|
|
||||||
//for moving diagonally
|
|
||||||
bool diagonal = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2013, 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
|
|||||||
@@ -1,139 +0,0 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
|
||||||
* arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any purpose,
|
|
||||||
* including commercial applications, and to alter it and redistribute it
|
|
||||||
* freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
* claim that you wrote the original software. If you use this software
|
|
||||||
* in a product, an acknowledgment in the product documentation would be
|
|
||||||
* appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
|
||||||
* misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source
|
|
||||||
* distribution.
|
|
||||||
*/
|
|
||||||
#include "base_scene.hpp"
|
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Static declarations
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
SDL_Surface* BaseScene::screen = nullptr;
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Public access members
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
BaseScene::BaseScene() {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
BaseScene::~BaseScene() {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Program control
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
SDL_Surface* BaseScene::SetScreen(int w, int h, int bpp, Uint32 flags) {
|
|
||||||
if (!bpp) {
|
|
||||||
bpp = SDL_GetVideoInfo()->vfmt->BitsPerPixel;
|
|
||||||
}
|
|
||||||
|
|
||||||
screen = SDL_SetVideoMode(w, h, bpp, flags);
|
|
||||||
|
|
||||||
if (!screen) {
|
|
||||||
throw(std::runtime_error("Failed to create the screen surface"));
|
|
||||||
}
|
|
||||||
|
|
||||||
return screen;
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_Surface* BaseScene::GetScreen() {
|
|
||||||
return screen;
|
|
||||||
}
|
|
||||||
|
|
||||||
SceneList BaseScene::SetNextScene(SceneList sceneIndex) {
|
|
||||||
return nextScene = sceneIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
SceneList BaseScene::GetNextScene() const {
|
|
||||||
return nextScene;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Frame loop
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
void BaseScene::RunFrame(double delta) {
|
|
||||||
FrameStart();
|
|
||||||
HandleEvents();
|
|
||||||
Update(delta);
|
|
||||||
FrameEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BaseScene::RenderFrame() {
|
|
||||||
SDL_FillRect(screen, 0, 0);
|
|
||||||
Render(screen);
|
|
||||||
SDL_Flip(screen);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Event handlers
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
void BaseScene::HandleEvents() {
|
|
||||||
SDL_Event event;
|
|
||||||
|
|
||||||
while(SDL_PollEvent(&event)) {
|
|
||||||
switch(event.type) {
|
|
||||||
case SDL_QUIT:
|
|
||||||
QuitEvent();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDL_VIDEORESIZE:
|
|
||||||
SetScreen(event.resize.w, event.resize.h, 0, screen->flags);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDL_MOUSEMOTION:
|
|
||||||
MouseMotion(event.motion);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDL_MOUSEBUTTONDOWN:
|
|
||||||
MouseButtonDown(event.button);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDL_MOUSEBUTTONUP:
|
|
||||||
MouseButtonUp(event.button);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDL_KEYDOWN:
|
|
||||||
KeyDown(event.key);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDL_KEYUP:
|
|
||||||
KeyUp(event.key);
|
|
||||||
break;
|
|
||||||
|
|
||||||
#ifdef USE_EVENT_JOYSTICK
|
|
||||||
//TODO: joystick/gamepad support
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_EVENT_UNKNOWN
|
|
||||||
default:
|
|
||||||
UnknownEvent(event);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
}//switch
|
|
||||||
}//while
|
|
||||||
}
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
|
||||||
*
|
|
||||||
* 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 BASESCENE_HPP_
|
|
||||||
#define BASESCENE_HPP_
|
|
||||||
|
|
||||||
#include "scene_list.hpp"
|
|
||||||
|
|
||||||
#include "SDL/SDL.h"
|
|
||||||
|
|
||||||
class BaseScene {
|
|
||||||
public:
|
|
||||||
//Public access members
|
|
||||||
BaseScene();
|
|
||||||
virtual ~BaseScene();
|
|
||||||
|
|
||||||
//Program control
|
|
||||||
static SDL_Surface* SetScreen(int w, int h, int bpp = 0, Uint32 flags = SDL_HWSURFACE|SDL_DOUBLEBUF);
|
|
||||||
static SDL_Surface* GetScreen();
|
|
||||||
|
|
||||||
SceneList SetNextScene(SceneList sceneIndex);
|
|
||||||
SceneList GetNextScene() const;
|
|
||||||
|
|
||||||
//Frame loop
|
|
||||||
virtual void RunFrame(double delta);
|
|
||||||
virtual void RenderFrame();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void FrameStart() {}
|
|
||||||
virtual void HandleEvents();
|
|
||||||
virtual void Update(double delta) {}
|
|
||||||
virtual void FrameEnd() {}
|
|
||||||
virtual void Render(SDL_Surface* const screen) {}
|
|
||||||
|
|
||||||
//Event handlers
|
|
||||||
virtual void QuitEvent() { SetNextScene(SceneList::QUIT); }
|
|
||||||
virtual void MouseMotion(SDL_MouseMotionEvent const&) {}
|
|
||||||
virtual void MouseButtonDown(SDL_MouseButtonEvent const&) {}
|
|
||||||
virtual void MouseButtonUp(SDL_MouseButtonEvent const&) {}
|
|
||||||
virtual void KeyDown(SDL_KeyboardEvent const&) {}
|
|
||||||
virtual void KeyUp(SDL_KeyboardEvent const&) {}
|
|
||||||
|
|
||||||
#ifdef USE_EVENT_JOYSTICK
|
|
||||||
//TODO: joystick/gamepad support
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_EVENT_UNKNOWN
|
|
||||||
virtual void UnknownEvent(SDL_Event const&) {}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
private:
|
|
||||||
static SDL_Surface* screen;
|
|
||||||
SceneList nextScene = SceneList::CONTINUE;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
|
||||||
*
|
|
||||||
* 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_
|
|
||||||
|
|
||||||
#include "base_scene.hpp"
|
|
||||||
|
|
||||||
class InCombat : public BaseScene {
|
|
||||||
public:
|
|
||||||
//Public access members
|
|
||||||
InCombat();
|
|
||||||
~InCombat();
|
|
||||||
|
|
||||||
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&);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2013, 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2013, 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
@@ -40,7 +40,7 @@ protected:
|
|||||||
void Update(double delta);
|
void Update(double delta);
|
||||||
void Render(SDL_Surface* const);
|
void Render(SDL_Surface* const);
|
||||||
|
|
||||||
//globals
|
//shared parameters
|
||||||
ConfigUtility& config;
|
ConfigUtility& config;
|
||||||
|
|
||||||
//members
|
//members
|
||||||
@@ -19,6 +19,18 @@
|
|||||||
* 3. This notice may not be removed or altered from any source
|
* 3. This notice may not be removed or altered from any source
|
||||||
* distribution.
|
* distribution.
|
||||||
*/
|
*/
|
||||||
#include "client_entry.hpp"
|
#ifndef ACCOUNTDATA_HPP_
|
||||||
|
#define ACCOUNTDATA_HPP_
|
||||||
|
|
||||||
unsigned int ClientEntry::uidCounter;
|
#include <string>
|
||||||
|
|
||||||
|
struct AccountData {
|
||||||
|
std::string username;
|
||||||
|
//TODO: password
|
||||||
|
bool blackListed = false;
|
||||||
|
bool whiteListed = true;
|
||||||
|
|
||||||
|
int clientIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
/* 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"
|
||||||
|
|
||||||
|
void CharacterData::Update(double delta) {
|
||||||
|
if (motion.x && motion.y) {
|
||||||
|
position += motion * delta * CHARACTER_WALKING_MOD;
|
||||||
|
}
|
||||||
|
else if (motion != 0) {
|
||||||
|
position += motion * delta;
|
||||||
|
}
|
||||||
|
#ifdef GRAPHICS
|
||||||
|
sprite.Update(delta);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef GRAPHICS
|
||||||
|
|
||||||
|
void CharacterData::DrawTo(SDL_Surface* const dest, int camX, int camY) {
|
||||||
|
sprite.DrawTo(dest, position.x - camX, position.y - camY);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CharacterData::CorrectSprite() {
|
||||||
|
//NOTE: These must correspond to the sprite sheet in use
|
||||||
|
if (motion.y > 0) {
|
||||||
|
sprite.SetYIndex(0);
|
||||||
|
}
|
||||||
|
else if (motion.y < 0) {
|
||||||
|
sprite.SetYIndex(1);
|
||||||
|
}
|
||||||
|
else if (motion.x > 0) {
|
||||||
|
sprite.SetYIndex(3);
|
||||||
|
}
|
||||||
|
else if (motion.x < 0) {
|
||||||
|
sprite.SetYIndex(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
//animation
|
||||||
|
if (motion != 0) {
|
||||||
|
sprite.SetDelay(0.1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sprite.SetDelay(0);
|
||||||
|
sprite.SetXIndex(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
/* 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 CHARACTERDATA_HPP_
|
||||||
|
#define CHARACTERDATA_HPP_
|
||||||
|
|
||||||
|
//POD members
|
||||||
|
#include "bbox.hpp"
|
||||||
|
#include "vector2.hpp"
|
||||||
|
#include "statistics.hpp"
|
||||||
|
|
||||||
|
//graphics
|
||||||
|
#ifdef GRAPHICS
|
||||||
|
#include "sprite_sheet.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//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;
|
||||||
|
|
||||||
|
//world position
|
||||||
|
int mapIndex = 0;
|
||||||
|
Vector2 position = {0.0,0.0};
|
||||||
|
Vector2 motion = {0.0,0.0};
|
||||||
|
|
||||||
|
//base statistics
|
||||||
|
Statistics stats;
|
||||||
|
|
||||||
|
//TODO: equipment
|
||||||
|
//TODO: items
|
||||||
|
//TODO: buffs
|
||||||
|
//TODO: debuffs
|
||||||
|
|
||||||
|
//methods
|
||||||
|
void Update(double delta);
|
||||||
|
#ifdef GRAPHICS
|
||||||
|
void DrawTo(SDL_Surface* const, int camX, int camY);
|
||||||
|
void CorrectSprite();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//active gameplay members
|
||||||
|
//NOTE: these are lost when unloaded
|
||||||
|
#ifdef GRAPHICS
|
||||||
|
SpriteSheet sprite;
|
||||||
|
#endif
|
||||||
|
BBox bbox = {0,0,0,0};
|
||||||
|
bool inCombat = false;
|
||||||
|
int atbGauge = 0;
|
||||||
|
//TODO: stored command
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -19,14 +19,13 @@
|
|||||||
* 3. This notice may not be removed or altered from any source
|
* 3. This notice may not be removed or altered from any source
|
||||||
* distribution.
|
* distribution.
|
||||||
*/
|
*/
|
||||||
#ifndef CLIENTENTRY_HPP_
|
#ifndef CLIENTDATA_HPP_
|
||||||
#define CLIENTENTRY_HPP_
|
#define CLIENTDATA_HPP_
|
||||||
|
|
||||||
#include "SDL/SDL_net.h"
|
#include "SDL/SDL_net.h"
|
||||||
|
|
||||||
struct ClientEntry {
|
struct ClientData {
|
||||||
IPaddress address;
|
IPaddress address = {0,0};
|
||||||
static unsigned int uidCounter;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
/* 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_
|
||||||
|
|
||||||
|
//POD members
|
||||||
|
#include "vector2.hpp"
|
||||||
|
#include "bbox.hpp"
|
||||||
|
|
||||||
|
//gameplay members
|
||||||
|
#include "character_data.hpp"
|
||||||
|
#include "enemy_data.hpp"
|
||||||
|
|
||||||
|
//graphics
|
||||||
|
#ifdef GRAPHICS
|
||||||
|
#include "sprite_sheet.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//std namespace
|
||||||
|
#include <chrono>
|
||||||
|
#include <list>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
struct CombatData {
|
||||||
|
typedef std::chrono::steady_clock Clock;
|
||||||
|
|
||||||
|
//combatants, point to the std::map's internal pairs
|
||||||
|
std::list<std::pair<const int, CharacterData>*> characterList;
|
||||||
|
std::list<std::pair<const int, EnemyData>*> enemyList;
|
||||||
|
|
||||||
|
//world interaction
|
||||||
|
int mapIndex = 0;
|
||||||
|
Vector2 position = {0.0,0.0};
|
||||||
|
BBox bbox = {0,0,0,0};
|
||||||
|
|
||||||
|
//time interval
|
||||||
|
Clock::time_point lastTick = Clock::now();
|
||||||
|
|
||||||
|
//graphics
|
||||||
|
#ifdef GRAPHICS
|
||||||
|
SpriteSheet sprite;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -19,44 +19,40 @@
|
|||||||
* 3. This notice may not be removed or altered from any source
|
* 3. This notice may not be removed or altered from any source
|
||||||
* distribution.
|
* distribution.
|
||||||
*/
|
*/
|
||||||
#ifndef PLAYERENTRY_HPP_
|
#ifndef ENEMYDATA_HPP_
|
||||||
#define PLAYERENTRY_HPP_
|
#define ENEMYDATA_HPP_
|
||||||
|
|
||||||
//POD members
|
//gameplay
|
||||||
#include "bbox.hpp"
|
#include "statistics.hpp"
|
||||||
#include "vector2.hpp"
|
|
||||||
|
|
||||||
|
//graphics
|
||||||
|
#ifdef GRAPHICS
|
||||||
|
#include "sprite_sheet.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//std namespace
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
struct PlayerEntry {
|
struct EnemyData {
|
||||||
//metadata
|
//metadata
|
||||||
int clientIndex;
|
|
||||||
std::string handle;
|
std::string handle;
|
||||||
std::string avatar;
|
std::string avatar;
|
||||||
|
|
||||||
//world position
|
//gameplay
|
||||||
int mapIndex;
|
Statistics stats;
|
||||||
Vector2 position;
|
|
||||||
Vector2 motion;
|
|
||||||
BBox bbox;
|
|
||||||
|
|
||||||
//statistics
|
//TODO: equipment
|
||||||
int level;
|
//TODO: items
|
||||||
int exp;
|
//TODO: buffs
|
||||||
int maxHP;
|
//TODO: debuffs
|
||||||
int health;
|
|
||||||
int maxMP;
|
|
||||||
int mana;
|
|
||||||
int attack;
|
|
||||||
int defence;
|
|
||||||
int intelligence;
|
|
||||||
int resistance;
|
|
||||||
float accuracy;
|
|
||||||
float evasion;
|
|
||||||
float luck;
|
|
||||||
|
|
||||||
//uid
|
//active gameplay members
|
||||||
static unsigned int uidCounter;
|
//NOTE: these are lost when unloaded
|
||||||
|
#ifdef GRAPHICS
|
||||||
|
SpriteSheet sprite;
|
||||||
|
#endif
|
||||||
|
int tableIndex;
|
||||||
|
int atbGauge = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,21 +1,18 @@
|
|||||||
#config
|
#config
|
||||||
INCLUDES+=. .. ../../common ../../common/graphics ../../common/map ../../common/network ../../common/ui
|
INCLUDES+=. ../utilities ../graphics
|
||||||
LIBS+=
|
LIBS+=
|
||||||
CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES))
|
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) -DGRAPHICS
|
||||||
CFLAGS+=-DDEBUG $(addprefix -I,$(INCLUDES))
|
|
||||||
|
|
||||||
#source
|
#source
|
||||||
CXXSRC=$(wildcard *.cpp)
|
CXXSRC=$(wildcard *.cpp)
|
||||||
CSRC=$(wildcard *.c)
|
|
||||||
|
|
||||||
#objects
|
#objects
|
||||||
OBJDIR=obj
|
OBJDIR=obj
|
||||||
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
|
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
|
||||||
OBJ+=$(addprefix $(OBJDIR)/,$(CSRC:.c=.o))
|
|
||||||
|
|
||||||
#output
|
#output
|
||||||
OUTDIR=..
|
OUTDIR=../..
|
||||||
OUT=$(addprefix $(OUTDIR)/,libclient.a)
|
OUT=$(addprefix $(OUTDIR)/,libcommon.a)
|
||||||
|
|
||||||
#targets
|
#targets
|
||||||
all: $(OBJ) $(OUT)
|
all: $(OBJ) $(OUT)
|
||||||
@@ -34,9 +31,6 @@ $(OUTDIR):
|
|||||||
$(OBJDIR)/%.o: %.cpp
|
$(OBJDIR)/%.o: %.cpp
|
||||||
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
$(OBJDIR)/%.o: %.c
|
|
||||||
$(CC) $(CFLAGS) -c -o $@ $<
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) *.o *.a *.exe
|
$(RM) *.o *.a *.exe
|
||||||
|
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
/* 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_data.hpp"
|
||||||
|
#include "character_data.hpp"
|
||||||
|
#include "client_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.
|
||||||
|
*
|
||||||
|
* Oddly enough, I'm pretty sure this is the first directory compiled in a
|
||||||
|
* clean build.
|
||||||
|
*/
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
/* 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
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2013, 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2013, 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
|
|||||||
@@ -1,17 +1,14 @@
|
|||||||
#config
|
#config
|
||||||
INCLUDES+=. .. ../map
|
INCLUDES+=. ../map
|
||||||
LIBS+=
|
LIBS+=
|
||||||
CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES))
|
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
|
||||||
CFLAGS+=-DDEBUG $(addprefix -I,$(INCLUDES))
|
|
||||||
|
|
||||||
#source
|
#source
|
||||||
CXXSRC=$(wildcard *.cpp)
|
CXXSRC=$(wildcard *.cpp)
|
||||||
CSRC=$(wildcard *.c)
|
|
||||||
|
|
||||||
#objects
|
#objects
|
||||||
OBJDIR=obj
|
OBJDIR=obj
|
||||||
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
|
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
|
||||||
OBJ+=$(addprefix $(OBJDIR)/,$(CSRC:.c=.o))
|
|
||||||
|
|
||||||
#output
|
#output
|
||||||
OUTDIR=../..
|
OUTDIR=../..
|
||||||
@@ -34,9 +31,6 @@ $(OUTDIR):
|
|||||||
$(OBJDIR)/%.o: %.cpp
|
$(OBJDIR)/%.o: %.cpp
|
||||||
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
$(OBJDIR)/%.o: %.c
|
|
||||||
$(CC) $(CFLAGS) -c -o $@ $<
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) *.o *.a *.exe
|
$(RM) *.o *.a *.exe
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2013, 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2013, 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
|
|||||||
+4
-39
@@ -1,46 +1,11 @@
|
|||||||
#config
|
all:
|
||||||
INCLUDES+=.
|
$(MAKE) -C gameplay
|
||||||
LIBS+=
|
|
||||||
CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES))
|
|
||||||
CFLAGS+=-DDEBUG $(addprefix -I,$(INCLUDES))
|
|
||||||
|
|
||||||
#source
|
|
||||||
CXXSRC=$(wildcard *.cpp)
|
|
||||||
CSRC=$(wildcard *.c)
|
|
||||||
|
|
||||||
#objects
|
|
||||||
OBJDIR=obj
|
|
||||||
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
|
|
||||||
OBJ+=$(addprefix $(OBJDIR)/,$(CSRC:.c=.o))
|
|
||||||
|
|
||||||
#output
|
|
||||||
OUTDIR=..
|
|
||||||
OUT=$(addprefix $(OUTDIR)/,libcommon.a)
|
|
||||||
|
|
||||||
#targets
|
|
||||||
all: $(OBJ) $(OUT)
|
|
||||||
ar -crs $(OUT) $(OBJ)
|
|
||||||
$(MAKE) -C graphics
|
$(MAKE) -C graphics
|
||||||
$(MAKE) -C map
|
$(MAKE) -C map
|
||||||
$(MAKE) -C script
|
|
||||||
$(MAKE) -C network
|
$(MAKE) -C network
|
||||||
|
$(MAKE) -C script
|
||||||
$(MAKE) -C ui
|
$(MAKE) -C ui
|
||||||
|
$(MAKE) -C utilities
|
||||||
$(OBJ): | $(OBJDIR)
|
|
||||||
|
|
||||||
$(OUT): | $(OUTDIR)
|
|
||||||
|
|
||||||
$(OBJDIR):
|
|
||||||
mkdir $(OBJDIR)
|
|
||||||
|
|
||||||
$(OUTDIR):
|
|
||||||
mkdir $(OUTDIR)
|
|
||||||
|
|
||||||
$(OBJDIR)/%.o: %.cpp
|
|
||||||
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
|
||||||
|
|
||||||
$(OBJDIR)/%.o: %.c
|
|
||||||
$(CC) $(CFLAGS) -c -o $@ $<
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) *.o *.a *.exe
|
$(RM) *.o *.a *.exe
|
||||||
|
|||||||
+2
-8
@@ -1,17 +1,14 @@
|
|||||||
#config
|
#config
|
||||||
INCLUDES+=. .. ../graphics
|
INCLUDES+=. ../utilities
|
||||||
LIBS+=
|
LIBS+=
|
||||||
CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES))
|
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
|
||||||
CFLAGS+=-DDEBUG $(addprefix -I,$(INCLUDES))
|
|
||||||
|
|
||||||
#source
|
#source
|
||||||
CXXSRC=$(wildcard *.cpp)
|
CXXSRC=$(wildcard *.cpp)
|
||||||
CSRC=$(wildcard *.c)
|
|
||||||
|
|
||||||
#objects
|
#objects
|
||||||
OBJDIR=obj
|
OBJDIR=obj
|
||||||
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
|
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
|
||||||
OBJ+=$(addprefix $(OBJDIR)/,$(CSRC:.c=.o))
|
|
||||||
|
|
||||||
#output
|
#output
|
||||||
OUTDIR=../..
|
OUTDIR=../..
|
||||||
@@ -34,9 +31,6 @@ $(OUTDIR):
|
|||||||
$(OBJDIR)/%.o: %.cpp
|
$(OBJDIR)/%.o: %.cpp
|
||||||
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
$(OBJDIR)/%.o: %.c
|
|
||||||
$(CC) $(CFLAGS) -c -o $@ $<
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) *.o *.a *.exe
|
$(RM) *.o *.a *.exe
|
||||||
|
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ void LuaAllocator::Create(Region** const ptr, int x, int y) {
|
|||||||
(*ptr) = new Region(x, y);
|
(*ptr) = new Region(x, y);
|
||||||
|
|
||||||
//API hook
|
//API hook
|
||||||
lua_getglobal(state, "Region");
|
lua_getglobal(state, "map");
|
||||||
lua_getfield(state, -1, "Create");
|
lua_getfield(state, -1, "create");
|
||||||
lua_pushlightuserdata(state, *ptr);
|
lua_pushlightuserdata(state, *ptr);
|
||||||
if (lua_pcall(state, 1, 0, 0) != LUA_OK) {
|
if (lua_pcall(state, 1, 0, 0) != LUA_OK) {
|
||||||
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(state, -1) ));
|
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(state, -1) ));
|
||||||
@@ -47,8 +47,8 @@ void LuaAllocator::Create(Region** const ptr, int x, int y) {
|
|||||||
|
|
||||||
void LuaAllocator::Unload(Region* const ptr) {
|
void LuaAllocator::Unload(Region* const ptr) {
|
||||||
//API hook
|
//API hook
|
||||||
lua_getglobal(state, "Region");
|
lua_getglobal(state, "map");
|
||||||
lua_getfield(state, -1, "Unload");
|
lua_getfield(state, -1, "unload");
|
||||||
lua_pushlightuserdata(state, ptr);
|
lua_pushlightuserdata(state, ptr);
|
||||||
if (lua_pcall(state, 1, 0, 0) != LUA_OK) {
|
if (lua_pcall(state, 1, 0, 0) != LUA_OK) {
|
||||||
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(state, -1) ));
|
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(state, -1) ));
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ void LuaFormat::Load(Region** const ptr, int x, int y) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//API hook
|
//API hook
|
||||||
lua_getglobal(state, "Region");
|
lua_getglobal(state, "map");
|
||||||
lua_getfield(state, -1, "Load");
|
lua_getfield(state, -1, "load");
|
||||||
lua_pushlightuserdata(state, *ptr);
|
lua_pushlightuserdata(state, *ptr);
|
||||||
lua_pushstring(state, saveDir.c_str());
|
lua_pushstring(state, saveDir.c_str());
|
||||||
if (lua_pcall(state, 2, 1, 0) != LUA_OK) {
|
if (lua_pcall(state, 2, 1, 0) != LUA_OK) {
|
||||||
@@ -55,8 +55,8 @@ void LuaFormat::Load(Region** const ptr, int x, int y) {
|
|||||||
|
|
||||||
void LuaFormat::Save(Region* const ptr) {
|
void LuaFormat::Save(Region* const ptr) {
|
||||||
//API hook
|
//API hook
|
||||||
lua_getglobal(state, "Region");
|
lua_getglobal(state, "map");
|
||||||
lua_getfield(state, -1, "Save");
|
lua_getfield(state, -1, "save");
|
||||||
lua_pushlightuserdata(state, ptr);
|
lua_pushlightuserdata(state, ptr);
|
||||||
lua_pushstring(state, saveDir.c_str());
|
lua_pushstring(state, saveDir.c_str());
|
||||||
if (lua_pcall(state, 2, 0, 0) != LUA_OK) {
|
if (lua_pcall(state, 2, 0, 0) != LUA_OK) {
|
||||||
|
|||||||
@@ -1,17 +1,14 @@
|
|||||||
#config
|
#config
|
||||||
INCLUDES+=. .. ../map
|
INCLUDES+=. ../gameplay ../map ../utilities
|
||||||
LIBS+=
|
LIBS+=
|
||||||
CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES))
|
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
|
||||||
CFLAGS+=-DDEBUG $(addprefix -I,$(INCLUDES))
|
|
||||||
|
|
||||||
#source
|
#source
|
||||||
CXXSRC=$(wildcard *.cpp)
|
CXXSRC=$(wildcard *.cpp)
|
||||||
CSRC=$(wildcard *.c)
|
|
||||||
|
|
||||||
#objects
|
#objects
|
||||||
OBJDIR=obj
|
OBJDIR=obj
|
||||||
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
|
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
|
||||||
OBJ+=$(addprefix $(OBJDIR)/,$(CSRC:.c=.o))
|
|
||||||
|
|
||||||
#output
|
#output
|
||||||
OUTDIR=../..
|
OUTDIR=../..
|
||||||
@@ -34,9 +31,6 @@ $(OUTDIR):
|
|||||||
$(OBJDIR)/%.o: %.cpp
|
$(OBJDIR)/%.o: %.cpp
|
||||||
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
$(OBJDIR)/%.o: %.c
|
|
||||||
$(CC) $(CFLAGS) -c -o $@ $<
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) *.o *.a *.exe
|
$(RM) *.o *.a *.exe
|
||||||
|
|
||||||
|
|||||||
+264
-134
@@ -22,88 +22,65 @@
|
|||||||
#include "serial.hpp"
|
#include "serial.hpp"
|
||||||
|
|
||||||
#include "map_allocator.hpp"
|
#include "map_allocator.hpp"
|
||||||
|
#include "statistics.hpp"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
//Convenience Macros
|
||||||
|
//-------------------------
|
||||||
|
|
||||||
|
#define SERIALIZE(buffer, data, size) memcpy(buffer, data, size); buffer += size;
|
||||||
|
#define DESERIALIZE(buffer, data, size) memcpy(data, buffer, size); buffer += size;
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
//internal serialization functions
|
//internal serialization functions
|
||||||
//-------------------------
|
//-------------------------
|
||||||
|
|
||||||
void serializeType(SerialPacket* packet, char* buffer) {
|
void serializeType(SerialPacket* packet, char* buffer) {
|
||||||
memcpy(buffer, &packet->meta.type, sizeof(SerialPacket::Type));
|
SERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type));
|
||||||
}
|
}
|
||||||
|
|
||||||
void serializeServer(SerialPacket* packet, char* buffer) {
|
void serializeServer(SerialPacket* packet, char* buffer) {
|
||||||
memcpy(buffer, &packet->meta.type, sizeof(SerialPacket::Type));
|
SERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type));
|
||||||
buffer += sizeof(SerialPacket::Type);
|
|
||||||
|
|
||||||
//server info
|
//server info
|
||||||
//Note: version info serialization goes here
|
SERIALIZE(buffer, &packet->serverInfo.networkVersion, sizeof(int));
|
||||||
memcpy(buffer, packet->serverInfo.name, PACKET_STRING_SIZE);
|
SERIALIZE(buffer, packet->serverInfo.name, PACKET_STRING_SIZE);
|
||||||
buffer += PACKET_STRING_SIZE;
|
SERIALIZE(buffer, &packet->serverInfo.playerCount, sizeof(int));
|
||||||
memcpy(buffer, &packet->serverInfo.playerCount, sizeof(int));
|
|
||||||
buffer += sizeof(int);
|
|
||||||
|
|
||||||
//map format
|
|
||||||
memcpy(buffer, &packet->serverInfo.regionWidth, sizeof(int));
|
|
||||||
buffer += sizeof(int);
|
|
||||||
memcpy(buffer, &packet->serverInfo.regionHeight, sizeof(int));
|
|
||||||
buffer += sizeof(int);
|
|
||||||
memcpy(buffer, &packet->serverInfo.regionDepth, sizeof(int));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void serializeClient(SerialPacket* packet, char* buffer) {
|
void serializeClient(SerialPacket* packet, char* buffer) {
|
||||||
memcpy(buffer, &packet->meta.type, sizeof(SerialPacket::Type));
|
SERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type));
|
||||||
buffer += sizeof(SerialPacket::Type);
|
|
||||||
memcpy(buffer, &packet->clientInfo.index, sizeof(int));
|
|
||||||
}
|
|
||||||
|
|
||||||
void serializePlayer(SerialPacket* packet, char* buffer) {
|
|
||||||
memcpy(buffer, &packet->meta.type, sizeof(SerialPacket::Type));
|
|
||||||
buffer += sizeof(SerialPacket::Type);
|
|
||||||
|
|
||||||
//indexes
|
//indexes
|
||||||
memcpy(buffer, &packet->playerInfo.clientIndex, sizeof(int));
|
SERIALIZE(buffer, &packet->clientInfo.clientIndex, sizeof(int));
|
||||||
buffer += sizeof(int);
|
SERIALIZE(buffer, &packet->clientInfo.accountIndex, sizeof(int));
|
||||||
memcpy(buffer, &packet->playerInfo.playerIndex, sizeof(int));
|
SERIALIZE(buffer, &packet->clientInfo.characterIndex, sizeof(int));
|
||||||
buffer += sizeof(int);
|
|
||||||
|
|
||||||
//text
|
//texts
|
||||||
memcpy(buffer, packet->playerInfo.handle, PACKET_STRING_SIZE);
|
SERIALIZE(buffer, packet->clientInfo.username, PACKET_STRING_SIZE);
|
||||||
buffer += PACKET_STRING_SIZE;
|
//TODO: password
|
||||||
memcpy(buffer, packet->playerInfo.avatar, PACKET_STRING_SIZE);
|
SERIALIZE(buffer, packet->clientInfo.handle, PACKET_STRING_SIZE);
|
||||||
buffer += PACKET_STRING_SIZE;
|
SERIALIZE(buffer, packet->clientInfo.avatar, PACKET_STRING_SIZE);
|
||||||
|
|
||||||
//vectors
|
|
||||||
memcpy(buffer, &packet->playerInfo.position.x, sizeof(double));
|
|
||||||
buffer += sizeof(double);
|
|
||||||
memcpy(buffer, &packet->playerInfo.position.y, sizeof(double));
|
|
||||||
buffer += sizeof(double);
|
|
||||||
memcpy(buffer, &packet->playerInfo.motion.x, sizeof(double));
|
|
||||||
buffer += sizeof(double);
|
|
||||||
memcpy(buffer, &packet->playerInfo.motion.y, sizeof(double));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void serializeRegionFormat(SerialPacket* packet, char* buffer) {
|
void serializeRegionFormat(SerialPacket* packet, char* buffer) {
|
||||||
memcpy(buffer, &packet->meta.type, sizeof(SerialPacket::Type));
|
SERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type));
|
||||||
buffer += sizeof(SerialPacket::Type);
|
|
||||||
|
|
||||||
//x & y
|
//format
|
||||||
memcpy(buffer, &packet->regionInfo.x, sizeof(int));
|
SERIALIZE(buffer, &packet->regionInfo.mapIndex, sizeof(int));
|
||||||
buffer += sizeof(int);
|
SERIALIZE(buffer, &packet->regionInfo.x, sizeof(int));
|
||||||
memcpy(buffer, &packet->regionInfo.y, sizeof(int));
|
SERIALIZE(buffer, &packet->regionInfo.y, sizeof(int));
|
||||||
}
|
}
|
||||||
|
|
||||||
void serializeRegionContent(SerialPacket* packet, char* buffer) {
|
void serializeRegionContent(SerialPacket* packet, char* buffer) {
|
||||||
//format
|
SERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type));
|
||||||
memcpy(buffer, &packet->meta.type, sizeof(SerialPacket::Type));
|
|
||||||
buffer += sizeof(SerialPacket::Type);
|
|
||||||
|
|
||||||
//x & y
|
//format
|
||||||
*reinterpret_cast<int*>(buffer) = packet->regionInfo.region->GetX();
|
SERIALIZE(buffer, &packet->regionInfo.mapIndex, sizeof(int));
|
||||||
buffer += sizeof(int);
|
SERIALIZE(buffer, &packet->regionInfo.x, sizeof(int));
|
||||||
*reinterpret_cast<int*>(buffer) = packet->regionInfo.region->GetY();
|
SERIALIZE(buffer, &packet->regionInfo.y, sizeof(int));
|
||||||
buffer += sizeof(int);
|
|
||||||
|
|
||||||
//content
|
//content
|
||||||
for (register int i = 0; i < REGION_WIDTH; i++) {
|
for (register int i = 0; i < REGION_WIDTH; i++) {
|
||||||
@@ -116,92 +93,127 @@ void serializeRegionContent(SerialPacket* packet, char* buffer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void serializeCombat(SerialPacket* packet, char* buffer) {
|
||||||
|
SERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type));
|
||||||
|
|
||||||
|
//integers
|
||||||
|
SERIALIZE(buffer, &packet->combatInfo.combatIndex, sizeof(int));
|
||||||
|
SERIALIZE(buffer, &packet->combatInfo.difficulty, sizeof(int));
|
||||||
|
//TODO: more comabat info
|
||||||
|
}
|
||||||
|
|
||||||
|
void serializeStatistics(Statistics* stats, char* 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 serializeCharacter(SerialPacket* packet, char* buffer) {
|
||||||
|
SERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type));
|
||||||
|
|
||||||
|
//indexes
|
||||||
|
SERIALIZE(buffer, &packet->characterInfo.clientIndex, sizeof(int));
|
||||||
|
SERIALIZE(buffer, &packet->characterInfo.accountIndex, sizeof(int));
|
||||||
|
SERIALIZE(buffer, &packet->characterInfo.characterIndex, sizeof(int));
|
||||||
|
|
||||||
|
//texts
|
||||||
|
SERIALIZE(buffer, packet->clientInfo.handle, PACKET_STRING_SIZE);
|
||||||
|
SERIALIZE(buffer, packet->clientInfo.avatar, PACKET_STRING_SIZE);
|
||||||
|
|
||||||
|
//vectors
|
||||||
|
SERIALIZE(buffer, &packet->characterInfo.position.x, sizeof(double));
|
||||||
|
SERIALIZE(buffer, &packet->characterInfo.position.y, sizeof(double));
|
||||||
|
SERIALIZE(buffer, &packet->characterInfo.motion.x, sizeof(double));
|
||||||
|
SERIALIZE(buffer, &packet->characterInfo.motion.y, sizeof(double));
|
||||||
|
|
||||||
|
//stats structure
|
||||||
|
serializeStatistics(&packet->characterInfo.stats, buffer);
|
||||||
|
buffer += sizeof(Statistics);
|
||||||
|
}
|
||||||
|
|
||||||
|
void serializeEnemy(SerialPacket* packet, char* buffer) {
|
||||||
|
SERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type));
|
||||||
|
|
||||||
|
//texts
|
||||||
|
SERIALIZE(buffer, packet->clientInfo.handle, PACKET_STRING_SIZE);
|
||||||
|
SERIALIZE(buffer, packet->clientInfo.avatar, PACKET_STRING_SIZE);
|
||||||
|
|
||||||
|
//stats structure
|
||||||
|
serializeStatistics(&packet->characterInfo.stats, buffer);
|
||||||
|
buffer += sizeof(Statistics);
|
||||||
|
}
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
//internal deserialization functions
|
//internal deserialization functions
|
||||||
//-------------------------
|
//-------------------------
|
||||||
|
|
||||||
void deserializeType(SerialPacket* packet, char* buffer) {
|
void deserializeType(SerialPacket* packet, char* buffer) {
|
||||||
memcpy(&packet->meta.type, buffer, sizeof(SerialPacket::Type));
|
DESERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type));
|
||||||
}
|
}
|
||||||
|
|
||||||
void deserializeServer(SerialPacket* packet, char* buffer) {
|
void deserializeServer(SerialPacket* packet, char* buffer) {
|
||||||
memcpy(&packet->meta.type, buffer, sizeof(SerialPacket::Type));
|
DESERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type));
|
||||||
buffer += sizeof(SerialPacket::Type);
|
|
||||||
|
|
||||||
//server info
|
//server info
|
||||||
//Note: version info deserialization goes here
|
DESERIALIZE(buffer, &packet->serverInfo.networkVersion, sizeof(int));
|
||||||
memcpy(packet->serverInfo.name, buffer, PACKET_STRING_SIZE);
|
DESERIALIZE(buffer, packet->serverInfo.name, PACKET_STRING_SIZE);
|
||||||
buffer += PACKET_STRING_SIZE;
|
DESERIALIZE(buffer, &packet->serverInfo.playerCount, sizeof(int));
|
||||||
memcpy(&packet->serverInfo.playerCount, buffer, sizeof(int));
|
|
||||||
buffer += sizeof(int);
|
|
||||||
|
|
||||||
//map format
|
|
||||||
memcpy(&packet->serverInfo.regionWidth, buffer, sizeof(int));
|
|
||||||
buffer += sizeof(int);
|
|
||||||
memcpy(&packet->serverInfo.regionHeight, buffer, sizeof(int));
|
|
||||||
buffer += sizeof(int);
|
|
||||||
memcpy(&packet->serverInfo.regionDepth, buffer, sizeof(int));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void deserializeClient(SerialPacket* packet, char* buffer) {
|
void deserializeClient(SerialPacket* packet, char* buffer) {
|
||||||
memcpy(&packet->meta.type, buffer, sizeof(SerialPacket::Type));
|
DESERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type));
|
||||||
buffer += sizeof(SerialPacket::Type);
|
|
||||||
memcpy(&packet->clientInfo.index, buffer, sizeof(int));
|
|
||||||
}
|
|
||||||
|
|
||||||
void deserializePlayer(SerialPacket* packet, char* buffer) {
|
|
||||||
memcpy(&packet->meta.type, buffer, sizeof(SerialPacket::Type));
|
|
||||||
buffer += sizeof(SerialPacket::Type);
|
|
||||||
|
|
||||||
//indexes
|
//indexes
|
||||||
memcpy(&packet->playerInfo.clientIndex, buffer, sizeof(int));
|
DESERIALIZE(buffer, &packet->clientInfo.clientIndex, sizeof(int));
|
||||||
buffer += sizeof(int);
|
DESERIALIZE(buffer, &packet->clientInfo.accountIndex, sizeof(int));
|
||||||
memcpy(&packet->playerInfo.playerIndex, buffer, sizeof(int));
|
DESERIALIZE(buffer, &packet->clientInfo.characterIndex, sizeof(int));
|
||||||
buffer += sizeof(int);
|
|
||||||
|
|
||||||
//text
|
//texts
|
||||||
memcpy(packet->playerInfo.handle, buffer, PACKET_STRING_SIZE);
|
DESERIALIZE(buffer, packet->clientInfo.username, PACKET_STRING_SIZE);
|
||||||
buffer += PACKET_STRING_SIZE;
|
//TODO: password
|
||||||
memcpy(packet->playerInfo.avatar, buffer, PACKET_STRING_SIZE);
|
DESERIALIZE(buffer, packet->clientInfo.handle, PACKET_STRING_SIZE);
|
||||||
buffer += PACKET_STRING_SIZE;
|
DESERIALIZE(buffer, packet->clientInfo.avatar, PACKET_STRING_SIZE);
|
||||||
|
|
||||||
//vectors
|
|
||||||
memcpy(&packet->playerInfo.position.x, buffer, sizeof(double));
|
|
||||||
buffer += sizeof(double);
|
|
||||||
memcpy(&packet->playerInfo.position.y, buffer, sizeof(double));
|
|
||||||
buffer += sizeof(double);
|
|
||||||
memcpy(&packet->playerInfo.motion.x, buffer, sizeof(double));
|
|
||||||
buffer += sizeof(double);
|
|
||||||
memcpy(&packet->playerInfo.motion.y, buffer, sizeof(double));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void deserializeRegionFormat(SerialPacket* packet, char* buffer) {
|
void deserializeRegionFormat(SerialPacket* packet, char* buffer) {
|
||||||
memcpy(&packet->meta.type, buffer, sizeof(SerialPacket::Type));
|
DESERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type));
|
||||||
buffer += sizeof(SerialPacket::Type);
|
|
||||||
|
|
||||||
//x & y
|
//format
|
||||||
memcpy(&packet->regionInfo.x, buffer, sizeof(int));
|
DESERIALIZE(buffer, &packet->regionInfo.mapIndex, sizeof(int));
|
||||||
buffer += sizeof(int);
|
DESERIALIZE(buffer, &packet->regionInfo.x, sizeof(int));
|
||||||
memcpy(&packet->regionInfo.y, buffer, sizeof(int));
|
DESERIALIZE(buffer, &packet->regionInfo.y, sizeof(int));
|
||||||
}
|
}
|
||||||
|
|
||||||
void deserializeRegionContent(SerialPacket* packet, char* buffer) {
|
void deserializeRegionContent(SerialPacket* packet, char* buffer) {
|
||||||
memcpy(&packet->meta.type, buffer, sizeof(SerialPacket::Type));
|
DESERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type));
|
||||||
buffer += sizeof(SerialPacket::Type);
|
|
||||||
|
|
||||||
//x & y
|
//format
|
||||||
memcpy(&packet->regionInfo.x, buffer, sizeof(int));
|
DESERIALIZE(buffer, &packet->regionInfo.mapIndex, sizeof(int));
|
||||||
buffer += sizeof(int);
|
DESERIALIZE(buffer, &packet->regionInfo.x, sizeof(int));
|
||||||
memcpy(&packet->regionInfo.y, buffer, sizeof(int));
|
DESERIALIZE(buffer, &packet->regionInfo.y, sizeof(int));
|
||||||
buffer += sizeof(int);
|
|
||||||
|
|
||||||
//content
|
//an object to work on
|
||||||
BlankAllocator().Create(
|
BlankAllocator().Create(
|
||||||
&packet->regionInfo.region,
|
&packet->regionInfo.region,
|
||||||
packet->regionInfo.x,
|
packet->regionInfo.x,
|
||||||
packet->regionInfo.y
|
packet->regionInfo.y
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//content
|
||||||
for (register int i = 0; i < REGION_WIDTH; i++) {
|
for (register int i = 0; i < REGION_WIDTH; i++) {
|
||||||
for (register int j = 0; j < REGION_HEIGHT; j++) {
|
for (register int j = 0; j < REGION_HEIGHT; j++) {
|
||||||
for (register int k = 0; k < REGION_DEPTH; k++) {
|
for (register int k = 0; k < REGION_DEPTH; k++) {
|
||||||
@@ -212,41 +224,109 @@ void deserializeRegionContent(SerialPacket* packet, char* buffer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void deserializeCombat(SerialPacket* packet, char* buffer) {
|
||||||
|
DESERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type));
|
||||||
|
|
||||||
|
//integers
|
||||||
|
DESERIALIZE(buffer, &packet->combatInfo.combatIndex, sizeof(int));
|
||||||
|
DESERIALIZE(buffer, &packet->combatInfo.difficulty, sizeof(int));
|
||||||
|
//TODO: more comabat info
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void deserializeStatistics(Statistics* stats, char* 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));
|
||||||
|
}
|
||||||
|
|
||||||
|
void deserializeCharacter(SerialPacket* packet, char* buffer) {
|
||||||
|
DESERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type));
|
||||||
|
|
||||||
|
//indexes
|
||||||
|
DESERIALIZE(buffer, &packet->characterInfo.clientIndex, sizeof(int));
|
||||||
|
DESERIALIZE(buffer, &packet->characterInfo.accountIndex, sizeof(int));
|
||||||
|
DESERIALIZE(buffer, &packet->characterInfo.characterIndex, sizeof(int));
|
||||||
|
|
||||||
|
//texts
|
||||||
|
DESERIALIZE(buffer, packet->clientInfo.handle, PACKET_STRING_SIZE);
|
||||||
|
DESERIALIZE(buffer, packet->clientInfo.avatar, PACKET_STRING_SIZE);
|
||||||
|
|
||||||
|
//vectors
|
||||||
|
DESERIALIZE(buffer, &packet->characterInfo.position.x, sizeof(double));
|
||||||
|
DESERIALIZE(buffer, &packet->characterInfo.position.y, sizeof(double));
|
||||||
|
DESERIALIZE(buffer, &packet->characterInfo.motion.x, sizeof(double));
|
||||||
|
DESERIALIZE(buffer, &packet->characterInfo.motion.y, sizeof(double));
|
||||||
|
|
||||||
|
//stats structure
|
||||||
|
deserializeStatistics(&packet->characterInfo.stats, buffer);
|
||||||
|
buffer += sizeof(Statistics);
|
||||||
|
}
|
||||||
|
|
||||||
|
void deserializeEnemy(SerialPacket* packet, char* buffer) {
|
||||||
|
DESERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type));
|
||||||
|
|
||||||
|
//texts
|
||||||
|
DESERIALIZE(buffer, packet->clientInfo.handle, PACKET_STRING_SIZE);
|
||||||
|
DESERIALIZE(buffer, packet->clientInfo.avatar, PACKET_STRING_SIZE);
|
||||||
|
|
||||||
|
//stats structure
|
||||||
|
deserializeStatistics(&packet->characterInfo.stats, buffer);
|
||||||
|
buffer += sizeof(Statistics);
|
||||||
|
}
|
||||||
|
|
||||||
//-------------------------
|
//-------------------------
|
||||||
//the interface functions
|
//the interface functions
|
||||||
//-------------------------
|
//-------------------------
|
||||||
|
|
||||||
void serialize(SerialPacket* packet, void* buffer) {
|
void serialize(SerialPacket* packet, void* buffer) {
|
||||||
switch(packet->meta.type) {
|
switch(packet->meta.type) {
|
||||||
//No extra data
|
//no extra data
|
||||||
case SerialPacket::Type::NONE:
|
case SerialPacket::Type::NONE:
|
||||||
case SerialPacket::Type::PING:
|
case SerialPacket::Type::PING:
|
||||||
case SerialPacket::Type::PONG:
|
case SerialPacket::Type::PONG:
|
||||||
case SerialPacket::Type::BROADCAST_REQUEST:
|
case SerialPacket::Type::BROADCAST_REQUEST:
|
||||||
case SerialPacket::Type::JOIN_REQUEST:
|
|
||||||
case SerialPacket::Type::SYNCHRONIZE:
|
//all rejections
|
||||||
|
case SerialPacket::Type::BROADCAST_REJECTION:
|
||||||
|
case SerialPacket::Type::JOIN_REJECTION:
|
||||||
|
case SerialPacket::Type::REGION_REJECTION:
|
||||||
|
case SerialPacket::Type::CHARACTER_REJECTION:
|
||||||
|
case SerialPacket::Type::ENEMY_REJECTION:
|
||||||
|
case SerialPacket::Type::COMBAT_REJECTION:
|
||||||
|
|
||||||
serializeType(packet, reinterpret_cast<char*>(buffer));
|
serializeType(packet, reinterpret_cast<char*>(buffer));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//Server info
|
//server info
|
||||||
case SerialPacket::Type::BROADCAST_RESPONSE:
|
case SerialPacket::Type::BROADCAST_RESPONSE:
|
||||||
serializeServer(packet, reinterpret_cast<char*>(buffer));
|
serializeServer(packet, reinterpret_cast<char*>(buffer));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//Client info
|
//client info
|
||||||
|
case SerialPacket::Type::JOIN_REQUEST:
|
||||||
case SerialPacket::Type::JOIN_RESPONSE:
|
case SerialPacket::Type::JOIN_RESPONSE:
|
||||||
|
case SerialPacket::Type::SYNCHRONIZE:
|
||||||
case SerialPacket::Type::DISCONNECT:
|
case SerialPacket::Type::DISCONNECT:
|
||||||
case SerialPacket::Type::SHUTDOWN:
|
case SerialPacket::Type::SHUTDOWN:
|
||||||
serializeClient(packet, reinterpret_cast<char*>(buffer));
|
serializeClient(packet, reinterpret_cast<char*>(buffer));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//Player info
|
|
||||||
case SerialPacket::Type::PLAYER_NEW:
|
|
||||||
case SerialPacket::Type::PLAYER_DELETE:
|
|
||||||
case SerialPacket::Type::PLAYER_UPDATE:
|
|
||||||
serializePlayer(packet, reinterpret_cast<char*>(buffer));
|
|
||||||
break;
|
|
||||||
|
|
||||||
//region info
|
//region info
|
||||||
case SerialPacket::Type::REGION_REQUEST:
|
case SerialPacket::Type::REGION_REQUEST:
|
||||||
serializeRegionFormat(packet, reinterpret_cast<char*>(buffer));
|
serializeRegionFormat(packet, reinterpret_cast<char*>(buffer));
|
||||||
@@ -255,6 +335,30 @@ void serialize(SerialPacket* packet, void* buffer) {
|
|||||||
case SerialPacket::Type::REGION_CONTENT:
|
case SerialPacket::Type::REGION_CONTENT:
|
||||||
serializeRegionContent(packet, reinterpret_cast<char*>(buffer));
|
serializeRegionContent(packet, reinterpret_cast<char*>(buffer));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
//combat info
|
||||||
|
case SerialPacket::Type::COMBAT_ENTER:
|
||||||
|
case SerialPacket::Type::COMBAT_EXIT:
|
||||||
|
serializeCombat(packet, reinterpret_cast<char*>(buffer));
|
||||||
|
break;
|
||||||
|
|
||||||
|
//character info
|
||||||
|
case SerialPacket::Type::CHARACTER_NEW:
|
||||||
|
case SerialPacket::Type::CHARACTER_DELETE:
|
||||||
|
case SerialPacket::Type::CHARACTER_UPDATE:
|
||||||
|
case SerialPacket::Type::CHARACTER_STATS_REQUEST:
|
||||||
|
case SerialPacket::Type::CHARACTER_STATS_RESPONSE:
|
||||||
|
serializeCharacter(packet, reinterpret_cast<char*>(buffer));
|
||||||
|
break;
|
||||||
|
|
||||||
|
//enemy info
|
||||||
|
case SerialPacket::Type::ENEMY_NEW:
|
||||||
|
case SerialPacket::Type::ENEMY_DELETE:
|
||||||
|
case SerialPacket::Type::ENEMY_UPDATE:
|
||||||
|
case SerialPacket::Type::ENEMY_STATS_REQUEST:
|
||||||
|
case SerialPacket::Type::ENEMY_STATS_RESPONSE:
|
||||||
|
serializeEnemy(packet, reinterpret_cast<char*>(buffer));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,35 +366,37 @@ void deserialize(SerialPacket* packet, void* buffer) {
|
|||||||
//find the type, so that you can actually deserialize the packet!
|
//find the type, so that you can actually deserialize the packet!
|
||||||
deserializeType(packet, reinterpret_cast<char*>(buffer));
|
deserializeType(packet, reinterpret_cast<char*>(buffer));
|
||||||
switch(packet->meta.type) {
|
switch(packet->meta.type) {
|
||||||
//No extra data
|
//no extra data
|
||||||
case SerialPacket::Type::NONE:
|
case SerialPacket::Type::NONE:
|
||||||
case SerialPacket::Type::PING:
|
case SerialPacket::Type::PING:
|
||||||
case SerialPacket::Type::PONG:
|
case SerialPacket::Type::PONG:
|
||||||
case SerialPacket::Type::BROADCAST_REQUEST:
|
case SerialPacket::Type::BROADCAST_REQUEST:
|
||||||
case SerialPacket::Type::JOIN_REQUEST:
|
|
||||||
case SerialPacket::Type::SYNCHRONIZE:
|
//all rejections
|
||||||
|
case SerialPacket::Type::BROADCAST_REJECTION:
|
||||||
|
case SerialPacket::Type::JOIN_REJECTION:
|
||||||
|
case SerialPacket::Type::REGION_REJECTION:
|
||||||
|
case SerialPacket::Type::CHARACTER_REJECTION:
|
||||||
|
case SerialPacket::Type::ENEMY_REJECTION:
|
||||||
|
case SerialPacket::Type::COMBAT_REJECTION:
|
||||||
|
|
||||||
//NOTHING
|
//NOTHING
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//Server info
|
//server info
|
||||||
case SerialPacket::Type::BROADCAST_RESPONSE:
|
case SerialPacket::Type::BROADCAST_RESPONSE:
|
||||||
deserializeServer(packet, reinterpret_cast<char*>(buffer));
|
deserializeServer(packet, reinterpret_cast<char*>(buffer));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//Client info
|
//client info
|
||||||
|
case SerialPacket::Type::JOIN_REQUEST:
|
||||||
case SerialPacket::Type::JOIN_RESPONSE:
|
case SerialPacket::Type::JOIN_RESPONSE:
|
||||||
|
case SerialPacket::Type::SYNCHRONIZE:
|
||||||
case SerialPacket::Type::DISCONNECT:
|
case SerialPacket::Type::DISCONNECT:
|
||||||
case SerialPacket::Type::SHUTDOWN:
|
case SerialPacket::Type::SHUTDOWN:
|
||||||
deserializeClient(packet, reinterpret_cast<char*>(buffer));
|
deserializeClient(packet, reinterpret_cast<char*>(buffer));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//Player info
|
|
||||||
case SerialPacket::Type::PLAYER_NEW:
|
|
||||||
case SerialPacket::Type::PLAYER_DELETE:
|
|
||||||
case SerialPacket::Type::PLAYER_UPDATE:
|
|
||||||
deserializePlayer(packet, reinterpret_cast<char*>(buffer));
|
|
||||||
break;
|
|
||||||
|
|
||||||
//region info
|
//region info
|
||||||
case SerialPacket::Type::REGION_REQUEST:
|
case SerialPacket::Type::REGION_REQUEST:
|
||||||
deserializeRegionFormat(packet, reinterpret_cast<char*>(buffer));
|
deserializeRegionFormat(packet, reinterpret_cast<char*>(buffer));
|
||||||
@@ -299,5 +405,29 @@ void deserialize(SerialPacket* packet, void* buffer) {
|
|||||||
case SerialPacket::Type::REGION_CONTENT:
|
case SerialPacket::Type::REGION_CONTENT:
|
||||||
deserializeRegionContent(packet, reinterpret_cast<char*>(buffer));
|
deserializeRegionContent(packet, reinterpret_cast<char*>(buffer));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
//combat info
|
||||||
|
case SerialPacket::Type::COMBAT_ENTER:
|
||||||
|
case SerialPacket::Type::COMBAT_EXIT:
|
||||||
|
serializeCombat(packet, reinterpret_cast<char*>(buffer));
|
||||||
|
break;
|
||||||
|
|
||||||
|
//character info
|
||||||
|
case SerialPacket::Type::CHARACTER_NEW:
|
||||||
|
case SerialPacket::Type::CHARACTER_DELETE:
|
||||||
|
case SerialPacket::Type::CHARACTER_UPDATE:
|
||||||
|
case SerialPacket::Type::CHARACTER_STATS_REQUEST:
|
||||||
|
case SerialPacket::Type::CHARACTER_STATS_RESPONSE:
|
||||||
|
deserializeCharacter(packet, reinterpret_cast<char*>(buffer));
|
||||||
|
break;
|
||||||
|
|
||||||
|
//enemy info
|
||||||
|
case SerialPacket::Type::ENEMY_NEW:
|
||||||
|
case SerialPacket::Type::ENEMY_DELETE:
|
||||||
|
case SerialPacket::Type::ENEMY_UPDATE:
|
||||||
|
case SerialPacket::Type::ENEMY_STATS_REQUEST:
|
||||||
|
case SerialPacket::Type::ENEMY_STATS_RESPONSE:
|
||||||
|
serializeEnemy(packet, reinterpret_cast<char*>(buffer));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -27,12 +27,12 @@
|
|||||||
/* NOTE: Keep the PACKET_BUFFER_SIZE up to date
|
/* NOTE: Keep the PACKET_BUFFER_SIZE up to date
|
||||||
* NOTE: REGION_CONTENT is currently the largest type of packet
|
* NOTE: REGION_CONTENT is currently the largest type of packet
|
||||||
* map content: REGION_WIDTH * REGION_HEIGHT * REGION_DEPTH * sizoeof(region::type_t)
|
* map content: REGION_WIDTH * REGION_HEIGHT * REGION_DEPTH * sizoeof(region::type_t)
|
||||||
* map format: sizeof(int) * 2
|
* map format: sizeof(int) * 3
|
||||||
* metadata: sizeof(metadata)
|
* metadata: sizeof(SerialPacket::Type)
|
||||||
*/
|
*/
|
||||||
#define PACKET_BUFFER_SIZE REGION_WIDTH * REGION_HEIGHT * REGION_DEPTH * sizeof(Region::type_t) + sizeof(int) * 2 + sizeof(SerialPacket::Metadata)
|
#define PACKET_BUFFER_SIZE REGION_WIDTH * REGION_HEIGHT * REGION_DEPTH * sizeof(Region::type_t) + sizeof(int) * 3 + sizeof(SerialPacket::Type)
|
||||||
|
|
||||||
void serialize(SerialPacket* const, void*);
|
void serialize(SerialPacket* const, void* dest);
|
||||||
void deserialize(SerialPacket* const, void*);
|
void deserialize(SerialPacket* const, void* src);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2013, 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
@@ -24,48 +24,79 @@
|
|||||||
|
|
||||||
#include "vector2.hpp"
|
#include "vector2.hpp"
|
||||||
#include "region.hpp"
|
#include "region.hpp"
|
||||||
|
#include "statistics.hpp"
|
||||||
|
|
||||||
#include "SDL/SDL_net.h"
|
#include "SDL/SDL_net.h"
|
||||||
|
|
||||||
|
#define NETWORK_VERSION 20140528
|
||||||
#define PACKET_STRING_SIZE 100
|
#define PACKET_STRING_SIZE 100
|
||||||
|
|
||||||
#pragma pack(push, 0)
|
|
||||||
|
|
||||||
union SerialPacket {
|
union SerialPacket {
|
||||||
//types of packets
|
//types of packets
|
||||||
enum class Type {
|
enum class Type {
|
||||||
//default: there is something wrong
|
//default: there is something wrong
|
||||||
NONE = 0,
|
NONE = 0,
|
||||||
|
|
||||||
//not used
|
//keep alive
|
||||||
PING = 1,
|
PING = 1,
|
||||||
PONG = 2,
|
PONG = 2,
|
||||||
|
|
||||||
//Searching for a server to join
|
//searching for a server to join
|
||||||
BROADCAST_REQUEST = 3,
|
BROADCAST_REQUEST = 3,
|
||||||
BROADCAST_RESPONSE = 4,
|
BROADCAST_RESPONSE = 4,
|
||||||
|
BROADCAST_REJECTION = 5,
|
||||||
|
|
||||||
//try to join the server
|
//try to join the server
|
||||||
JOIN_REQUEST = 5,
|
JOIN_REQUEST = 6,
|
||||||
JOIN_RESPONSE = 6,
|
JOIN_RESPONSE = 7,
|
||||||
|
JOIN_REJECTION = 8,
|
||||||
//disconnect from the server
|
|
||||||
DISCONNECT = 7,
|
|
||||||
|
|
||||||
//mass update
|
//mass update
|
||||||
SYNCHRONIZE = 8,
|
SYNCHRONIZE = 9,
|
||||||
|
|
||||||
|
//disconnect from the server
|
||||||
|
DISCONNECT = 10,
|
||||||
|
|
||||||
//shut down the server
|
//shut down the server
|
||||||
SHUTDOWN = 9,
|
SHUTDOWN = 11,
|
||||||
|
|
||||||
//Player movement, etc.
|
|
||||||
PLAYER_NEW = 10,
|
|
||||||
PLAYER_DELETE = 11,
|
|
||||||
PLAYER_UPDATE = 12,
|
|
||||||
|
|
||||||
//map data
|
//map data
|
||||||
REGION_REQUEST = 13,
|
REGION_REQUEST = 12,
|
||||||
REGION_CONTENT = 14,
|
REGION_CONTENT = 13,
|
||||||
|
REGION_REJECTION = 14,
|
||||||
|
|
||||||
|
//combat data
|
||||||
|
COMBAT_ENTER = 15,
|
||||||
|
COMBAT_EXIT = 16,
|
||||||
|
|
||||||
|
COMBAT_UPDATE = 17,
|
||||||
|
|
||||||
|
COMBAT_REJECTION = 18,
|
||||||
|
|
||||||
|
//character data
|
||||||
|
CHARACTER_NEW = 19,
|
||||||
|
CHARACTER_DELETE = 20,
|
||||||
|
CHARACTER_UPDATE = 21,
|
||||||
|
|
||||||
|
CHARACTER_STATS_REQUEST = 22,
|
||||||
|
CHARACTER_STATS_RESPONSE = 23,
|
||||||
|
|
||||||
|
CHARACTER_REJECTION = 24,
|
||||||
|
|
||||||
|
//enemy data
|
||||||
|
ENEMY_NEW = 25,
|
||||||
|
ENEMY_DELETE = 26,
|
||||||
|
ENEMY_UPDATE = 27,
|
||||||
|
|
||||||
|
ENEMY_STATS_REQUEST = 28,
|
||||||
|
ENEMY_STATS_RESPONSE = 29,
|
||||||
|
|
||||||
|
ENEMY_REJECTION = 30,
|
||||||
|
|
||||||
|
//more packet types go here
|
||||||
|
|
||||||
|
//not used
|
||||||
|
LAST,
|
||||||
};
|
};
|
||||||
|
|
||||||
//metadata on the packet itself
|
//metadata on the packet itself
|
||||||
@@ -74,45 +105,66 @@ union SerialPacket {
|
|||||||
IPaddress srcAddress;
|
IPaddress srcAddress;
|
||||||
}meta;
|
}meta;
|
||||||
|
|
||||||
//information about the server
|
//info about the server
|
||||||
struct ServerInformation {
|
struct ServerInformation {
|
||||||
Metadata meta;
|
Metadata meta;
|
||||||
//TODO: version info
|
int networkVersion;
|
||||||
char name[PACKET_STRING_SIZE];
|
char name[PACKET_STRING_SIZE];
|
||||||
int playerCount;
|
int playerCount;
|
||||||
|
|
||||||
//map format
|
|
||||||
int regionWidth;
|
|
||||||
int regionHeight;
|
|
||||||
int regionDepth;
|
|
||||||
}serverInfo;
|
}serverInfo;
|
||||||
|
|
||||||
//information about the client
|
//info about the client
|
||||||
//TODO: login credentials
|
|
||||||
struct ClientInformation {
|
struct ClientInformation {
|
||||||
Metadata meta;
|
|
||||||
int index;
|
|
||||||
}clientInfo;
|
|
||||||
|
|
||||||
//information about a player
|
|
||||||
struct PlayerInformation {
|
|
||||||
Metadata meta;
|
Metadata meta;
|
||||||
int clientIndex;
|
int clientIndex;
|
||||||
int playerIndex;
|
int accountIndex;
|
||||||
//TODO: should move handle/avatar into clientInfo; these might actually do better during the login system
|
int characterIndex;
|
||||||
|
char username[PACKET_STRING_SIZE];
|
||||||
|
//TODO: password
|
||||||
char handle[PACKET_STRING_SIZE];
|
char handle[PACKET_STRING_SIZE];
|
||||||
char avatar[PACKET_STRING_SIZE];
|
char avatar[PACKET_STRING_SIZE];
|
||||||
Vector2 position;
|
}clientInfo;
|
||||||
Vector2 motion;
|
|
||||||
}playerInfo;
|
|
||||||
|
|
||||||
//map data
|
//info about a region
|
||||||
struct RegionInformation {
|
struct RegionInformation {
|
||||||
Metadata meta;
|
Metadata meta;
|
||||||
|
int mapIndex;
|
||||||
int x, y;
|
int x, y;
|
||||||
Region* region;
|
Region* region;
|
||||||
}regionInfo;
|
}regionInfo;
|
||||||
|
|
||||||
|
//info about a combat scenario
|
||||||
|
struct CombatInformation {
|
||||||
|
Metadata meta;
|
||||||
|
int combatIndex;
|
||||||
|
int difficulty;
|
||||||
|
//TODO: background image, based on terrain type
|
||||||
|
//TODO: array of combatants
|
||||||
|
//TODO: rewards
|
||||||
|
}combatInfo;
|
||||||
|
|
||||||
|
//info about a character
|
||||||
|
struct CharacterInformation {
|
||||||
|
Metadata meta;
|
||||||
|
int clientIndex;
|
||||||
|
int accountIndex;
|
||||||
|
int characterIndex;
|
||||||
|
char handle[PACKET_STRING_SIZE];
|
||||||
|
char avatar[PACKET_STRING_SIZE];
|
||||||
|
int mapIndex;
|
||||||
|
Vector2 position;
|
||||||
|
Vector2 motion;
|
||||||
|
Statistics stats;
|
||||||
|
}characterInfo;
|
||||||
|
|
||||||
|
//info about an enemy
|
||||||
|
struct EnemyInformation {
|
||||||
|
Metadata meta;
|
||||||
|
char handle[PACKET_STRING_SIZE];
|
||||||
|
char avatar[PACKET_STRING_SIZE];
|
||||||
|
Statistics stats;
|
||||||
|
}enemyInfo;
|
||||||
|
|
||||||
//defaults
|
//defaults
|
||||||
SerialPacket() {
|
SerialPacket() {
|
||||||
meta.type = Type::NONE;
|
meta.type = Type::NONE;
|
||||||
@@ -120,6 +172,4 @@ union SerialPacket {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2013, 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
@@ -21,34 +21,33 @@
|
|||||||
*/
|
*/
|
||||||
#include "udp_network_utility.hpp"
|
#include "udp_network_utility.hpp"
|
||||||
|
|
||||||
|
#include "serial.hpp"
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
void UDPNetworkUtility::Open(int port, int packSize) {
|
//DOCS: memset() is used before sending a packet to remove old data; you don't want to send sensitive data over the network
|
||||||
if (!(socket = SDLNet_UDP_Open(port))) {
|
//NOTE: don't confuse SerialPacket with UDPpacket
|
||||||
Close();
|
|
||||||
throw(std::runtime_error("Failed to open a UDP socket"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(packOut = SDLNet_AllocPacket(packSize))) {
|
void UDPNetworkUtility::Open(int port) {
|
||||||
|
socket = SDLNet_UDP_Open(port);
|
||||||
|
packet = SDLNet_AllocPacket(PACKET_BUFFER_SIZE);
|
||||||
|
if (!socket || !packet) {
|
||||||
Close();
|
Close();
|
||||||
throw(std::runtime_error("Failed to allocate the out packet"));
|
throw(std::runtime_error("Failed to open UDPNetworkUtility"));
|
||||||
}
|
|
||||||
|
|
||||||
if (!(packIn = SDLNet_AllocPacket(packSize))) {
|
|
||||||
Close();
|
|
||||||
throw(std::runtime_error("Failed to allocate the in packet"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UDPNetworkUtility::Close() {
|
void UDPNetworkUtility::Close() {
|
||||||
SDLNet_UDP_Close(socket);
|
SDLNet_UDP_Close(socket);
|
||||||
SDLNet_FreePacket(packOut);
|
SDLNet_FreePacket(packet);
|
||||||
SDLNet_FreePacket(packIn);
|
|
||||||
socket = nullptr;
|
socket = nullptr;
|
||||||
packOut = nullptr;
|
packet = nullptr;
|
||||||
packIn = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
//bind to a channel
|
||||||
|
//-------------------------
|
||||||
|
|
||||||
int UDPNetworkUtility::Bind(const char* ip, int port, int channel) {
|
int UDPNetworkUtility::Bind(const char* ip, int port, int channel) {
|
||||||
IPaddress add;
|
IPaddress add;
|
||||||
if (SDLNet_ResolveHost(&add, ip, port) == -1) {
|
if (SDLNet_ResolveHost(&add, ip, port) == -1) {
|
||||||
@@ -61,7 +60,7 @@ int UDPNetworkUtility::Bind(const char* ip, int port, int channel) {
|
|||||||
int UDPNetworkUtility::Bind(IPaddress* add, int channel) {
|
int UDPNetworkUtility::Bind(IPaddress* add, int channel) {
|
||||||
int ret = SDLNet_UDP_Bind(socket, channel, add);
|
int ret = SDLNet_UDP_Bind(socket, channel, add);
|
||||||
|
|
||||||
if (ret == -1) {
|
if (ret < 0) {
|
||||||
throw(std::runtime_error("Failed to bind to a channel"));
|
throw(std::runtime_error("Failed to bind to a channel"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,25 +71,29 @@ void UDPNetworkUtility::Unbind(int channel) {
|
|||||||
SDLNet_UDP_Unbind(socket, channel);
|
SDLNet_UDP_Unbind(socket, channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
int UDPNetworkUtility::Send(const char* ip, int port, void* data, int len) {
|
//-------------------------
|
||||||
|
//send a buffer
|
||||||
|
//-------------------------
|
||||||
|
|
||||||
|
int UDPNetworkUtility::SendTo(const char* ip, int port, void* data, int len) {
|
||||||
IPaddress add;
|
IPaddress add;
|
||||||
if (SDLNet_ResolveHost(&add, ip, port) == -1) {
|
if (SDLNet_ResolveHost(&add, ip, port) == -1) {
|
||||||
throw(std::runtime_error("Failed to resolve a host"));
|
throw(std::runtime_error("Failed to resolve a host"));
|
||||||
}
|
}
|
||||||
|
|
||||||
Send(&add, data, len);
|
SendTo(&add, data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
int UDPNetworkUtility::Send(IPaddress* add, void* data, int len) {
|
int UDPNetworkUtility::SendTo(IPaddress* add, void* data, int len) {
|
||||||
if (len > packOut->maxlen) {
|
if (len > packet->maxlen) {
|
||||||
throw(std::runtime_error("Failed to copy the data into the packet"));
|
throw(std::runtime_error("The buffer is to large for the UDPpacket"));
|
||||||
}
|
}
|
||||||
memset(packOut->data, 0, packOut->maxlen);
|
memset(packet->data, 0, packet->maxlen);
|
||||||
memcpy(packOut->data, data, len);
|
memcpy(packet->data, data, len);
|
||||||
packOut->len = len;
|
packet->len = len;
|
||||||
packOut->address = *add;
|
packet->address = *add;
|
||||||
|
|
||||||
int ret = SDLNet_UDP_Send(socket, -1, packOut);
|
int ret = SDLNet_UDP_Send(socket, -1, packet);
|
||||||
|
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
throw(std::runtime_error("Failed to send a packet"));
|
throw(std::runtime_error("Failed to send a packet"));
|
||||||
@@ -99,15 +102,15 @@ int UDPNetworkUtility::Send(IPaddress* add, void* data, int len) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int UDPNetworkUtility::Send(int channel, void* data, int len) {
|
int UDPNetworkUtility::SendTo(int channel, void* data, int len) {
|
||||||
if (len > packOut->maxlen) {
|
if (len > packet->maxlen) {
|
||||||
throw(std::runtime_error("Failed to copy the data into the packet"));
|
throw(std::runtime_error("The buffer is to large for the UDPpacket"));
|
||||||
}
|
}
|
||||||
memset(packOut->data, 0, packOut->maxlen);
|
memset(packet->data, 0, packet->maxlen);
|
||||||
memcpy(packOut->data, data, len);
|
memcpy(packet->data, data, len);
|
||||||
packOut->len = len;
|
packet->len = len;
|
||||||
|
|
||||||
int ret = SDLNet_UDP_Send(socket, channel, packOut);
|
int ret = SDLNet_UDP_Send(socket, channel, packet);
|
||||||
|
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
throw(std::runtime_error("Failed to send a packet"));
|
throw(std::runtime_error("Failed to send a packet"));
|
||||||
@@ -116,29 +119,30 @@ int UDPNetworkUtility::Send(int channel, void* data, int len) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int UDPNetworkUtility::SendAll(void* data, int len) {
|
int UDPNetworkUtility::SendToAllChannels(void* data, int len) {
|
||||||
if (len > packOut->maxlen) {
|
if (len > packet->maxlen) {
|
||||||
throw(std::runtime_error("Failed to copy the data into the packet"));
|
throw(std::runtime_error("The buffer is to large for the UDPpacket"));
|
||||||
}
|
}
|
||||||
memset(packOut->data, 0, packOut->maxlen);
|
memset(packet->data, 0, packet->maxlen);
|
||||||
memcpy(packOut->data, data, len);
|
memcpy(packet->data, data, len);
|
||||||
packOut->len = len;
|
packet->len = len;
|
||||||
|
|
||||||
int sent = 0;
|
int sent = 0;
|
||||||
|
|
||||||
//send to all bound channels
|
//send to all bound channels
|
||||||
for (int i = 0; i < SDLNET_MAX_UDPCHANNELS; i++) {
|
for (int i = 0; i < SDLNET_MAX_UDPCHANNELS; i++) {
|
||||||
if (SDLNet_UDP_GetPeerAddress(socket, i)) {
|
if (SDLNet_UDP_GetPeerAddress(socket, i)) {
|
||||||
sent += SDLNet_UDP_Send(socket, i, packOut);
|
sent += SDLNet_UDP_Send(socket, i, packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return sent;
|
return sent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: put a void* and int* parameter list here
|
||||||
int UDPNetworkUtility::Receive() {
|
int UDPNetworkUtility::Receive() {
|
||||||
memset(packIn->data, 0, packIn->maxlen);
|
memset(packet->data, 0, packet->maxlen);
|
||||||
int ret = SDLNet_UDP_Recv(socket, packIn);
|
int ret = SDLNet_UDP_Recv(socket, packet);
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
throw(std::runtime_error("Unknown network error occured"));
|
throw(std::runtime_error("Unknown network error occured"));
|
||||||
@@ -146,3 +150,75 @@ int UDPNetworkUtility::Receive() {
|
|||||||
|
|
||||||
return ret;
|
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);
|
||||||
|
serialize(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);
|
||||||
|
serialize(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);
|
||||||
|
serialize(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);
|
||||||
|
deserialize(serialPacket, packet->data);
|
||||||
|
serialPacket->meta.srcAddress = packet->address;
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
throw(std::runtime_error("Unknown network error occured"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2013, 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
@@ -24,12 +24,14 @@
|
|||||||
|
|
||||||
#include "SDL/SDL_net.h"
|
#include "SDL/SDL_net.h"
|
||||||
|
|
||||||
|
#include "serial_packet.hpp"
|
||||||
|
|
||||||
class UDPNetworkUtility {
|
class UDPNetworkUtility {
|
||||||
public:
|
public:
|
||||||
UDPNetworkUtility() = default;
|
UDPNetworkUtility() = default;
|
||||||
~UDPNetworkUtility() = default;
|
~UDPNetworkUtility() = default;
|
||||||
|
|
||||||
void Open(int port, int packSize);
|
void Open(int port);
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
//bind to a channel
|
//bind to a channel
|
||||||
@@ -41,31 +43,30 @@ public:
|
|||||||
return SDLNet_UDP_GetPeerAddress(socket, channel);
|
return SDLNet_UDP_GetPeerAddress(socket, channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Send(const char* ip, int port, void* data, int len);
|
//send a buffer
|
||||||
int Send(IPaddress* add, void* data, int len);
|
int SendTo(const char* ip, int port, void* data, int len);
|
||||||
int Send(int channel, void* data, int len);
|
int SendTo(IPaddress* add, void* data, int len);
|
||||||
int SendAll(void* data, int len);
|
int SendTo(int channel, void* data, int len);
|
||||||
|
int SendToAllChannels(void* data, int len);
|
||||||
int Receive();
|
int Receive();
|
||||||
|
|
||||||
void* GetOutData() const {
|
//send a SerialPacket
|
||||||
return reinterpret_cast<void*>(packOut->data);
|
int SendTo(const char* ip, int port, SerialPacket* serialPacket);
|
||||||
};
|
int SendTo(IPaddress* add, SerialPacket* serialPacket);
|
||||||
void* GetInData() const {
|
int SendTo(int channel, SerialPacket* serialPacket);
|
||||||
return reinterpret_cast<void*>(packIn->data);
|
int SendToAllChannels(SerialPacket* serialPacket);
|
||||||
};
|
int Receive(SerialPacket* serialPacket);
|
||||||
UDPpacket* GetOutPacket() const {
|
|
||||||
return packOut;
|
//accessors
|
||||||
}
|
UDPpacket* GetPacket() const {
|
||||||
UDPpacket* GetInPacket() const {
|
return packet;
|
||||||
return packIn;
|
|
||||||
}
|
}
|
||||||
UDPsocket GetSocket() const {
|
UDPsocket GetSocket() const {
|
||||||
return socket;
|
return socket;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
UDPsocket socket = nullptr;
|
UDPsocket socket = nullptr;
|
||||||
UDPpacket* packOut = nullptr;
|
UDPpacket* packet = nullptr;
|
||||||
UDPpacket* packIn = nullptr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
#define LUA_LIB
|
#define LUA_LIB
|
||||||
|
|
||||||
#include "lua/lua.hpp"
|
#include "lua/lua.hpp"
|
||||||
#include "region_api.hpp"
|
#include "map_api.hpp"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -41,7 +41,7 @@ static const luaL_Reg loadedlibs[] = {
|
|||||||
{LUA_DBLIBNAME, luaopen_debug},
|
{LUA_DBLIBNAME, luaopen_debug},
|
||||||
|
|
||||||
/* custom libs */
|
/* custom libs */
|
||||||
{LUA_REGIONLIBNAME, luaopen_regionapi},
|
{LUA_MAPLIBNAME, luaopen_mapapi},
|
||||||
|
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,17 +1,14 @@
|
|||||||
#config
|
#config
|
||||||
INCLUDES+=. .. ../map
|
INCLUDES+=. ../map ../utilities
|
||||||
LIBS+=
|
LIBS+=
|
||||||
CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES))
|
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
|
||||||
CFLAGS+=-DDEBUG $(addprefix -I,$(INCLUDES))
|
|
||||||
|
|
||||||
#source
|
#source
|
||||||
CXXSRC=$(wildcard *.cpp)
|
CXXSRC=$(wildcard *.cpp)
|
||||||
CSRC=$(wildcard *.c)
|
|
||||||
|
|
||||||
#objects
|
#objects
|
||||||
OBJDIR=obj
|
OBJDIR=obj
|
||||||
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
|
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
|
||||||
OBJ+=$(addprefix $(OBJDIR)/,$(CSRC:.c=.o))
|
|
||||||
|
|
||||||
#output
|
#output
|
||||||
OUTDIR=../..
|
OUTDIR=../..
|
||||||
@@ -34,9 +31,6 @@ $(OUTDIR):
|
|||||||
$(OBJDIR)/%.o: %.cpp
|
$(OBJDIR)/%.o: %.cpp
|
||||||
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
$(OBJDIR)/%.o: %.c
|
|
||||||
$(CC) $(CFLAGS) -c -o $@ $<
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) *.o *.a *.exe
|
$(RM) *.o *.a *.exe
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,126 @@
|
|||||||
|
/* 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 "map_api.hpp"
|
||||||
|
|
||||||
|
//map headers
|
||||||
|
#include "map_allocator.hpp"
|
||||||
|
#include "map_file_format.hpp"
|
||||||
|
#include "region_pager.hpp"
|
||||||
|
|
||||||
|
//NOTE: When operating on a region, setTile() & getTile() *are not* zero indexed, but when operating on the entire map they *are* zero indexed.
|
||||||
|
|
||||||
|
static int setTile(lua_State* L) {
|
||||||
|
if (lua_gettop(L) == 5) {
|
||||||
|
//operating on a region
|
||||||
|
Region* ptr = (Region*)lua_touserdata(L, 1);
|
||||||
|
ptr->SetTile(lua_tointeger(L, 2)-1, lua_tointeger(L, 3)-1, lua_tointeger(L, 4)-1, lua_tointeger(L, 5));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//operating on the whole map
|
||||||
|
lua_pushstring(L, "pager");
|
||||||
|
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||||
|
|
||||||
|
//assume the pager is using lua
|
||||||
|
RegionPager<LuaAllocator, LuaFormat>* pager = reinterpret_cast<RegionPager<LuaAllocator, LuaFormat>*>(lua_touserdata(L, -1));
|
||||||
|
|
||||||
|
//balance the stack
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
pager->SetTile(lua_tointeger(L, 1), lua_tointeger(L, 2), lua_tointeger(L, 3), lua_tointeger(L, 4));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int getTile(lua_State* L) {
|
||||||
|
if (lua_gettop(L) == 4) {
|
||||||
|
//operating on a region
|
||||||
|
Region* ptr = (Region*)lua_touserdata(L, 1);
|
||||||
|
int ret = ptr->GetTile(lua_tointeger(L, 2)-1, lua_tointeger(L, 3)-1, lua_tointeger(L, 4)-1);
|
||||||
|
lua_pushnumber(L, ret);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//operating on the whole map
|
||||||
|
lua_pushstring(L, "pager");
|
||||||
|
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||||
|
|
||||||
|
//assume the pager is using lua
|
||||||
|
RegionPager<LuaAllocator, LuaFormat>* pager = reinterpret_cast<RegionPager<LuaAllocator, LuaFormat>*>(lua_touserdata(L, -1));
|
||||||
|
|
||||||
|
//balance the stack
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
int ret = pager->GetTile(lua_tointeger(L, 1), lua_tointeger(L, 2), lua_tointeger(L, 3));
|
||||||
|
lua_pushnumber(L, ret);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int getX(lua_State* L) {
|
||||||
|
Region* ptr = (Region*)lua_touserdata(L, 1);
|
||||||
|
lua_pushinteger(L, ptr->GetX());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int getY(lua_State* L) {
|
||||||
|
Region* ptr = (Region*)lua_touserdata(L, 1);
|
||||||
|
lua_pushinteger(L, ptr->GetY());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int getRegionWidth(lua_State* L) {
|
||||||
|
lua_pushinteger(L, REGION_WIDTH);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int getRegionHeight(lua_State* L) {
|
||||||
|
lua_pushinteger(L, REGION_HEIGHT);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int getRegionDepth(lua_State* L) {
|
||||||
|
lua_pushinteger(L, REGION_DEPTH);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dummy(lua_State* L) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const luaL_Reg regionlib[] = {
|
||||||
|
{"create", dummy},
|
||||||
|
{"unload", dummy},
|
||||||
|
{"load", dummy},
|
||||||
|
{"save", dummy},
|
||||||
|
{"settile",setTile},
|
||||||
|
{"gettile",getTile},
|
||||||
|
{"getx",getX},
|
||||||
|
{"gety",getY},
|
||||||
|
{"getregionwidth",getRegionWidth},
|
||||||
|
{"getregionheight",getRegionHeight},
|
||||||
|
{"getregiondepth",getRegionDepth},
|
||||||
|
{nullptr, nullptr}
|
||||||
|
};
|
||||||
|
|
||||||
|
LUAMOD_API int luaopen_mapapi(lua_State* L) {
|
||||||
|
luaL_newlib(L, regionlib);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
@@ -19,12 +19,12 @@
|
|||||||
* 3. This notice may not be removed or altered from any source
|
* 3. This notice may not be removed or altered from any source
|
||||||
* distribution.
|
* distribution.
|
||||||
*/
|
*/
|
||||||
#ifndef REGIONAPI_HPP_
|
#ifndef MAPAPI_HPP_
|
||||||
#define REGIONAPI_HPP_
|
#define MAPAPI_HPP_
|
||||||
|
|
||||||
#include "lua/lua.hpp"
|
#include "lua/lua.hpp"
|
||||||
|
|
||||||
#define LUA_REGIONLIBNAME "Region"
|
#define LUA_MAPLIBNAME "map"
|
||||||
LUAMOD_API int luaopen_regionapi(lua_State* L);
|
LUAMOD_API int luaopen_mapapi(lua_State* L);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,88 +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 "region_api.hpp"
|
|
||||||
|
|
||||||
#include "region.hpp"
|
|
||||||
|
|
||||||
static int setTile(lua_State* L) {
|
|
||||||
Region* ptr = (Region*)lua_touserdata(L, 1);
|
|
||||||
ptr->SetTile(lua_tointeger(L, 2)-1, lua_tointeger(L, 3)-1, lua_tointeger(L, 4)-1, lua_tointeger(L, 5));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int getTile(lua_State* L) {
|
|
||||||
Region* ptr = (Region*)lua_touserdata(L, 1);
|
|
||||||
int ret = ptr->GetTile(lua_tointeger(L, 2)-1, lua_tointeger(L, 3)-1, lua_tointeger(L, 4)-1);
|
|
||||||
lua_pushnumber(L, ret);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int getWidth(lua_State* L) {
|
|
||||||
lua_pushinteger(L, REGION_WIDTH);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int getHeight(lua_State* L) {
|
|
||||||
lua_pushinteger(L, REGION_HEIGHT);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int getDepth(lua_State* L) {
|
|
||||||
lua_pushinteger(L, REGION_DEPTH);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int getX(lua_State* L) {
|
|
||||||
Region* ptr = (Region*)lua_touserdata(L, 1);
|
|
||||||
lua_pushinteger(L, ptr->GetX());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int getY(lua_State* L) {
|
|
||||||
Region* ptr = (Region*)lua_touserdata(L, 1);
|
|
||||||
lua_pushinteger(L, ptr->GetY());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int dummy(lua_State* L) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const luaL_Reg regionlib[] = {
|
|
||||||
{"SetTile",setTile},
|
|
||||||
{"GetTile",getTile},
|
|
||||||
{"GetWidth",getWidth},
|
|
||||||
{"GetHeight",getHeight},
|
|
||||||
{"GetDepth",getDepth},
|
|
||||||
{"GetX",getX},
|
|
||||||
{"GetY",getY},
|
|
||||||
{"Create", dummy},
|
|
||||||
{"Unload", dummy},
|
|
||||||
{"Load", dummy},
|
|
||||||
{"Save", dummy},
|
|
||||||
{nullptr, nullptr}
|
|
||||||
};
|
|
||||||
|
|
||||||
LUAMOD_API int luaopen_regionapi(lua_State* L) {
|
|
||||||
luaL_newlib(L, regionlib);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2013, 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2013, 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
|
|||||||
+2
-8
@@ -1,17 +1,14 @@
|
|||||||
#config
|
#config
|
||||||
INCLUDES+=. .. ../graphics
|
INCLUDES+=. ../graphics
|
||||||
LIBS+=
|
LIBS+=
|
||||||
CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES))
|
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
|
||||||
CFLAGS+=-DDEBUG $(addprefix -I,$(INCLUDES))
|
|
||||||
|
|
||||||
#source
|
#source
|
||||||
CXXSRC=$(wildcard *.cpp)
|
CXXSRC=$(wildcard *.cpp)
|
||||||
CSRC=$(wildcard *.c)
|
|
||||||
|
|
||||||
#objects
|
#objects
|
||||||
OBJDIR=obj
|
OBJDIR=obj
|
||||||
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
|
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
|
||||||
OBJ+=$(addprefix $(OBJDIR)/,$(CSRC:.c=.o))
|
|
||||||
|
|
||||||
#output
|
#output
|
||||||
OUTDIR=../..
|
OUTDIR=../..
|
||||||
@@ -34,9 +31,6 @@ $(OUTDIR):
|
|||||||
$(OBJDIR)/%.o: %.cpp
|
$(OBJDIR)/%.o: %.cpp
|
||||||
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
$(OBJDIR)/%.o: %.c
|
|
||||||
$(CC) $(CFLAGS) -c -o $@ $<
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) *.o *.a *.exe
|
$(RM) *.o *.a *.exe
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2013, 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2013, 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2013, 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2013, 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2013, 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2013, 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
#config
|
||||||
|
INCLUDES+=.
|
||||||
|
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
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
* 3. This notice may not be removed or altered from any source
|
* 3. This notice may not be removed or altered from any source
|
||||||
* distribution.
|
* distribution.
|
||||||
*/
|
*/
|
||||||
#include "server_utility.hpp"
|
#include "sql_utility.hpp"
|
||||||
|
|
||||||
#include "utility.hpp"
|
#include "utility.hpp"
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2013, 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2013, 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2013, 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
|
||||||
*
|
|
||||||
* 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 EditorApplications, 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 "editor_application.hpp"
|
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <chrono>
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Scene headers
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
//Add the custom scene headers here
|
|
||||||
#include "editor_scene.hpp"
|
|
||||||
#include "testificate_scene.hpp"
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Public access members
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
void EditorApplication::Init(int argc, char** argv) {
|
|
||||||
config.Load("rsc\\config.cfg");
|
|
||||||
if (SDL_Init(SDL_INIT_VIDEO))
|
|
||||||
throw(std::runtime_error("Failed to initialize SDL"));
|
|
||||||
|
|
||||||
BaseScene::SetScreen(config.Int("screen.w"), config.Int("screen.h"));
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditorApplication::Proc() {
|
|
||||||
LoadScene(SceneList::FIRST);
|
|
||||||
|
|
||||||
//prepare the time system
|
|
||||||
typedef std::chrono::steady_clock Clock;
|
|
||||||
|
|
||||||
Clock::duration delta(16 * Clock::duration::period::den / std::milli::den);
|
|
||||||
Clock::time_point simTime = Clock::now();
|
|
||||||
Clock::time_point realTime;
|
|
||||||
|
|
||||||
//The main loop
|
|
||||||
while(activeScene->GetNextScene() != SceneList::QUIT) {
|
|
||||||
//switch scenes when necessary
|
|
||||||
if (activeScene->GetNextScene() != SceneList::CONTINUE) {
|
|
||||||
LoadScene(activeScene->GetNextScene());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//update the current time
|
|
||||||
realTime = Clock::now();
|
|
||||||
|
|
||||||
//simulate game time
|
|
||||||
while (simTime < realTime) {
|
|
||||||
//call each user defined function
|
|
||||||
activeScene->RunFrame(double(delta.count()) / Clock::duration::period::den);
|
|
||||||
simTime += delta;
|
|
||||||
}
|
|
||||||
|
|
||||||
//draw the game to the screen
|
|
||||||
activeScene->RenderFrame();
|
|
||||||
|
|
||||||
//give the computer a break
|
|
||||||
SDL_Delay(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
UnloadScene();
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditorApplication::Quit() {
|
|
||||||
SDL_Quit();
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Private access members
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
void EditorApplication::LoadScene(SceneList sceneIndex) {
|
|
||||||
UnloadScene();
|
|
||||||
|
|
||||||
switch(sceneIndex) {
|
|
||||||
//add scene creation calls here
|
|
||||||
case SceneList::FIRST:
|
|
||||||
case SceneList::EDITORSCENE:
|
|
||||||
activeScene = new EditorScene(&config);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SceneList::TESTIFICATESCENE:
|
|
||||||
activeScene = new TestificateScene(&config);
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw(std::logic_error("Failed to recognize the scene index"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditorApplication::UnloadScene() {
|
|
||||||
delete activeScene;
|
|
||||||
activeScene = nullptr;
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
|
||||||
*
|
|
||||||
* 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 EDITORAPPLICATION_HPP_
|
|
||||||
#define EDITORAPPLICATION_HPP_
|
|
||||||
|
|
||||||
#include "scene_list.hpp"
|
|
||||||
#include "base_scene.hpp"
|
|
||||||
#include "config_utility.hpp"
|
|
||||||
|
|
||||||
class EditorApplication {
|
|
||||||
public:
|
|
||||||
EditorApplication() = default;
|
|
||||||
~EditorApplication() = default;
|
|
||||||
|
|
||||||
void Init(int argc, char** argv);
|
|
||||||
void Proc();
|
|
||||||
void Quit();
|
|
||||||
|
|
||||||
private:
|
|
||||||
//Private access members
|
|
||||||
void LoadScene(SceneList sceneIndex);
|
|
||||||
void UnloadScene();
|
|
||||||
|
|
||||||
//globals
|
|
||||||
ConfigUtility config;
|
|
||||||
|
|
||||||
BaseScene* activeScene = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,230 +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 "editor_scene.hpp"
|
|
||||||
|
|
||||||
#include "utility.hpp"
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include <iostream>
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Public access members
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
EditorScene::EditorScene(ConfigUtility* const arg1):
|
|
||||||
config(*arg1)
|
|
||||||
{
|
|
||||||
//create the debugging "window"
|
|
||||||
debugInfo.CreateSurface(256, 256);
|
|
||||||
|
|
||||||
//setup the utility objects
|
|
||||||
font.LoadSurface(config["dir.fonts"] + "pk_white_8.bmp");
|
|
||||||
|
|
||||||
buttonImage.LoadSurface(config["dir.interface"] + "button_menu.bmp");
|
|
||||||
buttonImage.SetClipH(buttonImage.GetClipH()/3);
|
|
||||||
|
|
||||||
//setup the menu bar
|
|
||||||
menuBar.SetFont(&font);
|
|
||||||
menuBar.SetImage(&buttonImage);
|
|
||||||
|
|
||||||
menuBar.SetEntries({
|
|
||||||
{"File", "New", "Open", "Save", "Close"},
|
|
||||||
{"Edit", "Set Tile", "Set Brush", "Script"},
|
|
||||||
{"Debug", "Debug On", "Debug Off", "Toggle", "Testificate"}
|
|
||||||
});
|
|
||||||
|
|
||||||
//debug
|
|
||||||
tsheet.Load(config["dir.tilesets"] + "terrain.bmp", 12, 15);
|
|
||||||
for (int i = 0; i < REGION_WIDTH; i++) {
|
|
||||||
for (int j = 0; j < REGION_HEIGHT; j++) {
|
|
||||||
pager.SetTile(i, j, 0, 14);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pager.SetTile(5, 10, 1, 48);
|
|
||||||
}
|
|
||||||
|
|
||||||
EditorScene::~EditorScene() {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Frame loop
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
void EditorScene::FrameStart() {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditorScene::Update(double delta) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditorScene::FrameEnd() {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditorScene::Render(SDL_Surface* const screen) {
|
|
||||||
tsheet.DrawRegionTo(screen, pager.GetRegion(0, 0), camera.x, camera.y);
|
|
||||||
/* //debug
|
|
||||||
for (int i = 0; i < pager.GetRegionWidth()*2; i++) {
|
|
||||||
for (int j = 0; j < pager.GetRegionHeight()*2; j++) {
|
|
||||||
for (int k = 0; k < pager.GetRegionDepth(); k++) {
|
|
||||||
//TODO: skip the out-of-bounds regions
|
|
||||||
tsheet.DrawTo(
|
|
||||||
screen,
|
|
||||||
i*tsheet.GetTileW()-camera.x,
|
|
||||||
j*tsheet.GetTileH()-camera.y,
|
|
||||||
pager.GetTile(i,j,k)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
//draw a big bar across the top (hackish)
|
|
||||||
buttonImage.SetClipY(0);
|
|
||||||
for (int i = 0; i < screen->w; i += buttonImage.GetClipW()) {
|
|
||||||
buttonImage.DrawTo(screen, i, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
//draw the menu bar
|
|
||||||
menuBar.DrawTo(screen);
|
|
||||||
|
|
||||||
//draw some debugging info
|
|
||||||
if (debugOpen) {
|
|
||||||
SDL_FillRect(debugInfo.GetSurface(), 0, 0);
|
|
||||||
DrawToDebugInfo(string("camera.x: ") + to_string_custom(camera.x), 0);
|
|
||||||
DrawToDebugInfo(string("camera.y: ") + to_string_custom(camera.y), 1);
|
|
||||||
debugInfo.DrawTo(screen, screen->w - debugInfo.GetClipW(), buttonImage.GetClipH());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditorScene::DrawToDebugInfo(std::string str, int line) {
|
|
||||||
//draw the debug info on the right, with a grey background
|
|
||||||
SDL_Rect clip = {
|
|
||||||
Sint16(debugInfo.GetClipW() - str.size() * font.GetCharW()),
|
|
||||||
Sint16(font.GetCharH() * line),
|
|
||||||
Uint16(str.size() * font.GetCharW()),
|
|
||||||
Uint16(font.GetCharH())
|
|
||||||
};
|
|
||||||
SDL_FillRect(debugInfo.GetSurface(), &clip, SDL_MapRGB(debugInfo.GetSurface()->format, 64, 64, 64));
|
|
||||||
font.DrawStringTo(str, debugInfo.GetSurface(), clip.x, clip.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Event handlers
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
void EditorScene::MouseMotion(SDL_MouseMotionEvent const& motion) {
|
|
||||||
menuBar.MouseMotion(motion);
|
|
||||||
|
|
||||||
if (motion.state & SDL_BUTTON_RMASK) {
|
|
||||||
camera.x -= motion.xrel;
|
|
||||||
camera.y -= motion.yrel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditorScene::MouseButtonDown(SDL_MouseButtonEvent const& button) {
|
|
||||||
menuBar.MouseButtonDown(button);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditorScene::MouseButtonUp(SDL_MouseButtonEvent const& button) {
|
|
||||||
int entry, drop;
|
|
||||||
menuBar.MouseButtonUp(button, &entry, &drop);
|
|
||||||
HandleMenuOption(entry, drop);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditorScene::KeyDown(SDL_KeyboardEvent const& key) {
|
|
||||||
switch(key.keysym.sym) {
|
|
||||||
case SDLK_ESCAPE:
|
|
||||||
QuitEvent();
|
|
||||||
break;
|
|
||||||
case SDLK_SPACE:
|
|
||||||
camera.x = 0;
|
|
||||||
camera.y = 0;
|
|
||||||
break;
|
|
||||||
case SDLK_TAB:
|
|
||||||
debugOpen = !debugOpen;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditorScene::KeyUp(SDL_KeyboardEvent const& key) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Members
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
void EditorScene::HandleMenuOption(int entry, int drop) {
|
|
||||||
//manage input from the menu bar
|
|
||||||
switch(entry) {
|
|
||||||
case 0: //File
|
|
||||||
switch(drop) {
|
|
||||||
case 0:
|
|
||||||
//TODO: NEW
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
//TODO: OPEN
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
//TODO: SAVE
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
//TODO: CLOSE
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 1: //Edit
|
|
||||||
switch(drop) {
|
|
||||||
case 0:
|
|
||||||
//TODO: SET TILE
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
//TODO: SET BRUSH
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
//TODO: SCRIPT
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 2: //Debug
|
|
||||||
switch(drop) {
|
|
||||||
case 0:
|
|
||||||
debugOpen = true;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
debugOpen = false;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
debugOpen = !debugOpen;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
SetNextScene(SceneList::TESTIFICATESCENE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
|
||||||
*
|
|
||||||
* 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 "editor_application.hpp"
|
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
|
||||||
cout << "Beginning editor" << endl;
|
|
||||||
try {
|
|
||||||
EditorApplication app;
|
|
||||||
app.Init(argc, argv);
|
|
||||||
app.Proc();
|
|
||||||
app.Quit();
|
|
||||||
}
|
|
||||||
catch(exception& e) {
|
|
||||||
cerr << "Fatal exception thrown: " << e.what() << endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
cout << "Clean exit" << endl;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
#config
|
|
||||||
INCLUDES+=../common ../common/graphics ../common/map ../common/ui
|
|
||||||
LIBS+=../libcommon.a -lmingw32 -lSDLmain -lSDL -llua
|
|
||||||
CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES))
|
|
||||||
CFLAGS+=-DDEBUG $(addprefix -I,$(INCLUDES))
|
|
||||||
|
|
||||||
#source
|
|
||||||
CXXSRC=$(wildcard *.cpp)
|
|
||||||
CSRC=$(wildcard *.c)
|
|
||||||
|
|
||||||
#objects
|
|
||||||
OBJDIR=obj
|
|
||||||
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
|
|
||||||
OBJ+=$(addprefix $(OBJDIR)/,$(CSRC:.c=.o))
|
|
||||||
|
|
||||||
#output
|
|
||||||
OUTDIR=../out
|
|
||||||
OUT=$(addprefix $(OUTDIR)/,editor)
|
|
||||||
|
|
||||||
#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 $@ $<
|
|
||||||
|
|
||||||
$(OBJDIR)/%.o: %.c
|
|
||||||
$(CC) $(CFLAGS) -c -o $@ $<
|
|
||||||
|
|
||||||
clean:
|
|
||||||
$(RM) *.o *.a *.exe
|
|
||||||
|
|
||||||
rebuild: clean all
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
|
||||||
*
|
|
||||||
* 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 SCENELIST_HPP_
|
|
||||||
#define SCENELIST_HPP_
|
|
||||||
|
|
||||||
enum class SceneList {
|
|
||||||
//these are reserved
|
|
||||||
QUIT,
|
|
||||||
CONTINUE,
|
|
||||||
FIRST,
|
|
||||||
|
|
||||||
//custom indexes
|
|
||||||
TESTIFICATESCENE,
|
|
||||||
EDITORSCENE,
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
|
||||||
*
|
|
||||||
* 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 "testificate_scene.hpp"
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
using std::cout;
|
|
||||||
using std::endl;
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Public access members
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
TestificateScene::TestificateScene(ConfigUtility* const arg1):
|
|
||||||
config(*arg1)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
TestificateScene::~TestificateScene() {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Frame loop
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
void TestificateScene::FrameStart() {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestificateScene::Update(double delta) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestificateScene::FrameEnd() {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestificateScene::Render(SDL_Surface* const screen) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Event handlers
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
void TestificateScene::MouseMotion(SDL_MouseMotionEvent const& motion) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void TestificateScene::MouseButtonDown(SDL_MouseButtonEvent const& button) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestificateScene::MouseButtonUp(SDL_MouseButtonEvent const& button) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestificateScene::KeyDown(SDL_KeyboardEvent const& key) {
|
|
||||||
switch(key.keysym.sym) {
|
|
||||||
case SDLK_ESCAPE:
|
|
||||||
// QuitEvent();
|
|
||||||
SetNextScene(SceneList::EDITORSCENE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestificateScene::KeyUp(SDL_KeyboardEvent const& key) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
#TODO: The build process needs revising
|
|
||||||
#for use on Windows:
|
#for use on Windows:
|
||||||
|
|
||||||
#MKDIR=mkdir
|
#MKDIR=mkdir
|
||||||
@@ -15,7 +14,6 @@ all: $(OUTDIR)
|
|||||||
$(MAKE) -C common
|
$(MAKE) -C common
|
||||||
$(MAKE) -C server
|
$(MAKE) -C server
|
||||||
$(MAKE) -C client
|
$(MAKE) -C client
|
||||||
$(MAKE) -C editor
|
|
||||||
|
|
||||||
$(OUTDIR):
|
$(OUTDIR):
|
||||||
mkdir $(OUTDIR)
|
mkdir $(OUTDIR)
|
||||||
|
|||||||
+3
-2
@@ -23,7 +23,8 @@ map.pager.height = 20
|
|||||||
map.pager.depth = 3
|
map.pager.depth = 3
|
||||||
|
|
||||||
#player options
|
#player options
|
||||||
player.handle = username
|
client.username = Kayne Ruse
|
||||||
player.avatar = elliot2.bmp
|
client.handle = Ratstail91
|
||||||
|
client.avatar = elliot2.bmp
|
||||||
|
|
||||||
#debugging
|
#debugging
|
||||||
|
|||||||
@@ -1,29 +1,36 @@
|
|||||||
print("Lua script check OK (./rsc)")
|
print("Lua script check (./rsc)")
|
||||||
|
|
||||||
function Region.Create(r)
|
-------------------------
|
||||||
-- print("Region:Create(r", Region.GetX(r), Region.GetY(r), ")")
|
--Map API overrides
|
||||||
for i = 1, Region.GetWidth(r) do
|
-------------------------
|
||||||
for j = 1, Region.GetHeight(r) do
|
|
||||||
if math.abs(i) == math.abs(j) then
|
function map.create(region)
|
||||||
Region.SetTile(r, i, j, 1, 50)
|
for i = 1, map.getregionwidth() do
|
||||||
|
for j = 1, map.getregionheight() do
|
||||||
|
if math.abs(map.getx(region) + i -1) == math.abs(map.gety(region) + j -1) then
|
||||||
|
map.settile(region, i, j, 1, 50)
|
||||||
else
|
else
|
||||||
Region.SetTile(r, i, j, 1, 14)
|
map.settile(region, i, j, 1, 14)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- print("done")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function Region.Unload(r)
|
function map.unload(region)
|
||||||
-- print("Region:Unload(r", Region.GetX(r), Region.GetY(r), ")")
|
--
|
||||||
end
|
end
|
||||||
|
|
||||||
--return true if file loaded, otherwise return false
|
function map.load(region, dir)
|
||||||
function Region.Load(r, saveDir)
|
--return true if file loaded, otherwise return false
|
||||||
-- print("Region:Load(r,", saveDir, Region.GetX(r), Region.GetY(r), ")")
|
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
function Region.Save(r, saveDir)
|
function map.save(region, dir)
|
||||||
-- print("Region:Save(r,", saveDir, Region.GetX(r), Region.GetY(r), ")")
|
--
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-------------------------
|
||||||
|
--Enemy API
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
--TODO
|
||||||
@@ -1,55 +1,18 @@
|
|||||||
--TODO: The SQL startup script needs revising
|
CREATE TABLE IF NOT EXISTS Accounts (
|
||||||
|
|
||||||
-------------------------
|
|
||||||
--Server
|
|
||||||
-------------------------
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS UserAccounts (
|
|
||||||
uid INTEGER PRIMARY KEY AUTOINCREMENT,
|
uid INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
username varchar(100) UNIQUE,
|
username varchar(100) UNIQUE,
|
||||||
password varchar(100), --NOTE: DO NOT DO THIS!!
|
--TODO: server-client security
|
||||||
|
-- password varchar(100),
|
||||||
blacklisted BIT DEFAULT 0,
|
blacklisted BIT DEFAULT 0,
|
||||||
whitelisted BIT DEFAULT 1
|
whitelisted BIT DEFAULT 1,
|
||||||
|
administrator BIT DEFAULT 0
|
||||||
);
|
);
|
||||||
|
|
||||||
-------------------------
|
CREATE TABLE IF NOT EXISTS Characters (
|
||||||
--Items
|
|
||||||
-------------------------
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS MundaneItems (
|
|
||||||
--metadata
|
|
||||||
uid INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
itemID INTEGER,
|
|
||||||
stackSize INTEGER DEFAULT 0,
|
|
||||||
owner INTEGER REFERENCES PlayerCharacters(uid)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS Consumables (
|
|
||||||
--metadata
|
|
||||||
uid INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
itemID INTEGER,
|
|
||||||
stackSize INTEGER DEFAULT 0,
|
|
||||||
owner INTEGER REFERENCES PlayerCharacters(uid)
|
|
||||||
--holds all consumable items info (food, potions, etc.)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS Equipment (
|
|
||||||
--metadata
|
|
||||||
uid INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
itemID INTEGER,
|
|
||||||
owner INTEGER REFERENCES PlayerCharacters(uid)
|
|
||||||
--hold all equipment info
|
|
||||||
--stat mods, special effects, etc.
|
|
||||||
);
|
|
||||||
|
|
||||||
-------------------------
|
|
||||||
--Players
|
|
||||||
-------------------------
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS PlayerCharacters (
|
|
||||||
uid INTEGER PRIMARY KEY AUTOINCREMENT,
|
uid INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
|
||||||
--metadata
|
--metadata
|
||||||
|
owner INTEGER REFERENCES Accounts(uid),
|
||||||
handle varchar(100) UNIQUE,
|
handle varchar(100) UNIQUE,
|
||||||
avatar varchar(100),
|
avatar varchar(100),
|
||||||
birth timestamp NOT NULL DEFAULT (datetime()),
|
birth timestamp NOT NULL DEFAULT (datetime()),
|
||||||
@@ -70,13 +33,31 @@ CREATE TABLE IF NOT EXISTS PlayerCharacters (
|
|||||||
defence INTEGER DEFAULT 0,
|
defence INTEGER DEFAULT 0,
|
||||||
intelligence INTEGER DEFAULT 0,
|
intelligence INTEGER DEFAULT 0,
|
||||||
resistance INTEGER DEFAULT 0,
|
resistance INTEGER DEFAULT 0,
|
||||||
|
speed INTEGER DEFAULT 0,
|
||||||
accuracy REAL DEFAULT 0.0,
|
accuracy REAL DEFAULT 0.0,
|
||||||
evasion REAL DEFAULT 0.0,
|
evasion REAL DEFAULT 0.0,
|
||||||
luck REAL DEFAULT 0.0,
|
luck REAL DEFAULT 0.0,
|
||||||
|
|
||||||
--equipment
|
--equipment
|
||||||
weapon INTEGER REFERENCES Equipment(uid),
|
weapon INTEGER REFERENCES WornEquipment(uid),
|
||||||
helmet INTEGER REFERENCES Equipment(uid),
|
helmet INTEGER REFERENCES WornEquipment(uid),
|
||||||
armour INTEGER REFERENCES Equipment(uid)
|
armour INTEGER REFERENCES WornEquipment(uid)
|
||||||
--etc.
|
--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.
|
||||||
|
);
|
||||||
@@ -0,0 +1,191 @@
|
|||||||
|
/* 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 "sqlite3/sqlite3.h"
|
||||||
|
|
||||||
|
#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 WHERE uid = ?1;";
|
||||||
|
static const char* DELETE_USER_ACCOUNT = "DELETE FROM Accounts WHERE uid = ?;";
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
//Define the methods
|
||||||
|
//-------------------------
|
||||||
|
|
||||||
|
int ServerApplication::CreateUserAccount(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 LoadUserAccount(username, clientIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ServerApplication::LoadUserAccount(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.clientIndex = clientIndex;
|
||||||
|
|
||||||
|
//finish the routine
|
||||||
|
sqlite3_finalize(statement);
|
||||||
|
return uid;
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_finalize(statement);
|
||||||
|
|
||||||
|
if (ret == SQLITE_DONE) {
|
||||||
|
//create the non-existant account instead
|
||||||
|
return CreateUserAccount(username, clientIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw(std::runtime_error(std::string() + "Unknown SQL error in LoadUserAccount: " + sqlite3_errmsg(database) ));
|
||||||
|
}
|
||||||
|
|
||||||
|
int ServerApplication::SaveUserAccount(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;
|
||||||
|
|
||||||
|
//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 ServerApplication::UnloadUserAccount(int uid) {
|
||||||
|
//save this user account, and then unload it
|
||||||
|
//NOTE: the associated characters are unloaded externally
|
||||||
|
SaveUserAccount(uid);
|
||||||
|
accountMap.erase(uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerApplication::DeleteUserAccount(int uid) {
|
||||||
|
//delete a user account from the database, and remove it from memory
|
||||||
|
//NOTE: the associated characters are unloaded 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);
|
||||||
|
}
|
||||||
@@ -0,0 +1,231 @@
|
|||||||
|
/* 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 "sqlite3/sqlite3.h"
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
//Define the queries
|
||||||
|
//-------------------------
|
||||||
|
|
||||||
|
//TODO: save and load the statistics
|
||||||
|
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 mapIndex = ?2, positionX = ?3, positionY = ?4 WHERE uid = ?1;";
|
||||||
|
static const char* DELETE_CHARACTER = "DELETE FROM Characters WHERE uid = ?;";
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
//Define the methods
|
||||||
|
//-------------------------
|
||||||
|
|
||||||
|
//TODO: default stats as a parameter
|
||||||
|
int ServerApplication::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 ServerApplication::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 position
|
||||||
|
newChar.mapIndex = sqlite3_column_int(statement, 5);
|
||||||
|
newChar.position.x = (double)sqlite3_column_int(statement, 6);
|
||||||
|
newChar.position.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
|
||||||
|
|
||||||
|
//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 ServerApplication::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.mapIndex) != SQLITE_OK;
|
||||||
|
ret |= sqlite3_bind_int(statement, 3, (int)character.position.x) != SQLITE_OK;
|
||||||
|
ret |= sqlite3_bind_int(statement, 4, (int)character.position.y) != SQLITE_OK;
|
||||||
|
//TODO: stats, etc.
|
||||||
|
|
||||||
|
//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 ServerApplication::UnloadCharacter(int uid) {
|
||||||
|
//save this character, then unload it
|
||||||
|
SaveCharacter(uid);
|
||||||
|
characterMap.erase(uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerApplication::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);
|
||||||
|
}
|
||||||
@@ -19,6 +19,16 @@
|
|||||||
* 3. This notice may not be removed or altered from any source
|
* 3. This notice may not be removed or altered from any source
|
||||||
* distribution.
|
* distribution.
|
||||||
*/
|
*/
|
||||||
#include "player_entry.hpp"
|
#include "enemy_factory_generic.hpp"
|
||||||
|
|
||||||
unsigned int PlayerEntry::uidCounter;
|
EnemyFactoryGeneric::EnemyFactoryGeneric() : EnemyFactoryInterface() {
|
||||||
|
//EMPTY
|
||||||
|
}
|
||||||
|
|
||||||
|
EnemyFactoryGeneric::~EnemyFactoryGeneric() noexcept {
|
||||||
|
//EMPTY
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnemyFactoryGeneric::Generate(std::list<EnemyData>* container) {
|
||||||
|
//TODO: fill this out
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
/* 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
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
@@ -19,35 +19,38 @@
|
|||||||
* 3. This notice may not be removed or altered from any source
|
* 3. This notice may not be removed or altered from any source
|
||||||
* distribution.
|
* distribution.
|
||||||
*/
|
*/
|
||||||
#ifndef TESTIFICATESCENE_HPP_
|
#ifndef ENEMYFACTORYINTERFACE_HPP_
|
||||||
#define TESTIFICATESCENE_HPP_
|
#define ENEMYFACTORYINTERFACE_HPP_
|
||||||
|
|
||||||
#include "base_scene.hpp"
|
#include "enemy_data.hpp"
|
||||||
|
|
||||||
#include "config_utility.hpp"
|
#include <list>
|
||||||
|
|
||||||
class TestificateScene : public BaseScene {
|
//TODO: move this elsewhere
|
||||||
|
enum RoomType {
|
||||||
|
OVERWORLD,
|
||||||
|
RUINS,
|
||||||
|
TOWERS,
|
||||||
|
FORESTS,
|
||||||
|
CAVES,
|
||||||
|
};
|
||||||
|
|
||||||
|
//NOTE: Based on biome, world difficulty, etc.
|
||||||
|
class EnemyFactoryInterface {
|
||||||
public:
|
public:
|
||||||
//Public access members
|
EnemyFactoryInterface() = default;
|
||||||
TestificateScene(ConfigUtility* const);
|
virtual ~EnemyFactoryInterface() = default;
|
||||||
~TestificateScene();
|
|
||||||
|
|
||||||
|
virtual void Generate(std::list<EnemyData>* container) = 0;
|
||||||
|
|
||||||
|
//control the difficulty of the room
|
||||||
|
RoomType SetType(RoomType t) { return type = t; }
|
||||||
|
int SetDifficulty(int d) { return difficulty = d; }
|
||||||
|
RoomType GetType() { return type; }
|
||||||
|
int GetDifficulty() { return difficulty; }
|
||||||
protected:
|
protected:
|
||||||
//Frame loop
|
RoomType type;
|
||||||
void FrameStart();
|
int difficulty;
|
||||||
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&);
|
|
||||||
|
|
||||||
//globals
|
|
||||||
ConfigUtility& config;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright: (c) Kayne Ruse 2013
|
/* Copyright: (c) Kayne Ruse 2013, 2014
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
|
|||||||
+2
-8
@@ -1,17 +1,14 @@
|
|||||||
#config
|
#config
|
||||||
INCLUDES+=. ../common ../common/map ../common/script ../common/network
|
INCLUDES+=. ../common/gameplay ../common/map ../common/network ../common/script ../common/utilities
|
||||||
LIBS+=../libcommon.a -lSDL_net -lwsock32 -liphlpapi -lmingw32 -lSDLmain -lSDL -llua -lsqlite3
|
LIBS+=../libcommon.a -lSDL_net -lwsock32 -liphlpapi -lmingw32 -lSDLmain -lSDL -llua -lsqlite3
|
||||||
CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES))
|
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
|
||||||
CFLAGS+=-DDEBUG $(addprefix -I,$(INCLUDES))
|
|
||||||
|
|
||||||
#source
|
#source
|
||||||
CXXSRC=$(wildcard *.cpp)
|
CXXSRC=$(wildcard *.cpp)
|
||||||
CSRC=$(wildcard *.c)
|
|
||||||
|
|
||||||
#objects
|
#objects
|
||||||
OBJDIR=obj
|
OBJDIR=obj
|
||||||
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
|
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
|
||||||
OBJ+=$(addprefix $(OBJDIR)/,$(CSRC:.c=.o))
|
|
||||||
|
|
||||||
#output
|
#output
|
||||||
OUTDIR=../out
|
OUTDIR=../out
|
||||||
@@ -34,9 +31,6 @@ $(OUTDIR):
|
|||||||
$(OBJDIR)/%.o: %.cpp
|
$(OBJDIR)/%.o: %.cpp
|
||||||
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
$(OBJDIR)/%.o: %.c
|
|
||||||
$(CC) $(CFLAGS) -c -o $@ $<
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) *.o *.a *.exe
|
$(RM) *.o *.a *.exe
|
||||||
|
|
||||||
|
|||||||
@@ -1,373 +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 "utility.hpp"
|
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Define the public members
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
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
|
|
||||||
ClientEntry::uidCounter = 0;
|
|
||||||
PlayerEntry::uidCounter = 0;
|
|
||||||
config.Load("rsc\\config.cfg");
|
|
||||||
|
|
||||||
//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"), PACKET_BUFFER_SIZE);
|
|
||||||
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;
|
|
||||||
|
|
||||||
//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 << "Initialized SQL's setup script" << std::endl;
|
|
||||||
|
|
||||||
//lua
|
|
||||||
luaState = luaL_newstate();
|
|
||||||
if (!luaState) {
|
|
||||||
throw(std::runtime_error("Failed to initialize lua"));
|
|
||||||
}
|
|
||||||
luaL_openlibs(luaState);
|
|
||||||
std::cout << "Initialized lua" << std::endl;
|
|
||||||
|
|
||||||
//run the 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 << "Initialized lua's setup script" << std::endl;
|
|
||||||
|
|
||||||
//setup the map object
|
|
||||||
regionPager.GetAllocator()->SetLuaState(luaState);
|
|
||||||
regionPager.GetFormat()->SetLuaState(luaState);
|
|
||||||
//TODO: config parameter
|
|
||||||
regionPager.GetFormat()->SetSaveDir("save/mapname/");
|
|
||||||
|
|
||||||
std::cout << "Initialized the map system" << std::endl;
|
|
||||||
std::cout << "\tsizeof(SerialPacket): " << sizeof(SerialPacket) << std::endl;
|
|
||||||
std::cout << "\tPACKET_BUFFER_SIZE: " << PACKET_BUFFER_SIZE << std::endl;
|
|
||||||
|
|
||||||
//finalize the startup
|
|
||||||
std::cout << "Startup completed successfully" << std::endl;
|
|
||||||
|
|
||||||
//debugging
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerApplication::Proc() {
|
|
||||||
SerialPacket packet;
|
|
||||||
while(running) {
|
|
||||||
//suck in the waiting packets & process them
|
|
||||||
while(network.Receive()) {
|
|
||||||
//get the packet
|
|
||||||
deserialize(&packet, network.GetInData());
|
|
||||||
//cache the source address
|
|
||||||
packet.meta.srcAddress = network.GetInPacket()->address;
|
|
||||||
//we need to go deeper
|
|
||||||
HandlePacket(packet);
|
|
||||||
}
|
|
||||||
//give the computer a break
|
|
||||||
//TODO: remove this delay?
|
|
||||||
SDL_Delay(10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerApplication::Quit() {
|
|
||||||
std::cout << "Shutting down" << std::endl;
|
|
||||||
//empty the members
|
|
||||||
regionPager.UnloadAll();
|
|
||||||
|
|
||||||
//APIs
|
|
||||||
lua_close(luaState);
|
|
||||||
sqlite3_close_v2(database);
|
|
||||||
network.Close();
|
|
||||||
SDLNet_Quit();
|
|
||||||
SDL_Quit();
|
|
||||||
std::cout << "Shutdown finished" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Define the uber switch
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
void ServerApplication::HandlePacket(SerialPacket packet) {
|
|
||||||
switch(packet.meta.type) {
|
|
||||||
case SerialPacket::Type::BROADCAST_REQUEST:
|
|
||||||
HandleBroadcastRequest(packet);
|
|
||||||
break;
|
|
||||||
case SerialPacket::Type::JOIN_REQUEST:
|
|
||||||
HandleJoinRequest(packet);
|
|
||||||
break;
|
|
||||||
case SerialPacket::Type::DISCONNECT:
|
|
||||||
HandleDisconnect(packet);
|
|
||||||
break;
|
|
||||||
case SerialPacket::Type::SYNCHRONIZE:
|
|
||||||
HandleSynchronize(packet);
|
|
||||||
break;
|
|
||||||
case SerialPacket::Type::SHUTDOWN:
|
|
||||||
HandleShutdown(packet);
|
|
||||||
break;
|
|
||||||
case SerialPacket::Type::PLAYER_NEW:
|
|
||||||
HandlePlayerNew(packet);
|
|
||||||
break;
|
|
||||||
case SerialPacket::Type::PLAYER_DELETE:
|
|
||||||
HandlePlayerDelete(packet);
|
|
||||||
break;
|
|
||||||
case SerialPacket::Type::PLAYER_UPDATE:
|
|
||||||
HandlePlayerUpdate(packet);
|
|
||||||
break;
|
|
||||||
case SerialPacket::Type::REGION_REQUEST:
|
|
||||||
HandleRegionRequest(packet);
|
|
||||||
break;
|
|
||||||
//handle errors
|
|
||||||
default:
|
|
||||||
throw(std::runtime_error("Unknown SerialPacket::Type encountered"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------
|
|
||||||
//Handle various network input
|
|
||||||
//-------------------------
|
|
||||||
|
|
||||||
void ServerApplication::HandleBroadcastRequest(SerialPacket packet) {
|
|
||||||
//send back the server's metadata
|
|
||||||
packet.meta.type = SerialPacket::Type::BROADCAST_RESPONSE;
|
|
||||||
|
|
||||||
//pack the data
|
|
||||||
//TODO: version info
|
|
||||||
snprintf(packet.serverInfo.name, PACKET_STRING_SIZE, "%s", config["server.name"].c_str());
|
|
||||||
packet.serverInfo.playerCount = playerMap.size();
|
|
||||||
packet.serverInfo.regionWidth = REGION_WIDTH;
|
|
||||||
packet.serverInfo.regionHeight = REGION_HEIGHT;
|
|
||||||
packet.serverInfo.regionDepth = REGION_DEPTH;
|
|
||||||
|
|
||||||
//send the data
|
|
||||||
char buffer[PACKET_BUFFER_SIZE];
|
|
||||||
serialize(&packet, buffer);
|
|
||||||
network.Send(&packet.meta.srcAddress, buffer, PACKET_BUFFER_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerApplication::HandleJoinRequest(SerialPacket packet) {
|
|
||||||
//register the new client
|
|
||||||
ClientEntry newClient;
|
|
||||||
newClient.address = packet.meta.srcAddress;
|
|
||||||
clientMap[ClientEntry::uidCounter] = newClient;
|
|
||||||
|
|
||||||
//send the client their index
|
|
||||||
char buffer[PACKET_BUFFER_SIZE];
|
|
||||||
packet.meta.type = SerialPacket::Type::JOIN_RESPONSE;
|
|
||||||
packet.clientInfo.index = ClientEntry::uidCounter;
|
|
||||||
serialize(&packet, buffer);
|
|
||||||
|
|
||||||
//bounce this packet
|
|
||||||
network.Send(&newClient.address, buffer, PACKET_BUFFER_SIZE);
|
|
||||||
|
|
||||||
//finished this routine
|
|
||||||
ClientEntry::uidCounter++;
|
|
||||||
std::cout << "Connect, total: " << clientMap.size() << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerApplication::HandleDisconnect(SerialPacket packet) {
|
|
||||||
//TODO: authenticate who is disconnecting/kicking
|
|
||||||
|
|
||||||
//disconnect the specified client
|
|
||||||
char buffer[PACKET_BUFFER_SIZE];
|
|
||||||
serialize(&packet, buffer);
|
|
||||||
network.Send(&clientMap[packet.clientInfo.index].address, buffer, PACKET_BUFFER_SIZE);
|
|
||||||
clientMap.erase(packet.clientInfo.index);
|
|
||||||
|
|
||||||
//prep the delete packet
|
|
||||||
SerialPacket delPacket;
|
|
||||||
delPacket.meta.type = SerialPacket::Type::PLAYER_DELETE;
|
|
||||||
|
|
||||||
//TODO: can this use DeletePlayer() instead?
|
|
||||||
//delete server and client side players
|
|
||||||
erase_if(playerMap, [&](std::pair<unsigned int, PlayerEntry> it) -> bool {
|
|
||||||
//find the internal players to delete
|
|
||||||
if (it.second.clientIndex == packet.clientInfo.index) {
|
|
||||||
//send the delete player command to all clients
|
|
||||||
delPacket.playerInfo.playerIndex = it.first;
|
|
||||||
PumpPacket(delPacket);
|
|
||||||
|
|
||||||
//delete this player object
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//don't delete this player object
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
//finished this routine
|
|
||||||
std::cout << "Disconnect, total: " << clientMap.size() << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerApplication::HandleSynchronize(SerialPacket packet) {
|
|
||||||
//TODO: compensate for large distances
|
|
||||||
|
|
||||||
//send all the server's data to this client
|
|
||||||
SerialPacket newPacket;
|
|
||||||
char buffer[PACKET_BUFFER_SIZE];
|
|
||||||
|
|
||||||
//TODO: syncronize the map?
|
|
||||||
|
|
||||||
//players
|
|
||||||
newPacket.meta.type = SerialPacket::Type::PLAYER_UPDATE;
|
|
||||||
for (auto& it : playerMap) {
|
|
||||||
//TODO: update this for the expanded PlayerEntry structure
|
|
||||||
newPacket.playerInfo.playerIndex = it.first;
|
|
||||||
snprintf(newPacket.playerInfo.handle, PACKET_STRING_SIZE, "%s", it.second.handle.c_str());
|
|
||||||
snprintf(newPacket.playerInfo.avatar, PACKET_STRING_SIZE, "%s", it.second.avatar.c_str());
|
|
||||||
newPacket.playerInfo.position = it.second.position;
|
|
||||||
newPacket.playerInfo.motion = it.second.motion;
|
|
||||||
serialize(&newPacket, buffer);
|
|
||||||
network.Send(&clientMap[packet.clientInfo.index].address, buffer, PACKET_BUFFER_SIZE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerApplication::HandleShutdown(SerialPacket packet) {
|
|
||||||
//end the server
|
|
||||||
running = false;
|
|
||||||
|
|
||||||
//disconnect all clients
|
|
||||||
packet.meta.type = SerialPacket::Type::DISCONNECT;
|
|
||||||
PumpPacket(packet);
|
|
||||||
|
|
||||||
//finished this routine
|
|
||||||
std::cout << "Shutdown signal accepted" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerApplication::HandlePlayerNew(SerialPacket packet) {
|
|
||||||
//register the new PlayerEntry
|
|
||||||
//NOTE: assigning each field one-by-one so adding or moving a field doesn't break this code
|
|
||||||
PlayerEntry newPlayer;
|
|
||||||
|
|
||||||
//metadata
|
|
||||||
newPlayer.clientIndex = packet.playerInfo.clientIndex;
|
|
||||||
newPlayer.handle = packet.playerInfo.handle;
|
|
||||||
newPlayer.avatar = packet.playerInfo.avatar;
|
|
||||||
|
|
||||||
//position
|
|
||||||
newPlayer.mapIndex = 0;
|
|
||||||
newPlayer.position = {0,0};
|
|
||||||
newPlayer.motion = {0,0};
|
|
||||||
newPlayer.bbox = {0, 0, 0, 0};
|
|
||||||
|
|
||||||
//stats
|
|
||||||
//TODO
|
|
||||||
|
|
||||||
//push this player
|
|
||||||
playerMap[PlayerEntry::uidCounter] = newPlayer;
|
|
||||||
|
|
||||||
//send the client their info
|
|
||||||
packet.playerInfo.playerIndex = PlayerEntry::uidCounter;
|
|
||||||
packet.playerInfo.position = newPlayer.position;
|
|
||||||
packet.playerInfo.motion = newPlayer.motion;
|
|
||||||
|
|
||||||
//actually send to everyone
|
|
||||||
PumpPacket(packet);
|
|
||||||
|
|
||||||
//finish this routine
|
|
||||||
PlayerEntry::uidCounter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: differentiate between delete and unload
|
|
||||||
void ServerApplication::HandlePlayerDelete(SerialPacket packet) {
|
|
||||||
//TODO: authenticate who is deleting this player
|
|
||||||
if (playerMap.find(packet.playerInfo.playerIndex) == playerMap.end()) {
|
|
||||||
throw(std::runtime_error("Cannot delete a non-existant player"));
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: remove the deleted player from the database?
|
|
||||||
|
|
||||||
//prep the delete packet
|
|
||||||
SerialPacket delPacket;
|
|
||||||
delPacket.meta.type = SerialPacket::Type::PLAYER_DELETE;
|
|
||||||
|
|
||||||
//delete the specified playerEntry
|
|
||||||
erase_if(playerMap, [&](std::pair<unsigned int, PlayerEntry> it) -> bool {
|
|
||||||
//find the specified PlayerEntry
|
|
||||||
if (it.first == packet.playerInfo.playerIndex) {
|
|
||||||
//send to all
|
|
||||||
delPacket.playerInfo.playerIndex = it.first;
|
|
||||||
PumpPacket(delPacket);
|
|
||||||
|
|
||||||
//delete this player
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
//skip this player
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerApplication::HandlePlayerUpdate(SerialPacket packet) {
|
|
||||||
if (playerMap.find(packet.playerInfo.playerIndex) == playerMap.end()) {
|
|
||||||
throw(std::runtime_error("Cannot update a non-existant player"));
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: the server needs it's own movement system too
|
|
||||||
playerMap[packet.playerInfo.playerIndex].position = packet.playerInfo.position;
|
|
||||||
playerMap[packet.playerInfo.playerIndex].motion = packet.playerInfo.motion;
|
|
||||||
|
|
||||||
PumpPacket(packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerApplication::HandleRegionRequest(SerialPacket packet) {
|
|
||||||
char buffer[PACKET_BUFFER_SIZE];
|
|
||||||
packet.meta.type = SerialPacket::Type::REGION_CONTENT;
|
|
||||||
packet.regionInfo.region = regionPager.GetRegion(packet.regionInfo.x, packet.regionInfo.y);
|
|
||||||
serialize(&packet, buffer);
|
|
||||||
network.Send(&packet.meta.srcAddress, buffer, PACKET_BUFFER_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerApplication::PumpPacket(SerialPacket packet) {
|
|
||||||
//I don't really like this, but it'll do for now
|
|
||||||
char buffer[PACKET_BUFFER_SIZE];
|
|
||||||
serialize(&packet, buffer);
|
|
||||||
for (auto& it : clientMap) {
|
|
||||||
network.Send(&it.second.address, buffer, PACKET_BUFFER_SIZE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -23,9 +23,11 @@
|
|||||||
#define SERVERAPPLICATION_HPP_
|
#define SERVERAPPLICATION_HPP_
|
||||||
|
|
||||||
//server specific stuff
|
//server specific stuff
|
||||||
#include "server_utility.hpp"
|
#include "client_data.hpp"
|
||||||
#include "client_entry.hpp"
|
#include "account_data.hpp"
|
||||||
#include "player_entry.hpp"
|
#include "character_data.hpp"
|
||||||
|
#include "combat_data.hpp"
|
||||||
|
#include "enemy_factory_generic.hpp"
|
||||||
|
|
||||||
//maps
|
//maps
|
||||||
#include "map_allocator.hpp"
|
#include "map_allocator.hpp"
|
||||||
@@ -33,9 +35,7 @@
|
|||||||
#include "region_pager.hpp"
|
#include "region_pager.hpp"
|
||||||
|
|
||||||
//networking
|
//networking
|
||||||
#include "serial_packet.hpp"
|
|
||||||
#include "udp_network_utility.hpp"
|
#include "udp_network_utility.hpp"
|
||||||
#include "serial.hpp"
|
|
||||||
|
|
||||||
//common
|
//common
|
||||||
#include "config_utility.hpp"
|
#include "config_utility.hpp"
|
||||||
@@ -48,8 +48,10 @@
|
|||||||
|
|
||||||
//STL
|
//STL
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
//The main application class
|
//The main application class
|
||||||
|
//TODO: modulate this god class
|
||||||
class ServerApplication {
|
class ServerApplication {
|
||||||
public:
|
public:
|
||||||
//standard functions
|
//standard functions
|
||||||
@@ -63,19 +65,34 @@ public:
|
|||||||
private:
|
private:
|
||||||
void HandlePacket(SerialPacket);
|
void HandlePacket(SerialPacket);
|
||||||
|
|
||||||
//high cohesion utility functions
|
//handle incoming traffic
|
||||||
void HandleBroadcastRequest(SerialPacket);
|
void HandleBroadcastRequest(SerialPacket);
|
||||||
void HandleJoinRequest(SerialPacket);
|
void HandleJoinRequest(SerialPacket);
|
||||||
void HandleDisconnect(SerialPacket);
|
|
||||||
void HandleSynchronize(SerialPacket);
|
void HandleSynchronize(SerialPacket);
|
||||||
|
void HandleDisconnect(SerialPacket);
|
||||||
void HandleShutdown(SerialPacket);
|
void HandleShutdown(SerialPacket);
|
||||||
void HandlePlayerNew(SerialPacket);
|
void HandleCharacterUpdate(SerialPacket);
|
||||||
void HandlePlayerDelete(SerialPacket);
|
|
||||||
void HandlePlayerUpdate(SerialPacket);
|
|
||||||
void HandleRegionRequest(SerialPacket);
|
void HandleRegionRequest(SerialPacket);
|
||||||
|
|
||||||
//TODO: a function that only sends to players in a certain proximity
|
//TODO: a function that only sends to characters in a certain proximity
|
||||||
void PumpPacket(SerialPacket);
|
void PumpPacket(SerialPacket);
|
||||||
|
void PumpCharacterUnload(int uid);
|
||||||
|
|
||||||
|
//Account management
|
||||||
|
int CreateUserAccount(std::string username, int clientIndex);
|
||||||
|
int LoadUserAccount(std::string username, int clientIndex);
|
||||||
|
int SaveUserAccount(int uid);
|
||||||
|
void UnloadUserAccount(int uid);
|
||||||
|
void DeleteUserAccount(int uid);
|
||||||
|
|
||||||
|
//character management
|
||||||
|
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);
|
||||||
|
|
||||||
|
//TODO: combat management
|
||||||
|
|
||||||
//APIs
|
//APIs
|
||||||
UDPNetworkUtility network;
|
UDPNetworkUtility network;
|
||||||
@@ -83,16 +100,24 @@ private:
|
|||||||
lua_State* luaState = nullptr;
|
lua_State* luaState = nullptr;
|
||||||
|
|
||||||
//server tables
|
//server tables
|
||||||
std::map<unsigned int, ClientEntry> clientMap;
|
std::map<int, ClientData> clientMap;
|
||||||
std::map<unsigned int, PlayerEntry> playerMap;
|
std::map<int, AccountData> accountMap;
|
||||||
|
std::map<int, CharacterData> characterMap;
|
||||||
|
std::map<int, CombatData> combatMap;
|
||||||
|
std::map<int, EnemyData> enemyMap;
|
||||||
|
|
||||||
//maps
|
//maps
|
||||||
//TODO: I need to handle multiple map objects
|
//TODO: I need to handle multiple map objects
|
||||||
|
//TODO: Unload regions that are distant from any characters
|
||||||
RegionPager<LuaAllocator, LuaFormat> regionPager;
|
RegionPager<LuaAllocator, LuaFormat> regionPager;
|
||||||
|
EnemyFactoryGeneric enemyFactory;
|
||||||
|
|
||||||
//misc
|
//misc
|
||||||
bool running = true;
|
bool running = true;
|
||||||
ConfigUtility config;
|
ConfigUtility config;
|
||||||
|
int clientUID = 0;
|
||||||
|
int combatUID = 0;
|
||||||
|
int enemyUID = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,186 @@
|
|||||||
|
/* 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 <stdexcept>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
//Handle various network input
|
||||||
|
//-------------------------
|
||||||
|
|
||||||
|
void ServerApplication::HandleBroadcastRequest(SerialPacket packet) {
|
||||||
|
//pack the server's data
|
||||||
|
packet.meta.type = SerialPacket::Type::BROADCAST_RESPONSE;
|
||||||
|
packet.serverInfo.networkVersion = NETWORK_VERSION;
|
||||||
|
snprintf(packet.serverInfo.name, PACKET_STRING_SIZE, "%s", config["server.name"].c_str());
|
||||||
|
packet.serverInfo.playerCount = characterMap.size();
|
||||||
|
|
||||||
|
//bounce this packet
|
||||||
|
network.SendTo(&packet.meta.srcAddress, &packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerApplication::HandleJoinRequest(SerialPacket packet) {
|
||||||
|
//create the new client
|
||||||
|
ClientData newClient;
|
||||||
|
newClient.address = packet.meta.srcAddress;
|
||||||
|
|
||||||
|
//load the user account
|
||||||
|
int accountIndex = LoadUserAccount(packet.clientInfo.username, clientUID);
|
||||||
|
if (accountIndex < 0) {
|
||||||
|
//TODO: send rejection packet
|
||||||
|
std::cerr << "Error: Account already loaded: " << accountIndex << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//load the new character
|
||||||
|
int characterIndex = LoadCharacter(accountIndex, packet.clientInfo.handle, packet.clientInfo.avatar);
|
||||||
|
if (characterIndex < 0) {
|
||||||
|
//TODO: send rejection packet
|
||||||
|
std::cerr << "Error: Character already loaded: " << characterIndex << std::endl;
|
||||||
|
UnloadUserAccount(accountIndex);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//send the client their info
|
||||||
|
packet.meta.type = SerialPacket::Type::JOIN_RESPONSE;
|
||||||
|
packet.clientInfo.clientIndex = clientUID;
|
||||||
|
packet.clientInfo.accountIndex = accountIndex;
|
||||||
|
packet.clientInfo.characterIndex = characterIndex;
|
||||||
|
|
||||||
|
//bounce this packet
|
||||||
|
network.SendTo(&newClient.address, &packet);
|
||||||
|
|
||||||
|
//send the new character to all clients
|
||||||
|
packet.meta.type = SerialPacket::Type::CHARACTER_NEW;
|
||||||
|
packet.characterInfo.characterIndex = characterIndex;
|
||||||
|
strncpy(packet.characterInfo.handle, characterMap[characterIndex].handle.c_str(), PACKET_STRING_SIZE);
|
||||||
|
strncpy(packet.characterInfo.avatar, characterMap[characterIndex].avatar.c_str(), PACKET_STRING_SIZE);
|
||||||
|
packet.characterInfo.position = characterMap[characterIndex].position;
|
||||||
|
packet.characterInfo.motion = characterMap[characterIndex].motion;
|
||||||
|
PumpPacket(packet);
|
||||||
|
|
||||||
|
//TODO: don't send anything to a certain client until they send the OK (the sync packet? or ignore client side?)
|
||||||
|
//finished this routine
|
||||||
|
clientMap[clientUID++] = newClient;
|
||||||
|
std::cout << "Connect, total: " << clientMap.size() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerApplication::HandleSynchronize(SerialPacket packet) {
|
||||||
|
//TODO: compensate for large distances
|
||||||
|
|
||||||
|
//send all the server's data to this client
|
||||||
|
SerialPacket newPacket;
|
||||||
|
|
||||||
|
//characters
|
||||||
|
newPacket.meta.type = SerialPacket::Type::CHARACTER_UPDATE;
|
||||||
|
for (auto& it : characterMap) {
|
||||||
|
//TODO: update this for the expanded CharacterData structure
|
||||||
|
newPacket.characterInfo.characterIndex = it.first;
|
||||||
|
snprintf(newPacket.characterInfo.handle, PACKET_STRING_SIZE, "%s", it.second.handle.c_str());
|
||||||
|
snprintf(newPacket.characterInfo.avatar, PACKET_STRING_SIZE, "%s", it.second.avatar.c_str());
|
||||||
|
newPacket.characterInfo.mapIndex = it.second.mapIndex;
|
||||||
|
newPacket.characterInfo.position = it.second.position;
|
||||||
|
newPacket.characterInfo.motion = it.second.motion;
|
||||||
|
newPacket.characterInfo.stats = it.second.stats;
|
||||||
|
|
||||||
|
network.SendTo(&clientMap[packet.clientInfo.clientIndex].address, &newPacket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerApplication::HandleDisconnect(SerialPacket packet) {
|
||||||
|
//TODO: authenticate who is disconnecting/kicking
|
||||||
|
|
||||||
|
//forward to the specified client
|
||||||
|
network.SendTo(&clientMap[accountMap[packet.clientInfo.accountIndex].clientIndex].address, &packet);
|
||||||
|
|
||||||
|
//unload client and server-side characters
|
||||||
|
for (std::map<int, CharacterData>::iterator it = characterMap.begin(); it != characterMap.end(); /* EMPTY */ ) {
|
||||||
|
if (it->second.owner == packet.clientInfo.accountIndex) {
|
||||||
|
PumpCharacterUnload(it->first);
|
||||||
|
SaveCharacter(it->first);
|
||||||
|
it = characterMap.erase(it); //efficient
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//erase the in-memory stuff
|
||||||
|
clientMap.erase(accountMap[packet.clientInfo.accountIndex].clientIndex);
|
||||||
|
UnloadUserAccount(packet.clientInfo.accountIndex);
|
||||||
|
|
||||||
|
//finished this routine
|
||||||
|
std::cout << "Disconnect, total: " << clientMap.size() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerApplication::HandleShutdown(SerialPacket packet) {
|
||||||
|
//TODO: authenticate who is shutting the server down
|
||||||
|
|
||||||
|
//end the server
|
||||||
|
running = false;
|
||||||
|
|
||||||
|
//disconnect all clients
|
||||||
|
packet.meta.type = SerialPacket::Type::DISCONNECT;
|
||||||
|
PumpPacket(packet);
|
||||||
|
|
||||||
|
//finished this routine
|
||||||
|
std::cout << "Shutdown signal accepted" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerApplication::HandleCharacterUpdate(SerialPacket packet) {
|
||||||
|
//TODO: this should be moved elsewhere
|
||||||
|
if (characterMap.find(packet.characterInfo.characterIndex) == characterMap.end()) {
|
||||||
|
throw(std::runtime_error("Cannot update a non-existant character"));
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: the server needs it's own movement system too
|
||||||
|
characterMap[packet.characterInfo.characterIndex].position = packet.characterInfo.position;
|
||||||
|
characterMap[packet.characterInfo.characterIndex].motion = packet.characterInfo.motion;
|
||||||
|
|
||||||
|
PumpPacket(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerApplication::HandleRegionRequest(SerialPacket packet) {
|
||||||
|
//TODO: this should be moved elsewhere
|
||||||
|
packet.meta.type = SerialPacket::Type::REGION_CONTENT;
|
||||||
|
packet.regionInfo.region = regionPager.GetRegion(packet.regionInfo.x, packet.regionInfo.y);
|
||||||
|
|
||||||
|
//send the content
|
||||||
|
network.SendTo(&packet.meta.srcAddress, &packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerApplication::PumpPacket(SerialPacket packet) {
|
||||||
|
//NOTE: I don't really like this, but it'll do for now
|
||||||
|
for (auto& it : clientMap) {
|
||||||
|
network.SendTo(&it.second.address, &packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerApplication::PumpCharacterUnload(int uid) {
|
||||||
|
//delete the client-side character(s)
|
||||||
|
SerialPacket delPacket;
|
||||||
|
delPacket.meta.type = SerialPacket::Type::CHARACTER_DELETE;
|
||||||
|
delPacket.characterInfo.characterIndex = uid;
|
||||||
|
PumpPacket(delPacket);
|
||||||
|
}
|
||||||
@@ -0,0 +1,191 @@
|
|||||||
|
/* 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 <stdexcept>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
//Define the public members
|
||||||
|
//-------------------------
|
||||||
|
|
||||||
|
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
|
||||||
|
//-------------------------
|
||||||
|
|
||||||
|
//setup the map object
|
||||||
|
regionPager.GetAllocator()->SetLuaState(luaState);
|
||||||
|
regionPager.GetFormat()->SetLuaState(luaState);
|
||||||
|
//TODO: config parameter
|
||||||
|
regionPager.GetFormat()->SetSaveDir("save/mapname/");
|
||||||
|
std::cout << "Prepared the map system" << std::endl;
|
||||||
|
|
||||||
|
//push the pager onto the lua registry
|
||||||
|
lua_pushstring(luaState, "pager");
|
||||||
|
lua_pushlightuserdata(luaState, reinterpret_cast<void*>(®ionPager));
|
||||||
|
lua_settable(luaState, LUA_REGISTRYINDEX);
|
||||||
|
std::cout << "Registered the map system in 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 << "\tsizeof(SerialPacket): " << sizeof(SerialPacket) << std::endl;
|
||||||
|
std::cout << "\tPACKET_BUFFER_SIZE: " << PACKET_BUFFER_SIZE << std::endl;
|
||||||
|
|
||||||
|
//finalize the startup
|
||||||
|
std::cout << "Startup completed successfully" << std::endl;
|
||||||
|
|
||||||
|
//debugging
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerApplication::Proc() {
|
||||||
|
SerialPacket packet;
|
||||||
|
while(running) {
|
||||||
|
//suck in the waiting packets & process them
|
||||||
|
while(network.Receive(&packet)) {
|
||||||
|
HandlePacket(packet);
|
||||||
|
}
|
||||||
|
//update the internals
|
||||||
|
//TODO: update the internals i.e. player positions
|
||||||
|
//give the computer a break
|
||||||
|
SDL_Delay(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerApplication::Quit() {
|
||||||
|
std::cout << "Shutting down" << std::endl;
|
||||||
|
|
||||||
|
//save the server state
|
||||||
|
for (auto& it : accountMap) {
|
||||||
|
SaveUserAccount(it.first);
|
||||||
|
}
|
||||||
|
for (auto& it : characterMap) {
|
||||||
|
SaveCharacter(it.first);
|
||||||
|
}
|
||||||
|
|
||||||
|
//empty the members
|
||||||
|
accountMap.clear();
|
||||||
|
characterMap.clear();
|
||||||
|
regionPager.UnloadAll();
|
||||||
|
|
||||||
|
//APIs
|
||||||
|
lua_close(luaState);
|
||||||
|
sqlite3_close_v2(database);
|
||||||
|
network.Close();
|
||||||
|
SDLNet_Quit();
|
||||||
|
SDL_Quit();
|
||||||
|
|
||||||
|
std::cout << "Shutdown finished" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
//Define the uber switch
|
||||||
|
//-------------------------
|
||||||
|
|
||||||
|
void ServerApplication::HandlePacket(SerialPacket packet) {
|
||||||
|
switch(packet.meta.type) {
|
||||||
|
case SerialPacket::Type::BROADCAST_REQUEST:
|
||||||
|
HandleBroadcastRequest(packet);
|
||||||
|
break;
|
||||||
|
case SerialPacket::Type::JOIN_REQUEST:
|
||||||
|
HandleJoinRequest(packet);
|
||||||
|
break;
|
||||||
|
case SerialPacket::Type::SYNCHRONIZE:
|
||||||
|
HandleSynchronize(packet);
|
||||||
|
break;
|
||||||
|
case SerialPacket::Type::DISCONNECT:
|
||||||
|
HandleDisconnect(packet);
|
||||||
|
break;
|
||||||
|
case SerialPacket::Type::SHUTDOWN:
|
||||||
|
HandleShutdown(packet);
|
||||||
|
break;
|
||||||
|
case SerialPacket::Type::CHARACTER_UPDATE:
|
||||||
|
HandleCharacterUpdate(packet);
|
||||||
|
break;
|
||||||
|
case SerialPacket::Type::REGION_REQUEST:
|
||||||
|
HandleRegionRequest(packet);
|
||||||
|
break;
|
||||||
|
//handle errors
|
||||||
|
default:
|
||||||
|
throw(std::runtime_error("Unknown SerialPacket::Type encountered"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user