Compare commits

..

98 Commits

Author SHA1 Message Date
Kayne Ruse 07885cca1b Merge branch 'develop' into master (read more)
Following a rather educational "game jam" using components of Tortuga, I've
made a significant number of revisions.

A brief summary:

* The entirety of the map system now have lua APIs
* The ConfigUtility handles recusive config files
* Collisions are functional
* I've added a singleton template base class, which is used by the apps
* I've decided that focusing on the engine's stability is important
* I need to push through the generated TODO list
2014-08-04 01:32:21 +10:00
Kayne Ruse 956e920b7a Added the debug and release targets 2014-08-04 01:04:13 +10:00
Kayne Ruse 908f91d674 ClientApplication and ServerApplication are now Singletons 2014-08-04 00:45:09 +10:00
Kayne Ruse fd320767c5 Implemented the changes to ConfigUtility in the client and server
The server's changes were easy. The clients means that the constructors
for each scene have one less argument, and each scene has one less member.
The exception to this is LobbyMenu, where the config is used in multiple
places, so it was easier to have the config's reference as a member.

To replace the config's usage, I added this line in most cases:

ConfigUtility& config = ConfigUtility::GetSingleton();

The only requirement is that ConfigUtility::Create() and
ConfigUtility::Delete() are called from the main() function.
2014-08-03 23:20:39 +10:00
Kayne Ruse c830fa0537 ConfigUtility now supports recursion; is a Singleton
If you have "config.next" set, the config system will load that as another
config file. Higher config files have a higher precedence over subfiles
when conflicting keys are encountered.

* Added singleton.hpp, containing Singleton<T>
* ConfigUtility now inherits from Singleton
* Tweaked timer.*pp layouts
2014-08-03 23:14:56 +10:00
Kayne Ruse 10c89970cc Merge branch 'splice' into develop, read more
This branch's primary purpose has been to intergrate changes from the "jam" branch into the main repository. I decided to do a 48 hour jam, to see what I could accomplish. I believe that, although nothing major came out of it, the result are beneficial overall. The changes in this branch, while still experimental, will hopefully help me to push towards something playable soon.
2014-07-31 20:17:31 +10:00
Kayne Ruse 0b512305a9 Added last additions from jam (read more)
I should also mention that the client is throwing up a warning that
HandleCharacterUpdate() is passing to HandleCharacterNew().
2014-07-31 20:04:58 +10:00
Kayne Ruse 555abf9c95 Fixed the map issue (read more)
The map generation was being written to a trigger function instead of a
glue method. Fixed, map is being drawn correctly now.
2014-07-31 19:17:29 +10:00
Kayne Ruse 2b3ea5eb80 Updated map system (read more)
Project compiles and runs, multiplayer works, but the map is not visible

There are a number of major changes to the map system, beth directly from the
jam branch and from the splicing process. The changes that are listed here have
been noted as they were added to the index for committing.

* tile_sheet.*pp moved from 'common/graphics/' to 'common/map/'
* Minor method and member name changes to TileSheet
* TileSheet has a lua API, but it isn't used anywhere
    NOTE: Nothing uses both lua and graphics, but a theoretical editor might
* Region API's glue functions have been changed from triggers to simple dummy
    methods. These should simply be over written.
* RegionPagerBase::GetRegion(int x, int y) now snaps it's parameters
    Presicely why is unknown, but I do remember there was a bug without it
* RegionPagerLua has been rewritten to use the Region API's methods, rather
    than the triggers.
* RegionPagerLua no longer stores the map's save directory, or passes it to the
    the Region API's methods.
* RegionPagerLua::luaState renamed to RegionPagerLua::lua
    conforms to changes elsewhere
* Removed the directory glue functions from the RegionPager API
* region_pager_api.hpp preprocessor guard changed
* Adjusted makefiles to account for TileSheet's movement
2014-07-31 18:01:50 +10:00
Kayne Ruse 66815016ba Fixed the debugging makefile's output directory 2014-07-31 17:18:25 +10:00
Kayne Ruse 46f02dcfdd Minor tweak to ConfigUtility 2014-07-31 17:14:40 +10:00
Kayne Ruse 414a0896c9 Began merging the jam branch into the development (read more)
The list of changes committed:

* Removed SimpleRNG
* Added Timer (for debugging)
* Added BoundingBox
* Added floating point snapToBase()
* Added error check to Vector2::Normalize()
* Updated makefiles, project compiles
2014-07-30 21:10:43 +10:00
Kayne Ruse 0077d501ac Merge branch 'develop' 2014-07-08 16:28:07 +10:00
Kayne Ruse e946a0741d Encapsulated the Character class 2014-07-04 00:55:12 +10:00
Kayne Ruse 839c2af940 Merge branch 'rebuild' into develop, read more
This branch was mostly used for streamlining the code after not seeing it
for a week. It's quite surprising what you realize after taking a break
for a while.
2014-07-03 02:26:42 +10:00
Kayne Ruse f70241cc57 Merge branch 'config' into rebuild 2014-07-03 02:17:44 +10:00
Kayne Ruse 36d30ce39b Moved the scenes into a subdirectory 2014-07-03 02:01:53 +10:00
Kayne Ruse 28d083cba4 Hammered out server-side issues, read more
* Removed the client-only code from CharacterData, including the .cpp file
* Removed CombatManager and EnemyManager instanciation
2014-07-03 01:41:58 +10:00
Kayne Ruse 4dd4b37fc0 It now builds cleanly, but I cut a few code stubs 2014-07-03 00:56:30 +10:00
Kayne Ruse 82b1b589dc Moved some files around 2014-07-03 00:23:43 +10:00
Kayne Ruse bac493c96b Rearranged the debug output 2014-07-02 21:59:26 +10:00
Kayne Ruse d5520e83c6 Merge branch 'collision' into develop, read more
Began working on the collision system. Currently, the collision data which
is set server-side is transferred to the client, and stored in the Region
class. It's incomplete, but it's going well.
2014-07-02 01:10:23 +10:00
Kayne Ruse 93480be685 Solid data is moving from the server to the client, read more
The APIs have access to the solid data, and I fixed a bug: Basically, the
template parameter for std::bitset  expects an integer representing the
number of bits to hold, but I initially misread it as the number of bytes.
This has been corrected.

I've also added a sandy beach to the generated island. I'm tempted to
start working on some simple generators soon.
2014-07-02 00:47:37 +10:00
Kayne Ruse 8ed308e89a Switched the hack for the bitset
I've also added acessors and mutators to the Region and RegionPagerBase
classes.
2014-07-01 22:55:43 +10:00
Kayne Ruse 8df1ecd804 This hack for the collision map was a terrible idea
I'm committing these changes before undoing these, and coding it properly.
2014-07-01 22:04:45 +10:00
Kayne Ruse 8c9d071c7a Minor tweaks 2014-07-01 01:03:03 +10:00
Kayne Ruse ac1098fa86 Merge branch 'develop', Major API expansion 2014-06-24 02:46:39 +10:00
Kayne Ruse deba324449 Merge branch 'api' into develop 2014-06-23 10:46:39 +10:00
Kayne Ruse 95362286f8 Committing the island generator script, and a bugfix
region_api.cpp had a bug, where a glue function's name was used twice. It
was an easy catch, but there was an issue in the new script, where I was
counting from 0 instead of 1. As a result, I was chasing a segfault for 5
hours.
2014-06-23 10:29:39 +10:00
Kayne Ruse f5c58bf5ad Minor tweaks after a failed attempt at metatables 2014-06-23 05:58:54 +10:00
Kayne Ruse 316db43b0a Fixed CreateRoom()'s return type 2014-06-23 04:54:01 +10:00
Kayne Ruse 46ed196bf4 All current lua hooks are being called 2014-06-23 04:10:21 +10:00
Kayne Ruse 64baa63d12 Changed the naming conventions (read more)
I've changed some naming concentions in the lua APIs. I've also made a few
other tweaks, like region_pager_api.cpp delegating to the passed
RegionPager object. This won't explicitly run, becuase there's still a few
more changes needed.
2014-06-23 03:45:30 +10:00
Kayne Ruse e19b6fbc23 Updated RoomManager and the API 2014-06-21 19:02:43 +10:00
Kayne Ruse a64411a567 Filled out the APIs a bit 2014-06-21 18:24:58 +10:00
Kayne Ruse 3662a97475 Added mapType to BaseGenerator 2014-06-21 18:24:01 +10:00
Kayne Ruse 97aaacbc23 Merge branch 'mapgen' into develop 2014-06-21 07:25:46 +10:00
Kayne Ruse 8afd0e7c8a Created a separate API for the RoomManager class 2014-06-21 07:19:51 +10:00
Kayne Ruse 82c776df83 Moved the generators into a subdirectory 2014-06-21 07:00:48 +10:00
Kayne Ruse 924ebc2ee9 Created the generator hierarchy 2014-06-21 06:47:30 +10:00
Kayne Ruse d3bf099a98 Arranged server's source into directories 2014-06-21 05:52:27 +10:00
Kayne Ruse a6de5f9e69 Imported the files from branch 'fixed-map' 2014-06-21 05:28:06 +10:00
Kayne Ruse 618666de43 Renamed the Restart scene to CleanUp 2014-06-15 22:39:10 +10:00
Kayne Ruse 5c74ecdd72 Removed ESC key exit, and tweaked some comments 2014-06-15 22:24:50 +10:00
Kayne Ruse 61848db65b Merging branch 'develop' into master (read more)
List of major changes:
* Refactored the server into smaller modules
 * Server now partially supports multiple rooms
* Overhauled the networking code
 * Packets are now a hierarchy of classes
 * Changed the way packets are moved about
 * Initial login protocol altered
* Reworked the map system
 * Two separate pager classes, one with lua one without
 * lua API supports these changes, and partially supports rooms
* Major and minor bugfixes as the need arose

This is the culmination of three weeks of work, but it feels like so much longer. Ideally there shouldn't be any major visible changes to the game, even though the code has undergone a huge revision. The intent of these changes was to make future progress much faster, and I'm not planning on doing this again any time soon. This commit is intened for 'release-0.4.1', whereas 'release-0.4' was only the first half. Naturally when you think something is done, you're only half way there.

My plans are to return to the combat system, and get it working as an actual playable system to show off. Following that, I'll begin researching the terrain generation. I'm estimating that these tasks will take 2 months each, but I'll probably be pouring as much effort into these as I did with this commit. As usual, development is rarely straight forward, so I'll probably get sidetracked at some point (hence the large development window). If I do stick to my timeline, I'll reach a "playable" alpha by mid-october. From there I'll have 2.5 months to flesh out some gameplay, and possibly submit the game to Greenlight.

After working on this game for a year, I wonder how much further there is to go before other people play it.
2014-06-15 00:04:41 +10:00
Kayne Ruse dfc464ddd6 Merge branch 'char-add' into develop, characters working again 2014-06-14 23:30:57 +10:00
Kayne Ruse bd5e57401e Minor comment tweaks 2014-06-14 23:27:33 +10:00
Kayne Ruse a23fbbfb38 Characters are working correctly again 2014-06-14 23:13:11 +10:00
Kayne Ruse c021032512 The character is visible, fixed a database issue 2014-06-14 22:37:21 +10:00
Kayne Ruse d4be22a6eb Merge branch 'develop' into char-add
I just want that minor tweak from master here
2014-06-14 04:14:36 +10:00
Kayne Ruse c210b99a5f Merging a slight change to master 2014-06-14 04:08:18 +10:00
Kayne Ruse 01eb934fad Merge branch 'client-fix' into develop (read more)
Summary of changes:
* Changed the way I handle packets
* RoomManager is now functional
* Split RegionPager into two classes
* Fixed several major and minor bugs
2014-06-14 04:03:55 +10:00
Kayne Ruse 52e6b144c1 Merge branch 'map-redo' into client-fix (read more)
This merge splits RegionPager into two parts: RegionPagerBase, with the
basic Region management code, and RegionPagerLua, which has lua hooks. The
former is used by the client while the latter is used by the server. Both
classes' internals have been optimized.

There are also changes to the client and server code, to account for the
new system, and I've fixed a couple of bugs.

The player's character is not created, but the client can login and see
the map.
2014-06-14 03:46:16 +10:00
Kayne Ruse b418ad713d Worked these changes into the client & server (read more)
The changes were fairly easy, and I was actually able to find and fix an
out-of-sequence bug: The destructors for the AccountManager and the
CharacterManager were using SQL code after the call to SQLite3_close_v2(),
so I added and called UnloadAll() for both of them.
2014-06-14 03:38:13 +10:00
Kayne Ruse 1bc51fe035 Removed the 'erase_if' template, that was silly 2014-06-14 03:08:33 +10:00
Kayne Ruse 793737e1ed Experimenting with the map 2014-06-14 03:05:21 +10:00
Kayne Ruse e57b047343 Added some basic code to RoomManager 2014-06-14 00:44:13 +10:00
Kayne Ruse a11867126c Fixed segfault in common, changed casting of packets to static_cast
This required that I switch from using a char array for the packet buffers
to using malloc() and free(). They make more sense anyway, and I've
learned (or relearned) something about casting.
2014-06-12 03:47:49 +10:00
Kayne Ruse bf4a7561ed Merge branch 'client-fix' into develop (read more)
The entire repository builds cleanly, but the client is still broken and
incompatible with the server. Still, I'm merging this build into develop.

I don't know if the client runs correctly.

Much of the modifications since branching from master are untested.
2014-06-11 21:59:44 +10:00
Kayne Ruse 13332bf3fc in_combat.cpp builds; entire repo builds
Doesn't mean I'm done yet.
2014-06-11 21:57:34 +10:00
Kayne Ruse 955aed2224 in_world.cpp is building 2014-06-11 21:48:01 +10:00
Kayne Ruse ee79231de0 Began bringing the client into line with the server's changes
Several parts of the client already built correctly.

Updated LobbyMenu, it not builds.
2014-06-10 02:42:07 +10:00
Kayne Ruse 5128d17759 Merge branch 'new-map' into develop 2014-06-10 01:47:52 +10:00
Kayne Ruse a07e7418a6 Implemented a basic API for the server's rooms 2014-06-10 01:46:42 +10:00
Kayne Ruse 1ef5eb7a0f Pager's heavyweight API methods call the Region's counterparts 2014-06-10 00:52:19 +10:00
Kayne Ruse 135e650ec8 Moved the map API to the map directory 2014-06-10 00:38:00 +10:00
Kayne Ruse b7c12ba106 Fleshed out the pager's API 2014-06-10 00:20:51 +10:00
Kayne Ruse 2d27399fd1 Added the pager API placeholder files 2014-06-08 19:43:24 +10:00
Kayne Ruse ba83fac29f Changed map API to region API 2014-06-08 19:30:03 +10:00
Kayne Ruse 3bd4f1bb1d Merge branch 'new-server' (early part) into develop
Merging the server's refactored aspects into develop so that I can work on the map systems separately. See the logs for changes, because I'm too busy to add them here.
2014-06-08 19:19:08 +10:00
Kayne Ruse b269ce5fb9 Re-added the lua hooks 2014-06-08 04:20:07 +10:00
Kayne Ruse f034c32c38 Collapsed the pager into a single file, removing lua hooks
I need to re-add the lua hooks, but it'll be easy.
2014-06-08 04:01:09 +10:00
Kayne Ruse 5175a4e40d Fleshed out and rewrote some code
Fleshed out HandleCharacterNew() and HandleCharacterDelete(), and rewrote
HandleSynchronize().
2014-06-08 02:55:56 +10:00
Kayne Ruse ee2ac0b7a9 Created MAX_PACKET_SIZE 2014-06-08 00:36:05 +10:00
Kayne Ruse 63be0ee70d The server is building, but still needs work
There is some missing character creation/unloading code, and there are a
few other issues highlighted by TODO tags, see below.

In general, 'mapIndex' has been renamed to 'roomIndex'. Multiple rooms
have not been fully implemented yet, but I'm working on it.

Other issues:

* FileFormat needs to be changed to MapLoader
* Server's character movement is still slaved to the clients

The client does not build.
2014-06-07 02:15:40 +10:00
Kayne Ruse cac273da5e Partial rewrite of server_application.cpp
I've also fixed some other issues along the way. However, the next step
requires support for multiple rooms. Finally.
2014-06-07 01:14:54 +10:00
Kayne Ruse 170096b5db Server is nearly done, only server_application.cpp is failing 2014-06-06 23:34:38 +10:00
Kayne Ruse 10e857ecd1 Added empty managers for CombatData, RoomData and EnemyData
These are just placeholders for now, but I'll flesh them out later.

I should note that the server's managers all build cleanly.
2014-06-06 23:17:57 +10:00
Kayne Ruse 5c8572d811 Rearranged the methods 2014-06-06 22:57:10 +10:00
Kayne Ruse 973a2be16b Merged server_internals.cpp and network_handlers.cpp into
server_application.cpp
2014-06-06 22:11:05 +10:00
Kayne Ruse 9b9f6700af Merge commit '2c9b0fc' into develop (read more)
These changes split SerialPacket and the serialization code into more
managable chunks. I've also included some comment and error message
tweaks, just because they seem to fit into this merge rather than the
next.

I'm currently refactoring the server into more easily manageable modules,
and I might do the same to the client later. This is all to make
development easier, but I wonder if I'm just moving sideways instead of
forward.

This merge will not build.
2014-06-06 21:57:22 +10:00
Kayne Ruse 7fb458ddc1 Refactored the character management into a separate class 2014-06-06 21:53:17 +10:00
Kayne Ruse 310f701b0d Began modulating ServerApplication, beginning with the accounts 2014-06-06 21:43:54 +10:00
Kayne Ruse 6664f8a8bc Renamed server_connections.cpp => network_handlers.cpp 2014-06-06 21:14:41 +10:00
Kayne Ruse 2c9b0fc3e7 Committing some comment tweaks 2014-06-06 21:12:46 +10:00
Kayne Ruse 5966d7b51a Fleshed out the serialization internals 2014-06-04 23:30:20 +10:00
Kayne Ruse 46dff9b97b Implemented the minor changes into UDPNetworkPacket 2014-06-04 23:08:52 +10:00
Kayne Ruse 23364b2810 Split up the serial code, but had to gut it in the process
Since the contents of the packets are different than before, I decided to
gut the serialization code. I'll reimplement the internals soon.
2014-06-04 23:03:24 +10:00
Kayne Ruse da60fa8f94 Began reworking the network code
This commit devides SerialPacket into a series of different structures,
all decended from a common base class.

Using a union was not a good idea.
2014-06-04 21:16:51 +10:00
Kayne Ruse fbac14e188 Merge branch 'develop' 2014-06-02 22:42:36 +10:00
Kayne Ruse 0a03535ecb Replaced several lookups to the same object with a reference 2014-06-02 22:35:55 +10:00
Kayne Ruse 2bebfdfb97 Updated database control, character stats are saving
Just for the record, I don't like the way SAVE_CHARACTER is expanded like
that.
2014-06-02 22:22:51 +10:00
Kayne Ruse fb6fba9564 Removed BBox, renamed position to origin
I've replaced the BBox class with a pair of inline functions in
check_bounds.hpp. I've also renamed the 'position' variable to 'origin' in
several locations.

