Compare commits

..

71 Commits

Author SHA1 Message Date
Kayne Ruse 93c41bb19c Merge branch 'develop'; major refactoring complete (read more)
Streamlined the build process, including:
* Restructured the common directory
* Moved the client's scenes up one level
* Removed the unused DEBUG flag, added the GRAPHICS flag
* Moved the server's data structures to the common/gameplay directory
* Data structures are now shared by the client and server

Other changes include:
* Created the StatisticData structure
* Removed the server's static variables
* Some progress on basic combat system framework
* CharacterData now has methods (derived from the delete PlayerCharacter)
* Client-side tables are now shared between the scenes
* Refactored UDPNetworkUtility, tying it to SerialPacket
* Added new structures to SerialPacket, and serialization
* Renamed and rearranged the SQL tables
* Solved a few other TODO tags
* Updated the license headers
2014-05-29 00:28:55 +10:00
Kayne Ruse bf922ec598 Updated the license headers
It only took me 5 months.
2014-05-29 00:16:49 +10:00
Kayne Ruse de902d2d3d Bumped the network version 2014-05-28 23:39:31 +10:00
Kayne Ruse 7b3bf24e5d Refactored UDPNetworkUtility, and tied it to SerialPacket 2014-05-28 23:22:00 +10:00
Kayne Ruse de7da81102 Solved a few items on the TODO list 2014-05-28 22:16:36 +10:00
Kayne Ruse 6428b02d85 Refactored some code from InWorld into methods in CharacterData 2014-05-28 21:25:52 +10:00
Kayne Ruse 519b8a1e36 Entire project is building cleanly again, but characters are static 2014-05-28 00:50:14 +10:00
Kayne Ruse 967f0653a1 Threaded the tables through the scenes 2014-05-27 23:59:42 +10:00
Kayne Ruse b86d393571 Moved the scenes up one directory level, subdirs no longer needed 2014-05-27 23:28:29 +10:00
Kayne Ruse 6b38501c27 Added the GRAPHICS flag, to simplify the gameplay structures 2014-05-27 23:25:07 +10:00
Kayne Ruse 5893342ad8 Removed the shared parameters structure (read more)
I've also stopped using a separate branch for sharing the CharacterData
structre. This commit won't build, mostly because I need to refactor
InWorld to handle the loss of the PlayerCharacter class.

I should probably rename SQL's tables too.
2014-05-27 22:27:30 +10:00
Kayne Ruse ac4a264f12 Merge branch 'dev-charshare' into develop (read more)
Using several branches never really works out well for me. I'm merging
these changes back into develop, because I want to undo the shared
parameters change, but that's tied up with something else. It's just
easier if I do this.
2014-05-27 21:44:55 +10:00
Kayne Ruse 43895a462a Merge branch 'dev-charshare' (early part) into develop (read more)
Moved the server's containers into the common directories, and removed the
server's static members.

This commit does build, but the next commit in 'dev-charshare' won't so
I'm merging this while I can.
2014-05-26 18:38:21 +10:00
Kayne Ruse 1bde0ed3f7 Began unifying the server and client side character classes
This commit won't build
2014-05-26 18:36:09 +10:00
Kayne Ruse d903c0df30 Removed the UID counters from the data containers 2014-05-26 17:42:55 +10:00
Kayne Ruse 9620826d65 Moved the server's data containers into common/gameplay 2014-05-26 17:29:15 +10:00
Kayne Ruse 0a71f43ef3 Implemented SharedParameters system in the client (read more)
Here are more tweaks:
* InWorld's quit event now exits to the main menu, bypassing a relayed disconnect message
* InWorld's disconnect hander no longer throws exceptions (dropped creation packet bugfix)
* CombatData's internals now point to std::pair objects
* Enemies are stored in a global list
2014-05-26 17:11:26 +10:00
Kayne Ruse a47e76845f Removed common/ from the build process, and the DEBUG flag
The common/ directory is empty, only containing more directories to be
built, and the DEBUG flag isn't being used.
2014-05-26 02:21:56 +10:00
Kayne Ruse c2eb08bd5e Restructured the common/ directory, and simplified the build process 2014-05-26 02:10:12 +10:00
Kayne Ruse 7b76e07231 Hooked up the new serial code, nothing broke 2014-05-26 01:08:10 +10:00
Kayne Ruse 1dd8042d3d Added some structures to SerialPacket, and serial.cpp
I've also created the Statistics structure for simplicity.
2014-05-26 00:49:31 +10:00
Kayne Ruse c575ee9ce1 Committing todo.txt 2014-05-24 01:48:35 +10:00
Kayne Ruse 1befc76b70 Merge branch 'develop' (read more)
Deleted in the merge:
* combat_management.cpp
* todo.txt

Amended in the merge:
* server/enemy_factory_interface.hpp
* server/server_application.hpp
* server/server_internals.cpp

That version of combat_management.cpp was not what I was looking for. I'll
try again, this time by working my way down from SerialPacket. It's worked
in the past as far as establishing a standard goes.

todo.txt was deleted in this commit, but will be carried over into the
next develop branch.

I'll release a new demo build without changing the version number, since
there are no functional changes.
2014-05-24 01:24:57 +10:00
Kayne Ruse 6a6e7f7125 Adjusted the README and tweaked some notes 2014-05-19 20:04:17 +10:00
Kayne Ruse bb6e248583 Implemented EnemyFactory, still empty 2014-05-18 03:45:36 +10:00
Kayne Ruse f7df4fba6c Wrote some basic combat management code 2014-05-18 01:48:22 +10:00
Kayne Ruse e7403be508 Minor tweak to CombatInstance 2014-05-17 02:33:02 +10:00
Kayne Ruse 873715b28c Added the "speed" statistic 2014-05-16 17:56:40 +10:00
Kayne Ruse b1d6e5a314 Mostly planning 2014-05-16 02:05:52 +10:00
Kayne Ruse f0453375c4 Stating to implement the combat system 2014-05-16 00:01:05 +10:00
Kayne Ruse e5a98efd7d Merge branch 'develop' (bugfix, read more)
Found an error in the SQL save statements; fixed.

Character positions are now saved between logins.
2014-05-13 04:37:33 +10:00
Kayne Ruse 14b330009b BUGFIX: Found an error in SQL save statements
The character's positions are now persistent between logins.
2014-05-13 04:36:59 +10:00
Kayne Ruse 288b62d3f8 Merge branch 'develop' 2014-05-13 03:26:13 +10:00
Kayne Ruse c5e8f1b3af Added account and character saving on shutdown 2014-05-13 03:25:50 +10:00
Kayne Ruse 980717f9fd Merge branch 'develop' 2014-05-13 03:01:26 +10:00
Kayne Ruse 68475eee0f Created PumpCharacterUnload 2014-05-13 02:51:50 +10:00
Kayne Ruse eeb2400e79 Rearranged the server-side object hierarchy (read more)
This has been a long-running problem for days, but I've finally
implemented a correctly working hierarchy between the ClientData,
AccountData and CharacterData objects:

CharacterData -> AccountData -> ClientData

There doesn't seem to be any issues with it right now, touch wood.
2014-05-13 02:09:00 +10:00
Kayne Ruse 01244005e9 Minor file renaming and tweaks 2014-05-13 00:23:04 +10:00
Kayne Ruse c5005b9b07 Merge branch 'develop' 2014-05-12 22:40:21 +10:00
Kayne Ruse 80a26341b1 Finished the character management, but it needs testing. 2014-05-11 20:13:27 +10:00
Kayne Ruse b7877962f1 Implemented CreateCharacter() and LoadCharacter() (read more)
There are issues with the indexes. That is, the accounts and the
characters need each other's indexes upon creation. I'll need to rectify
this now.
2014-05-10 20:30:33 +10:00
Kayne Ruse 688d064085 Merge branch 'database'
Conflicts:
	todo.txt