These changes are mostly to alleviate ambiguity.
2014-06-02 21:13:08 +10:00
Kayne Ruse d2f03b98dc Screwing around with some settings 2014-06-02 20:02:19 +10:00
Kayne Ruse 4acd350219 Added the restart scene 2014-06-02 00:45:57 +10:00
Kayne Ruse 9d83abbd38 Copied some boilerplate code from InWorld to InCombat 2014-06-01 23:42:30 +10:00
Kayne Ruse 1cfb814ee4 Added the rest of the combat info to the network code 2014-06-01 23:07:02 +10:00
Kayne Ruse 2e8a474792 Committing todo.txt 2014-05-29 00:30:25 +10:00
129 changed files with 5286 additions and 2656 deletions
+1
View File
@@ -8,6 +8,7 @@ This game is inspired by classic 2D RPGs, as well as more modern sandbox MMOs. T
Tortuga's full documentation can be found in a separate branch, see [Tortuga/docs](https://github.com/Ratstail91/Tortuga/tree/docs). 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). 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).
For a list of known bugs, see the [GitHub bug tracker](https://github.com/Ratstail91/Tortuga/issues).
## External Dependencies ## External Dependencies
@@ -19,27 +19,23 @@
* 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 "character_data.hpp" #include "character.hpp"
void CharacterData::Update(double delta) { void Character::Update(double delta) {
if (motion.x && motion.y) { if (motion.x && motion.y) {
position += motion * delta * CHARACTER_WALKING_MOD; origin += motion * delta * CHARACTER_WALKING_MOD;
} }
else if (motion != 0) { else if (motion != 0) {
position += motion * delta; origin += motion * delta;
} }
#ifdef GRAPHICS
sprite.Update(delta); sprite.Update(delta);
#endif
} }
#ifdef GRAPHICS void Character::DrawTo(SDL_Surface* const dest, int camX, int camY) {
sprite.DrawTo(dest, origin.x - camX, origin.y - camY);
void CharacterData::DrawTo(SDL_Surface* const dest, int camX, int camY) {
sprite.DrawTo(dest, position.x - camX, position.y - camY);
} }
void CharacterData::CorrectSprite() { void Character::CorrectSprite() {
//NOTE: These must correspond to the sprite sheet in use //NOTE: These must correspond to the sprite sheet in use
if (motion.y > 0) { if (motion.y > 0) {
sprite.SetYIndex(0); sprite.SetYIndex(0);
@@ -63,5 +59,3 @@ void CharacterData::CorrectSprite() {
sprite.SetXIndex(0); sprite.SetXIndex(0);
} }
} }
#endif
+95
View File
@@ -0,0 +1,95 @@
/* 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 CHARACTER_HPP_
#define CHARACTER_HPP_
//components
#include "character_defines.hpp"
#include "vector2.hpp"
#include "bounding_box.hpp"
#include "statistics.hpp"
//graphics
#include "sprite_sheet.hpp"
//std namespace
#include <string>
#include <cmath>
class Character {
public:
Character() = default;
~Character() = default;
void Update(double delta);
//graphics
void DrawTo(SDL_Surface* const, int camX, int camY);
void CorrectSprite();
SpriteSheet* GetSprite() { return &sprite; }
//gameplay
Statistics* GetStats() { return &stats; }
//accessors and mutators
//metadata
int SetOwner(int i) { return owner = i; }
int GetOwner() { return owner; }
std::string SetHandle(std::string s) { return handle = s; }
std::string GetHandle() const { return handle; }
std::string SetAvatar(std::string s) { return avatar = s; }
std::string GetAvatar() const { return avatar; }
//position
Vector2 SetOrigin(Vector2 v) { return origin = v; }
Vector2 GetOrigin() const { return origin; }
Vector2 SetMotion(Vector2 v) { return motion = v; }
Vector2 GetMotion() const { return motion; }
BoundingBox SetBounds(BoundingBox b) { return bounds = b; }
BoundingBox GetBounds() { return bounds; }
private:
//graphics
SpriteSheet sprite;
//base statistics
Statistics stats;
//TODO: gameplay components: equipment, items, buffs, debuffs
//metadata
int owner;
std::string handle;
std::string avatar;
//position
Vector2 origin = {0.0,0.0};
Vector2 motion = {0.0,0.0};
BoundingBox bounds;
};
//tmp
#include <map>
typedef std::map<int, Character> CharacterMap;
#endif
+67 -7
View File
@@ -22,9 +22,11 @@
#include "client_application.hpp" #include "client_application.hpp"
#include "serial.hpp" #include "serial.hpp"
#include "config_utility.hpp"
#include <stdexcept> #include <stdexcept>
#include <chrono> #include <chrono>
#include <iostream>
//------------------------- //-------------------------
//Scene headers //Scene headers
@@ -37,26 +39,79 @@
#include "lobby_menu.hpp" #include "lobby_menu.hpp"
#include "in_world.hpp" #include "in_world.hpp"
#include "in_combat.hpp" #include "in_combat.hpp"
#include "clean_up.hpp"
//------------------------- //-------------------------
//Public access members //Public access members
//------------------------- //-------------------------
void ClientApplication::Init(int argc, char** argv) { void ClientApplication::Init(int argc, char** argv) {
std::cout << "Beginning " << argv[0] << std::endl;
//load the prerequisites //load the prerequisites
ConfigUtility& config = ConfigUtility::GetSingleton();
config.Load("rsc\\config.cfg"); config.Load("rsc\\config.cfg");
//-------------------------
//Initialize the APIs
//-------------------------
//initialize SDL //initialize SDL
if (SDL_Init(SDL_INIT_VIDEO)) { if (SDL_Init(SDL_INIT_VIDEO)) {
throw(std::runtime_error("Failed to initialize SDL")); throw(std::runtime_error("Failed to initialize SDL"));
} }
BaseScene::SetScreen(config.Int("screen.w"), config.Int("screen.h"), 0, (config.Bool("screen.f")) ? SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_FULLSCREEN : SDL_HWSURFACE|SDL_DOUBLEBUF); std::cout << "Initialized SDL" << std::endl;
//initialize SDL_net //initialize SDL_net
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); network.Open(0);
std::cout << "Initialized SDL_net" << std::endl;
//-------------------------
//Setup the screen
//-------------------------
int w = config.Int("client.screen.w");
int h = config.Int("client.screen.h");
int f = config.Bool("client.screen.f") ? SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_FULLSCREEN : SDL_HWSURFACE|SDL_DOUBLEBUF;
BaseScene::SetScreen(w ? w : 800, h ? h : 600, 0, f);
std::cout << "Initialized the screen" << std::endl;
//-------------------------
//debug output
//-------------------------
//TODO: enable/disable these with a switch
#define DEBUG_OUTPUT_VAR(x) std::cout << "\t" << #x << ": " << x << std::endl;
std::cout << "Internal sizes:" << std::endl;
DEBUG_OUTPUT_VAR(sizeof(Region::type_t));
DEBUG_OUTPUT_VAR(sizeof(Region));
DEBUG_OUTPUT_VAR(REGION_WIDTH);
DEBUG_OUTPUT_VAR(REGION_HEIGHT);
DEBUG_OUTPUT_VAR(REGION_DEPTH);
DEBUG_OUTPUT_VAR(REGION_SOLID_FOOTPRINT);
DEBUG_OUTPUT_VAR(REGION_FOOTPRINT);
DEBUG_OUTPUT_VAR(PACKET_BUFFER_SIZE);
DEBUG_OUTPUT_VAR(MAX_PACKET_SIZE);
#undef DEBUG_OUTPUT_VAR
//-------------------------
//finalize the startup
//-------------------------
std::cout << "Startup completed successfully" << std::endl;
//-------------------------
//debugging
//-------------------------
//...
} }
void ClientApplication::Proc() { void ClientApplication::Proc() {
@@ -95,9 +150,11 @@ void ClientApplication::Proc() {
} }
void ClientApplication::Quit() { void ClientApplication::Quit() {
std::cout << "Shutting down" << std::endl;
network.Close(); network.Close();
SDLNet_Quit(); SDLNet_Quit();
SDL_Quit(); SDL_Quit();
std::cout << "Clean exit" << std::endl;
} }
//------------------------- //-------------------------
@@ -110,22 +167,25 @@ void ClientApplication::LoadScene(SceneList sceneIndex) {
//add scene creation calls here //add scene creation calls here
case SceneList::FIRST: case SceneList::FIRST:
case SceneList::SPLASHSCREEN: case SceneList::SPLASHSCREEN:
activeScene = new SplashScreen(&config); activeScene = new SplashScreen();
break; break;
case SceneList::MAINMENU: case SceneList::MAINMENU:
activeScene = new MainMenu(&config); activeScene = new MainMenu();
break; break;
case SceneList::OPTIONSMENU: case SceneList::OPTIONSMENU:
activeScene = new OptionsMenu(&config); activeScene = new OptionsMenu();
break; break;
case SceneList::LOBBYMENU: case SceneList::LOBBYMENU:
activeScene = new LobbyMenu(&config, &network, &clientIndex, &accountIndex, &characterIndex); activeScene = new LobbyMenu(&network, &clientIndex, &accountIndex);
break; break;
case SceneList::INWORLD: case SceneList::INWORLD:
activeScene = new InWorld(&config, &network, &clientIndex, &accountIndex, &characterIndex, &combatMap, &characterMap); activeScene = new InWorld(&network, &clientIndex, &accountIndex, &characterIndex, &characterMap);
break; break;
case SceneList::INCOMBAT: case SceneList::INCOMBAT:
activeScene = new InCombat(&config, &network, &clientIndex, &accountIndex, &characterIndex, &combatMap, &characterMap, &enemyMap); activeScene = new InCombat(&network, &clientIndex, &accountIndex, &characterIndex, &characterMap);
break;
case SceneList::CLEANUP:
activeScene = new CleanUp(&network, &clientIndex, &accountIndex, &characterIndex, &characterMap);
break; break;
default: default:
throw(std::logic_error("Failed to recognize the scene index")); throw(std::logic_error("Failed to recognize the scene index"));
+11 -12
View File
@@ -25,24 +25,26 @@
#include "scene_list.hpp" #include "scene_list.hpp"
#include "base_scene.hpp" #include "base_scene.hpp"
#include "config_utility.hpp"
#include "udp_network_utility.hpp" #include "udp_network_utility.hpp"
#include "character_data.hpp" #include "character.hpp"
#include "combat_data.hpp"
#include "enemy_data.hpp" #include "singleton.hpp"
#include <map> #include <map>
class ClientApplication { class ClientApplication: public Singleton<ClientApplication> {
public: public:
ClientApplication() = default; //public methods
~ClientApplication() = default;
void Init(int argc, char** argv); void Init(int argc, char** argv);
void Proc(); void Proc();
void Quit(); void Quit();
private: private:
friend Singleton<ClientApplication>;
ClientApplication() = default;
~ClientApplication() = default;
//Private access members //Private access members
void LoadScene(SceneList sceneIndex); void LoadScene(SceneList sceneIndex);
void UnloadScene(); void UnloadScene();
@@ -50,15 +52,12 @@ private:
BaseScene* activeScene = nullptr; BaseScene* activeScene = nullptr;
//shared parameters //shared parameters
ConfigUtility config;
UDPNetworkUtility network; UDPNetworkUtility network;
int clientIndex = -1; int clientIndex = -1;
int accountIndex = -1; int accountIndex = -1;
int characterIndex = -1; int characterIndex = -1;
std::map<int, CombatData> combatMap; CharacterMap characterMap;
std::map<int, CharacterData> characterMap;
std::map<int, EnemyData> enemyMap;
}; };
#endif #endif
-125
View File
@@ -1,125 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "in_combat.hpp"
//-------------------------
//Public access members
//-------------------------
InCombat::InCombat(
ConfigUtility* const argConfig,
UDPNetworkUtility* const argNetwork,
int* const argClientIndex,
int* const argAccountIndex,
int* const argCharacterIndex,
std::map<int, CombatData>* argCombatMap,
std::map<int, CharacterData>* argCharacterMap,
std::map<int, EnemyData>* argEnemyMap
):
config(*argConfig),
network(*argNetwork),
clientIndex(*argClientIndex),
accountIndex(*argAccountIndex),
characterIndex(*argCharacterIndex),
combatMap(*argCombatMap),
characterMap(*argCharacterMap),
enemyMap(*argEnemyMap)
{
//
}
InCombat::~InCombat() {
//
}
//-------------------------
//Frame loop
//-------------------------
void InCombat::FrameStart() {
//
}
void InCombat::Update(double delta) {
//
}
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) {
//
}
//-------------------------
//Event handlers
//-------------------------
void InCombat::QuitEvent() {
//exit the game AND the server
// RequestDisconnect();
SetNextScene(SceneList::MAINMENU);
}
void InCombat::MouseMotion(SDL_MouseMotionEvent const& motion) {
//
}
void InCombat::MouseButtonDown(SDL_MouseButtonEvent const& button) {
//
}
void InCombat::MouseButtonUp(SDL_MouseButtonEvent const& button) {
//
}
void InCombat::KeyDown(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) {
case SDLK_ESCAPE:
QuitEvent();
break;
}
}
void InCombat::KeyUp(SDL_KeyboardEvent const& key) {
//
}
//-------------------------
//Network handlers
//-------------------------
//TODO: network handlers
//-------------------------
//Server control
//-------------------------
//TODO: server control
-452
View File
@@ -1,452 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "in_world.hpp"
#include "channels.hpp"
#include <algorithm>
#include <cmath>
#include <stdexcept>
//-------------------------
//Public access members
//-------------------------
InWorld::InWorld(
ConfigUtility* const argConfig,
UDPNetworkUtility* const argNetwork,
int* const argClientIndex,
int* const argAccountIndex,
int* const argCharacterIndex,
std::map<int, CombatData>* argCombatMap,
std::map<int, CharacterData>* argCharacterMap
):
config(*argConfig),
network(*argNetwork),
clientIndex(*argClientIndex),
accountIndex(*argAccountIndex),
characterIndex(*argCharacterIndex),
combatMap(*argCombatMap),
characterMap(*argCharacterMap)
{
//setup the utility objects
buttonImage.LoadSurface(config["dir.interface"] + "button_menu.bmp");
buttonImage.SetClipH(buttonImage.GetClipH()/3);
font.LoadSurface(config["dir.fonts"] + "pk_white_8.bmp");
//pass the utility objects
disconnectButton.SetImage(&buttonImage);
disconnectButton.SetFont(&font);
shutDownButton.SetImage(&buttonImage);
shutDownButton.SetFont(&font);
//set the button positions
disconnectButton.SetX(50);
disconnectButton.SetY(50 + buttonImage.GetClipH() * 0);
shutDownButton.SetX(50);
shutDownButton.SetY(50 + buttonImage.GetClipH() * 1);
//set the button texts
disconnectButton.SetText("Disconnect");
shutDownButton.SetText("Shut Down");
//load the tilesheet
//TODO: add the tilesheet to the map system?
tileSheet.Load(config["dir.tilesets"] + "terrain.bmp", 12, 15);
//request a sync
RequestSynchronize();
//debug
// RequestRegion(0, 0);
}
InWorld::~InWorld() {
//
}
//-------------------------
//Frame loop
//-------------------------
void InWorld::FrameStart() {
//
}
void InWorld::Update(double delta) {
SerialPacket packet;
//suck in all waiting packets
while(network.Receive(&packet)) {
HandlePacket(packet);
}
//update the characters
for (auto& it : characterMap) {
it.second.Update(delta);
}
//update the camera
if(localCharacter) {
camera.x = localCharacter->position.x - camera.marginX;
camera.y = localCharacter->position.y - camera.marginY;
}
//check the map
UpdateMap();
}
void InWorld::FrameEnd() {
//
}
void InWorld::RenderFrame() {
// SDL_FillRect(GetScreen(), 0, 0);
Render(GetScreen());
SDL_Flip(GetScreen());
fps.Calculate();
}
void InWorld::Render(SDL_Surface* const screen) {
//draw the map
for (auto it = regionPager.GetContainer()->begin(); it != regionPager.GetContainer()->end(); it++) {
tileSheet.DrawRegionTo(screen, *it, camera.x, camera.y);
}
//draw characters
for (auto& it : characterMap) {
//TODO: drawing order according to Y position
it.second.DrawTo(screen, camera.x, camera.y);
}
//draw UI
disconnectButton.DrawTo(screen);
shutDownButton.DrawTo(screen);
font.DrawStringTo(to_string_custom(fps.GetFrameRate()), screen, 0, 0);
}
//-------------------------
//Event handlers
//-------------------------
void InWorld::QuitEvent() {
//exit the game AND the server
RequestDisconnect();
SetNextScene(SceneList::MAINMENU);
}
void InWorld::MouseMotion(SDL_MouseMotionEvent const& motion) {
disconnectButton.MouseMotion(motion);
shutDownButton.MouseMotion(motion);
}
void InWorld::MouseButtonDown(SDL_MouseButtonEvent const& button) {
disconnectButton.MouseButtonDown(button);
shutDownButton.MouseButtonDown(button);
}
void InWorld::MouseButtonUp(SDL_MouseButtonEvent const& button) {
if (disconnectButton.MouseButtonUp(button) == Button::State::HOVER) {
RequestDisconnect();
}
if (shutDownButton.MouseButtonUp(button) == Button::State::HOVER) {
RequestShutDown();
}
}
void InWorld::KeyDown(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) {
case SDLK_ESCAPE: {
QuitEvent();
}
break;
//player movement
case SDLK_LEFT:
if (localCharacter) {
localCharacter->motion.x -= CHARACTER_WALKING_SPEED;
SendPlayerUpdate();
}
break;
case SDLK_RIGHT:
if (localCharacter) {
localCharacter->motion.x += CHARACTER_WALKING_SPEED;
SendPlayerUpdate();
}
break;
case SDLK_UP:
if (localCharacter) {
localCharacter->motion.y -= CHARACTER_WALKING_SPEED;
SendPlayerUpdate();
}
break;
case SDLK_DOWN:
if (localCharacter) {
localCharacter->motion.y += CHARACTER_WALKING_SPEED;
SendPlayerUpdate();
}
break;
}
}
void InWorld::KeyUp(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) {
//player movement
case SDLK_LEFT:
if (localCharacter) {
localCharacter->motion.x += CHARACTER_WALKING_SPEED;
SendPlayerUpdate();
}
break;
case SDLK_RIGHT:
if (localCharacter) {
localCharacter->motion.x -= CHARACTER_WALKING_SPEED;
SendPlayerUpdate();
}
break;
case SDLK_UP:
if (localCharacter) {
localCharacter->motion.y += CHARACTER_WALKING_SPEED;
SendPlayerUpdate();
}
break;
case SDLK_DOWN:
if (localCharacter) {
localCharacter->motion.y -= CHARACTER_WALKING_SPEED;
SendPlayerUpdate();
}
break;
}
}
//-------------------------
//Network handlers
//-------------------------
void InWorld::HandlePacket(SerialPacket packet) {
switch(packet.meta.type) {
case SerialPacket::Type::DISCONNECT:
HandleDisconnect(packet);
break;
case SerialPacket::Type::REGION_CONTENT:
HandleRegionContent(packet);
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
default:
throw(std::runtime_error(std::string() + "Unknown SerialPacket::Type encountered in InWorld: " + to_string_custom(int(packet.meta.type))));
break;
}
}
void InWorld::HandleDisconnect(SerialPacket packet) {
network.Unbind(Channels::SERVER);
clientIndex = -1;
accountIndex = -1;
characterIndex = -1;
SetNextScene(SceneList::MAINMENU);
}
void InWorld::HandleRegionContent(SerialPacket packet) {
//replace existing regions
regionPager.UnloadRegion(packet.regionInfo.x, packet.regionInfo.y);
regionPager.PushRegion(packet.regionInfo.region);
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
//-------------------------
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;
//pack the packet
packet.meta.type = SerialPacket::Type::CHARACTER_UPDATE;
packet.characterInfo.clientIndex = clientIndex;
packet.characterInfo.accountIndex = accountIndex;
packet.characterInfo.characterIndex = characterIndex;
packet.characterInfo.position = localCharacter->position;
packet.characterInfo.motion = localCharacter->motion;
network.SendTo(Channels::SERVER, &packet);
}
void InWorld::RequestDisconnect() {
SerialPacket packet;
//send a disconnect request
packet.meta.type = SerialPacket::Type::DISCONNECT;
packet.clientInfo.clientIndex = clientIndex;
packet.clientInfo.accountIndex = accountIndex;
packet.clientInfo.characterIndex = characterIndex;
network.SendTo(Channels::SERVER, &packet);
}
void InWorld::RequestShutDown() {
SerialPacket packet;
//send a shutdown request
packet.meta.type = SerialPacket::Type::SHUTDOWN;
packet.clientInfo.clientIndex = clientIndex;
packet.clientInfo.accountIndex = accountIndex;
packet.clientInfo.characterIndex = characterIndex;
network.SendTo(Channels::SERVER, &packet);
}
void InWorld::RequestRegion(int mapIndex, int x, int y) {
SerialPacket packet;
//pack the region's data
packet.meta.type = SerialPacket::Type::REGION_REQUEST;
packet.regionInfo.mapIndex = mapIndex;
packet.regionInfo.x = x;
packet.regionInfo.y = y;
network.SendTo(Channels::SERVER, &packet);
}
//-------------------------
//Utilities
//-------------------------
//TODO: convert this into a more generic function?; using parameters for the bounds
void InWorld::UpdateMap() {
//these represent the zone of regions that the client needs loaded, including the mandatory buffers (+1/-1)
int xStart = snapToBase(REGION_WIDTH, camera.x/tileSheet.GetTileW()) - REGION_WIDTH;
int xEnd = snapToBase(REGION_WIDTH, (camera.x+camera.width)/tileSheet.GetTileW()) + REGION_WIDTH;
int yStart = snapToBase(REGION_HEIGHT, camera.y/tileSheet.GetTileH()) - REGION_HEIGHT;
int yEnd = snapToBase(REGION_HEIGHT, (camera.y+camera.height)/tileSheet.GetTileH()) + REGION_HEIGHT;
//prune distant regions
for (auto it = regionPager.GetContainer()->begin(); it != regionPager.GetContainer()->end(); /* EMPTY */) {
//check if the region is outside off this area
if ((*it)->GetX() < xStart || (*it)->GetX() > xEnd || (*it)->GetY() < yStart || (*it)->GetY() > yEnd) {
//clunky, but the alternative was time consuming
int tmpX = (*it)->GetX();
int tmpY = (*it)->GetY();
++it;
regionPager.UnloadRegion(tmpX, tmpY);
continue;
}
++it;
}
//request empty regions within this zone
for (int i = xStart; i <= xEnd; i += REGION_WIDTH) {
for (int j = yStart; j <= yEnd; j += REGION_HEIGHT) {
if (!regionPager.FindRegion(i, j)) {
RequestRegion(0, i, j);
}
}
}
}
+14 -4
View File
@@ -21,23 +21,33 @@
*/ */
#include "client_application.hpp" #include "client_application.hpp"
//singletons
#include "config_utility.hpp"
#include <stdexcept> #include <stdexcept>
#include <iostream> #include <iostream>
using namespace std; using namespace std;
int main(int argc, char** argv) { int main(int argc, char** argv) {
cout << "Beginning client" << endl;
try { try {
ClientApplication app; //create the singletons
ClientApplication::Create();
ConfigUtility::Create();
//call the server's routines
ClientApplication& app = ClientApplication::GetSingleton();
app.Init(argc, argv); app.Init(argc, argv);
app.Proc(); app.Proc();
app.Quit(); app.Quit();
//delete the singletons
ConfigUtility::Delete();
ClientApplication::Delete();
} }
catch(exception& e) { catch(exception& e) {
cerr << "Fatal exception thrown: " << e.what() << endl; cerr << "Fatal exception thrown: " << e.what() << endl;
return 1; return 1;
} }
cout << "Clean exit" << endl;
return 0; return 0;
} }
+4 -3
View File
@@ -1,7 +1,7 @@
#config #config
INCLUDES+=. ../common/gameplay ../common/graphics ../common/map ../common/network ../common/ui ../common/utilities INCLUDES+=. scenes ../common/debugging ../common/gameplay ../common/graphics ../common/map ../common/network ../common/network/packet ../common/network/serial ../common/ui ../common/utilities
LIBS+=../libcommon.a -lSDL_net -lwsock32 -liphlpapi -lmingw32 -lSDLmain -lSDL -llua LIBS+=client.a ../libcommon.a -lSDL_net -lwsock32 -liphlpapi -lmingw32 -lSDLmain -lSDL -llua
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) -DGRAPHICS CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
#source #source
CXXSRC=$(wildcard *.cpp) CXXSRC=$(wildcard *.cpp)
@@ -16,6 +16,7 @@ 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)
+1
View File
@@ -35,6 +35,7 @@ enum class SceneList {
LOBBYMENU, LOBBYMENU,
INWORLD, INWORLD,
INCOMBAT, INCOMBAT,
CLEANUP,
}; };
#endif #endif
+134
View File
@@ -0,0 +1,134 @@
/* 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 "clean_up.hpp"
#include "channels.hpp"
#include "config_utility.hpp"
#include <stdexcept>
//-------------------------
//Public access members
//-------------------------
CleanUp::CleanUp(
UDPNetworkUtility* const argNetwork,
int* const argClientIndex,
int* const argAccountIndex,
int* const argCharacterIndex,
CharacterMap* argCharacterMap
):
network(*argNetwork),
clientIndex(*argClientIndex),
accountIndex(*argAccountIndex),
characterIndex(*argCharacterIndex),
characterMap(*argCharacterMap)
{
ConfigUtility& config = ConfigUtility::GetSingleton();
//setup the utility objects
image.LoadSurface(config["dir.interface"] + "button_menu.bmp");
image.SetClipH(image.GetClipH()/3);
font.LoadSurface(config["dir.fonts"] + "pk_white_8.bmp");
//pass the utility objects
backButton.SetImage(&image);
backButton.SetFont(&font);
//set the button positions
backButton.SetX(50);
backButton.SetY(50 + image.GetClipH() * 0);
//set the button texts
backButton.SetText("Back");
//full reset
network.Unbind(Channels::SERVER);
clientIndex = -1;
accountIndex = -1;
characterIndex = -1;
// combatMap.clear();
characterMap.clear();
// enemyMap.clear();
//auto return
startTick = std::chrono::steady_clock::now();
}
CleanUp::~CleanUp() {
//
}
//-------------------------
//Frame loop
//-------------------------
void CleanUp::Update(double delta) {
if (std::chrono::steady_clock::now() - startTick > std::chrono::duration<int>(10)) {
QuitEvent();
}
//BUGFIX: Eat incoming packets
while(network.Receive());
}
void CleanUp::RenderFrame() {
SDL_FillRect(GetScreen(), 0, 0);
Render(GetScreen());
SDL_Flip(GetScreen());
fps.Calculate();
}
void CleanUp::Render(SDL_Surface* const screen) {
backButton.DrawTo(screen);
font.DrawStringTo("You have been disconnected.", screen, 50, 30);
}
//-------------------------
//Event handlers
//-------------------------
void CleanUp::QuitEvent() {
SetNextScene(SceneList::QUIT);
}
void CleanUp::MouseMotion(SDL_MouseMotionEvent const& motion) {
backButton.MouseMotion(motion);
}
void CleanUp::MouseButtonDown(SDL_MouseButtonEvent const& button) {
backButton.MouseButtonDown(button);
}
void CleanUp::MouseButtonUp(SDL_MouseButtonEvent const& button) {
if (backButton.MouseButtonUp(button) == Button::State::HOVER) {
SetNextScene(SceneList::MAINMENU);
}
}
void CleanUp::KeyDown(SDL_KeyboardEvent const& key) {
//
}
void CleanUp::KeyUp(SDL_KeyboardEvent const& key) {
//
}
+89
View File
@@ -0,0 +1,89 @@
/* 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 CLEANUP_HPP_
#define CLEANUP_HPP_
//network
#include "udp_network_utility.hpp"
//graphics
#include "image.hpp"
#include "raster_font.hpp"
#include "button.hpp"
//common
#include "frame_rate.hpp"
#include "character.hpp"
//client
#include "base_scene.hpp"
//std namespace
#include <chrono>
class CleanUp : public BaseScene {
public:
//Public access members
CleanUp(
UDPNetworkUtility* const argNetwork,
int* const argClientIndex,
int* const argAccountIndex,
int* const argCharacterIndex,
CharacterMap* argCharacterMap
);
~CleanUp();
protected:
//Frame loop
void Update(double delta);
void RenderFrame();
void Render(SDL_Surface* const);
//Event handlers
void QuitEvent();
void MouseMotion(SDL_MouseMotionEvent const&);
void MouseButtonDown(SDL_MouseButtonEvent const&);
void MouseButtonUp(SDL_MouseButtonEvent const&);
void KeyDown(SDL_KeyboardEvent const&);
void KeyUp(SDL_KeyboardEvent const&);
//shared parameters
UDPNetworkUtility& network;
int& clientIndex;
int& accountIndex;
int& characterIndex;
CharacterMap& characterMap;
//graphics
Image image;
RasterFont font;
//UI
Button backButton;
FrameRate fps;
//auto return
std::chrono::steady_clock::time_point startTick;
};
#endif
+220
View File
@@ -0,0 +1,220 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "in_combat.hpp"
#include "channels.hpp"
#include "utility.hpp"
#include "config_utility.hpp"
#include <stdexcept>
//-------------------------
//Public access members
//-------------------------
InCombat::InCombat(
UDPNetworkUtility* const argNetwork,
int* const argClientIndex,
int* const argAccountIndex,
int* const argCharacterIndex,
CharacterMap* argCharacterMap
):
network(*argNetwork),
clientIndex(*argClientIndex),
accountIndex(*argAccountIndex),
characterIndex(*argCharacterIndex),
characterMap(*argCharacterMap)
{
/* //setup the utility objects
buttonImage.LoadSurface(config["dir.interface"] + "button_menu.bmp");
buttonImage.SetClipH(buttonImage.GetClipH()/3);
font.LoadSurface(config["dir.fonts"] + "pk_white_8.bmp");
//pass the utility objects
backButton.SetImage(&buttonImage);
backButton.SetFont(&font);
//set the button positions
backButton.SetX(50);
backButton.SetY(50 + buttonImage.GetClipH() * 0);
//set the button texts
backButton.SetText("Back");
//request a sync
RequestSynchronize();
*/
//debug
//
}
InCombat::~InCombat() {
//
}
//-------------------------
//Frame loop
//-------------------------
void InCombat::FrameStart() {
//
}
void InCombat::Update(double delta) {
//suck in and process all waiting packets
SerialPacket* packetBuffer = static_cast<SerialPacket*>(malloc(MAX_PACKET_SIZE));
while(network.Receive(packetBuffer)) {
HandlePacket(packetBuffer);
}
free(static_cast<void*>(packetBuffer));
//TODO: more
}
void InCombat::FrameEnd() {
//
}
void InCombat::RenderFrame() {
SDL_FillRect(GetScreen(), 0, 0);
Render(GetScreen());
SDL_Flip(GetScreen());
fps.Calculate();
}
void InCombat::Render(SDL_Surface* const screen) {
//TODO: draw the background
//TODO: draw the characters
//TODO: draw the enemies
//TODO: draw the UI
}
//-------------------------
//Event handlers
//-------------------------
void InCombat::QuitEvent() {
//exit the game AND the server
RequestDisconnect();
SetNextScene(SceneList::QUIT);
}
void InCombat::MouseMotion(SDL_MouseMotionEvent const& motion) {
//
}
void InCombat::MouseButtonDown(SDL_MouseButtonEvent const& button) {
//
}
void InCombat::MouseButtonUp(SDL_MouseButtonEvent const& button) {
//
}
void InCombat::KeyDown(SDL_KeyboardEvent const& key) {
//
}
void InCombat::KeyUp(SDL_KeyboardEvent const& key) {
//
}
//-------------------------
//Network handlers
//-------------------------
void InCombat::HandlePacket(SerialPacket* const argPacket) {
switch(argPacket->type) {
case SerialPacketType::DISCONNECT:
HandleDisconnect(argPacket);
break;
//handle errors
default:
throw(std::runtime_error(std::string() + "Unknown SerialPacketType encountered in InCombat: " + to_string_custom(static_cast<int>(argPacket->type)) ));
break;
}
}
void InCombat::HandleDisconnect(SerialPacket* const) {
SetNextScene(SceneList::CLEANUP);
}
//TODO: more network handlers
//-------------------------
//Server control
//-------------------------
void InCombat::RequestSynchronize() {
ClientPacket newPacket;
//request a sync
newPacket.type = SerialPacketType::SYNCHRONIZE;
newPacket.clientIndex = clientIndex;
newPacket.accountIndex = accountIndex;
network.SendTo(Channels::SERVER, &newPacket);
}
void InCombat::SendPlayerUpdate() {
CharacterPacket newPacket;
//pack the packet
newPacket.type = SerialPacketType::CHARACTER_UPDATE;
newPacket.characterIndex = characterIndex;
//handle, avatar
newPacket.accountIndex = accountIndex;
// newPacket.roomIndex = localCharacter->roomIndex;
// newPacket.origin = localCharacter->origin;
// newPacket.motion = localCharacter->motion;
// newPacket.stats = localCharacter->stats;
//TODO: gameplay components: equipment, items, buffs, debuffs
network.SendTo(Channels::SERVER, &newPacket);
}
void InCombat::RequestDisconnect() {
ClientPacket newPacket;
//send a disconnect request
newPacket.type = SerialPacketType::DISCONNECT;
newPacket.clientIndex = clientIndex;
newPacket.accountIndex = accountIndex;
network.SendTo(Channels::SERVER, &newPacket);
}
void InCombat::RequestShutdown() {
ClientPacket newPacket;
//send a shutdown request
newPacket.type = SerialPacketType::SHUTDOWN;
newPacket.clientIndex = clientIndex;
newPacket.accountIndex = accountIndex;
network.SendTo(Channels::SERVER, &newPacket);
}
@@ -31,12 +31,9 @@
#include "button.hpp" #include "button.hpp"
//common //common
#include "config_utility.hpp"
#include "frame_rate.hpp" #include "frame_rate.hpp"
#include "combat_data.hpp" #include "character.hpp"
#include "character_data.hpp"
#include "enemy_data.hpp"
//client //client
#include "base_scene.hpp" #include "base_scene.hpp"
@@ -45,14 +42,11 @@ class InCombat : public BaseScene {
public: public:
//Public access members //Public access members
InCombat( InCombat(
ConfigUtility* const argConfig,
UDPNetworkUtility* const argNetwork, UDPNetworkUtility* const argNetwork,
int* const argClientIndex, int* const argClientIndex,
int* const argAccountIndex, int* const argAccountIndex,
int* const argCharacterIndex, int* const argCharacterIndex,
std::map<int, CombatData>* argCombatMap, CharacterMap* argCharacterMap
std::map<int, CharacterData>* argCharacterMap,
std::map<int, EnemyData>* argEnemyMap
); );
~InCombat(); ~InCombat();
@@ -73,25 +67,21 @@ protected:
void KeyUp(SDL_KeyboardEvent const&); void KeyUp(SDL_KeyboardEvent const&);
//Network handlers //Network handlers
void HandlePacket(SerialPacket); void HandlePacket(SerialPacket* const);
void HandleDisconnect(SerialPacket); void HandleDisconnect(SerialPacket* const);
//TODO: more
//Server control //Server control
void RequestSynchronize();
void SendPlayerUpdate(); void SendPlayerUpdate();
void RequestDisconnect(); void RequestDisconnect();
void RequestShutdown(); void RequestShutdown();
//TODO: more
//shared parameters //shared parameters
ConfigUtility& config;
UDPNetworkUtility& network; UDPNetworkUtility& network;
int& clientIndex; int& clientIndex;
int& accountIndex; int& accountIndex;
int& characterIndex; int& characterIndex;
std::map<int, CombatData>& combatMap; CharacterMap& characterMap;
std::map<int, CharacterData>& characterMap;
std::map<int, EnemyData>& enemyMap;
//graphics //graphics
//TODO: graphics //TODO: graphics
+479
View File
@@ -0,0 +1,479 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "in_world.hpp"
#include "channels.hpp"
#include "utility.hpp"
#include "config_utility.hpp"
#include <stdexcept>
#include <algorithm>
#include <cmath>
#include <iostream>
//-------------------------
//Public access members
//-------------------------
InWorld::InWorld(
UDPNetworkUtility* const argNetwork,
int* const argClientIndex,
int* const argAccountIndex,
int* const argCharacterIndex,
CharacterMap* argCharacterMap
):
network(*argNetwork),
clientIndex(*argClientIndex),
accountIndex(*argAccountIndex),
characterIndex(*argCharacterIndex),
characterMap(*argCharacterMap)
{
ConfigUtility& config = ConfigUtility::GetSingleton();
//setup the utility objects
buttonImage.LoadSurface(config["dir.interface"] + "button_menu.bmp");
buttonImage.SetClipH(buttonImage.GetClipH()/3);
font.LoadSurface(config["dir.fonts"] + "pk_white_8.bmp");
//pass the utility objects
disconnectButton.SetImage(&buttonImage);
disconnectButton.SetFont(&font);
shutDownButton.SetImage(&buttonImage);
shutDownButton.SetFont(&font);
//set the button positions
disconnectButton.SetX(50);
disconnectButton.SetY(50 + buttonImage.GetClipH() * 0);
shutDownButton.SetX(50);
shutDownButton.SetY(50 + buttonImage.GetClipH() * 1);
//set the button texts
disconnectButton.SetText("Disconnect");
shutDownButton.SetText("Shut Down");
//load the tilesheet
//TODO: add the tilesheet to the map system?
//TODO: Tile size and tile sheet should be loaded elsewhere
tileSheet.Load(config["dir.tilesets"] + "terrain.bmp", 32, 32);
//request a sync
RequestSynchronize();
//debug
//
}
InWorld::~InWorld() {
//
}
//-------------------------
//Frame loop
//-------------------------
void InWorld::FrameStart() {
//
}
void InWorld::Update(double delta) {
//suck in and process all waiting packets
SerialPacket* packetBuffer = static_cast<SerialPacket*>(malloc(MAX_PACKET_SIZE));
while(network.Receive(packetBuffer)) {
HandlePacket(packetBuffer);
}
free(static_cast<void*>(packetBuffer));
//update the characters
for (auto& it : characterMap) {
it.second.Update(delta);
}
//check the map
UpdateMap();
//skip the rest
if (!localCharacter) {
return;
}
//check for collisions with the map
BoundingBox wallBounds = {0, 0, tileSheet.GetTileW(), tileSheet.GetTileH()};
const int xCount = localCharacter->GetBounds().w / wallBounds.w + 1;
const int yCount = localCharacter->GetBounds().h / wallBounds.h + 1;
for (int i = -1; i <= xCount; ++i) {
for (int j = -1; j <= yCount; ++j) {
//set the wall's position
wallBounds.x = wallBounds.w * i + snapToBase((double)wallBounds.w, localCharacter->GetOrigin().x);
wallBounds.y = wallBounds.h * j + snapToBase((double)wallBounds.h, localCharacter->GetOrigin().y);
if (!regionPager.GetSolid(wallBounds.x / wallBounds.w, wallBounds.y / wallBounds.h)) {
continue;
}
if ((localCharacter->GetOrigin() + localCharacter->GetBounds()).CheckOverlap(wallBounds)) {
localCharacter->SetOrigin(localCharacter->GetOrigin() - (localCharacter->GetMotion() * delta));
localCharacter->SetMotion({0,0});
localCharacter->CorrectSprite();
SendPlayerUpdate();
}
}
}
//update the camera
camera.x = localCharacter->GetOrigin().x - camera.marginX;
camera.y = localCharacter->GetOrigin().y - camera.marginY;
}
void InWorld::FrameEnd() {
//
}
void InWorld::RenderFrame() {
// SDL_FillRect(GetScreen(), 0, 0);
Render(GetScreen());
SDL_Flip(GetScreen());
fps.Calculate();
}
void InWorld::Render(SDL_Surface* const screen) {
//draw the map
for (std::list<Region>::iterator it = regionPager.GetContainer()->begin(); it != regionPager.GetContainer()->end(); it++) {
tileSheet.DrawRegionTo(screen, &(*it), camera.x, camera.y);
}
//draw characters
for (auto& it : characterMap) {
//BUG: #29 drawing order according to Y origin
it.second.DrawTo(screen, camera.x, camera.y);
}
//draw UI
disconnectButton.DrawTo(screen);
shutDownButton.DrawTo(screen);
font.DrawStringTo(to_string_custom(fps.GetFrameRate()), screen, 0, 0);
}
//-------------------------
//Event handlers
//-------------------------
void InWorld::QuitEvent() {
//exit the game AND the server
RequestDisconnect();
SetNextScene(SceneList::QUIT);
}
void InWorld::MouseMotion(SDL_MouseMotionEvent const& motion) {
disconnectButton.MouseMotion(motion);
shutDownButton.MouseMotion(motion);
}
void InWorld::MouseButtonDown(SDL_MouseButtonEvent const& button) {
disconnectButton.MouseButtonDown(button);
shutDownButton.MouseButtonDown(button);
}
void InWorld::MouseButtonUp(SDL_MouseButtonEvent const& button) {
if (disconnectButton.MouseButtonUp(button) == Button::State::HOVER) {
RequestDisconnect();
}
if (shutDownButton.MouseButtonUp(button) == Button::State::HOVER) {
RequestShutDown();
}
}
void InWorld::KeyDown(SDL_KeyboardEvent const& key) {
if (!localCharacter) {
return;
}
//player movement
Vector2 motion = localCharacter->GetMotion();
switch(key.keysym.sym) {
case SDLK_LEFT:
motion.x -= CHARACTER_WALKING_SPEED;
break;
case SDLK_RIGHT:
motion.x += CHARACTER_WALKING_SPEED;
break;
case SDLK_UP:
motion.y -= CHARACTER_WALKING_SPEED;
break;
case SDLK_DOWN:
motion.y += CHARACTER_WALKING_SPEED;
break;
default:
return;
}
localCharacter->SetMotion(motion);
localCharacter->CorrectSprite();
SendPlayerUpdate();
}
void InWorld::KeyUp(SDL_KeyboardEvent const& key) {
if (!localCharacter) {
return;
}
//player movement
Vector2 motion = localCharacter->GetMotion();
switch(key.keysym.sym) {
//NOTE: The use of min/max here are to prevent awkward movements
case SDLK_LEFT:
motion.x = std::min(motion.x + CHARACTER_WALKING_SPEED, 0.0);
break;
case SDLK_RIGHT:
motion.x = std::max(motion.x - CHARACTER_WALKING_SPEED, 0.0);
break;
case SDLK_UP:
motion.y = std::min(motion.y + CHARACTER_WALKING_SPEED, 0.0);
break;
case SDLK_DOWN:
motion.y = std::max(motion.y - CHARACTER_WALKING_SPEED, 0.0);
break;
default:
return;
}
localCharacter->SetMotion(motion);
localCharacter->CorrectSprite();
SendPlayerUpdate();
}
//-------------------------
//Network handlers
//-------------------------
void InWorld::HandlePacket(SerialPacket* const argPacket) {
switch(argPacket->type) {
case SerialPacketType::DISCONNECT:
HandleDisconnect(argPacket);
break;
case SerialPacketType::CHARACTER_NEW:
HandleCharacterNew(static_cast<CharacterPacket*>(argPacket));
break;
case SerialPacketType::CHARACTER_DELETE:
HandleCharacterDelete(static_cast<CharacterPacket*>(argPacket));
break;
case SerialPacketType::CHARACTER_UPDATE:
HandleCharacterUpdate(static_cast<CharacterPacket*>(argPacket));
break;
case SerialPacketType::REGION_CONTENT:
HandleRegionContent(static_cast<RegionPacket*>(argPacket));
break;
//handle errors
default:
throw(std::runtime_error(std::string() + "Unknown SerialPacketType encountered in InWorld: " + to_string_custom(static_cast<int>(argPacket->type)) ));
break;
}
}
void InWorld::HandleDisconnect(SerialPacket* const argPacket) {
SetNextScene(SceneList::CLEANUP);
}
void InWorld::HandleCharacterNew(CharacterPacket* const argPacket) {
if (characterMap.find(argPacket->characterIndex) != characterMap.end()) {
throw(std::runtime_error("Cannot create duplicate characters"));
}
//create the character object
Character& newCharacter = characterMap[argPacket->characterIndex];
//fill out the character's members
newCharacter.SetHandle(argPacket->handle);
newCharacter.SetAvatar(argPacket->avatar);
newCharacter.GetSprite()->LoadSurface(ConfigUtility::GetSingleton()["dir.sprites"] + newCharacter.GetAvatar(), 4, 4);
newCharacter.SetOrigin(argPacket->origin);
newCharacter.SetMotion(argPacket->motion);
newCharacter.SetBounds({0, 16, 32, 32}); //TODO: magic numbers, fix this
(*newCharacter.GetStats()) = argPacket->stats;
//bookkeeping code
newCharacter.CorrectSprite();
//catch this client's player object
if (argPacket->accountIndex == accountIndex && !localCharacter) {
characterIndex = argPacket->characterIndex;
localCharacter = &newCharacter;
//setup the camera
//TODO: move this?
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::HandleCharacterDelete(CharacterPacket* const argPacket) {
//TODO: authenticate when own character is being deleted (linked to a TODO in the server)
//catch this client's player object
if (argPacket->characterIndex == characterIndex) {
characterIndex = -1;
localCharacter = nullptr;
}
characterMap.erase(argPacket->characterIndex);
}
void InWorld::HandleCharacterUpdate(CharacterPacket* const argPacket) {
if (characterMap.find(argPacket->characterIndex) == characterMap.end()) {
std::cout << "Warning: HandleCharacterUpdate() is passing to HandleCharacterNew()" << std::endl;
HandleCharacterNew(argPacket);
return;
}
Character& character = characterMap[argPacket->characterIndex];
//other characters moving
if (argPacket->characterIndex != characterIndex) {
character.SetOrigin(argPacket->origin);
character.SetMotion(argPacket->motion);
character.CorrectSprite();
}
}
void InWorld::HandleRegionContent(RegionPacket* const argPacket) {
//replace existing regions
regionPager.UnloadRegion(argPacket->x, argPacket->y);
regionPager.PushRegion(argPacket->region);
//clean up after the serial code
delete argPacket->region;
argPacket->region = nullptr;
}
//-------------------------
//Server control
//-------------------------
void InWorld::RequestSynchronize() {
ClientPacket newPacket;
//request a sync
newPacket.type = SerialPacketType::SYNCHRONIZE;
newPacket.clientIndex = clientIndex;
newPacket.accountIndex = accountIndex;
//TODO: location, range for sync request
network.SendTo(Channels::SERVER, &newPacket);
}
void InWorld::SendPlayerUpdate() {
CharacterPacket newPacket;
//pack the packet
newPacket.type = SerialPacketType::CHARACTER_UPDATE;
newPacket.characterIndex = characterIndex;
//NOTE: omitting the handle and avatar here
newPacket.accountIndex = accountIndex;
newPacket.roomIndex = 0; //TODO: room index
newPacket.origin = localCharacter->GetOrigin();
newPacket.motion = localCharacter->GetMotion();
newPacket.stats = *localCharacter->GetStats();
//TODO: gameplay components: equipment, items, buffs, debuffs
network.SendTo(Channels::SERVER, &newPacket);
}
void InWorld::RequestDisconnect() {
ClientPacket newPacket;
//send a disconnect request
newPacket.type = SerialPacketType::DISCONNECT;
newPacket.clientIndex = clientIndex;
newPacket.accountIndex = accountIndex;
network.SendTo(Channels::SERVER, &newPacket);
}
void InWorld::RequestShutDown() {
ClientPacket newPacket;
//send a shutdown request
newPacket.type = SerialPacketType::SHUTDOWN;
newPacket.clientIndex = clientIndex;
newPacket.accountIndex = accountIndex;
network.SendTo(Channels::SERVER, &newPacket);
}
void InWorld::RequestRegion(int roomIndex, int x, int y) {
RegionPacket packet;
//pack the region's data
packet.type = SerialPacketType::REGION_REQUEST;
packet.roomIndex = roomIndex;
packet.x = x;
packet.y = y;
network.SendTo(Channels::SERVER, &packet);
}
//-------------------------
//Utilities
//-------------------------
//TODO: convert this into a more generic function?; using parameters for the bounds
void InWorld::UpdateMap() {
//these represent the zone of regions that the client needs loaded, including the mandatory buffers (+1/-1)
int xStart = snapToBase(REGION_WIDTH, camera.x/tileSheet.GetTileW()) - REGION_WIDTH;
int xEnd = snapToBase(REGION_WIDTH, (camera.x+camera.width)/tileSheet.GetTileW()) + REGION_WIDTH;
int yStart = snapToBase(REGION_HEIGHT, camera.y/tileSheet.GetTileH()) - REGION_HEIGHT;
int yEnd = snapToBase(REGION_HEIGHT, (camera.y+camera.height)/tileSheet.GetTileH()) + REGION_HEIGHT;
//prune distant regions
for (std::list<Region>::iterator it = regionPager.GetContainer()->begin(); it != regionPager.GetContainer()->end(); /* EMPTY */) {
//check if the region is outside of this area
if (it->GetX() < xStart || it->GetX() > xEnd || it->GetY() < yStart || it->GetY() > yEnd) {
//clunky, but the alternative was time consuming
int tmpX = it->GetX();
int tmpY = it->GetY();
++it;
regionPager.UnloadRegion(tmpX, tmpY);
continue;
}
++it;
}
//request empty regions within this zone
for (int i = xStart; i <= xEnd; i += REGION_WIDTH) {
for (int j = yStart; j <= yEnd; j += REGION_HEIGHT) {
if (!regionPager.FindRegion(i, j)) {
RequestRegion(0, i, j);
}
}
}
}
@@ -23,9 +23,7 @@
#define INWORLD_HPP_ #define INWORLD_HPP_
//maps //maps
#include "map_allocator.hpp" #include "region_pager_base.hpp"
#include "map_file_format.hpp"
#include "region_pager.hpp"
//networking //networking
#include "udp_network_utility.hpp" #include "udp_network_utility.hpp"
@@ -37,11 +35,9 @@
#include "tile_sheet.hpp" #include "tile_sheet.hpp"
//common //common
#include "config_utility.hpp"
#include "frame_rate.hpp" #include "frame_rate.hpp"
#include "combat_data.hpp" #include "character.hpp"
#include "character_data.hpp"
//client //client
#include "base_scene.hpp" #include "base_scene.hpp"
@@ -53,13 +49,11 @@ class InWorld : public BaseScene {
public: public:
//Public access members //Public access members
InWorld( InWorld(
ConfigUtility* const argConfig,
UDPNetworkUtility* const argNetwork, UDPNetworkUtility* const argNetwork,
int* const argClientIndex, int* const argClientIndex,
int* const argAccountIndex, int* const argAccountIndex,
int* const argCharacterIndex, int* const argCharacterIndex,
std::map<int, CombatData>* argCombatMap, CharacterMap* argCharacterMap
std::map<int, CharacterData>* argCharacterMap
); );
~InWorld(); ~InWorld();
@@ -80,31 +74,29 @@ protected:
void KeyUp(SDL_KeyboardEvent const&); void KeyUp(SDL_KeyboardEvent const&);
//Network handlers //Network handlers
void HandlePacket(SerialPacket); void HandlePacket(SerialPacket* const);
void HandleDisconnect(SerialPacket); void HandleDisconnect(SerialPacket* const);
void HandleCharacterNew(SerialPacket); void HandleCharacterNew(CharacterPacket* const);
void HandleCharacterDelete(SerialPacket); void HandleCharacterDelete(CharacterPacket* const);
void HandleCharacterUpdate(SerialPacket); void HandleCharacterUpdate(CharacterPacket* const);
void HandleRegionContent(SerialPacket); void HandleRegionContent(RegionPacket* const);
//Server control //Server control
void RequestSynchronize(); void RequestSynchronize();
void SendPlayerUpdate(); void SendPlayerUpdate();
void RequestDisconnect(); void RequestDisconnect();
void RequestShutDown(); void RequestShutDown();
void RequestRegion(int mapIndex, int x, int y); void RequestRegion(int roomIndex, int x, int y);
//utilities //utilities
void UpdateMap(); void UpdateMap();
//shared parameters //shared parameters
ConfigUtility& config;
UDPNetworkUtility& network; UDPNetworkUtility& network;
int& clientIndex; int& clientIndex;
int& accountIndex; int& accountIndex;
int& characterIndex; int& characterIndex;
std::map<int, CombatData>& combatMap; CharacterMap& characterMap;
std::map<int, CharacterData>& characterMap;
//graphics //graphics
Image buttonImage; Image buttonImage;
@@ -112,7 +104,7 @@ protected:
TileSheet tileSheet; TileSheet tileSheet;
//map //map
RegionPager<BlankAllocator, DummyFormat> regionPager; RegionPagerBase regionPager;
//UI //UI
Button disconnectButton; Button disconnectButton;
@@ -126,7 +118,7 @@ protected:
FrameRate fps; FrameRate fps;
//game //game
CharacterData* localCharacter = nullptr; Character* localCharacter = nullptr;
}; };
#endif #endif
@@ -31,17 +31,13 @@
//------------------------- //-------------------------
LobbyMenu::LobbyMenu( LobbyMenu::LobbyMenu(
ConfigUtility* const argConfig,
UDPNetworkUtility* const argNetwork, UDPNetworkUtility* const argNetwork,
int* const argClientIndex, int* const argClientIndex,
int* const argAccountIndex, int* const argAccountIndex
int* const argCharacterIndex
): ):
config(*argConfig),
network(*argNetwork), network(*argNetwork),
clientIndex(*argClientIndex), clientIndex(*argClientIndex),
accountIndex(*argAccountIndex), 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");
@@ -71,6 +67,9 @@ LobbyMenu::LobbyMenu(
//set the server list's position //set the server list's position
listBox = {300, 50, 200, font.GetCharH()}; listBox = {300, 50, 200, font.GetCharH()};
//BUGFIX: Eat incoming packets
while(network.Receive());
} }
LobbyMenu::~LobbyMenu() { LobbyMenu::~LobbyMenu() {
@@ -87,10 +86,11 @@ void LobbyMenu::FrameStart() {
void LobbyMenu::Update(double delta) { void LobbyMenu::Update(double delta) {
//suck in and process all waiting packets //suck in and process all waiting packets
SerialPacket packet; SerialPacket* packetBuffer = static_cast<SerialPacket*>(malloc(MAX_PACKET_SIZE));
while(network.Receive(&packet)) { while(network.Receive(packetBuffer)) {
HandlePacket(packet); HandlePacket(packetBuffer);
} }
free(static_cast<void*>(packetBuffer));
} }
void LobbyMenu::FrameEnd() { void LobbyMenu::FrameEnd() {
@@ -149,7 +149,7 @@ void LobbyMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) {
if (search.MouseButtonUp(button) == Button::State::HOVER) { if (search.MouseButtonUp(button) == Button::State::HOVER) {
//broadcast to the network, or a specific server //broadcast to the network, or a specific server
SerialPacket packet; SerialPacket packet;
packet.meta.type = SerialPacket::Type::BROADCAST_REQUEST; packet.type = SerialPacketType::BROADCAST_REQUEST;
network.SendTo(config["server.host"].c_str(), config.Int("server.port"), &packet); network.SendTo(config["server.host"].c_str(), config.Int("server.port"), &packet);
//reset the server list //reset the server list
@@ -159,11 +159,9 @@ 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) {
//pack the packet //pack the packet
SerialPacket packet; ClientPacket packet;
packet.meta.type = SerialPacket::Type::JOIN_REQUEST; packet.type = SerialPacketType::JOIN_REQUEST;
strncpy(packet.clientInfo.username, config["client.username"].c_str(), PACKET_STRING_SIZE); strncpy(packet.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
network.SendTo(&selection->address, &packet); network.SendTo(&selection->address, &packet);
@@ -176,6 +174,7 @@ void LobbyMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) {
else if ( else if (
//has the user selected a server on the list? //has the user selected a server on the list?
//TODO: replace with regular collision checker
button.x > listBox.x && button.x > listBox.x &&
button.x < listBox.x + listBox.w && button.x < listBox.x + listBox.w &&
button.y > listBox.y && button.y > listBox.y &&
@@ -189,11 +188,7 @@ void LobbyMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) {
} }
void LobbyMenu::KeyDown(SDL_KeyboardEvent const& key) { void LobbyMenu::KeyDown(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) { //
case SDLK_ESCAPE:
SetNextScene(SceneList::MAINMENU);
break;
}
} }
void LobbyMenu::KeyUp(SDL_KeyboardEvent const& key) { void LobbyMenu::KeyUp(SDL_KeyboardEvent const& key) {
@@ -204,34 +199,47 @@ void LobbyMenu::KeyUp(SDL_KeyboardEvent const& key) {
//Network handlers //Network handlers
//------------------------- //-------------------------
void LobbyMenu::HandlePacket(SerialPacket packet) { void LobbyMenu::HandlePacket(SerialPacket* const argPacket) {
switch(packet.meta.type) { switch(argPacket->type) {
case SerialPacket::Type::BROADCAST_RESPONSE: { case SerialPacketType::BROADCAST_RESPONSE:
//extract the data HandleBroadcastResponse(static_cast<ServerPacket*>(argPacket));
ServerInformation server;
server.address = packet.meta.srcAddress;
server.networkVersion = packet.serverInfo.networkVersion;
server.name = packet.serverInfo.name;
server.playerCount = packet.serverInfo.playerCount;
//NOTE: Check compatibility here
server.compatible = server.networkVersion == NETWORK_VERSION;
//push
serverInfo.push_back(server);
}
break; break;
case SerialPacket::Type::JOIN_RESPONSE: case SerialPacketType::JOIN_RESPONSE:
clientIndex = packet.clientInfo.clientIndex; HandleJoinResponse(static_cast<ClientPacket*>(argPacket));
accountIndex = packet.clientInfo.accountIndex;
characterIndex = packet.clientInfo.characterIndex;
network.Bind(&packet.meta.srcAddress, Channels::SERVER);
SetNextScene(SceneList::INWORLD);
break; break;
//handle errors //handle errors
default: default:
throw(std::runtime_error(std::string() + "Unknown SerialPacket::Type encountered in LobbyMenu: " + to_string_custom(int(packet.meta.type)))); throw(std::runtime_error(std::string() + "Unknown SerialPacketType encountered in LobbyMenu: " + to_string_custom(static_cast<int>(argPacket->type)) ));
break; break;
} }
}
void LobbyMenu::HandleBroadcastResponse(ServerPacket* const argPacket) {
//extract the data
ServerInformation server;
server.address = argPacket->srcAddress;
server.name = argPacket->name;
server.playerCount = argPacket->playerCount;
server.version = argPacket->version;
//Checking compatibility
server.compatible = server.version == NETWORK_VERSION;
//push
serverInfo.push_back(server);
}
void LobbyMenu::HandleJoinResponse(ClientPacket* const argPacket) {
clientIndex = argPacket->clientIndex;
accountIndex = argPacket->accountIndex;
network.Bind(&argPacket->srcAddress, Channels::SERVER);
SetNextScene(SceneList::INWORLD);
//send this player's character info
CharacterPacket newPacket;
newPacket.type = SerialPacketType::CHARACTER_NEW;
strncpy(newPacket.handle, config["client.handle"].c_str(), PACKET_STRING_SIZE);
strncpy(newPacket.avatar, config["client.avatar"].c_str(), PACKET_STRING_SIZE);
newPacket.accountIndex = accountIndex;
network.SendTo(Channels::SERVER, &newPacket);
} }
@@ -22,13 +22,13 @@
#ifndef LOBBYMENU_HPP_ #ifndef LOBBYMENU_HPP_
#define LOBBYMENU_HPP_ #define LOBBYMENU_HPP_
//graphics & utilities //graphics & ui
#include "image.hpp" #include "image.hpp"
#include "raster_font.hpp" #include "raster_font.hpp"
#include "button.hpp" #include "button.hpp"
#include "config_utility.hpp"
//network //utilities
#include "config_utility.hpp"
#include "udp_network_utility.hpp" #include "udp_network_utility.hpp"
//client //client
@@ -41,11 +41,9 @@ class LobbyMenu : public BaseScene {
public: public:
//Public access members //Public access members
LobbyMenu( LobbyMenu(
ConfigUtility* const argConfig,
UDPNetworkUtility* const argNetwork, UDPNetworkUtility* const argNetwork,
int* const argClientIndex, int* const argClientIndex,
int* const argAccountIndex, int* const argAccountIndex
int* const argCharacterIndex
); );
~LobbyMenu(); ~LobbyMenu();
@@ -64,14 +62,15 @@ protected:
void KeyUp(SDL_KeyboardEvent const&); void KeyUp(SDL_KeyboardEvent const&);
//Network handlers //Network handlers
void HandlePacket(SerialPacket); void HandlePacket(SerialPacket* const);
void HandleBroadcastResponse(ServerPacket* const);
void HandleJoinResponse(ClientPacket* const);
//shared parameters //shared parameters
ConfigUtility& config; ConfigUtility& config = ConfigUtility::GetSingleton();
UDPNetworkUtility& network; UDPNetworkUtility& network;
int& clientIndex; int& clientIndex;
int& accountIndex; int& accountIndex;
int& characterIndex;
//members //members
Image image; Image image;
@@ -83,9 +82,9 @@ protected:
//server list //server list
struct ServerInformation { struct ServerInformation {
IPaddress address; IPaddress address;
int networkVersion;
std::string name; std::string name;
int playerCount; int playerCount;
int version;
bool compatible; bool compatible;
}; };
@@ -21,13 +21,15 @@
*/ */
#include "main_menu.hpp" #include "main_menu.hpp"
#include "config_utility.hpp"
//------------------------- //-------------------------
//Public access members //Public access members
//------------------------- //-------------------------
MainMenu::MainMenu(ConfigUtility* const argConfig): MainMenu::MainMenu() {
config(*argConfig) ConfigUtility& config = ConfigUtility::GetSingleton();
{
//setup the utility objects //setup the utility objects
image.LoadSurface(config["dir.interface"] + "button_menu.bmp"); image.LoadSurface(config["dir.interface"] + "button_menu.bmp");
image.SetClipH(image.GetClipH()/3); image.SetClipH(image.GetClipH()/3);
@@ -53,6 +55,9 @@ MainMenu::MainMenu(ConfigUtility* const argConfig):
startButton.SetText("Start"); startButton.SetText("Start");
optionsButton.SetText("Options"); optionsButton.SetText("Options");
quitButton.SetText("Quit"); quitButton.SetText("Quit");
//debug
//
} }
MainMenu::~MainMenu() { MainMenu::~MainMenu() {
@@ -98,6 +103,7 @@ void MainMenu::MouseButtonDown(SDL_MouseButtonEvent const& button) {
} }
void MainMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) { void MainMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) {
//TODO: Buttons should only register as "selected" when the left button is used
if (startButton.MouseButtonUp(button) == Button::State::HOVER) { if (startButton.MouseButtonUp(button) == Button::State::HOVER) {
SetNextScene(SceneList::LOBBYMENU); SetNextScene(SceneList::LOBBYMENU);
} }
@@ -110,11 +116,7 @@ void MainMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) {
} }
void MainMenu::KeyDown(SDL_KeyboardEvent const& key) { void MainMenu::KeyDown(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) { //
case SDLK_ESCAPE:
QuitEvent();
break;
}
} }
void MainMenu::KeyUp(SDL_KeyboardEvent const& key) { void MainMenu::KeyUp(SDL_KeyboardEvent const& key) {
@@ -24,7 +24,6 @@
#include "base_scene.hpp" #include "base_scene.hpp"
#include "config_utility.hpp"
#include "image.hpp" #include "image.hpp"
#include "raster_font.hpp" #include "raster_font.hpp"
#include "button.hpp" #include "button.hpp"
@@ -32,7 +31,7 @@
class MainMenu : public BaseScene { class MainMenu : public BaseScene {
public: public:
//Public access members //Public access members
MainMenu(ConfigUtility* const); MainMenu();
~MainMenu(); ~MainMenu();
protected: protected:
@@ -49,9 +48,6 @@ protected:
void KeyDown(SDL_KeyboardEvent const&); void KeyDown(SDL_KeyboardEvent const&);
void KeyUp(SDL_KeyboardEvent const&); void KeyUp(SDL_KeyboardEvent const&);
//shared parameters
ConfigUtility& config;
//members //members
Image image; Image image;
RasterFont font; RasterFont font;
+37
View File
@@ -0,0 +1,37 @@
#config
INCLUDES+=. .. ../../common/gameplay ../../common/graphics ../../common/map ../../common/network ../../common/network/packet ../../common/network/serial ../../common/ui ../../common/utilities
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
#source
CXXSRC=$(wildcard *.cpp)
#objects
OBJDIR=obj
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
#output
OUTDIR=..
OUT=$(addprefix $(OUTDIR)/,client.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
@@ -21,13 +21,15 @@
*/ */
#include "options_menu.hpp" #include "options_menu.hpp"
#include "config_utility.hpp"
//------------------------- //-------------------------
//Public access members //Public access members
//------------------------- //-------------------------
OptionsMenu::OptionsMenu(ConfigUtility* const argConfig): OptionsMenu::OptionsMenu() {
config(*argConfig) ConfigUtility& config = ConfigUtility::GetSingleton();
{
//setup the utility objects //setup the utility objects
image.LoadSurface(config["dir.interface"] + "button_menu.bmp"); image.LoadSurface(config["dir.interface"] + "button_menu.bmp");
image.SetClipH(image.GetClipH()/3); image.SetClipH(image.GetClipH()/3);
@@ -90,11 +92,7 @@ void OptionsMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) {
} }
void OptionsMenu::KeyDown(SDL_KeyboardEvent const& key) { void OptionsMenu::KeyDown(SDL_KeyboardEvent const& key) {
switch(key.keysym.sym) { //
case SDLK_ESCAPE:
SetNextScene(SceneList::MAINMENU);
break;
}
} }
void OptionsMenu::KeyUp(SDL_KeyboardEvent const& key) { void OptionsMenu::KeyUp(SDL_KeyboardEvent const& key) {
@@ -24,15 +24,15 @@
#include "base_scene.hpp" #include "base_scene.hpp"
#include "config_utility.hpp"
#include "image.hpp" #include "image.hpp"
#include "raster_font.hpp" #include "raster_font.hpp"
#include "button.hpp" #include "button.hpp"
//TODO: The options screen needs to be USED
class OptionsMenu : public BaseScene { class OptionsMenu : public BaseScene {
public: public:
//Public access members //Public access members
OptionsMenu(ConfigUtility* const); OptionsMenu();
~OptionsMenu(); ~OptionsMenu();
protected: protected:
@@ -49,9 +49,6 @@ protected:
void KeyDown(SDL_KeyboardEvent const&); void KeyDown(SDL_KeyboardEvent const&);
void KeyUp(SDL_KeyboardEvent const&); void KeyUp(SDL_KeyboardEvent const&);
//shared parameters
ConfigUtility& config;
//members //members
Image image; Image image;
RasterFont font; RasterFont font;
@@ -21,14 +21,14 @@
*/ */
#include "splash_screen.hpp" #include "splash_screen.hpp"
#include "config_utility.hpp"
//------------------------- //-------------------------
//Public access members //Public access members
//------------------------- //-------------------------
SplashScreen::SplashScreen(ConfigUtility* const argConfig): SplashScreen::SplashScreen() {
config(*argConfig) logo.LoadSurface(ConfigUtility::GetSingleton()["dir.logos"] + "krstudios.bmp");
{
logo.LoadSurface(config["dir.logos"] + "krstudios.bmp");
startTick = std::chrono::steady_clock::now(); startTick = std::chrono::steady_clock::now();
} }
@@ -24,7 +24,6 @@
#include "base_scene.hpp" #include "base_scene.hpp"
#include "config_utility.hpp"
#include "image.hpp" #include "image.hpp"
#include <chrono> #include <chrono>
@@ -32,7 +31,7 @@
class SplashScreen : public BaseScene { class SplashScreen : public BaseScene {
public: public:
//Public access members //Public access members
SplashScreen(ConfigUtility* const); SplashScreen();
~SplashScreen(); ~SplashScreen();
protected: protected:
@@ -40,9 +39,6 @@ protected:
void Update(double delta); void Update(double delta);
void Render(SDL_Surface* const); void Render(SDL_Surface* const);
//shared parameters
ConfigUtility& config;
//members //members
std::chrono::steady_clock::time_point startTick; std::chrono::steady_clock::time_point startTick;
Image logo; Image logo;
@@ -1,5 +1,5 @@
#config #config
INCLUDES+=. ../map ../utilities INCLUDES+=.
LIBS+= LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
+45
View File
@@ -0,0 +1,45 @@
/* 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 "timer.hpp"
Timer::Timer(): start(Timer::Clock::now()) {
//
}
Timer::Timer(std::string s): name(s), start(Timer::Clock::now()) {
//
}
void Timer::Start() {
start = Clock::now();
}
void Timer::Stop() {
timeSpan = Clock::now() - start;
}
std::ostream& operator<<(std::ostream& os, Timer& t) {
os << t.GetName() << ": ";
os << std::chrono::duration_cast<std::chrono::milliseconds>(t.GetTime()).count();
os << "ms";
return os;
}
@@ -19,20 +19,36 @@
* 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 SERIAL_HPP_ #ifndef TIMER_HPP_
#define SERIAL_HPP_ #define TIMER_HPP_
#include "serial_packet.hpp" #include <chrono>
#include <string>
#include <ostream>
/* NOTE: Keep the PACKET_BUFFER_SIZE up to date class Timer {
* NOTE: REGION_CONTENT is currently the largest type of packet public:
* map content: REGION_WIDTH * REGION_HEIGHT * REGION_DEPTH * sizoeof(region::type_t) typedef std::chrono::high_resolution_clock Clock;
* map format: sizeof(int) * 3
* metadata: sizeof(SerialPacket::Type)
*/
#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* dest); Timer();
void deserialize(SerialPacket* const, void* src); Timer(std::string s);
~Timer() = default;
inline void Start();
inline void Stop();
//accessors and mutators
Clock::duration GetTime() { return timeSpan; }
std::string SetName(std::string s) { return name = s; }
std::string GetName() { return name; }
private:
std::string name;
Clock::time_point start;
Clock::duration timeSpan;
};
std::ostream& operator<<(std::ostream& os, Timer& t);
#endif #endif
+35
View File
@@ -0,0 +1,35 @@
/* 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 CHARACTERDEFINES_HPP_
#define CHARACTERDEFINES_HPP_
#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);
//the bounding boxes for the characters
constexpr double CHARACTER_BOUNDS_WIDTH = 32.0;
constexpr double CHARACTER_BOUNDS_HEIGHT = 32.0;
#endif
@@ -19,16 +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 "enemy_factory_generic.hpp" #ifndef COMBATDEFINES_HPP_
#define COMBATDEFINES_HPP_
EnemyFactoryGeneric::EnemyFactoryGeneric() : EnemyFactoryInterface() { #define COMBAT_MAX_CHARACTERS 16
//EMPTY #define COMBAT_MAX_ENEMIES 16
}
EnemyFactoryGeneric::~EnemyFactoryGeneric() noexcept { enum class TerrainType {
//EMPTY NONE = 0,
} GRASSLANDS,
//etc.
};
void EnemyFactoryGeneric::Generate(std::list<EnemyData>* container) { #endif
//TODO: fill this out
}
+2 -2
View File
@@ -1,7 +1,7 @@
#config #config
INCLUDES+=. ../utilities ../graphics INCLUDES+=.
LIBS+= LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) -DGRAPHICS CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
#source #source
CXXSRC=$(wildcard *.cpp) CXXSRC=$(wildcard *.cpp)
+1 -1
View File
@@ -1,5 +1,5 @@
#config #config
INCLUDES+=. ../map INCLUDES+=.
LIBS+= LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
+1 -1
View File
@@ -1,9 +1,9 @@
all: all:
$(MAKE) -C debugging
$(MAKE) -C gameplay $(MAKE) -C gameplay
$(MAKE) -C graphics $(MAKE) -C graphics
$(MAKE) -C map $(MAKE) -C map
$(MAKE) -C network $(MAKE) -C network
$(MAKE) -C script
$(MAKE) -C ui $(MAKE) -C ui
$(MAKE) -C utilities $(MAKE) -C utilities
+1 -1
View File
@@ -1,5 +1,5 @@
#config #config
INCLUDES+=. ../utilities INCLUDES+=. ../graphics ../utilities
LIBS+= LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
-60
View File
@@ -1,60 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "map_allocator.hpp"
#include <stdexcept>
void BlankAllocator::Create(Region** const ptr, int x, int y) {
(*ptr) = new Region(x, y);
}
void BlankAllocator::Unload(Region* const ptr) {
delete ptr;
}
void LuaAllocator::Create(Region** const ptr, int x, int y) {
//something to work on
(*ptr) = new Region(x, y);
//API hook
lua_getglobal(state, "map");
lua_getfield(state, -1, "create");
lua_pushlightuserdata(state, *ptr);
if (lua_pcall(state, 1, 0, 0) != LUA_OK) {
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(state, -1) ));
}
lua_pop(state, 1);
}
void LuaAllocator::Unload(Region* const ptr) {
//API hook
lua_getglobal(state, "map");
lua_getfield(state, -1, "unload");
lua_pushlightuserdata(state, ptr);
if (lua_pcall(state, 1, 0, 0) != LUA_OK) {
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(state, -1) ));
}
lua_pop(state, 1);
//clean up the memory
delete ptr;
}
-66
View File
@@ -1,66 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "map_file_format.hpp"
#include <stdexcept>
void DummyFormat::Load(Region** const ptr, int x, int y) {
//EMPTY
}
void DummyFormat::Save(Region* const ptr) {
//EMPTY
}
void LuaFormat::Load(Region** const ptr, int x, int y) {
//something to load into
if (!(*ptr)) {
(*ptr) = new Region(x, y);
}
//API hook
lua_getglobal(state, "map");
lua_getfield(state, -1, "load");
lua_pushlightuserdata(state, *ptr);
lua_pushstring(state, saveDir.c_str());
if (lua_pcall(state, 2, 1, 0) != LUA_OK) {
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(state, -1) ));
}
if (lua_toboolean(state, -1) == false) {
delete (*ptr);
(*ptr) = nullptr;
}
lua_pop(state, 2);
}
void LuaFormat::Save(Region* const ptr) {
//API hook
lua_getglobal(state, "map");
lua_getfield(state, -1, "save");
lua_pushlightuserdata(state, ptr);
lua_pushstring(state, saveDir.c_str());
if (lua_pcall(state, 2, 0, 0) != LUA_OK) {
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(state, -1) ));
}
lua_pop(state, 1);
}
+22 -6
View File
@@ -21,13 +21,21 @@
*/ */
#include "region.hpp" #include "region.hpp"
Region::Region(int argX, int argY): #include "utility.hpp"
x(argX),
y(argY) #include <stdexcept>
{ #include <cstring>
for (register int i = 0; i < REGION_WIDTH*REGION_HEIGHT*REGION_DEPTH; ++i) {
*(reinterpret_cast<type_t*>(tiles) + i) = 0; Region::Region(int argX, int argY): x(argX), y(argY) {
if (x != snapToBase(REGION_WIDTH, x) || y != snapToBase(REGION_HEIGHT, y)) {
throw(std::invalid_argument("Region location is off grid"));
} }
memset(tiles, 0, REGION_WIDTH*REGION_HEIGHT*REGION_DEPTH*sizeof(type_t));
}
Region::Region(Region const& rhs): x(rhs.x), y(rhs.y) {
memcpy(tiles, rhs.tiles, REGION_WIDTH*REGION_HEIGHT*REGION_DEPTH*sizeof(type_t));
solid = rhs.solid;
} }
Region::type_t Region::SetTile(int x, int y, int z, type_t v) { Region::type_t Region::SetTile(int x, int y, int z, type_t v) {
@@ -37,3 +45,11 @@ Region::type_t Region::SetTile(int x, int y, int z, type_t v) {
Region::type_t Region::GetTile(int x, int y, int z) { Region::type_t Region::GetTile(int x, int y, int z) {
return tiles[x][y][z]; return tiles[x][y][z];
} }
bool Region::SetSolid(int x, int y, bool b) {
return solid[x * REGION_WIDTH + y] = b;
}
bool Region::GetSolid(int x, int y) {
return solid[x * REGION_WIDTH + y];
}
+21 -4
View File
@@ -22,29 +22,46 @@
#ifndef REGION_HPP_ #ifndef REGION_HPP_
#define REGION_HPP_ #define REGION_HPP_
#define REGION_WIDTH 20 #include <bitset>
#define REGION_HEIGHT 20 #include <cmath>
#define REGION_DEPTH 3
//the region's storage format
constexpr int REGION_WIDTH = 20;
constexpr int REGION_HEIGHT = 20;
constexpr int REGION_DEPTH = 3;
//the size of the solid map
constexpr int REGION_SOLID_FOOTPRINT = ceil(REGION_WIDTH * REGION_HEIGHT / 8.0);
class Region { class Region {
public: public:
typedef unsigned short type_t; typedef unsigned char type_t;
Region() = delete; Region() = delete;
Region(int x, int y); Region(int x, int y);
Region(Region const&);
~Region() = default; ~Region() = default;
type_t SetTile(int x, int y, int z, type_t v); type_t SetTile(int x, int y, int z, type_t v);
type_t GetTile(int x, int y, int z); type_t GetTile(int x, int y, int z);
bool SetSolid(int x, int y, bool b);
bool GetSolid(int x, int y);
//accessors //accessors
int GetX() const { return x; } int GetX() const { return x; }
int GetY() const { return y; } int GetY() const { return y; }
std::bitset<REGION_WIDTH*REGION_HEIGHT>* GetSolidBitset() { return &solid; }
private: private:
const int x; const int x;
const int y; const int y;
type_t tiles[REGION_WIDTH][REGION_HEIGHT][REGION_DEPTH]; type_t tiles[REGION_WIDTH][REGION_HEIGHT][REGION_DEPTH];
std::bitset<REGION_WIDTH*REGION_HEIGHT> solid;
}; };
//the memory footprint of the tile and solid data; not including any metadata
constexpr int REGION_FOOTPRINT = REGION_WIDTH * REGION_HEIGHT * REGION_DEPTH * sizeof(Region::type_t) + REGION_SOLID_FOOTPRINT;
#endif #endif
+122
View File
@@ -0,0 +1,122 @@
/* 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* region = reinterpret_cast<Region*>(lua_touserdata(L, 1));
int ret = region->SetTile(lua_tointeger(L, 2)-1, lua_tointeger(L, 3)-1, lua_tointeger(L, 4)-1, lua_tointeger(L, 5));
lua_pushinteger(L, ret);
return 1;
}
static int getTile(lua_State* L) {
Region* region = reinterpret_cast<Region*>(lua_touserdata(L, 1));
int ret = region->GetTile(lua_tointeger(L, 2)-1, lua_tointeger(L, 3)-1, lua_tointeger(L, 4)-1);
lua_pushinteger(L, ret);
return 1;
}
static int setSolid(lua_State* L) {
Region* region = reinterpret_cast<Region*>(lua_touserdata(L, 1));
bool ret = region->SetSolid(lua_tointeger(L, 2)-1, lua_tointeger(L, 3)-1, lua_toboolean(L, 4));
lua_pushboolean(L, ret);
return 1;
}
static int getSolid(lua_State* L) {
Region* region = reinterpret_cast<Region*>(lua_touserdata(L, 1));
bool ret = region->GetSolid(lua_tointeger(L, 2)-1, lua_tointeger(L, 3)-1);
lua_pushboolean(L, ret);
return 1;
}
static int getX(lua_State* L) {
Region* region = reinterpret_cast<Region*>(lua_touserdata(L, 1));
lua_pushinteger(L, region->GetX());
return 1;
}
static int getY(lua_State* L) {
Region* region = reinterpret_cast<Region*>(lua_touserdata(L, 1));
lua_pushinteger(L, region->GetY());
return 1;
}
static int getWidth(lua_State* L) {
lua_pushinteger(L, REGION_WIDTH);
return 1;
}
static int getHeight(lua_State* L) {
lua_pushinteger(L, REGION_HEIGHT);
return 1;
}
static int getDepth(lua_State* L) {
lua_pushinteger(L, REGION_DEPTH);
return 1;
}
static int load(lua_State* L) {
//EMPTY
lua_pushboolean(L, false);
return 1;
}
static int save(lua_State* L) {
//EMPTY
return 0;
}
static int create(lua_State* L) {
//EMPTY
return 0;
}
static int unload(lua_State* L) {
//EMPTY
return 0;
}
static const luaL_Reg regionLib[] = {
{"SetTile",setTile},
{"GetTile",getTile},
{"SetSolid",setSolid},
{"GetSolid",getSolid},
{"GetX",getX},
{"GetY",getY},
{"GetWidth",getWidth},
{"GetHeight",getHeight},
{"GetDepth",getDepth},
{"Load",load},
{"Save",save},
{"Create",create},
{"Unload",unload},
{nullptr, nullptr}
};
LUAMOD_API int openRegionAPI(lua_State* L) {
luaL_newlib(L, regionLib);
return 1;
}
@@ -19,30 +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 MAPALLOCATOR_HPP_ #ifndef REGIONAPI_HPP_
#define MAPALLOCATOR_HPP_ #define REGIONAPI_HPP_
#include "region.hpp"
#include "lua/lua.hpp" #include "lua/lua.hpp"
class BlankAllocator { #define TORTUGA_REGION_NAME "Region"
public: LUAMOD_API int openRegionAPI(lua_State* L);
void Create(Region** const, int x, int y);
void Unload(Region* const);
private:
//
};
class LuaAllocator {
public:
void Create(Region** const, int x, int y);
void Unload(Region* const);
lua_State* SetLuaState(lua_State* L) { return state = L; }
lua_State* GetLuaState() { return state; }
private:
lua_State* state = nullptr;
};
#endif #endif
-133
View File
@@ -1,133 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef REGIONPAGER_HPP_
#define REGIONPAGER_HPP_
#include "region.hpp"
#include "utility.hpp"
#include <list>
class RegionPagerBase {
public:
RegionPagerBase() {};
virtual ~RegionPagerBase() {};
//tile manipulation
Region::type_t SetTile(int x, int y, int z, Region::type_t v);
Region::type_t GetTile(int x, int y, int z);
//region manipulation
Region* GetRegion(int x, int y);
Region* FindRegion(int x, int y);
Region* PushRegion(Region*);
//interface
virtual Region* LoadRegion(int x, int y) = 0;
virtual Region* SaveRegion(int x, int y) = 0;
virtual Region* CreateRegion(int x, int y) = 0;
virtual void UnloadRegion(int x, int y) = 0;
//TODO: delete existing regions
//accessors & mutators
std::list<Region*>* GetContainer() { return &regionList; }
protected:
std::list<Region*> regionList;
};
template<typename Allocator, typename FileFormat>
class RegionPager : public RegionPagerBase {
public:
RegionPager() {};
~RegionPager() {
UnloadAll();
}
Region* LoadRegion(int x, int y) {
//snap the coords
x = snapToBase(REGION_WIDTH, x);
y = snapToBase(REGION_HEIGHT, y);
//load the region if possible
Region* ptr = nullptr;
format.Load(&ptr, x, y);
if (ptr) {
return PushRegion(ptr);
}
return nullptr;
}
Region* SaveRegion(int x, int y) {
//snap the coords
x = snapToBase(REGION_WIDTH, x);
y = snapToBase(REGION_HEIGHT, y);
//find & save the region
Region* ptr = FindRegion(x, y);
if (ptr) {
format.Save(ptr);
}
return ptr;
}
Region* CreateRegion(int x, int y) {
//snap the coords
x = snapToBase(REGION_WIDTH, x);
y = snapToBase(REGION_HEIGHT, y);
//create and push the object
Region* ptr = nullptr;
allocator.Create(&ptr, x, y);
return PushRegion(ptr);
}
void UnloadRegion(int x, int y) {
//snap the coords
x = snapToBase(REGION_WIDTH, x);
y = snapToBase(REGION_HEIGHT, y);
//custom loop
for (std::list<Region*>::iterator it = regionList.begin(); it != regionList.end(); /* EMPTY */) {
if ((*it)->GetX() == x && (*it)->GetY() == y) {
allocator.Unload(*it);
it = regionList.erase(it);
continue;
}
++it;
}
}
void UnloadAll() {
for (auto& it : regionList) {
allocator.Unload(it);
}
regionList.clear();
}
//accessors
Allocator* GetAllocator() { return &allocator; }
FileFormat* GetFormat() { return &format; }
protected:
Allocator allocator;
FileFormat format;
};
#endif
+109
View File
@@ -0,0 +1,109 @@
/* 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_pager_api.hpp"
#include "region_pager_lua.hpp"
#include "region.hpp"
#include <string>
//DOCS: These glue functions simply wrap RegionPagerLua's methods
static int setTile(lua_State* L) {
RegionPagerLua* pager = reinterpret_cast<RegionPagerLua*>(lua_touserdata(L, 1));
int ret = pager->SetTile(lua_tointeger(L, 2), lua_tointeger(L, 3), lua_tointeger(L, 4), lua_tointeger(L, 5));
lua_pushinteger(L, ret);
return 1;
}
static int getTile(lua_State* L) {
RegionPagerLua* pager = reinterpret_cast<RegionPagerLua*>(lua_touserdata(L, 1));
int ret = pager->GetTile(lua_tointeger(L, 2), lua_tointeger(L, 3), lua_tointeger(L, 4));
lua_pushinteger(L, ret);
return 1;
}
static int setSolid(lua_State* L) {
RegionPagerLua* pager = reinterpret_cast<RegionPagerLua*>(lua_touserdata(L, 1));
bool ret = pager->SetSolid(lua_tointeger(L, 2), lua_tointeger(L, 3), lua_toboolean(L, 4));
lua_pushboolean(L, ret);
return 1;
}
static int getSolid(lua_State* L) {
RegionPagerLua* pager = reinterpret_cast<RegionPagerLua*>(lua_touserdata(L, 1));
bool ret = pager->GetSolid(lua_tointeger(L, 2), lua_tointeger(L, 3));
lua_pushboolean(L, ret);
return 1;
}
static int getRegion(lua_State* L) {
RegionPagerLua* pager = reinterpret_cast<RegionPagerLua*>(lua_touserdata(L, 1));
Region* region = pager->GetRegion(lua_tointeger(L, 2), lua_tointeger(L, 3));
lua_pushlightuserdata(L, region);
return 1;
}
static int loadRegion(lua_State* L) {
RegionPagerLua* pager = reinterpret_cast<RegionPagerLua*>(lua_touserdata(L, 1));
Region* region = pager->LoadRegion(lua_tointeger(L, 2), lua_tointeger(L, 3));
lua_pushlightuserdata(L, region);
return 1;
}
static int saveRegion(lua_State* L) {
RegionPagerLua* pager = reinterpret_cast<RegionPagerLua*>(lua_touserdata(L, 1));
Region* region = pager->SaveRegion(lua_tointeger(L, 2), lua_tointeger(L, 3));
lua_pushlightuserdata(L, region);
return 1;
}
static int createRegion(lua_State* L) {
RegionPagerLua* pager = reinterpret_cast<RegionPagerLua*>(lua_touserdata(L, 1));
Region* region = pager->CreateRegion(lua_tointeger(L, 2), lua_tointeger(L, 3));
lua_pushlightuserdata(L, region);
return 1;
}
static int unloadRegion(lua_State* L) {
RegionPagerLua* pager = reinterpret_cast<RegionPagerLua*>(lua_touserdata(L, 1));
pager->UnloadRegion(lua_tointeger(L, 2), lua_tointeger(L, 3));
return 0;
}
static const luaL_Reg regionPagerLib[] = {
{"SetTile", setTile},
{"GetTile", getTile},
{"SetSolid", setSolid},
{"GetSolid", getSolid},
{"GetRegion", getRegion},
{"LoadRegion", loadRegion},
{"SaveRegion", saveRegion},
{"CreateRegion", createRegion},
{"UnloadRegion", unloadRegion},
{nullptr, nullptr}
};
LUAMOD_API int openRegionPagerAPI(lua_State* L) {
luaL_newlib(L, regionPagerLib);
return 1;
}
+30
View File
@@ -0,0 +1,30 @@
/* 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 REGIONPAGERAPI_HPP_
#define REGIONPAGERAPI_HPP_
#include "lua/lua.hpp"
#define TORTUGA_REGION_PAGER_NAME "RegionPager"
LUAMOD_API int openRegionPagerAPI(lua_State* L);
#endif
@@ -19,10 +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.
*/ */
#include "region_pager.hpp" #include "region_pager_base.hpp"
#include "utility.hpp" #include "utility.hpp"
#include <stdexcept>
#include <algorithm>
Region::type_t RegionPagerBase::SetTile(int x, int y, int z, Region::type_t v) { Region::type_t RegionPagerBase::SetTile(int x, int y, int z, Region::type_t v) {
Region* ptr = GetRegion(x, y); Region* ptr = GetRegion(x, y);
return ptr->SetTile(x - ptr->GetX(), y - ptr->GetY(), z, v); return ptr->SetTile(x - ptr->GetX(), y - ptr->GetY(), z, v);
@@ -33,8 +36,17 @@ Region::type_t RegionPagerBase::GetTile(int x, int y, int z) {
return ptr->GetTile(x - ptr->GetX(), y - ptr->GetY(), z); return ptr->GetTile(x - ptr->GetX(), y - ptr->GetY(), z);
} }
bool RegionPagerBase::SetSolid(int x, int y, int b) {
Region* ptr = GetRegion(x, y);
return ptr->SetSolid(x - ptr->GetX(), y - ptr->GetY(), b);
}
bool RegionPagerBase::GetSolid(int x, int y) {
Region* ptr = GetRegion(x, y);
return ptr->GetSolid(x - ptr->GetX(), y - ptr->GetY());
}
Region* RegionPagerBase::GetRegion(int x, int y) { Region* RegionPagerBase::GetRegion(int x, int y) {
//snap the coords
x = snapToBase(REGION_WIDTH, x); x = snapToBase(REGION_WIDTH, x);
y = snapToBase(REGION_HEIGHT, y); y = snapToBase(REGION_HEIGHT, y);
@@ -48,20 +60,41 @@ Region* RegionPagerBase::GetRegion(int x, int y) {
} }
Region* RegionPagerBase::FindRegion(int x, int y) { Region* RegionPagerBase::FindRegion(int x, int y) {
//snap the coords
x = snapToBase(REGION_WIDTH, x);
y = snapToBase(REGION_HEIGHT, y);
//find the region //find the region
for (std::list<Region*>::iterator it = regionList.begin(); it != regionList.end(); it++) { std::list<Region>::iterator it = find_if(regionList.begin(), regionList.end(), [x, y](Region& region) -> bool {
if ((*it)->GetX() == x && (*it)->GetY() == y) { return region.GetX() == x && region.GetY() == y;
return *it; });
} return it != regionList.end() ? &(*it) : nullptr;
} }
Region* RegionPagerBase::PushRegion(Region* const ptr) {
regionList.push_front(*ptr);
return &regionList.front();
}
Region* RegionPagerBase::LoadRegion(int x, int y) {
//TODO: load the region if possible
return nullptr; return nullptr;
} }
Region* RegionPagerBase::PushRegion(Region* ptr) { Region* RegionPagerBase::SaveRegion(int x, int y) {
regionList.push_front(ptr); //TODO: find & save the region
return regionList.front(); return nullptr;
}
Region* RegionPagerBase::CreateRegion(int x, int y) {
if (FindRegion(x, y)) {
throw(std::logic_error("Cannot overwrite an existing region"));
}
regionList.emplace_front(x, y);
return &regionList.front();
}
void RegionPagerBase::UnloadRegion(int x, int y) {
//custom loop, not FindRegion()
regionList.remove_if([x, y](Region& region) -> bool { return region.GetX() == x && region.GetY() == y; });
}
void RegionPagerBase::UnloadAll() {
regionList.clear();
} }
+60
View File
@@ -0,0 +1,60 @@
/* 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 REGIONPAGERBASE_HPP_
#define REGIONPAGERBASE_HPP_
#include "region.hpp"
#include <list>
class RegionPagerBase {
public:
RegionPagerBase() = default;
virtual ~RegionPagerBase() { UnloadAll(); };
//tile manipulation
virtual Region::type_t SetTile(int x, int y, int z, Region::type_t v);
virtual Region::type_t GetTile(int x, int y, int z);
//solid manipulation
virtual bool SetSolid(int x, int y, int b);
virtual bool GetSolid(int x, int y);
//region manipulation
virtual Region* GetRegion(int x, int y);
virtual Region* FindRegion(int x, int y);
virtual Region* PushRegion(Region* const);
virtual Region* LoadRegion(int x, int y);
virtual Region* SaveRegion(int x, int y);
virtual Region* CreateRegion(int x, int y);
virtual void UnloadRegion(int x, int y);
virtual void UnloadAll();
//accessors & mutators
std::list<Region>* GetContainer() { return &regionList; }
protected:
std::list<Region> regionList;
};
#endif
+123
View File
@@ -0,0 +1,123 @@
/* 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_pager_lua.hpp"
#include "utility.hpp"
#include <stdexcept>
Region* RegionPagerLua::LoadRegion(int x, int y) {
//load the region if possible
//something to work on
Region tmpRegion(x, y);
//API hook
lua_getglobal(lua, "Region");
lua_getfield(lua, -1, "Load");
lua_pushlightuserdata(lua, &tmpRegion);
if (lua_pcall(lua, 1, 1, 0) != LUA_OK) {
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) ));
}
//success or failure
if (!lua_toboolean(lua, -1)) {
lua_pop(lua, 2);
return nullptr;
}
lua_pop(lua, 2);
regionList.push_front(tmpRegion);
return &regionList.front();
}
Region* RegionPagerLua::SaveRegion(int x, int y) {
//find & save the region
Region* ptr = FindRegion(x, y);
if (ptr) {
//API hook
lua_getglobal(lua, "Region");
lua_getfield(lua, -1, "Save");
lua_pushlightuserdata(lua, ptr);
if (lua_pcall(lua, 1, 0, 0) != LUA_OK) {
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) ));
}
lua_pop(lua, 1);
}
return ptr;
}
Region* RegionPagerLua::CreateRegion(int x, int y) {
if (FindRegion(x, y)) {
throw(std::logic_error("Cannot overwrite an existing region"));
}
//something to work on
Region tmpRegion(x, y);
//API hook
lua_getglobal(lua, "Region");
lua_getfield(lua, -1, "Create");
lua_pushlightuserdata(lua, &tmpRegion);
//TODO: parameters
if (lua_pcall(lua, 1, 0, 0) != LUA_OK) {
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) ));
}
lua_pop(lua, 1);
regionList.push_front(tmpRegion);
return &regionList.front();
}
void RegionPagerLua::UnloadRegion(int x, int y) {
lua_getglobal(lua, "Region");
regionList.remove_if([&](Region& region) -> bool {
if (region.GetX() == x && region.GetY() == y) {
//API hook
lua_getfield(lua, -1, "Unload");
lua_pushlightuserdata(lua, &region);
if (lua_pcall(lua, 1, 0, 0) != LUA_OK) {
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) ));
}
return true;
}
return false;
});
lua_pop(lua, 1);
}
void RegionPagerLua::UnloadAll() {
lua_getglobal(lua, "Region");
for (auto& it : regionList) {
//API hook
lua_getfield(lua, -1, "Unload");
lua_pushlightuserdata(lua, &it);
if (lua_pcall(lua, 1, 0, 0) != LUA_OK) {
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) ));
}
}
lua_pop(lua, 1);
regionList.clear();
}
+51
View File
@@ -0,0 +1,51 @@
/* 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 REGIONPAGERLUA_HPP_
#define REGIONPAGERLUA_HPP_
#include "region_pager_base.hpp"
#include "lua/lua.hpp"
#include <string>
class RegionPagerLua : public RegionPagerBase {
public:
RegionPagerLua() = default;
~RegionPagerLua() = default;
//region manipulation
Region* LoadRegion(int x, int y) override;
Region* SaveRegion(int x, int y) override;
Region* CreateRegion(int x, int y) override;
void UnloadRegion(int x, int y) override;
void UnloadAll() override;
//accessors & mutators
lua_State* SetLuaState(lua_State* L) { return lua = L; }
lua_State* GetLuaState() { return lua; }
protected:
lua_State* lua = nullptr;
};
#endif
@@ -21,24 +21,24 @@
*/ */
#include "tile_sheet.hpp" #include "tile_sheet.hpp"
void TileSheet::Load(std::string fname, int xc, int yc) { void TileSheet::Load(std::string fname, int tileWidth, int tileHeight) {
XCount = xc;
YCount = yc;
image.LoadSurface(fname); image.LoadSurface(fname);
image.SetClipW(image.GetClipW()/XCount); image.SetClipW(tileWidth);
image.SetClipH(image.GetClipH()/YCount); image.SetClipH(tileHeight);
xCount = image.GetSurface()->w / image.GetClipW();
yCount = image.GetSurface()->h / image.GetClipH();
} }
void TileSheet::Unload() { void TileSheet::Unload() {
image.FreeSurface(); image.FreeSurface();
XCount = YCount = 0; xCount = yCount = 0;
} }
void TileSheet::DrawTo(SDL_Surface* const dest, int x, int y, Region::type_t tile) { void TileSheet::DrawTileTo(SDL_Surface* const dest, int x, int y, Region::type_t tile) {
//0 is invisible //0 is invisible
if (tile == 0) return; if (tile == 0) return;
image.SetClipX((tile-1) % XCount * image.GetClipW()); image.SetClipX((tile-1) % xCount * image.GetClipW());
image.SetClipY((tile-1) / XCount * image.GetClipH()); image.SetClipY((tile-1) / xCount * image.GetClipH());
image.DrawTo(dest, x, y); image.DrawTo(dest, x, y);
} }
@@ -50,8 +50,8 @@ void TileSheet::DrawRegionTo(SDL_Surface* const dest, Region* const region, int
tile = region->GetTile(i, j, k); tile = region->GetTile(i, j, k);
//0 is invisible //0 is invisible
if (tile == 0) continue; if (tile == 0) continue;
image.SetClipX((tile-1) % XCount * image.GetClipW()); image.SetClipX((tile-1) % xCount * image.GetClipW());
image.SetClipY((tile-1) / XCount * image.GetClipH()); image.SetClipY((tile-1) / xCount * image.GetClipH());
image.DrawTo(dest, image.DrawTo(dest,
(region->GetX() + i) * image.GetClipW() - camX, (region->GetX() + i) * image.GetClipW() - camX,
(region->GetY() + j) * image.GetClipH() - camY); (region->GetY() + j) * image.GetClipH() - camY);
@@ -31,24 +31,24 @@
class TileSheet { class TileSheet {
public: public:
TileSheet() = default; TileSheet() = default;
TileSheet(std::string f, int x, int y) { Load(f, x, y); } TileSheet(std::string f, int w, int h) { Load(f, w, h); }
~TileSheet() = default; ~TileSheet() = default;
void Load(std::string fname, int XCount, int YCount); void Load(std::string fname, int tileWidth, int tileHeight);
void Unload(); void Unload();
void DrawTo(SDL_Surface* const dest, int x, int y, Region::type_t tile); void DrawTileTo(SDL_Surface* const dest, int x, int y, Region::type_t tile);
void DrawRegionTo(SDL_Surface* const dest, Region* const region, int camX, int camY); void DrawRegionTo(SDL_Surface* const dest, Region* const region, int camX, int camY);
//accessors //accessors
Image* GetImage() { return &image; } Image* GetImage() { return &image; }
int GetXCount() { return XCount; } int GetXCount() { return xCount; }
int GetYCount() { return YCount; } int GetYCount() { return yCount; }
int GetTileW() { return image.GetClipW(); } int GetTileW() { return image.GetClipW(); }
int GetTileH() { return image.GetClipH(); } int GetTileH() { return image.GetClipH(); }
private: private:
Image image; Image image;
int XCount = 0, YCount = 0; int xCount = 0, yCount = 0;
}; };
#endif #endif
+75
View File
@@ -0,0 +1,75 @@
/* 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 "tile_sheet_api.hpp"
#include "tile_sheet.hpp"
static int load(lua_State* L) {
TileSheet* sheet = reinterpret_cast<TileSheet*>(lua_touserdata(L, 1));
sheet->Load(lua_tostring(L, 2), lua_tointeger(L, 3), lua_tointeger(L, 4));
return 0;
}
static int unload(lua_State* L) {
TileSheet* sheet = reinterpret_cast<TileSheet*>(lua_touserdata(L, 1));
sheet->Unload();
return 0;
}
static int getXCount(lua_State* L) {
TileSheet* sheet = reinterpret_cast<TileSheet*>(lua_touserdata(L, 1));
lua_pushinteger(L, sheet->GetXCount());
return 1;
}
static int getYCount(lua_State* L) {
TileSheet* sheet = reinterpret_cast<TileSheet*>(lua_touserdata(L, 1));
lua_pushinteger(L, sheet->GetYCount());
return 1;
}
static int getTileW(lua_State* L) {
TileSheet* sheet = reinterpret_cast<TileSheet*>(lua_touserdata(L, 1));
lua_pushinteger(L, sheet->GetTileW());
return 1;
}
static int getTileH(lua_State* L) {
TileSheet* sheet = reinterpret_cast<TileSheet*>(lua_touserdata(L, 1));
lua_pushinteger(L, sheet->GetTileH());
return 1;
}
static const luaL_Reg tileSheetLib[] = {
{"Load",load},
{"Unload",unload},
{"GetXCount",getXCount},
{"GetYCount",getYCount},
{"GetTileW",getTileW},
{"GetTileH",getTileH},
{nullptr, nullptr}
};
LUAMOD_API int openTileSheetAPI(lua_State* L) {
luaL_newlib(L, tileSheetLib);
return 1;
}
+30
View File
@@ -0,0 +1,30 @@
/* 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 TILESHEETAPI_HPP_
#define TILESHEETAPI_HPP_
#include "lua/lua.hpp"
#define TORTUGA_TILE_SHEET_NAME "TileSheet"
LUAMOD_API int openTileSheetAPI(lua_State* L);
#endif
+3 -1
View File
@@ -1,5 +1,5 @@
#config #config
INCLUDES+=. ../gameplay ../map ../utilities INCLUDES+=. packet serial ../gameplay ../map ../utilities
LIBS+= LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
@@ -17,6 +17,8 @@ OUT=$(addprefix $(OUTDIR)/,libcommon.a)
#targets #targets
all: $(OBJ) $(OUT) all: $(OBJ) $(OUT)
ar -crs $(OUT) $(OBJ) ar -crs $(OUT) $(OBJ)
$(MAKE) -C packet
$(MAKE) -C serial
$(OBJ): | $(OBJDIR) $(OBJ): | $(OBJDIR)
@@ -0,0 +1,50 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef CHARACTERPACKET_HPP_
#define CHARACTERPACKET_HPP_
#include "serial_packet_base.hpp"
#include "vector2.hpp"
#include "statistics.hpp"
struct CharacterPacket : SerialPacketBase {
//identify the character
int characterIndex;
char handle[PACKET_STRING_SIZE];
char avatar[PACKET_STRING_SIZE];
//the owner
int accountIndex;
//location
int roomIndex;
Vector2 origin;
Vector2 motion;
//gameplay
Statistics stats;
//TODO: gameplay components: equipment, items, buffs, debuffs
};
#endif
+34
View File
@@ -0,0 +1,34 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef CLIENTPACKET_HPP_
#define CLIENTPACKET_HPP_
#include "serial_packet_base.hpp"
struct ClientPacket : SerialPacketBase {
int clientIndex;
int accountIndex;
char username[PACKET_STRING_SIZE];
// char password[PACKET_STRING_SIZE]; //hashed, not currently used
};
#endif
+46
View File
@@ -0,0 +1,46 @@
/* 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 COMBATPACKET_HPP_
#define COMBATPACKET_HPP_
#include "serial_packet_base.hpp"
#include "combat_defines.hpp"
struct CombatPacket : SerialPacketBase {
//identify the combat instance
int combatIndex;
int difficulty;
TerrainType terrainType;
//combatants
int characterArray[COMBAT_MAX_CHARACTERS];
int enemyArray[COMBAT_MAX_ENEMIES];
//location
int mapIndex;
Vector2 origin;
//TODO: gameplay components: rewards
};
#endif
+39
View File
@@ -0,0 +1,39 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef ENEMYPACKET_HPP_
#define ENEMYPACKET_HPP_
#include "serial_packet_base.hpp"
struct EnemyPacket : SerialPacketBase {
//identify the enemy
int enemyIndex;
char handle[PACKET_STRING_SIZE];
char avatar[PACKET_STRING_SIZE];
//gameplay
Statistics stats;
//TODO: gameplay components: equipment, items, buffs, debuffs, rewards
};
#endif
+37
View File
@@ -0,0 +1,37 @@
#config
INCLUDES+=. ../../gameplay ../../map ../../utilities
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
#source
CXXSRC=$(wildcard *.cpp)
#objects
OBJDIR=obj
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
#output
OUTDIR=../../..
OUT=$(addprefix $(OUTDIR)/,libcommon.a)
#targets
all: $(OBJ) $(OUT)
ar -crs $(OUT) $(OBJ)
$(OBJ): | $(OBJDIR)
$(OUT): | $(OUTDIR)
$(OBJDIR):
mkdir $(OBJDIR)
$(OUTDIR):
mkdir $(OUTDIR)
$(OBJDIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
clean:
$(RM) *.o *.a *.exe
rebuild: clean all
+38
View File
@@ -0,0 +1,38 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef REGIONPACKET_HPP_
#define REGIONPACKET_HPP_
#include "serial_packet_base.hpp"
#include "region.hpp"
struct RegionPacket : SerialPacketBase {
//location/identify the region
int roomIndex;
int x, y;
//the data
Region* region;
};
#endif
@@ -1,4 +1,4 @@
/* Copyright: (c) Kayne Ruse 2014 /* Copyright: (c) Kayne Ruse 2013, 2014
* *
* This software is provided 'as-is', without any express or implied * 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,18 +19,10 @@
* 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 "account_data.hpp" #include "serial_packet.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 /* DOCS: Sanity check, read more
* Since most/all of the files in this directory are header files, I've created * 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 * this source file as a "sanity check", to ensure that the above header files
* are written correctly via make. * are written correctly via make.
* */
* Oddly enough, I'm pretty sure this is the first directory compiled in a
* clean build.
*/
+44
View File
@@ -0,0 +1,44 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef SERIALPACKET_HPP_
#define SERIALPACKET_HPP_
#include "character_packet.hpp"
#include "client_packet.hpp"
#include "combat_packet.hpp"
#include "enemy_packet.hpp"
#include "region_packet.hpp"
#include "server_packet.hpp"
//NOTE: SerialPacket is defined in serial_packet_base.hpp
union MaxPacket {
CharacterPacket a;
ClientPacket b;
CombatPacket c;
EnemyPacket d;
RegionPacket e;
ServerPacket f;
};
constexpr int MAX_PACKET_SIZE = sizeof(MaxPacket);
#endif
@@ -0,0 +1,46 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef SERIALPACKETBASE_HPP_
#define SERIALPACKETBASE_HPP_
#ifndef SERIALPACKET_HPP_
#error Cannot include this file without 'serial_packet.hpp'
#endif
#include "serial_packet_type.hpp"
#include "SDL/SDL_net.h"
constexpr int NETWORK_VERSION = 20140701;
constexpr int PACKET_STRING_SIZE = 100;
struct SerialPacketBase {
//members
SerialPacketType type;
IPaddress srcAddress;
virtual ~SerialPacketBase() {};
};
typedef SerialPacketBase SerialPacket;
#endif
@@ -0,0 +1,113 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef SERIALPACKETTYPE_HPP_
#define SERIALPACKETTYPE_HPP_
/* Key for the comments:
* request => response
*/
enum class SerialPacketType {
//default: there is something wrong
NONE = 0,
//keep alive
//ping => pong
PING = 1,
PONG = 2,
//search for the server list
//none => server name, player count, version info (and source address)
BROADCAST_REQUEST = 3,
BROADCAST_RESPONSE = 4,
//try to join the server
//username, and password => client index, account index
JOIN_REQUEST = 5,
JOIN_RESPONSE = 6,
JOIN_REJECTION = 7,
//mass update of all surrounding content
//character.x, character.y => packet barrage
SYNCHRONIZE = 8,
//disconnect from the server
//autentication, account index => disconnect that account
DISCONNECT = 9,
//shut down the server
//autentication => disconnect, shutdown
SHUTDOWN = 10,
//map data
//room index, region.x, region.y => room index, region.x, region.y, region content
REGION_REQUEST = 11,
REGION_CONTENT = 12,
//combat data
//TODO: system incomplete
COMBAT_NEW = 13,
COMBAT_DELETE = 14,
COMBAT_UPDATE = 15,
COMBAT_ENTER_REQUEST = 16,
COMBAT_ENTER_RESPONSE = 17,
COMBAT_EXIT_REQUEST = 18,
COMBAT_EXIT_RESPONSE = 19,
//TODO: COMBAT info
COMBAT_REJECTION = 20,
//character data
//character data => etc.
CHARACTER_NEW = 21,
CHARACTER_DELETE = 22,
CHARACTER_UPDATE = 23,
//authentication, character index => character stats
CHARACTER_STATS_REQUEST= 24,
CHARACTER_STATS_RESPONSE = 25,
//character new => character rejection, disconnect?
CHARACTER_REJECTION = 26,
//enemy data
//enemy data => etc.
ENEMY_NEW = 27,
ENEMY_DELETE = 28,
ENEMY_UPDATE = 29,
ENEMY_STATS_REQUEST = 30,
ENEMY_STATS_RESPONSE = 31,
//enemy index => enemy doens't exist
ENEMY_REJECTION= 32,
//NOTE: more packet types go here
//not used
LAST
};
#endif
+34
View File
@@ -0,0 +1,34 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef SERVERPACKET_HPP_
#define SERVERPACKET_HPP_
#include "serial_packet_base.hpp"
struct ServerPacket : SerialPacketBase {
//identify the server
char name[PACKET_STRING_SIZE];
int playerCount;
int version;
};
#endif
-433
View File
@@ -1,433 +0,0 @@
/* Copyright: (c) Kayne Ruse 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "serial.hpp"
#include "map_allocator.hpp"
#include "statistics.hpp"
#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
//-------------------------
void serializeType(SerialPacket* packet, char* buffer) {
SERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type));
}
void serializeServer(SerialPacket* packet, char* buffer) {
SERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type));
//server info
SERIALIZE(buffer, &packet->serverInfo.networkVersion, sizeof(int));
SERIALIZE(buffer, packet->serverInfo.name, PACKET_STRING_SIZE);
SERIALIZE(buffer, &packet->serverInfo.playerCount, sizeof(int));
}
void serializeClient(SerialPacket* packet, char* buffer) {
SERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type));
//indexes
SERIALIZE(buffer, &packet->clientInfo.clientIndex, sizeof(int));
SERIALIZE(buffer, &packet->clientInfo.accountIndex, sizeof(int));
SERIALIZE(buffer, &packet->clientInfo.characterIndex, sizeof(int));
//texts
SERIALIZE(buffer, packet->clientInfo.username, PACKET_STRING_SIZE);
//TODO: password
SERIALIZE(buffer, packet->clientInfo.handle, PACKET_STRING_SIZE);
SERIALIZE(buffer, packet->clientInfo.avatar, PACKET_STRING_SIZE);
}
void serializeRegionFormat(SerialPacket* packet, char* buffer) {
SERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type));
//format
SERIALIZE(buffer, &packet->regionInfo.mapIndex, sizeof(int));
SERIALIZE(buffer, &packet->regionInfo.x, sizeof(int));
SERIALIZE(buffer, &packet->regionInfo.y, sizeof(int));
}
void serializeRegionContent(SerialPacket* packet, char* buffer) {
SERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type));
//format
SERIALIZE(buffer, &packet->regionInfo.mapIndex, sizeof(int));
SERIALIZE(buffer, &packet->regionInfo.x, sizeof(int));
SERIALIZE(buffer, &packet->regionInfo.y, sizeof(int));
//content
for (register int i = 0; i < REGION_WIDTH; i++) {
for (register int j = 0; j < REGION_HEIGHT; j++) {
for (register int k = 0; k < REGION_DEPTH; k++) {
*reinterpret_cast<Region::type_t*>(buffer) = packet->regionInfo.region->GetTile(i, j, k);
buffer += sizeof(Region::type_t);
}
}
}
}
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
//-------------------------
void deserializeType(SerialPacket* packet, char* buffer) {
DESERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type));
}
void deserializeServer(SerialPacket* packet, char* buffer) {
DESERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type));
//server info
DESERIALIZE(buffer, &packet->serverInfo.networkVersion, sizeof(int));
DESERIALIZE(buffer, packet->serverInfo.name, PACKET_STRING_SIZE);
DESERIALIZE(buffer, &packet->serverInfo.playerCount, sizeof(int));
}
void deserializeClient(SerialPacket* packet, char* buffer) {
DESERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type));
//indexes
DESERIALIZE(buffer, &packet->clientInfo.clientIndex, sizeof(int));
DESERIALIZE(buffer, &packet->clientInfo.accountIndex, sizeof(int));
DESERIALIZE(buffer, &packet->clientInfo.characterIndex, sizeof(int));
//texts
DESERIALIZE(buffer, packet->clientInfo.username, PACKET_STRING_SIZE);
//TODO: password
DESERIALIZE(buffer, packet->clientInfo.handle, PACKET_STRING_SIZE);
DESERIALIZE(buffer, packet->clientInfo.avatar, PACKET_STRING_SIZE);
}
void deserializeRegionFormat(SerialPacket* packet, char* buffer) {
DESERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type));
//format
DESERIALIZE(buffer, &packet->regionInfo.mapIndex, sizeof(int));
DESERIALIZE(buffer, &packet->regionInfo.x, sizeof(int));
DESERIALIZE(buffer, &packet->regionInfo.y, sizeof(int));
}
void deserializeRegionContent(SerialPacket* packet, char* buffer) {
DESERIALIZE(buffer, &packet->meta.type, sizeof(SerialPacket::Type));
//format
DESERIALIZE(buffer, &packet->regionInfo.mapIndex, sizeof(int));
DESERIALIZE(buffer, &packet->regionInfo.x, sizeof(int));
DESERIALIZE(buffer, &packet->regionInfo.y, sizeof(int));
//an object to work on
BlankAllocator().Create(
&packet->regionInfo.region,
packet->regionInfo.x,
packet->regionInfo.y
);
//content
for (register int i = 0; i < REGION_WIDTH; i++) {
for (register int j = 0; j < REGION_HEIGHT; j++) {
for (register int k = 0; k < REGION_DEPTH; k++) {
packet->regionInfo.region->SetTile(i, j, k, *reinterpret_cast<Region::type_t*>(buffer));
buffer += sizeof(Region::type_t);
}
}
}
}
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
//-------------------------
void serialize(SerialPacket* packet, void* buffer) {
switch(packet->meta.type) {
//no extra data
case SerialPacket::Type::NONE:
case SerialPacket::Type::PING:
case SerialPacket::Type::PONG:
case SerialPacket::Type::BROADCAST_REQUEST:
//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));
break;
//server info
case SerialPacket::Type::BROADCAST_RESPONSE:
serializeServer(packet, reinterpret_cast<char*>(buffer));
break;
//client info
case SerialPacket::Type::JOIN_REQUEST:
case SerialPacket::Type::JOIN_RESPONSE:
case SerialPacket::Type::SYNCHRONIZE:
case SerialPacket::Type::DISCONNECT:
case SerialPacket::Type::SHUTDOWN:
serializeClient(packet, reinterpret_cast<char*>(buffer));
break;
//region info
case SerialPacket::Type::REGION_REQUEST:
serializeRegionFormat(packet, reinterpret_cast<char*>(buffer));
break;
case SerialPacket::Type::REGION_CONTENT:
serializeRegionContent(packet, reinterpret_cast<char*>(buffer));
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;
}
}
void deserialize(SerialPacket* packet, void* buffer) {
//find the type, so that you can actually deserialize the packet!
deserializeType(packet, reinterpret_cast<char*>(buffer));
switch(packet->meta.type) {
//no extra data
case SerialPacket::Type::NONE:
case SerialPacket::Type::PING:
case SerialPacket::Type::PONG:
case SerialPacket::Type::BROADCAST_REQUEST:
//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
break;
//server info
case SerialPacket::Type::BROADCAST_RESPONSE:
deserializeServer(packet, reinterpret_cast<char*>(buffer));
break;
//client info
case SerialPacket::Type::JOIN_REQUEST:
case SerialPacket::Type::JOIN_RESPONSE:
case SerialPacket::Type::SYNCHRONIZE:
case SerialPacket::Type::DISCONNECT:
case SerialPacket::Type::SHUTDOWN:
deserializeClient(packet, reinterpret_cast<char*>(buffer));
break;
//region info
case SerialPacket::Type::REGION_REQUEST:
deserializeRegionFormat(packet, reinterpret_cast<char*>(buffer));
break;
case SerialPacket::Type::REGION_CONTENT:
deserializeRegionContent(packet, reinterpret_cast<char*>(buffer));
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;
}
}
+37
View File
@@ -0,0 +1,37 @@
#config
INCLUDES+=. ../packet ../../gameplay ../../map ../../utilities
LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
#source
CXXSRC=$(wildcard *.cpp)
#objects
OBJDIR=obj
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
#output
OUTDIR=../../..
OUT=$(addprefix $(OUTDIR)/,libcommon.a)
#targets
all: $(OBJ) $(OUT)
ar -crs $(OUT) $(OBJ)
$(OBJ): | $(OBJDIR)
$(OUT): | $(OUTDIR)
$(OBJDIR):
mkdir $(OBJDIR)
$(OUTDIR):
mkdir $(OUTDIR)
$(OBJDIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
clean:
$(RM) *.o *.a *.exe
rebuild: clean all
+182
View File
@@ -0,0 +1,182 @@
/* Copyright: (c) Kayne Ruse 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "serial.hpp"
#include "serial_util.hpp"
//simple type functions
void serializeType(SerialPacketBase* packet, void* buffer) {
SERIALIZE(buffer, &packet->type, sizeof(SerialPacketType));
}
void deserializeType(SerialPacketBase* packet, void* buffer) {
DESERIALIZE(buffer, &packet->type, sizeof(SerialPacketType));
}
//main switch functions
void serializePacket(SerialPacketBase* packet, void* buffer) {
switch(packet->type) {
//no extra data
case SerialPacketType::NONE:
case SerialPacketType::PING:
case SerialPacketType::PONG:
case SerialPacketType::BROADCAST_REQUEST:
//all rejections
case SerialPacketType::JOIN_REJECTION:
case SerialPacketType::CHARACTER_REJECTION:
case SerialPacketType::ENEMY_REJECTION:
case SerialPacketType::COMBAT_REJECTION:
serializeType(packet, buffer);
break;
//character info
case SerialPacketType::CHARACTER_NEW:
case SerialPacketType::CHARACTER_DELETE:
case SerialPacketType::CHARACTER_UPDATE:
case SerialPacketType::CHARACTER_STATS_REQUEST:
case SerialPacketType::CHARACTER_STATS_RESPONSE:
serializeCharacter(static_cast<CharacterPacket*>(packet), buffer);
break;
//client info
case SerialPacketType::JOIN_REQUEST:
case SerialPacketType::JOIN_RESPONSE:
case SerialPacketType::SYNCHRONIZE:
case SerialPacketType::DISCONNECT:
case SerialPacketType::SHUTDOWN:
serializeClient(static_cast<ClientPacket*>(packet), buffer);
break;
//combat info
case SerialPacketType::COMBAT_NEW:
case SerialPacketType::COMBAT_DELETE:
case SerialPacketType::COMBAT_UPDATE:
case SerialPacketType::COMBAT_ENTER_REQUEST:
case SerialPacketType::COMBAT_ENTER_RESPONSE:
case SerialPacketType::COMBAT_EXIT_REQUEST:
case SerialPacketType::COMBAT_EXIT_RESPONSE:
serializeCombat(static_cast<CombatPacket*>(packet), buffer);
break;
//enemy info
case SerialPacketType::ENEMY_NEW:
case SerialPacketType::ENEMY_DELETE:
case SerialPacketType::ENEMY_UPDATE:
case SerialPacketType::ENEMY_STATS_REQUEST:
case SerialPacketType::ENEMY_STATS_RESPONSE:
serializeEnemy(static_cast<EnemyPacket*>(packet), buffer);
break;
//region info
case SerialPacketType::REGION_REQUEST:
serializeRegionFormat(static_cast<RegionPacket*>(packet), buffer);
break;
case SerialPacketType::REGION_CONTENT:
serializeRegionContent(static_cast<RegionPacket*>(packet), buffer);
break;
//server info
case SerialPacketType::BROADCAST_RESPONSE:
serializeServer(static_cast<ServerPacket*>(packet), buffer);
break;
}
}
void deserializePacket(SerialPacketBase* packet, void* buffer) {
//find the type, so that you can actually deserialize the packet!
deserializeType(packet, buffer);
switch(packet->type) {
//no extra data
case SerialPacketType::NONE:
case SerialPacketType::PING:
case SerialPacketType::PONG:
case SerialPacketType::BROADCAST_REQUEST:
//all rejections
case SerialPacketType::JOIN_REJECTION:
case SerialPacketType::CHARACTER_REJECTION:
case SerialPacketType::ENEMY_REJECTION:
case SerialPacketType::COMBAT_REJECTION:
//NOTHING
break;
//character info
case SerialPacketType::CHARACTER_NEW:
case SerialPacketType::CHARACTER_DELETE:
case SerialPacketType::CHARACTER_UPDATE:
case SerialPacketType::CHARACTER_STATS_REQUEST:
case SerialPacketType::CHARACTER_STATS_RESPONSE:
deserializeCharacter(static_cast<CharacterPacket*>(packet), buffer);
break;
//client info
case SerialPacketType::JOIN_REQUEST:
case SerialPacketType::JOIN_RESPONSE:
case SerialPacketType::SYNCHRONIZE:
case SerialPacketType::DISCONNECT:
case SerialPacketType::SHUTDOWN:
deserializeClient(static_cast<ClientPacket*>(packet), buffer);
break;
//combat info
case SerialPacketType::COMBAT_NEW:
case SerialPacketType::COMBAT_DELETE:
case SerialPacketType::COMBAT_UPDATE:
case SerialPacketType::COMBAT_ENTER_REQUEST:
case SerialPacketType::COMBAT_ENTER_RESPONSE:
case SerialPacketType::COMBAT_EXIT_REQUEST:
case SerialPacketType::COMBAT_EXIT_RESPONSE:
serializeCombat(static_cast<CombatPacket*>(packet), buffer);
break;
//enemy info
case SerialPacketType::ENEMY_NEW:
case SerialPacketType::ENEMY_DELETE:
case SerialPacketType::ENEMY_UPDATE:
case SerialPacketType::ENEMY_STATS_REQUEST:
case SerialPacketType::ENEMY_STATS_RESPONSE:
serializeEnemy(static_cast<EnemyPacket*>(packet), buffer);
break;
//region info
case SerialPacketType::REGION_REQUEST:
deserializeRegionFormat(static_cast<RegionPacket*>(packet), buffer);
break;
case SerialPacketType::REGION_CONTENT:
deserializeRegionContent(static_cast<RegionPacket*>(packet), buffer);
break;
//server info
case SerialPacketType::BROADCAST_RESPONSE:
deserializeServer(static_cast<ServerPacket*>(packet), buffer);
break;
}
}
+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.
*/
#ifndef SERIALIZE_HPP_
#define SERIALIZE_HPP_
#include "serial_packet.hpp"
#include "region.hpp"
#include "statistics.hpp"
//Primary interface functions
void serializePacket(SerialPacketBase*, void* dest);
void deserializePacket(SerialPacketBase*, void* src);
void serializeType(SerialPacketBase*, void*);
void deserializeType(SerialPacketBase*, void*);
//utility functions, exposed
void serializeCharacter(CharacterPacket*, void*);
void serializeClient(ClientPacket*, void*);
void serializeCombat(CombatPacket*, void*);
void serializeEnemy(EnemyPacket*, void*);
void serializeRegionFormat(RegionPacket*, void*);
void serializeRegionContent(RegionPacket*, void*);
void serializeServer(ServerPacket*, void*);
void serializeStatistics(Statistics*, void*);
void deserializeCharacter(CharacterPacket*, void*);
void deserializeClient(ClientPacket*, void*);
void deserializeCombat(CombatPacket*, void*);
void deserializeEnemy(EnemyPacket*, void*);
void deserializeRegionFormat(RegionPacket*, void*);
void deserializeRegionContent(RegionPacket*, void*);
void deserializeServer(ServerPacket*, void*);
void deserializeStatistics(Statistics*, void*);
/* DOCS: Keep PACKET_BUFFER_SIZE up to date
* DOCS: SerialPacketType::REGION_CONTENT is currently the largest type of packet, read more
* The metadata used are:
* SerialPacketType
* room index
* X & Y positon
* The rest is taken up by the Regions's content.
*/
constexpr int PACKET_BUFFER_SIZE = sizeof(SerialPacketType) + sizeof(int) * 3 + REGION_FOOTPRINT;
#endif
@@ -0,0 +1,74 @@
/* Copyright: (c) Kayne Ruse 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "serial.hpp"
#include "serial_util.hpp"
void serializeCharacter(CharacterPacket* packet, void* buffer) {
SERIALIZE(buffer, &packet->type, sizeof(SerialPacketType));
//identify the character
SERIALIZE(buffer, &packet->characterIndex, sizeof(int));
SERIALIZE(buffer, &packet->handle, PACKET_STRING_SIZE);
SERIALIZE(buffer, &packet->avatar, PACKET_STRING_SIZE);
//the owner
SERIALIZE(buffer, &packet->accountIndex, sizeof(int));
//location
SERIALIZE(buffer, &packet->roomIndex, sizeof(int));
SERIALIZE(buffer, &packet->origin.x, sizeof(double));
SERIALIZE(buffer, &packet->origin.y, sizeof(double));
SERIALIZE(buffer, &packet->motion.x, sizeof(double));
SERIALIZE(buffer, &packet->motion.y, sizeof(double));
//stats structure
serializeStatistics(&packet->stats, buffer);
buffer = reinterpret_cast<char*>(buffer) + sizeof(Statistics);
//TODO: gameplay components: equipment, items, buffs, debuffs
}
void deserializeCharacter(CharacterPacket* packet, void* buffer) {
DESERIALIZE(buffer, &packet->type, sizeof(SerialPacketType));
//identify the character
DESERIALIZE(buffer, &packet->characterIndex, sizeof(int));
DESERIALIZE(buffer, &packet->handle, PACKET_STRING_SIZE);
DESERIALIZE(buffer, &packet->avatar, PACKET_STRING_SIZE);
//the owner
DESERIALIZE(buffer, &packet->accountIndex, sizeof(int));
//location
DESERIALIZE(buffer, &packet->roomIndex, sizeof(int));
DESERIALIZE(buffer, &packet->origin.x, sizeof(double));
DESERIALIZE(buffer, &packet->origin.y, sizeof(double));
DESERIALIZE(buffer, &packet->motion.x, sizeof(double));
DESERIALIZE(buffer, &packet->motion.y, sizeof(double));
//stats structure
deserializeStatistics(&packet->stats, buffer);
buffer = reinterpret_cast<char*>(buffer) + sizeof(Statistics);
//TODO: gameplay components: equipment, items, buffs, debuffs
}
+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.
*/
#include "serial.hpp"
#include "serial_util.hpp"
void serializeClient(ClientPacket* packet, void* buffer) {
SERIALIZE(buffer, &packet->type, sizeof(SerialPacketType));
SERIALIZE(buffer, &packet->clientIndex, sizeof(int));
SERIALIZE(buffer, &packet->accountIndex, sizeof(int));
SERIALIZE(buffer, &packet->username, PACKET_STRING_SIZE);
// SERIALIZE(buffer, &packet->password, PACKET_STRING_SIZE);
}
void deserializeClient(ClientPacket* packet, void* buffer) {
DESERIALIZE(buffer, &packet->type, sizeof(SerialPacketType));
DESERIALIZE(buffer, &packet->clientIndex, sizeof(int));
DESERIALIZE(buffer, &packet->accountIndex, sizeof(int));
DESERIALIZE(buffer, &packet->username, PACKET_STRING_SIZE);
// DESERIALIZE(buffer, &packet->password, PACKET_STRING_SIZE);
}
+64
View File
@@ -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.
*/
#include "serial.hpp"
#include "serial_util.hpp"
void serializeCombat(CombatPacket* packet, void* buffer) {
SERIALIZE(buffer, &packet->type, sizeof(SerialPacketType));
//identify the combat instance
SERIALIZE(buffer, &packet->combatIndex, sizeof(int));
SERIALIZE(buffer, &packet->difficulty, sizeof(int));
SERIALIZE(buffer, &packet->terrainType, sizeof(TerrainType));
//combatants
SERIALIZE(buffer, &packet->characterArray, sizeof(int) * COMBAT_MAX_CHARACTERS);
SERIALIZE(buffer, &packet->enemyArray, sizeof(int) * COMBAT_MAX_ENEMIES);
//location
SERIALIZE(buffer, &packet->mapIndex, sizeof(int));
SERIALIZE(buffer, &packet->origin.x, sizeof(double));
SERIALIZE(buffer, &packet->origin.y, sizeof(double));
//TODO: gameplay components: rewards
}
void deserializeCombat(CombatPacket* packet, void* buffer) {
DESERIALIZE(buffer, &packet->type, sizeof(SerialPacketType));
//identify the combat instance
DESERIALIZE(buffer, &packet->combatIndex, sizeof(int));
DESERIALIZE(buffer, &packet->difficulty, sizeof(int));
DESERIALIZE(buffer, &packet->terrainType, sizeof(TerrainType));
//combatants
DESERIALIZE(buffer, &packet->characterArray, sizeof(int) * COMBAT_MAX_CHARACTERS);
DESERIALIZE(buffer, &packet->enemyArray, sizeof(int) * COMBAT_MAX_ENEMIES);
//location
DESERIALIZE(buffer, &packet->mapIndex, sizeof(int));
DESERIALIZE(buffer, &packet->origin.x, sizeof(double));
DESERIALIZE(buffer, &packet->origin.y, sizeof(double));
//TODO: gameplay components: rewards
}
+56
View File
@@ -0,0 +1,56 @@
/* Copyright: (c) Kayne Ruse 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "serial.hpp"
#include "serial_util.hpp"
void serializeEnemy(EnemyPacket* packet, void* buffer) {
SERIALIZE(buffer, &packet->type, sizeof(SerialPacketType));
//identify the enemy
SERIALIZE(buffer, &packet->enemyIndex, sizeof(int));
SERIALIZE(buffer, &packet->handle, PACKET_STRING_SIZE);
SERIALIZE(buffer, &packet->avatar, PACKET_STRING_SIZE);
//gameplay
//stats structure
serializeStatistics(&packet->stats, buffer);
buffer = reinterpret_cast<char*>(buffer) + sizeof(Statistics);
//TODO: gameplay components: equipment, items, buffs, debuffs, rewards
}
void deserializeEnemy(EnemyPacket* packet, void* buffer) {
DESERIALIZE(buffer, &packet->type, sizeof(SerialPacketType));
//identify the enemy
DESERIALIZE(buffer, &packet->enemyIndex, sizeof(int));
DESERIALIZE(buffer, &packet->handle, PACKET_STRING_SIZE);
DESERIALIZE(buffer, &packet->avatar, PACKET_STRING_SIZE);
//stats structure
deserializeStatistics(&packet->stats, buffer);
buffer = reinterpret_cast<char*>(buffer) + sizeof(Statistics);
//TODO: gameplay components: equipment, items, buffs, debuffs, rewards
}
+89
View File
@@ -0,0 +1,89 @@
/* Copyright: (c) Kayne Ruse 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "serial.hpp"
#include "serial_util.hpp"
void serializeRegionFormat(RegionPacket* packet, void* buffer) {
SERIALIZE(buffer, &packet->type, sizeof(SerialPacketType));
//format
SERIALIZE(buffer, &packet->roomIndex, sizeof(int));
SERIALIZE(buffer, &packet->x, sizeof(int));
SERIALIZE(buffer, &packet->y, sizeof(int));
}
void serializeRegionContent(RegionPacket* packet, void* buffer) {
SERIALIZE(buffer, &packet->type, sizeof(SerialPacketType));
//format
SERIALIZE(buffer, &packet->roomIndex, sizeof(int));
SERIALIZE(buffer, &packet->x, sizeof(int));
SERIALIZE(buffer, &packet->y, sizeof(int));
//tiles
for (register int i = 0; i < REGION_WIDTH; i++) {
for (register int j = 0; j < REGION_HEIGHT; j++) {
for (register int k = 0; k < REGION_DEPTH; k++) {
*reinterpret_cast<Region::type_t*>(buffer) = packet->region->GetTile(i, j, k);
buffer = reinterpret_cast<char*>(buffer) + sizeof(Region::type_t);
}
}
}
//solids
SERIALIZE(buffer, packet->region->GetSolidBitset(), REGION_SOLID_FOOTPRINT);
}
void deserializeRegionFormat(RegionPacket* packet, void* buffer) {
DESERIALIZE(buffer, &packet->type, sizeof(SerialPacketType));
//format
DESERIALIZE(buffer, &packet->roomIndex, sizeof(int));
DESERIALIZE(buffer, &packet->x, sizeof(int));
DESERIALIZE(buffer, &packet->y, sizeof(int));
}
void deserializeRegionContent(RegionPacket* packet, void* buffer) {
DESERIALIZE(buffer, &packet->type, sizeof(SerialPacketType));
//format
DESERIALIZE(buffer, &packet->roomIndex, sizeof(int));
DESERIALIZE(buffer, &packet->x, sizeof(int));
DESERIALIZE(buffer, &packet->y, sizeof(int));
//an object to work on
packet->region = new Region(packet->x, packet->y);
//tiles
for (register int i = 0; i < REGION_WIDTH; i++) {
for (register int j = 0; j < REGION_HEIGHT; j++) {
for (register int k = 0; k < REGION_DEPTH; k++) {
packet->region->SetTile(i, j, k, *reinterpret_cast<Region::type_t*>(buffer));
buffer = reinterpret_cast<char*>(buffer) + sizeof(Region::type_t);
}
}
}
//solids
DESERIALIZE(buffer, packet->region->GetSolidBitset(), REGION_SOLID_FOOTPRINT);
}
+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.
*/
#include "serial.hpp"
#include "serial_util.hpp"
void serializeServer(ServerPacket* packet, void* buffer) {
SERIALIZE(buffer, &packet->type, sizeof(SerialPacketType));
//identify the server
SERIALIZE(buffer, &packet->name, PACKET_STRING_SIZE);
SERIALIZE(buffer, &packet->playerCount, sizeof(int));
SERIALIZE(buffer, &packet->version, sizeof(int));
}
void deserializeServer(ServerPacket* packet, void* buffer) {
DESERIALIZE(buffer, &packet->type, sizeof(SerialPacketType));
//identify the server
DESERIALIZE(buffer, &packet->name, PACKET_STRING_SIZE);
DESERIALIZE(buffer, &packet->playerCount, sizeof(int));
DESERIALIZE(buffer, &packet->version, sizeof(int));
}
@@ -0,0 +1,65 @@
/* Copyright: (c) Kayne Ruse 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "serial.hpp"
#include "serial_util.hpp"
void serializeStatistics(Statistics* stats, void* buffer) {
//integers
SERIALIZE(buffer, &stats->level, sizeof(int));
SERIALIZE(buffer, &stats->exp, sizeof(int));
SERIALIZE(buffer, &stats->maxHP, sizeof(int));
SERIALIZE(buffer, &stats->health, sizeof(int));
SERIALIZE(buffer, &stats->maxMP, sizeof(int));
SERIALIZE(buffer, &stats->mana, sizeof(int));
SERIALIZE(buffer, &stats->attack, sizeof(int));
SERIALIZE(buffer, &stats->defence, sizeof(int));
SERIALIZE(buffer, &stats->intelligence, sizeof(int));
SERIALIZE(buffer, &stats->resistance, sizeof(int));
SERIALIZE(buffer, &stats->speed, sizeof(int));
//floats
SERIALIZE(buffer, &stats->accuracy, sizeof(float));
SERIALIZE(buffer, &stats->evasion, sizeof(float));
SERIALIZE(buffer, &stats->luck, sizeof(float));
}
void deserializeStatistics(Statistics* stats, void* buffer) {
//integers
DESERIALIZE(buffer, &stats->level, sizeof(int));
DESERIALIZE(buffer, &stats->exp, sizeof(int));
DESERIALIZE(buffer, &stats->maxHP, sizeof(int));
DESERIALIZE(buffer, &stats->health, sizeof(int));
DESERIALIZE(buffer, &stats->maxMP, sizeof(int));
DESERIALIZE(buffer, &stats->mana, sizeof(int));
DESERIALIZE(buffer, &stats->attack, sizeof(int));
DESERIALIZE(buffer, &stats->defence, sizeof(int));
DESERIALIZE(buffer, &stats->intelligence, sizeof(int));
DESERIALIZE(buffer, &stats->resistance, sizeof(int));
DESERIALIZE(buffer, &stats->speed, sizeof(int));
//floats
DESERIALIZE(buffer, &stats->accuracy, sizeof(float));
DESERIALIZE(buffer, &stats->evasion, sizeof(float));
DESERIALIZE(buffer, &stats->luck, sizeof(float));
}
+31
View File
@@ -0,0 +1,31 @@
/* Copyright: (c) Kayne Ruse 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef SERIALIZEUTIL_HPP_
#define SERIALIZEUTIL_HPP_
#include <cstring>
//NOTE: The strange assignments here used in order to move the void* parameter
#define SERIALIZE(buffer, data, size) memcpy(buffer, data, size); buffer = reinterpret_cast<char*>(buffer) + size;
#define DESERIALIZE(buffer, data, size) memcpy(data, buffer, size); buffer = reinterpret_cast<char*>(buffer) + size;
#endif
-175
View File
@@ -1,175 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef SERIALPACKET_HPP_
#define SERIALPACKET_HPP_
#include "vector2.hpp"
#include "region.hpp"
#include "statistics.hpp"
#include "SDL/SDL_net.h"
#define NETWORK_VERSION 20140528
#define PACKET_STRING_SIZE 100
union SerialPacket {
//types of packets
enum class Type {
//default: there is something wrong
NONE = 0,
//keep alive
PING = 1,
PONG = 2,
//searching for a server to join
BROADCAST_REQUEST = 3,
BROADCAST_RESPONSE = 4,
BROADCAST_REJECTION = 5,
//try to join the server
JOIN_REQUEST = 6,
JOIN_RESPONSE = 7,
JOIN_REJECTION = 8,
//mass update
SYNCHRONIZE = 9,
//disconnect from the server
DISCONNECT = 10,
//shut down the server
SHUTDOWN = 11,
//map data
REGION_REQUEST = 12,
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
struct Metadata {
Type type;
IPaddress srcAddress;
}meta;
//info about the server
struct ServerInformation {
Metadata meta;
int networkVersion;
char name[PACKET_STRING_SIZE];
int playerCount;
}serverInfo;
//info about the client
struct ClientInformation {
Metadata meta;
int clientIndex;
int accountIndex;
int characterIndex;
char username[PACKET_STRING_SIZE];
//TODO: password
char handle[PACKET_STRING_SIZE];
char avatar[PACKET_STRING_SIZE];
}clientInfo;
//info about a region
struct RegionInformation {
Metadata meta;
int mapIndex;
int x, y;
Region* region;
}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
SerialPacket() {
meta.type = Type::NONE;
meta.srcAddress = {0,0};
}
};
#endif
+6 -6
View File
@@ -25,7 +25,7 @@
#include <stdexcept> #include <stdexcept>
//DOCS: memset() is used before sending a packet to remove old data; you don't want to send sensitive data over the network //BUGFIX: memset() is used before sending a packet to remove old data; you don't want to send sensitive data over the network
//NOTE: don't confuse SerialPacket with UDPpacket //NOTE: don't confuse SerialPacket with UDPpacket
void UDPNetworkUtility::Open(int port) { void UDPNetworkUtility::Open(int port) {
@@ -166,7 +166,7 @@ int UDPNetworkUtility::SendTo(const char* ip, int port, SerialPacket* serialPack
int UDPNetworkUtility::SendTo(IPaddress* add, SerialPacket* serialPacket) { int UDPNetworkUtility::SendTo(IPaddress* add, SerialPacket* serialPacket) {
memset(packet->data, 0, packet->maxlen); memset(packet->data, 0, packet->maxlen);
serialize(serialPacket, packet->data); serializePacket(serialPacket, packet->data);
packet->len = PACKET_BUFFER_SIZE; packet->len = PACKET_BUFFER_SIZE;
packet->address = *add; packet->address = *add;
@@ -181,7 +181,7 @@ int UDPNetworkUtility::SendTo(IPaddress* add, SerialPacket* serialPacket) {
int UDPNetworkUtility::SendTo(int channel, SerialPacket* serialPacket) { int UDPNetworkUtility::SendTo(int channel, SerialPacket* serialPacket) {
memset(packet->data, 0, packet->maxlen); memset(packet->data, 0, packet->maxlen);
serialize(serialPacket, packet->data); serializePacket(serialPacket, packet->data);
packet->len = PACKET_BUFFER_SIZE; packet->len = PACKET_BUFFER_SIZE;
int ret = SDLNet_UDP_Send(socket, channel, packet); int ret = SDLNet_UDP_Send(socket, channel, packet);
@@ -195,7 +195,7 @@ int UDPNetworkUtility::SendTo(int channel, SerialPacket* serialPacket) {
int UDPNetworkUtility::SendToAllChannels(SerialPacket* serialPacket) { int UDPNetworkUtility::SendToAllChannels(SerialPacket* serialPacket) {
memset(packet->data, 0, packet->maxlen); memset(packet->data, 0, packet->maxlen);
serialize(serialPacket, packet->data); serializePacket(serialPacket, packet->data);
packet->len = PACKET_BUFFER_SIZE; packet->len = PACKET_BUFFER_SIZE;
int sent = 0; int sent = 0;
@@ -213,8 +213,8 @@ int UDPNetworkUtility::SendToAllChannels(SerialPacket* serialPacket) {
int UDPNetworkUtility::Receive(SerialPacket* serialPacket) { int UDPNetworkUtility::Receive(SerialPacket* serialPacket) {
memset(packet->data, 0, packet->maxlen); memset(packet->data, 0, packet->maxlen);
int ret = SDLNet_UDP_Recv(socket, packet); int ret = SDLNet_UDP_Recv(socket, packet);
deserialize(serialPacket, packet->data); deserializePacket(serialPacket, packet->data);
serialPacket->meta.srcAddress = packet->address; serialPacket->srcAddress = packet->address;
if (ret < 0) { if (ret < 0) {
throw(std::runtime_error("Unknown network error occured")); throw(std::runtime_error("Unknown network error occured"));
-72
View File
@@ -1,72 +0,0 @@
/*
** $Id: linit.c,v 1.32 2011/04/08 19:17:36 roberto Exp $
** Initialization of libraries for lua.c and other clients
** See Copyright Notice in lua.h
*/
/* Modified for use in Tortuga, renamed to linit.cpp
*/
/*
** If you embed Lua in your program and need to open the standard
** libraries, call luaL_openlibs in your program. If you need a
** different set of libraries, copy this file to your project and edit
** it to suit your needs.
*/
#define linit_c
#define LUA_LIB
#include "lua/lua.hpp"
#include "map_api.hpp"
/*
** these libs are loaded by lua.c and are readily available to any Lua
** program
*/
static const luaL_Reg loadedlibs[] = {
/* Standard libs */
{"_G", luaopen_base},
{LUA_LOADLIBNAME, luaopen_package},
{LUA_COLIBNAME, luaopen_coroutine},
{LUA_TABLIBNAME, luaopen_table},
{LUA_IOLIBNAME, luaopen_io},
{LUA_OSLIBNAME, luaopen_os},
{LUA_STRLIBNAME, luaopen_string},
{LUA_BITLIBNAME, luaopen_bit32},
{LUA_MATHLIBNAME, luaopen_math},
{LUA_DBLIBNAME, luaopen_debug},
/* custom libs */
{LUA_MAPLIBNAME, luaopen_mapapi},
{NULL, NULL}
};
/*
** these libs are preloaded and must be required before used
*/
static const luaL_Reg preloadedlibs[] = {
{NULL, NULL}
};
LUALIB_API void luaL_openlibs (lua_State *L) {
const luaL_Reg *lib;
/* call open functions from 'loadedlibs' and set results to global table */
for (lib = loadedlibs; lib->func; lib++) {
luaL_requiref(L, lib->name, lib->func, 1);
lua_pop(L, 1); /* remove lib */
}
/* add open functions from 'preloadedlibs' into 'package.preload' table */
luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD");
for (lib = preloadedlibs; lib->func; lib++) {
lua_pushcfunction(L, lib->func);
lua_setfield(L, -2, lib->name);
}
lua_pop(L, 1); /* remove _PRELOAD table */
}
-126
View File
@@ -1,126 +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 "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;
}
+1
View File
@@ -36,6 +36,7 @@
* This class needs a rewrite. * This class needs a rewrite.
*/ */
//TODO: This thing is fucking terrible, fix it and the button class
class MenuBar { class MenuBar {
public: public:
MenuBar() = default; MenuBar() = default;
@@ -19,57 +19,59 @@
* 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 BBOX_HPP_ #ifndef BOUNDINGBOX_HPP_
#define BBOX_HPP_ #define BOUNDINGBOX_HPP_
#include <type_traits> #include <type_traits>
#include <stdexcept>
#include <algorithm> #include <algorithm>
//TODO: This is supposed to interact with the vector class BoundingBox {
class BBox {
public: public:
double x, y; //This is explicitly a POD
double w, h; int x, y;
int w, h;
BBox() = default; BoundingBox() = default;
BBox(double i, double j, double k, double l): x(i), y(j), w(k), h(l) {}; BoundingBox(int i, int j, int k, int l): x(i), y(j), w(k), h(l) {};
~BBox() = default; ~BoundingBox() = default;
BBox& operator=(BBox const&) = default; BoundingBox& operator=(BoundingBox const&) = default;
double Size() { int Size() {
return std::max(w*h,0.0); return std::max(w*h,0);
} }
bool IsCollision(BBox rhs) { bool CheckOverlap(BoundingBox rhs) {
return not ( return !(
x >= rhs.x + rhs.w || x >= rhs.x + rhs.w ||
y >= rhs.y + rhs.h || y >= rhs.y + rhs.h ||
rhs.x >= x + w || rhs.x >= x + w ||
rhs.y >= y + h rhs.y >= y + h);
);
} }
BBox Intersection(BBox rhs) { BoundingBox CalcOverlap(BoundingBox rhs) {
if (!IsCollision(rhs)) { if (!CheckOverlap(rhs)) {
return {0, 0, 0, 0}; return {0, 0, 0, 0};
} }
BBox ret; BoundingBox ret;
ret.x = std::max(x, rhs.x); ret.x = std::max(x, rhs.x);
ret.y = std::max(y, rhs.y); ret.y = std::max(y, rhs.y);
ret.w = std::min(x+w, rhs.x+rhs.w) - ret.x; ret.w = std::min(x+w, rhs.x+rhs.w) - ret.x;
ret.h = std::min(y+h, rhs.y+rhs.h) - ret.y; ret.h = std::min(y+h, rhs.y+rhs.h) - ret.y;
return ret; return ret;
} }
double operator[](size_t i) {
if (i >= 4)
throw(std::domain_error("Out of range"));
return *(&x+i);
}
}; };
//This is explicitly a POD //This is explicitly a POD
static_assert(std::is_pod<BBox>::value, "BBox is not a POD"); static_assert(std::is_pod<Vector2>::value, "BoundingBox is not a POD");
#endif #include "vector2.hpp"
//operators
inline BoundingBox operator+(BoundingBox b, Vector2 v) {
return {b.x + (int)v.x, b.y + (int)v.y, b.w, b.h};
}
inline BoundingBox operator+(Vector2 v, BoundingBox b) {
return b + v;
}
#endif
+40
View File
@@ -0,0 +1,40 @@
/* Copyright: (c) Kayne Ruse 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "check_bounds.hpp"
bool checkPoint(Vector2 const& origin, Vector2 const& bound, Vector2 const& point) {
return !(
point.x < origin.x ||
point.y < origin.y ||
point.x >= origin.x + bound.x ||
point.y >= origin.y + bound.y
);
}
bool checkOverlap(Vector2 const& originOne, Vector2 const& boundOne, Vector2 const& originTwo, Vector2 const& boundTwo) {
return !(
originOne.x >= originTwo.x + boundTwo.x ||
originOne.x + boundOne.x >= originTwo.x ||
originOne.y >= originTwo.y + boundTwo.y ||
originOne.y + boundOne.y >= originTwo.y
);
}
+30
View File
@@ -0,0 +1,30 @@
/* Copyright: (c) Kayne Ruse 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef CHECKBOUNDS_HPP_
#define CHECKBOUNDS_HPP_
#include "vector2.hpp"
bool checkPoint(Vector2 const& origin, Vector2 const& bound, Vector2 const& point);
bool checkOverlap(Vector2 const& originOne, Vector2 const& boundOne, Vector2 const& originTwo, Vector2 const& boundTwo);
#endif
+42 -17
View File
@@ -25,25 +25,37 @@
#include <fstream> #include <fstream>
#include <stdexcept> #include <stdexcept>
using namespace std; void ConfigUtility::Load(std::string fname) {
//clear the stored configuration
configMap.clear();
//pass to the recursive method
configMap = Read(fname);
}
void ConfigUtility::Load(string fname) { ConfigUtility::table_t ConfigUtility::Read(std::string fname) {
ifstream is(fname); //read in and return this file's data
table_t retTable;
std::ifstream is(fname);
if (!is.is_open()) { if (!is.is_open()) {
throw(runtime_error("Failed to open config file")); std::string msg;
msg += "Failed to open a config file: ";
msg += fname;
throw(std::runtime_error(msg));
} }
string key, val; std::string key, val;
for (;;) { //forever while(true) { //forever
//eat whitespace //eat whitespace
while(isspace(is.peek())) while(isspace(is.peek())) {
is.ignore(); is.ignore();
}
//end of file //end of file
if (is.eof()) if (is.eof()) {
break; break;
}
//skip comment lines //skip comment lines
if (is.peek() == '#') { if (is.peek() == '#') {
@@ -64,41 +76,54 @@ void ConfigUtility::Load(string fname) {
while(key.size() && isspace(*(key.end()-1))) key.erase(key.end() - 1); while(key.size() && isspace(*(key.end()-1))) key.erase(key.end() - 1);
while(val.size() && isspace(*(val.end()-1))) val.erase(val.end() - 1); while(val.size() && isspace(*(val.end()-1))) val.erase(val.end() - 1);
//allow empty/wiped values //disallow empty/wiped values
if (key.size() == 0) { if (key.size() == 0) {
continue; continue;
} }
//save the pair //save the pair
table[key] = val; retTable[key] = val;
} }
is.close(); is.close();
//load in any subordinate config files
//TODO: Possibility of nesting config levels?
if (retTable.find("config.next") != retTable.end()) {
table_t subTable = Read(retTable["config.next"]);
retTable.insert(subTable.begin(), subTable.end());
}
return retTable;
} }
//-------------------------
//Convert to a type
//-------------------------
std::string& ConfigUtility::String(std::string s) { std::string& ConfigUtility::String(std::string s) {
return table[s]; return configMap[s];
} }
int ConfigUtility::Integer(std::string s) { int ConfigUtility::Integer(std::string s) {
std::map<std::string, std::string>::iterator it = table.find(s); table_t::iterator it = configMap.find(s);
if (it == table.end()) { if (it == configMap.end()) {
return 0; return 0;
} }
return atoi(it->second.c_str()); return atoi(it->second.c_str());
} }
double ConfigUtility::Double(std::string s) { double ConfigUtility::Double(std::string s) {
std::map<std::string, std::string>::iterator it = table.find(s); table_t::iterator it = configMap.find(s);
if (it == table.end()) { if (it == configMap.end()) {
return 0.0; return 0.0;
} }
return atof(it->second.c_str()); return atof(it->second.c_str());
} }
bool ConfigUtility::Boolean(std::string s) { bool ConfigUtility::Boolean(std::string s) {
std::map<std::string, std::string>::iterator it = table.find(s); table_t::iterator it = configMap.find(s);
if (it == table.end()) { if (it == configMap.end()) {
return false; return false;
} }
return it->second == "true"; return it->second == "true";
+16 -18
View File
@@ -22,14 +22,13 @@
#ifndef CONFIGUTILITY_HPP_ #ifndef CONFIGUTILITY_HPP_
#define CONFIGUTILITY_HPP_ #define CONFIGUTILITY_HPP_
#include "singleton.hpp"
#include <map> #include <map>
#include <string> #include <string>
class ConfigUtility { class ConfigUtility : public Singleton<ConfigUtility> {
public: public:
ConfigUtility() = default;
ConfigUtility(std::string s) { Load(s); }
void Load(std::string fname); void Load(std::string fname);
//convert to a type //convert to a type
@@ -39,22 +38,21 @@ public:
bool Boolean(std::string); bool Boolean(std::string);
//shorthand //shorthand
std::string& operator[](std::string s) { inline std::string& operator[](std::string s) { return configMap[s]; }
return String(s); inline int Int(std::string s) { return Integer(s); }
} inline bool Bool(std::string s) { return Boolean(s); }
int Int(std::string s) {
return Integer(s);
}
bool Bool(std::string s) {
return Boolean(s);
}
//OO breaker
std::map<std::string, std::string>* GetMap() {
return &table;
}
private: private:
std::map<std::string, std::string> table; typedef std::map<std::string, std::string> table_t;
friend Singleton<ConfigUtility>;
ConfigUtility() = default;
~ConfigUtility() = default;
table_t Read(std::string fname);
table_t configMap;
}; };
#endif #endif
+63
View File
@@ -0,0 +1,63 @@
/* 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 SINGLETON_HPP_
#define SINGLETON_HPP_
#include <stdexcept>
template<typename T>
class Singleton {
public:
static T& GetSingleton() {
if (!ptr) {
throw(std::logic_error("This singleton has not been created"));
}
return *ptr;
}
static void Create() {
if (ptr) {
throw(std::logic_error("This singleton has already been created"));
}
ptr = new T();
}
static void Delete() {
if (!ptr) {
throw(std::logic_error("A non-existant singleton cannot be deleted"));
}
delete ptr;
ptr = nullptr;
}
protected:
Singleton() = default;
Singleton(Singleton const&) = default;
Singleton(Singleton&&) = default;
~Singleton() = default;
private:
static T* ptr;
};
template<typename T>
T* Singleton<T>::ptr = nullptr;
#endif
+5 -1
View File
@@ -26,12 +26,16 @@
int snapToBase(int base, int x) { int snapToBase(int base, int x) {
//snap to a grid //snap to a grid
if (x < 0) { if (x < 0) {
x++; ++x;
return x / base * base - base; return x / base * base - base;
} }
return x / base * base; return x / base * base;
} }
double snapToBase(double base, double x) {
return floor(x / base) * base;
}
std::string truncatePath(std::string pathname) { std::string truncatePath(std::string pathname) {
return std::string( return std::string(
std::find_if( std::find_if(
+2 -13
View File
@@ -25,6 +25,8 @@
#include <string> #include <string>
int snapToBase(int base, int x); int snapToBase(int base, int x);
double snapToBase(double base, double x);
std::string truncatePath(std::string pathname); std::string truncatePath(std::string pathname);
//fixing known bugs in g++ //fixing known bugs in g++
@@ -32,17 +34,4 @@ std::string to_string_custom(int i);
int to_integer_custom(std::string); int to_integer_custom(std::string);
//wow
template<typename ContainerT, typename PredicateT>
void erase_if(ContainerT& items, const PredicateT& predicate) {
for(auto it = items.begin(); it != items.end(); /* empty */) {
if(predicate(*it)) {
it = items.erase(it);
}
else {
++it;
}
}
};
#endif #endif
+6 -14
View File
@@ -41,11 +41,12 @@ public:
double SquaredLength() const { double SquaredLength() const {
return x*x+y*y; return x*x+y*y;
} }
void Normalize() {
double operator[](size_t i) { double l = Length();
if (i >= 2) if (l == 0)
throw(std::domain_error("Out of range")); throw(std::domain_error("Divide by zero"));
return *(&x+i); x /= l;
y /= l;
} }
//Arithmetic operators //Arithmetic operators
@@ -103,15 +104,6 @@ public:
template<typename T> bool operator!=(T t) { return (x != t || y != t); } template<typename T> bool operator!=(T t) { return (x != t || y != t); }
}; };
//non-member templates (flip the order)
template<typename T> Vector2 operator+(T t, Vector2 v) { return v + t; }
template<typename T> Vector2 operator-(T t, Vector2 v) { return v - t; }
template<typename T> Vector2 operator*(T t, Vector2 v) { return v * t; }
template<typename T> Vector2 operator/(T t, Vector2 v) { return v / t; }
template<typename T> bool operator==(T t, Vector2 v) { return v == t; }
template<typename T> bool operator!=(T t, Vector2 v) { return v != t; }
//This is explicitly a POD //This is explicitly a POD
static_assert(std::is_pod<Vector2>::value, "Vector2 is not a POD"); static_assert(std::is_pod<Vector2>::value, "Vector2 is not a POD");
+9 -3
View File
@@ -3,10 +3,10 @@
#MKDIR=mkdir #MKDIR=mkdir
#RM=del /y #RM=del /y
CXXFLAGS+=-static-libgcc -static-libstdc++ #CXXFLAGS+=-static-libgcc -static-libstdc++ -g -fno-inline-functions -Wall
CFLAGS+=-static-libgcc #CXXFLAGS+=-static-libgcc -static-libstdc++
export #export
OUTDIR=out OUTDIR=out
@@ -15,6 +15,12 @@ all: $(OUTDIR)
$(MAKE) -C server $(MAKE) -C server
$(MAKE) -C client $(MAKE) -C client
debug: export CXXFLAGS+=-g
debug: clean all
release: export CXXFLAGS+=-static-libgcc -static-libstdc++
release: clean all
$(OUTDIR): $(OUTDIR):
mkdir $(OUTDIR) mkdir $(OUTDIR)
+12 -11
View File
@@ -1,13 +1,20 @@
#configuration of the programs #configuration of the programs
#server specific settings
server.host = 255.255.255.255 server.host = 255.255.255.255
server.port = 21795 server.port = 21795
server.name = local server.name = local
server.dbname = database.db server.dbname = database.db
screen.w = 800 #client specific settings
screen.h = 600 #client.screen.w = 800
screen.f = false #client.screen.h = 600
client.screen.f = false
client.username = Kayne Ruse
client.handle = Ratstail91
client.avatar = elliot2.bmp
#directories #directories
dir.fonts = rsc/graphics/fonts/ dir.fonts = rsc/graphics/fonts/
@@ -16,15 +23,9 @@ dir.sprites = rsc/graphics/sprites/
dir.tilesets = rsc/graphics/tilesets/ dir.tilesets = rsc/graphics/tilesets/
dir.interface = rsc/graphics/interface/ dir.interface = rsc/graphics/interface/
dir.scripts = rsc/scripts/ dir.scripts = rsc/scripts/
dir.maps = rsc/maps/
#map system #map system
map.pager.width = 20 map.savename = servermap
map.pager.height = 20
map.pager.depth = 3
#player options
client.username = Kayne Ruse
client.handle = Ratstail91
client.avatar = elliot2.bmp
#debugging #debugging
Binary file not shown.

After

Width:  |  Height:  |  Size: 768 KiB

+37 -27
View File
@@ -1,36 +1,46 @@
print("Lua script check (./rsc)") print("Lua script check")
------------------------- --uber lazy declarations
--Map API overrides function math.sqr(x) return x*x end
------------------------- function math.dist(x, y, i, j) return math.sqrt(math.sqr(x - i) + math.sqr(y - j)) end
function map.create(region) --tile macros, mapped to the tilesheet
for i = 1, map.getregionwidth() do local base = 14
for j = 1, map.getregionheight() do local shift = 36
if math.abs(map.getx(region) + i -1) == math.abs(map.gety(region) + j -1) then tiles = {
map.settile(region, i, j, 1, 50) plains = base + shift * 0,
grass = base + shift * 1,
dirt = base + shift * 2,
sand = base + shift * 3,
water = base + shift * 4
}
--could set custom generation systems here, that differ from the global generators, etc.
function Region.Create(region)
for i = 1, Region.GetWidth() do
for j = 1, Region.GetHeight() do
local dist = math.dist(0, 0, i + Region.GetX(region) -1, j + Region.GetY(region) -1)
if dist < 10 then
Region.SetTile(region, i, j, 1, tiles.plains)
elseif dist < 12 then
Region.SetTile(region, i, j, 1, tiles.sand)
else else
map.settile(region, i, j, 1, 14) Region.SetTile(region, i, j, 1, tiles.water)
Region.SetSolid(region, i, j, true)
end end
end end
end end
end end
function map.unload(region) --Get some regions
-- --BUG: The server fails without this
end newRoom = RoomMgr.CreateRoom("overworld")
pager = Room.GetPager(newRoom)
regionTable = {
RegionPager.GetRegion(pager, Region.GetWidth() * 0, Region.GetHeight() * 0),
RegionPager.GetRegion(pager, Region.GetWidth() *-1, Region.GetHeight() * 0),
RegionPager.GetRegion(pager, Region.GetWidth() * 0, Region.GetHeight() *-1),
RegionPager.GetRegion(pager, Region.GetWidth() *-1, Region.GetHeight() *-1)
}
function map.load(region, dir) print("Finished the lua script")
--return true if file loaded, otherwise return false
return false
end
function map.save(region, dir)
--
end
-------------------------
--Enemy API
-------------------------
--TODO
+9 -4
View File
@@ -1,3 +1,7 @@
--TODO: why is the database setup script scripted, while accessing, etc. hardcoded?
--there should be a way to control the database more directly
--TODO: move this script into a hardocded Init() method?
CREATE TABLE IF NOT EXISTS Accounts ( CREATE TABLE IF NOT EXISTS Accounts (
uid INTEGER PRIMARY KEY AUTOINCREMENT, uid INTEGER PRIMARY KEY AUTOINCREMENT,
username varchar(100) UNIQUE, username varchar(100) UNIQUE,
@@ -5,7 +9,8 @@ CREATE TABLE IF NOT EXISTS Accounts (
-- password varchar(100), -- password varchar(100),
blacklisted BIT DEFAULT 0, blacklisted BIT DEFAULT 0,
whitelisted BIT DEFAULT 1, whitelisted BIT DEFAULT 1,
administrator BIT DEFAULT 0 mod BIT DEFAULT 0,
admin BIT DEFAULT 0
); );
CREATE TABLE IF NOT EXISTS Characters ( CREATE TABLE IF NOT EXISTS Characters (
@@ -18,9 +23,9 @@ CREATE TABLE IF NOT EXISTS Characters (
birth timestamp NOT NULL DEFAULT (datetime()), birth timestamp NOT NULL DEFAULT (datetime()),
--position --position
mapIndex INTEGER DEFAULT 0, roomIndex INTEGER DEFAULT 0,
positionX INTEGER DEFAULT 0, originX INTEGER DEFAULT 0,
positionY INTEGER DEFAULT 0, originY INTEGER DEFAULT 0,
--statistics --statistics
level INTEGER DEFAULT 0, level INTEGER DEFAULT 0,
@@ -29,6 +29,8 @@ struct AccountData {
//TODO: password //TODO: password
bool blackListed = false; bool blackListed = false;
bool whiteListed = true; bool whiteListed = true;
bool mod = false;
bool admin = false;
int clientIndex; int clientIndex;
}; };
@@ -19,9 +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_application.hpp" #include "account_manager.hpp"
#include "sqlite3/sqlite3.h"
#include <stdexcept> #include <stdexcept>
@@ -31,14 +29,14 @@
static const char* CREATE_USER_ACCOUNT = "INSERT INTO Accounts (username) VALUES (?);"; 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* 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* SAVE_USER_ACCOUNT = "UPDATE OR FAIL Accounts SET blacklisted = ?2, whitelisted = ?3, mod = ?4, admin = ?5 WHERE uid = ?1;";
static const char* DELETE_USER_ACCOUNT = "DELETE FROM Accounts WHERE uid = ?;"; static const char* DELETE_USER_ACCOUNT = "DELETE FROM Accounts WHERE uid = ?;";
//------------------------- //-------------------------
//Define the methods //Define the public methods
//------------------------- //-------------------------
int ServerApplication::CreateUserAccount(std::string username, int clientIndex) { int AccountManager::CreateAccount(std::string username, int clientIndex) {
//create this user account, failing if it exists, leave this account in memory //create this user account, failing if it exists, leave this account in memory
sqlite3_stmt* statement = nullptr; sqlite3_stmt* statement = nullptr;
@@ -62,10 +60,10 @@ int ServerApplication::CreateUserAccount(std::string username, int clientIndex)
sqlite3_finalize(statement); sqlite3_finalize(statement);
//load this account into memory //load this account into memory
return LoadUserAccount(username, clientIndex); return LoadAccount(username, clientIndex);
} }
int ServerApplication::LoadUserAccount(std::string username, int clientIndex) { int AccountManager::LoadAccount(std::string username, int clientIndex) {
//load this user account, failing if it is in memory, creating it if it doesn't exist //load this user account, failing if it is in memory, creating it if it doesn't exist
sqlite3_stmt* statement = nullptr; sqlite3_stmt* statement = nullptr;
@@ -98,6 +96,8 @@ int ServerApplication::LoadUserAccount(std::string username, int clientIndex) {
newAccount.username = reinterpret_cast<const char*>(sqlite3_column_text(statement, 1)); newAccount.username = reinterpret_cast<const char*>(sqlite3_column_text(statement, 1));
newAccount.blackListed = sqlite3_column_int(statement, 2); newAccount.blackListed = sqlite3_column_int(statement, 2);
newAccount.whiteListed = sqlite3_column_int(statement, 3); newAccount.whiteListed = sqlite3_column_int(statement, 3);
newAccount.mod = sqlite3_column_int(statement, 4);
newAccount.admin = sqlite3_column_int(statement, 5);
newAccount.clientIndex = clientIndex; newAccount.clientIndex = clientIndex;
//finish the routine //finish the routine
@@ -109,13 +109,13 @@ int ServerApplication::LoadUserAccount(std::string username, int clientIndex) {
if (ret == SQLITE_DONE) { if (ret == SQLITE_DONE) {
//create the non-existant account instead //create the non-existant account instead
return CreateUserAccount(username, clientIndex); return CreateAccount(username, clientIndex);
} }
throw(std::runtime_error(std::string() + "Unknown SQL error in LoadUserAccount: " + sqlite3_errmsg(database) )); throw(std::runtime_error(std::string() + "Unknown SQL error in LoadAccount: " + sqlite3_errmsg(database) ));
} }
int ServerApplication::SaveUserAccount(int uid) { int AccountManager::SaveAccount(int uid) {
//save this user account from memory, replacing it if it exists in the database //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. //DOCS: To use this method, change the in-memory copy, and then call this function using that object's UID.
@@ -137,6 +137,8 @@ int ServerApplication::SaveUserAccount(int uid) {
ret |= sqlite3_bind_int(statement, 1, uid) != SQLITE_OK; ret |= sqlite3_bind_int(statement, 1, uid) != SQLITE_OK;
ret |= sqlite3_bind_int(statement, 2, account.blackListed) != SQLITE_OK; ret |= sqlite3_bind_int(statement, 2, account.blackListed) != SQLITE_OK;
ret |= sqlite3_bind_int(statement, 3, account.whiteListed) != SQLITE_OK; ret |= sqlite3_bind_int(statement, 3, account.whiteListed) != SQLITE_OK;
ret |= sqlite3_bind_int(statement, 4, account.mod) != SQLITE_OK;
ret |= sqlite3_bind_int(statement, 5, account.admin) != SQLITE_OK;
//check for binding errors //check for binding errors
if (ret) { if (ret) {
@@ -156,16 +158,16 @@ int ServerApplication::SaveUserAccount(int uid) {
return 0; return 0;
} }
void ServerApplication::UnloadUserAccount(int uid) { void AccountManager::UnloadAccount(int uid) {
//save this user account, and then unload it //save this user account, and then unload it
//NOTE: the associated characters are unloaded externally //NOTE: the associated characters are unloaded externally
SaveUserAccount(uid); SaveAccount(uid);
accountMap.erase(uid); accountMap.erase(uid);
} }
void ServerApplication::DeleteUserAccount(int uid) { void AccountManager::DeleteAccount(int uid) {
//delete a user account from the database, and remove it from memory //delete a user account from the database, and remove it from memory
//NOTE: the associated characters are unloaded externally //NOTE: the associated characters should be deleted externally
sqlite3_stmt* statement = nullptr; sqlite3_stmt* statement = nullptr;
//prep //prep
@@ -189,3 +191,36 @@ void ServerApplication::DeleteUserAccount(int uid) {
sqlite3_finalize(statement); sqlite3_finalize(statement);
accountMap.erase(uid); accountMap.erase(uid);
} }
void AccountManager::UnloadAll() {
for (auto& it : accountMap) {
SaveAccount(it.first);
}
accountMap.clear();
}
//-------------------------
//Define the accessors and mutators
//-------------------------
AccountData* AccountManager::GetAccount(int uid) {
std::map<int, AccountData>::iterator it = accountMap.find(uid);
if (it == accountMap.end()) {
return nullptr;
}
return &it->second;
}
std::map<int, AccountData>* AccountManager::GetContainer() {
return &accountMap;
}
sqlite3* AccountManager::SetDatabase(sqlite3* db) {
return database = db;
}
sqlite3* AccountManager::GetDatabase() {
return database;
}
@@ -19,38 +19,39 @@
* 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 ENEMYFACTORYINTERFACE_HPP_ #ifndef ACCOUNTMANAGER_HPP_
#define ENEMYFACTORYINTERFACE_HPP_ #define ACCOUNTMANAGER_HPP_
#include "enemy_data.hpp" #include "account_data.hpp"
#include <list> #include "sqlite3/sqlite3.h"
//TODO: move this elsewhere #include <map>
enum RoomType {
OVERWORLD,
RUINS,
TOWERS,
FORESTS,
CAVES,
};
//NOTE: Based on biome, world difficulty, etc. class AccountManager {
class EnemyFactoryInterface {
public: public:
EnemyFactoryInterface() = default; AccountManager() = default;
virtual ~EnemyFactoryInterface() = default; ~AccountManager() { UnloadAll(); };
virtual void Generate(std::list<EnemyData>* container) = 0; //public access methods
int CreateAccount(std::string username, int clientIndex);
int LoadAccount(std::string username, int clientIndex);
int SaveAccount(int uid);
void UnloadAccount(int uid);
void DeleteAccount(int uid);
//control the difficulty of the room void UnloadAll();
RoomType SetType(RoomType t) { return type = t; }
int SetDifficulty(int d) { return difficulty = d; } //accessors and mutators
RoomType GetType() { return type; } AccountData* GetAccount(int uid);
int GetDifficulty() { return difficulty; } std::map<int, AccountData>* GetContainer();
protected:
RoomType type; sqlite3* SetDatabase(sqlite3* db);
int difficulty; sqlite3* GetDatabase();
private:
std::map<int, AccountData> accountMap;
sqlite3* database = nullptr;
}; };
#endif #endif
+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)/,server.a)
#targets
all: $(OBJ) $(OUT)
ar -crs $(OUT) $(OBJ)
$(OBJ): | $(OBJDIR)
$(OUT): | $(OUTDIR)
$(OBJDIR):
mkdir $(OBJDIR)
$(OUTDIR):
mkdir $(OUTDIR)
$(OBJDIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
clean:
$(RM) *.o *.a *.exe
rebuild: clean all

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