Merging todo.txt into the master branch, despite trying to keep it
separate.
2014-05-07 21:12:22 +10:00
Kayne Ruse 1c4d53e3ef Updated TODO, might as well merge this into the master 2014-05-07 21:07:42 +10:00
Kayne Ruse a53a134163 Merge branch 'account'
Added the "accountIndex" variable to the SerialPacket.
2014-05-07 20:55:43 +10:00
Kayne Ruse 4d12788c53 Finished the server-side modifications (read more)
* There seems to be something iffy with this branch
* The size of SerialPacket may have changed

I've implemented the accountIndex variable as best I can, but I really
shouldn't code at night. I'll need to go over the changes again before
merging this.
2014-05-07 20:55:09 +10:00
Kayne Ruse 1beb7cbd5d Began adding basic authentication 2014-05-06 21:35:07 +10:00
Kayne Ruse 8358d72a98 Merge branch 'database' (read more)
* Implemented user accounts.
* Other minor tweaks

I think the general "clientIndex" variable needs to be changed to
"accountIndex", since this will allow for much easier authentication.
2014-05-06 19:21:52 +10:00
Kayne Ruse 4ebff4a25a Minor tweaks, prepping for a merge 2014-05-06 19:18:53 +10:00
Kayne Ruse 0ff787abda Added Unloading and Deletion of user accounts 2014-05-06 18:57:49 +10:00
Kayne Ruse 9b5b48a8ab Implemented saving of user accounts (read more)
To modify an existing user account, change the in memory copy and then
call the function SaveUserAccount(uid), where uid is the index of the
modified account. If the save function is not called immediately, then the
behaviour of the server is undefined.
2014-05-06 18:33:20 +10:00
Kayne Ruse 5dd0fb9e23 BUGFIX: Signal when a duplicate account is being loaded
If a duplicate account is being created or loaded then the functions
return -1. The higher code can take it from there.
2014-05-06 16:41:08 +10:00
Kayne Ruse 7c210e04a5 Switched to using a wildcard symbol 2014-05-06 00:17:50 +10:00
Kayne Ruse 9236e02101 Merge branch 'master' into database (read more)
Conflicts:
	todo.txt (kept)

Just merging the editor's deletion into this branch, nothing else major.
2014-05-06 00:08:06 +10:00
Kayne Ruse 8f4ebf20da Removed the editor, since it isn't currently needed 2014-05-06 00:07:02 +10:00
Kayne Ruse 910e51f637 Began to implement user accounts using the database
I'm mostly just testing the waters at this stage, and i've left some debug
code in. There's no way to unload, delete, etc. the accounts, but that
comes later.
2014-05-05 23:57:07 +10:00
Kayne Ruse 92fc9b4e25 Adjusted the lua's map API, requiring a large rewrite
One the whole nothing major has changed, but I think this makes things
more logical. I just hope its stable, since I'm releasing a new tag.
2014-04-29 15:53:04 +10:00
Kayne Ruse 2b8e7241c9 Merge branch 'tweaks'; nothing major 2014-04-29 13:12:39 +10:00
Kayne Ruse 124cb3ad13 Did some renaming and comment tweaks 2014-04-29 06:34:23 +10:00
Kayne Ruse 6d3400d948 Merge branch 'network' (read more)
I've refactored the network layout. Here is a brief list of changes:

* The new player object is created server-side rather than client-side
* serial.cpp now uses macros to prevent hard-to-find logic errors
* A few method definitions have been re-ordered
* SerialPacket's internals have been slightly changed
* SerialPacket now carries a datestamp defining the network protocol
* server_application.cpp has been split into two separate files
* HandleJoinRequest() has been modified to create the new player object
2014-04-29 02:14:25 +10:00
Kayne Ruse 5031352fe3 Fixed the bug (read more)
The bug was being caused by a lack of a new player object being sent to
some clients. Fixed this by adding in the sending code, and preventing the
new entries being "registered" until the end of the HandleJoinRequest()
method.

Hopefully I can simply abstract away some of this code soon.
2014-04-29 01:47:01 +10:00
Kayne Ruse 624369f147 Discovered a bug 2014-04-27 22:46:19 +10:00
Kayne Ruse 9a7f7b8684 Rewrote the TODO list 2014-04-27 03:55:44 +10:00
Kayne Ruse fa9487c2f2 Fixed the previous bug (read more)
The bug was being caused by not assigning default values to the player
objects' internals. I've added a quick fix to these structs, but I think
it's best to expand them into proper classes now.
2014-04-27 02:37:20 +10:00
Kayne Ruse 9ec1ddab99 Exceptions are being thrown; retiring for the night
I don't know what's causing these issues, so I'm leaving it for tonight.
2014-04-26 02:48:15 +10:00
Kayne Ruse 6f1c2d0555 Merge branch 'fragmented-server' into network (read more)
I've divided the server's source into several different files. This should hopefully make it a bit easier to manage.

Please note that I do know there's an exception being thrown by the client
in this build.
2014-04-26 02:34:17 +10:00
Kayne Ruse 01b50d5590 I guess it was easier to compile the fragmented server than I thought 2014-04-26 02:31:48 +10:00
Kayne Ruse 9c673928e6 Began segmenting the server's code
I've created a separate branch for this because it's gonna be a bitch to
get compiled, and then I'll still have to ensure that the client & server
are work together correctly.

This build does not compile.
2014-04-26 02:09:32 +10:00
Kayne Ruse d55dfb90e4 Worked the new protocol into the client (read more)
I've added the handle and avatar fields back into the PlayerInfo section
in the network code, because I need to be able to load a specific file
when a new player is created. This wasn't forseen, but it's fine. i'm
leaving the fields in ClientInfo as well, because LobbyMenu is using them
to login to the server.

PlayerIndex is now a shared parameter.

I've shifted some code around in InWorld, however the overall logic is the
same.

This build (as well as the last) does not compile.
2014-04-26 01:05:31 +10:00
Kayne Ruse 235a05d006 Rearranged the SerialPacket and serialization code
The serialization code is now using macros to simplify each line, and to
prevent errors. It should be noted that, apart from the region content,
the serialization and deserialization code is essentially identical.
2014-04-25 23:50:19 +10:00
Kayne Ruse dabb7b3b2e Compiled a list of tasks
The list in todo.txt are a list of tasks that will be needed to complete
the login/user accounts overhaul, and will hopefully make the server a
persistent system.

Once the server is persistent (via the database) I can start on the combat
system.
2014-04-22 01:55:09 +10:00
Kayne Ruse e756289c2b Adjusted a few comments 2014-04-22 01:54:26 +10:00
94 changed files with 2402 additions and 2281 deletions
+10 -8
View File
@@ -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
+21
View File
@@ -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_
+5 -5
View File
@@ -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"));
+14 -2
View File
@@ -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
+147 -135
View File
@@ -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
View File
@@ -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
View File
@@ -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
-117
View File
@@ -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;
}
}
-67
View File
@@ -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 -1
View File
@@ -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
-139
View File
@@ -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
}
-74
View File
@@ -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
-48
View File
@@ -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
+67
View File
@@ -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
+80
View File
@@ -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
+64
View File
@@ -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
+36
View File
@@ -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.
*/
+42
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
+4 -4
View File
@@ -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) ));
+4 -4
View File
@@ -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) {
+2 -8
View File
@@ -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
View File
@@ -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;
} }
} }
+5 -5
View File
@@ -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
+92 -42
View File
@@ -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
+120 -44
View File
@@ -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;
}
+20 -19
View File
@@ -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
+2 -2
View File
@@ -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}
}; };
+2 -8
View File
@@ -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
+126
View File
@@ -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
-88
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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
+37
View File
@@ -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
-116
View File
@@ -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;
}
-49
View File
@@ -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
-230
View File
@@ -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;
}
}
-43
View File
@@ -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;
}
-43
View File
@@ -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
-36
View File
@@ -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
-91
View File
@@ -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) {
//
}
-2
View File
@@ -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
View File
@@ -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
+23 -16
View File
@@ -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
+28 -47
View File
@@ -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.
);
+191
View File
@@ -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);
}
+231
View File
@@ -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
}
+42
View File
@@ -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
View File
@@ -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
View File
@@ -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
-373
View File
@@ -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);
}
}
+38 -13
View File
@@ -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
+186
View File
@@ -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);
}
+191
View File
@@ -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*>(&regionPager));
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;
}
}