Compare commits

..

35 Commits

Author SHA1 Message Date
Kayne Ruse da218ee8ab Builds and runs on windows 2015-09-03 15:36:48 +10:00
Kayne Ruse 0249352ca2 Committing changes to libcommon 2015-09-03 14:47:48 +10:00
Kayne Ruse 834cf63ca3 Moved the template scenes to the libcommon submodule 2015-09-03 14:30:14 +10:00
Kayne Ruse d7aef30c9a This builds again 2015-08-18 04:01:16 +10:00
Kayne Ruse 13fbedb87c Added libcommon as a submodule 2015-08-18 03:50:53 +10:00
Kayne Ruse 0ad3b6cdcd Added a 'blank' parameter to Image::Create() 2015-08-14 21:44:19 +10:00
Kayne Ruse b9a66e4f65 Reverted templated TextBox, too much unnecessary complexity 2015-08-14 20:47:53 +10:00
Kayne Ruse b82c8f7592 Made TextBox into a template class 2015-08-14 19:39:44 +10:00
Kayne Ruse 7dc092a0f1 Split the TextBox files into two proper modules 2015-08-13 23:19:26 +10:00
Kayne Ruse 9e5a39f251 Made a new TextBox class 2015-08-13 23:14:10 +10:00
Kayne Ruse d618023a91 Changed TextBox to TextLine 2015-08-13 22:46:45 +10:00
Kayne Ruse 8b0d2a700e Text is rendered without a black box
This makes it look nicer, IMO. textBox doesn't use Image, since TextBox is
more specialized.
2015-08-13 22:28:26 +10:00
Kayne Ruse f81032b718 Fleshing out TextBox 2015-08-13 21:45:20 +10:00
Kayne Ruse 2dec2a46fc Began working on TextBox] 2015-08-03 04:37:34 +10:00
Kayne Ruse 5ceb683e93 Closed the font 2015-08-02 04:16:24 +10:00
Kayne Ruse 1d1ac8657e Added the scenes as a template 2015-08-02 02:18:09 +10:00
Kayne Ruse 84fb77b3a3 Fixed missing position settings 2015-08-02 01:36:52 +10:00
Kayne Ruse f079bc76fb Perfected button responses 2015-07-30 04:43:33 +10:00
Kayne Ruse 44f8c90ce0 Button works, but the input needs to be interpreted 2015-07-29 00:31:51 +10:00
Kayne Ruse 19227882b9 Button is being drawn, if a little jenky; needs SDL2_ttf
I tweaked the Image::Create() implementation, to act as a render target.
2015-07-28 22:36:26 +10:00
Kayne Ruse 4cb9e05841 Minor comment tweaks 2015-07-21 23:04:53 +10:00
Kayne Ruse 3e7e366554 Tweak 2015-07-21 15:32:52 +10:00
Kayne Ruse d6157f6722 Corrected my compass directions 2015-07-21 14:55:28 +10:00
Kayne Ruse cfc6c381ae Cleaned up the generator; playing around 2015-07-21 14:29:46 +10:00
Kayne Ruse be1b23ddfb Wrote a simple dungeon generator 2015-07-20 17:34:19 +10:00
Kayne Ruse 1f49a997c6 Added a lua file which maps the indices of roguetileset.png 2015-07-20 15:39:11 +10:00
Kayne Ruse 029b2518e1 Added dynamic window sizing 2015-07-20 14:52:42 +10:00
Kayne Ruse 13ae560e28 Moved BaseScene::ProcessEvents() to Application::ProcessEvents()
This is so that events can interact with the window more easily (i.e.
logical resizing).
2015-07-20 14:19:14 +10:00
Kayne Ruse 69aee157b8 Implemented zoom in/out with the scroll wheel
The focus of the zooming is the top left of the screen, but that is fine
for now.
2015-07-20 13:00:38 +10:00
Kayne Ruse 2732612803 Added a simple roguelike tileset 2015-07-20 11:44:29 +10:00
Kayne Ruse ba6f92a6e7 Resolved an off-by-one error caused by integer devision 2015-07-17 19:30:00 +10:00
Kayne Ruse 0c11e0a98b Removed a crash bug when the lambdas are absent 2015-07-17 19:02:58 +10:00
Kayne Ruse 8b1a9aee91 Moved source files to src/ 2015-07-08 03:06:52 +10:00
Kayne Ruse f254c9d88f Implemented lua, shaking out latent bugs 2015-07-08 02:48:46 +10:00
Kayne Ruse 56ae0a13c9 Initial commit 2015-07-07 23:58:59 +10:00
97 changed files with 1252 additions and 17251 deletions
+25
View File
@@ -0,0 +1,25 @@
#Editor generated files
*.sln
*.vcproj
*.suo
*.ncb
*.user
#Directories
Release/
Debug/
Out/
release/
debug/
out/
bin/
#Project generated files
*.db
*.o
*.a
*.exe
#Shell files
*.bat
*.sh
+3
View File
@@ -0,0 +1,3 @@
[submodule "common"]
path = common
url = https://github.com/Ratstail91/Tortuga.git
Binary file not shown.
-57
View File
@@ -1,57 +0,0 @@
--TODO: each function needs to check it's parameter count
--TODO: Set metatables
--RoomManager interface
RoomMgr.GetRoom(index)
RoomMgr.CreateRoom([{params}])
RoomMgr.UnloadRoom(index)
--RoomData interface
Room.GetPager()
Room.GetGenerator()
Room.OnCreate([{params}])
Room.OnUnload()
Room.Get{params}()
--RegionPager interface
RegionPager.SetTile(x, y, z, v)
RegionPager.GetTile(x, y, z)
RegionPager.SetSolid(x, y, b)
RegionPager.GetSolid(x, y)
RegionPager.GetRegion(x, y)
RegionPager.SetDirectory(directory)
RegionPager.GetDirectory()
RegionPager.LoadRegion(x, y)
RegionPager.SaveRegion(x, y)
RegionPager.CreateRegion(x, y[, {params}])
RegionPager.UnloadRegion(x, y)
--Region interface
Region.SetTile(x, y, z, v)
Region.GetTile(x, y, z)
Region.SetSolid(x, y, b)
Region.GetSolid(x, y)
Region.GetX()
Region.GetY()
Region.GetWidth()
Region.GetHeight()
Region.GetDepth()
Region.OnLoad(directory)
Region.OnSave(directory)
Region.OnCreate([{params}])
Region.OnUnload([directory])
--*Generator interface
Generator.GetMapType()
Generator.GetChunk(x, y)
Generator.GetMapWidth()
Generator.GetMapHeight()
--Chunk interface
??
-19
View File
@@ -1,19 +0,0 @@
My game Tortuga will have permadeath; it's actually one of the first design decisions I made. How to implement it, however, is another decision all together.
A while ago, before the implementation of hardcore mode, I was playing on a Minecraft server that boasted something close to permadeath: your account would be banned for 15 days, so long that it's almost unavoidable that you'd lose all of your hidden items. This was a brutal server; the further you went from spawn, the more dangerous it became, not less. If the natural hazards didn't kill you, another player would.
I loved it.
Although I haven't been back to that server since I died for the last time, the experience will stay with me forever. I'd played and died on that server a few times, each time I had to wait for my ban to clear. I never really lost much, since I never survived for very long. Even today, in a single player world, I'm likely to die on the first night.
After playing for a while, I began to understand the mentality needed to survive there. Always fear other people, never take risks, and never hoard valuable items if they could be better spent keeping you alive. One day, the last day I played, I found a hole in the ground that someone was obviously using as a "hidden" base. I tried to get in, always careful not to trigger any traps. However, while I was trying to get in, the owner came home.
I was suddenly attacked from behind, I barely had enough sense to dig down, since they were wearing enchanted diamond armour. I had no chance against them. I thought I was safe, digging 10, 20, 30 meters down, but no, they poured lava down the hole and plugged it up. I was a gonner, and I knew it. I was futilely digging and thrashing around in what was now my tomb, about to lose my life. I'd survived for so long, only to lose it all by not keeping a lookout.
When the game over screen flashed up, I screamed. I screamed, and screamed, and screamed. For 5 minutes, my mind was blank, nothing but hatred and pain and loss. I'm sure you've seen the video of the angry German kid who died in WoW, but have you ever actually experienced that pain? Have you ever worked so hard, and lost it all?
For days afterwards, that loss was all I could think about. Even now, that experience stays with me. What about that game, that server, invoked so much pain that I almost lost consciousness from screaming? Me of all people, who thought he was invincible?
I've played games that have moved me, terrified me, made me fall in love and fight for the people that I care about. But never have I played a game that has made me feel pain and loss like that. I died that day. Me.
Pain and loss are part of life, but not games. Permadeath seems like the obvious choice for creating a sense of loss for the player, but there are so few games with permadeath, and even fewer multiplayer games. Pain and loss can be conveyed in other ways, I'm sure anybody who's played Final Fantasy 7 knows that, and some games are especially well suited to delivering that message. However, for a player to feel like they are the one who's died, that is a challenge.
-125
View File
@@ -1,125 +0,0 @@
Abstract:
The goal of this pseudocode is to create a collision system that brings several
colliding bodies to a near-contact state (no space between the bodies, but not
overlapping), while preserving the motion of said bodies. For simplicity, I've
decided to use a square box (BoundingBox, or BBox for short) for the collidable
bodies.
Example:
My current game has a tiled-map, where the tiles are arranged on a 2D grid. The
tiles each have a flag indicating if they are solid (i.e. collidable) or not. I
also have characters walking around on these tile maps, that must not intersect
with solid tiles. For stylistic reasons, I want characters moving at an angle
to "slide" along these walls, and continue along with their original velocity
when they've circumvented the obstacles.
I'd also like to keep the possibility of non-grid collisions using this logic
open (for objects like trees, etc.) if the code allows it.
Obviously, there are many in depth issues that I will need to take into
account when writing this logic, that have been glossed over or omitted in this
article.
-------------------------
```
velocity = motion + speed
if (collision(position + velocity)) then
if (collision(position + {velocity.x, 0})) then
velocity.x = 0
end
if (collision(position + {0, velocity.y})) then
velocity.y = 0
end
end
position = position + velocity
```
This code is a basic outline for a collision system that preserves the object's
motion, but it still leaves several pixels of space between the bounding boxes.
Notably, it also treats "collision" as an abstract concept, rather than as an
event that could happen multiple times per frame.
-------------------------
```
velocity = motion + speed
if (collisionSimple(BOXSET, position + velocity)) then
velocity.x = collisionX(BOXSET, velocity.x)
velocity.y = collisionY(BOXSET, velocity.y)
end
position = position + velocity
```
Here, collisions are still abstract, but "BOXSET" is defined externally
(probably as a set of solid boxes, and their positions). This does require more
in depth calculations, as well as three specialized utility functions, but the
results might be what I'm looking for.
If there are any collisions between the player object and the given box set,
then collisionX() and collisionY() are called to calculate the new distance
that the character will move.
-------------------------
```
bool collisionSimple(BOXSET, newPos):
for_each box in BOXSET do
if (box.overlap(PLAYER.box + newPos)) then
return true
end
end
return false
end
```
collisionSimple() first runs through the BOXSET, checking if any of the given
bounding boxes would collide with the player object's new position (just
pretend PLAYER is accessible). In this case, non-tile bounding boxes can be
included as part of BOXSET; they're treated just the same. The optimal outcome
is that there are no collisions.
A possible, but flawed, optimization that could be preformed here is to remove
any elements from BOXSET that do not collide with newPos, and let the other
utility functions operate only on what remains. However, if there are any
collisions, than newPos is not the algorithm's final result, therefore any
final result that the algorithm would calculate based on the remaining elements
would not have been checked against the removed elements.
Just something to note.
-------------------------
```
var collisionX(BOXSET, velocityX):
var ret = velocityX
for_each box in BOXSET do
if (box.overlap(PLAYER.box + PLAYER.position + {velocityX,0})) then
if (velocityX > 0) then
ret = min(ret, box.west - PLAYER.position.x)
else
ret = max(ret, box.east - PLAYER.position.x)
end
end
end
return ret
end
```
Two things: 1. collisionX() and collisionY() should be identical except for the
axis of operation and 2. if a player object is "sliding" along a wall (or
stuck), then these functions will be called every frame.
collisionX() and collisionY() check the sides of the elements in BOXSET, and if
there's a box that the player would collide with, given the current distance to
move, than the distance is reduced, based on if the character is moving left or
right (or up or down).
An unfortunate bug I can already see is that this logic doesn't check corners;
it might be possible to get stuck on a corner of a wall, but if this becomes an
issue in my implementation I will update this article with that information,
and you can promptly ignore it.
Submodule
+1
Submodule common added at 3eafb57403
-84
View File
@@ -1,84 +0,0 @@
The Game Map
This section outlines the games map system. This system utilizes pagination to create a theoretically infinite game map, as well as supporting multiple tilesets in the same map. The goal of this design is to create a system with as much flexibility as possible, and simply enforcing a more rigid approach higher in the tool chain.
Tile
The Tile class is the basic unit of the map system, and is explicitly a POD (plain old data) structure. A tile has these members:
X Position
Y Position
Depth
Width
Height
Tile Index
The tiles X and Y positions are relative to their container regions location. A tiles depth allows multiple tiles to be drawn at the same location, and in the correct order; tiles with lower depths (including below zero) are drawn first. If a new tile has the same X position, Y position and depth as an existing tile, the old tile is overwritten.
The width and height members indicate the graphical size of the tile (not actually used when drawing), while the tile index is the specific tile for the sheet manager to draw. A negative value here is considered an error message.
Region
The region class has these members:
X Position
Y Position
Width
Height
Tile Container
Each region in a certain map must have the same width and height, and its X and Y positions must be multiples of those width and height values, respectfully. The outcome of this restriction is a theoretically infinite grid of region objects.
Each region holds a set of tiles corresponding to the regions bounds. The tiles X and Y positions are relative to the regions, so moving the region will move the tiles as well. A region object is created or loaded when a tile is place in its bounds; similarly, if a region has no tiles it should be deleted or removed from memory.
The exact width and height of a region has no significant impact, other than loading or transmission costs. The width and height of a map can be adjusted as needed.
Region Pager
The region pager class has these members:
Region Width
Region Height
On New Callback
On Delete Callback
Region Container
The Region Pager class holds a series of region objects, as well as creating and deleting them as needed. Every region theoretically exists at any time, so if a non-existent region object is requested, it is created and then returned. This class also has the Prune() method, which removes all regions out of bounds from memory, and the DrawTo method, which takes (among other things) the sheet manager for the map.
The width and height members must be set before the pager is used, and must not be changed while it still has regions loaded. These are used to create region objects as needed.
Each pager can also have two different callbacks set: “on new” and “on delete”. If either of these are set (that is, not null) then each region objects address is passed to these after it is created or before it is destroyed, respectfully. The callbacks are intended to be used for domain specific processes, such as loading or saving data, or even requesting data from a remote server.
Tile Sheet
A tileset is a series of tile graphics stored in a single file. The tile sheet class loads a tile set into memory, and provides utilities for drawing them to the screen. The tile sheet class has these members:
Image
X Count
Y Count
Total Count
Begin
End
The Image class is utilized heavily here by storing the graphical data and the tile size. Any file loaded into a sheet object must have all tile images arranged in a grid pattern, and they must all have the same width and height. The width and height must be provided when the file is loaded.
The X and Y counts are the number of tiles along the X and Y axis of the sheets image, and the total count is the number of tiles in the whole sheet (which is equal to the product of the X and Y counts).
Begin is the index of the first tile on the sheet (default is zero), and end is the index after the last tile (defaults to the value of total count). These indicate the range of the tiles, and are mostly used by the sheet manager. They are also used by the InRange() method, which checks to see if a certain tile is in that sheet.
Tile Sheet Manager
This class has these members:
Tile Sheet Container
Range End
This class is a wrapper around a key-value container, using strings as the keys. Given a specific tile index, this class will draw the correct tile from the loaded sheets, or it throws an error.
Also, this class keeps track of the end of the sheets ranges.
TODO
Map File Format
TODO
-3
View File
@@ -1,3 +0,0 @@
This particular refactoring stage was absolute hell, mostly because I was wrestling with a severe bout of depression too. So, I've added the diffs, and a scary screenshot of the git console.
There are three diff files because server/server_application.cpp was split into two files: server/server_internals.cpp and server/server_connections.cpp, each with it's own diff.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

File diff suppressed because it is too large Load Diff
@@ -1,394 +0,0 @@
diff --git a/server/server_connections.cpp b/server/server_connections.cpp
index 1a96d5b..2f35566 100644
--- a/server/server_connections.cpp
+++ b/server/server_connections.cpp
@@ -21,212 +21,106 @@
*/
#include "server_application.hpp"
-#include "utility.hpp"
-
#include <stdexcept>
#include <iostream>
-#include <string>
-
-//-------------------------
-//Define the public members
-//-------------------------
-
-void ServerApplication::Init(int argc, char** argv) {
- //NOTE: I might need to rearrange the init process so that lua & SQL can interact with the map system as needed.
- std::cout << "Beginning startup" << std::endl;
-
- //initial setup
- ClientEntry::uidCounter = 0;
- PlayerEntry::uidCounter = 0;
- config.Load("rsc\\config.cfg");
-
- //Init SDL
- if (SDL_Init(0)) {
- throw(std::runtime_error("Failed to initialize SDL"));
- }
- std::cout << "Initialized SDL" << std::endl;
-
- //Init SDL_net
- if (SDLNet_Init()) {
- throw(std::runtime_error("Failed to initialize SDL_net"));
- }
- network.Open(config.Int("server.port"), PACKET_BUFFER_SIZE);
- std::cout << "Initialized SDL_net" << std::endl;
-
- //Init SQL
- int ret = sqlite3_open_v2(config["server.dbname"].c_str(), &database, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, nullptr);
- if (ret != SQLITE_OK || !database) {
- throw(std::runtime_error(std::string() + "Failed to initialize SQL: " + sqlite3_errmsg(database) ));
- }
- std::cout << "Initialized SQL" << std::endl;
-
- //setup the database
- if (runSQLScript(database, config["dir.scripts"] + "setup_server.sql")) {
- throw(std::runtime_error("Failed to initialize SQL's setup script"));
- }
- std::cout << "Initialized SQL's setup script" << std::endl;
-
- //lua
- luaState = luaL_newstate();
- if (!luaState) {
- throw(std::runtime_error("Failed to initialize lua"));
- }
- luaL_openlibs(luaState);
- std::cout << "Initialized lua" << std::endl;
-
- //run the startup script
- if (luaL_dofile(luaState, (config["dir.scripts"] + "setup_server.lua").c_str())) {
- throw(std::runtime_error(std::string() + "Failed to initialize lua's setup script: " + lua_tostring(luaState, -1) ));
- }
- std::cout << "Initialized lua's setup script" << std::endl;
-
- //setup the map object
- regionPager.GetAllocator()->SetLuaState(luaState);
- regionPager.GetFormat()->SetLuaState(luaState);
- //TODO: config parameter
- regionPager.GetFormat()->SetSaveDir("save/mapname/");
-
- std::cout << "Initialized the map system" << std::endl;
- std::cout << "\tsizeof(SerialPacket): " << sizeof(SerialPacket) << std::endl;
- std::cout << "\tPACKET_BUFFER_SIZE: " << PACKET_BUFFER_SIZE << std::endl;
-
- //finalize the startup
- std::cout << "Startup completed successfully" << std::endl;
-
- //debugging
- //
-}
-
-void ServerApplication::Proc() {
- SerialPacket packet;
- while(running) {
- //suck in the waiting packets & process them
- while(network.Receive()) {
- //get the packet
- deserialize(&packet, network.GetInData());
- //cache the source address
- packet.meta.srcAddress = network.GetInPacket()->address;
- //we need to go deeper
- HandlePacket(packet);
- }
- //give the computer a break
- SDL_Delay(10);
- }
-}
-
-void ServerApplication::Quit() {
- std::cout << "Shutting down" << std::endl;
- //empty the members
- regionPager.UnloadAll();
-
- //APIs
- lua_close(luaState);
- sqlite3_close_v2(database);
- network.Close();
- SDLNet_Quit();
- SDL_Quit();
- std::cout << "Shutdown finished" << std::endl;
-}
-
-//-------------------------
-//Define the uber switch
-//-------------------------
-
-void ServerApplication::HandlePacket(SerialPacket packet) {
- switch(packet.meta.type) {
- case SerialPacket::Type::BROADCAST_REQUEST:
- HandleBroadcastRequest(packet);
- break;
- case SerialPacket::Type::JOIN_REQUEST:
- HandleJoinRequest(packet);
- break;
- case SerialPacket::Type::DISCONNECT:
- HandleDisconnect(packet);
- break;
- case SerialPacket::Type::SYNCHRONIZE:
- HandleSynchronize(packet);
- break;
- case SerialPacket::Type::SHUTDOWN:
- HandleShutdown(packet);
- break;
- case SerialPacket::Type::PLAYER_NEW:
- HandlePlayerNew(packet);
- break;
- case SerialPacket::Type::PLAYER_DELETE:
- HandlePlayerDelete(packet);
- break;
- case SerialPacket::Type::PLAYER_UPDATE:
- HandlePlayerUpdate(packet);
- break;
- case SerialPacket::Type::REGION_REQUEST:
- HandleRegionRequest(packet);
- break;
- //handle errors
- default:
- throw(std::runtime_error("Unknown SerialPacket::Type encountered"));
- break;
- }
-}
//-------------------------
//Handle various network input
//-------------------------
void ServerApplication::HandleBroadcastRequest(SerialPacket packet) {
- //send back the server's metadata
+ //pack the server's data
packet.meta.type = SerialPacket::Type::BROADCAST_RESPONSE;
-
- //pack the data
+ packet.serverInfo.networkVersion = NETWORK_VERSION;
snprintf(packet.serverInfo.name, PACKET_STRING_SIZE, "%s", config["server.name"].c_str());
packet.serverInfo.playerCount = playerMap.size();
- packet.serverInfo.regionWidth = REGION_WIDTH;
- packet.serverInfo.regionHeight = REGION_HEIGHT;
- packet.serverInfo.regionDepth = REGION_DEPTH;
- //send the data
+ //bounce this packet
char buffer[PACKET_BUFFER_SIZE];
serialize(&packet, buffer);
network.Send(&packet.meta.srcAddress, buffer, PACKET_BUFFER_SIZE);
}
void ServerApplication::HandleJoinRequest(SerialPacket packet) {
- //register the new client
+ //create the new client
ClientEntry newClient;
newClient.address = packet.meta.srcAddress;
- clientMap[ClientEntry::uidCounter] = newClient;
- //send the client their index
- char buffer[PACKET_BUFFER_SIZE];
+ //TODO: move this into the player management code
+ //create the new player
+ PlayerEntry newPlayer;
+ newPlayer.clientIndex = ClientEntry::uidCounter;
+ newPlayer.player = packet.clientInfo.player;
+ newPlayer.handle = packet.clientInfo.handle;
+ newPlayer.avatar = packet.clientInfo.avatar;
+
+ //send the client their info
packet.meta.type = SerialPacket::Type::JOIN_RESPONSE;
- packet.clientInfo.index = ClientEntry::uidCounter;
- serialize(&packet, buffer);
+ packet.clientInfo.clientIndex = ClientEntry::uidCounter;
+ packet.clientInfo.playerIndex = PlayerEntry::uidCounter;
//bounce this packet
+ char buffer[PACKET_BUFFER_SIZE];
+ serialize(&packet, buffer);
network.Send(&newClient.address, buffer, PACKET_BUFFER_SIZE);
+ //send the new player to all clients
+ packet.meta.type = SerialPacket::Type::PLAYER_NEW;
+ packet.playerInfo.playerIndex = PlayerEntry::uidCounter;
+ strncpy(packet.playerInfo.handle, newPlayer.handle.c_str(), PACKET_STRING_SIZE);
+ strncpy(packet.playerInfo.avatar, newPlayer.avatar.c_str(), PACKET_STRING_SIZE);
+ packet.playerInfo.position = newPlayer.position;
+ packet.playerInfo.motion = newPlayer.motion;
+ PumpPacket(packet);
+
//finished this routine
+ clientMap[ClientEntry::uidCounter] = newClient;
+ playerMap[PlayerEntry::uidCounter] = newPlayer;
ClientEntry::uidCounter++;
+ PlayerEntry::uidCounter++;
std::cout << "Connect, total: " << clientMap.size() << std::endl;
}
+void ServerApplication::HandleSynchronize(SerialPacket packet) {
+ //TODO: compensate for large distances
+
+ //send all the server's data to this client
+ SerialPacket newPacket;
+ char buffer[PACKET_BUFFER_SIZE];
+
+ //players
+ newPacket.meta.type = SerialPacket::Type::PLAYER_UPDATE;
+ for (auto& it : playerMap) {
+ //TODO: update this for the expanded PlayerEntry structure
+ newPacket.playerInfo.playerIndex = it.first;
+ snprintf(newPacket.playerInfo.handle, PACKET_STRING_SIZE, "%s", it.second.handle.c_str());
+ snprintf(newPacket.playerInfo.avatar, PACKET_STRING_SIZE, "%s", it.second.avatar.c_str());
+ newPacket.playerInfo.mapIndex = it.second.mapIndex;
+ newPacket.playerInfo.position = it.second.position;
+ newPacket.playerInfo.motion = it.second.motion;
+ serialize(&newPacket, buffer);
+ network.Send(&clientMap[packet.clientInfo.clientIndex].address, buffer, PACKET_BUFFER_SIZE);
+ }
+}
+
void ServerApplication::HandleDisconnect(SerialPacket packet) {
//TODO: authenticate who is disconnecting/kicking
+ //TODO: define the difference between unloading and deletng a player
//disconnect the specified client
char buffer[PACKET_BUFFER_SIZE];
serialize(&packet, buffer);
- network.Send(&clientMap[packet.clientInfo.index].address, buffer, PACKET_BUFFER_SIZE);
- clientMap.erase(packet.clientInfo.index);
+ network.Send(&clientMap[packet.clientInfo.clientIndex].address, buffer, PACKET_BUFFER_SIZE);
+ clientMap.erase(packet.clientInfo.clientIndex);
//prep the delete packet
SerialPacket delPacket;
delPacket.meta.type = SerialPacket::Type::PLAYER_DELETE;
- //TODO: can this use DeletePlayer() instead?
//delete server and client side players
- erase_if(playerMap, [&](std::pair<unsigned int, PlayerEntry> it) -> bool {
+ erase_if(playerMap, [&](std::pair<int, PlayerEntry> it) -> bool {
//find the internal players to delete
- if (it.second.clientIndex == packet.clientInfo.index) {
+ if (it.second.clientIndex == packet.clientInfo.clientIndex) {
//send the delete player command to all clients
delPacket.playerInfo.playerIndex = it.first;
PumpPacket(delPacket);
@@ -243,102 +137,23 @@ void ServerApplication::HandleDisconnect(SerialPacket packet) {
std::cout << "Disconnect, total: " << clientMap.size() << std::endl;
}
-void ServerApplication::HandleSynchronize(SerialPacket packet) {
- //TODO: compensate for large distances
-
- //send all the server's data to this client
- SerialPacket newPacket;
- char buffer[PACKET_BUFFER_SIZE];
-
- //players
- newPacket.meta.type = SerialPacket::Type::PLAYER_UPDATE;
- for (auto& it : playerMap) {
- //TODO: update this for the expanded PlayerEntry structure
- newPacket.playerInfo.playerIndex = it.first;
- snprintf(newPacket.playerInfo.handle, PACKET_STRING_SIZE, "%s", it.second.handle.c_str());
- snprintf(newPacket.playerInfo.avatar, PACKET_STRING_SIZE, "%s", it.second.avatar.c_str());
- newPacket.playerInfo.position = it.second.position;
- newPacket.playerInfo.motion = it.second.motion;
- serialize(&newPacket, buffer);
- network.Send(&clientMap[packet.clientInfo.index].address, buffer, PACKET_BUFFER_SIZE);
- }
-}
-
void ServerApplication::HandleShutdown(SerialPacket packet) {
+ //TODO: authenticate who is shutting the server down
+
//end the server
running = false;
//disconnect all clients
packet.meta.type = SerialPacket::Type::DISCONNECT;
+ packet.clientInfo.clientIndex = -1;
PumpPacket(packet);
//finished this routine
std::cout << "Shutdown signal accepted" << std::endl;
}
-void ServerApplication::HandlePlayerNew(SerialPacket packet) {
- //register the new PlayerEntry
- //NOTE: assigning each field one-by-one so adding or moving a field doesn't break this code
- PlayerEntry newPlayer;
-
- //metadata
- newPlayer.clientIndex = packet.playerInfo.clientIndex;
- newPlayer.handle = packet.playerInfo.handle;
- newPlayer.avatar = packet.playerInfo.avatar;
-
- //position
- newPlayer.mapIndex = 0;
- newPlayer.position = {0,0};
- newPlayer.motion = {0,0};
- newPlayer.bbox = {0, 0, 0, 0};
-
- //TODO: Add the statistic creation code here
-
- //push this player
- playerMap[PlayerEntry::uidCounter] = newPlayer;
-
- //send the client their info
- packet.playerInfo.playerIndex = PlayerEntry::uidCounter;
- packet.playerInfo.position = newPlayer.position;
- packet.playerInfo.motion = newPlayer.motion;
-
- //actually send to everyone
- PumpPacket(packet);
-
- //finish this routine
- PlayerEntry::uidCounter++;
-}
-
-//TODO: differentiate between delete and unload
-void ServerApplication::HandlePlayerDelete(SerialPacket packet) {
- //TODO: authenticate who is deleting this player
- if (playerMap.find(packet.playerInfo.playerIndex) == playerMap.end()) {
- throw(std::runtime_error("Cannot delete a non-existant player"));
- }
-
- //TODO: remove the deleted player from the database?
-
- //prep the delete packet
- SerialPacket delPacket;
- delPacket.meta.type = SerialPacket::Type::PLAYER_DELETE;
-
- //delete the specified playerEntry
- erase_if(playerMap, [&](std::pair<unsigned int, PlayerEntry> it) -> bool {
- //find the specified PlayerEntry
- if (it.first == packet.playerInfo.playerIndex) {
- //send to all
- delPacket.playerInfo.playerIndex = it.first;
- PumpPacket(delPacket);
-
- //delete this player
- return true;
- }
- //skip this player
- return false;
- });
-}
-
void ServerApplication::HandlePlayerUpdate(SerialPacket packet) {
+ //TODO: this should be moved elsewhere
if (playerMap.find(packet.playerInfo.playerIndex) == playerMap.end()) {
throw(std::runtime_error("Cannot update a non-existant player"));
}
@@ -351,9 +166,12 @@ void ServerApplication::HandlePlayerUpdate(SerialPacket packet) {
}
void ServerApplication::HandleRegionRequest(SerialPacket packet) {
- char buffer[PACKET_BUFFER_SIZE];
+ //TODO: this should be moved elsewhere
packet.meta.type = SerialPacket::Type::REGION_CONTENT;
packet.regionInfo.region = regionPager.GetRegion(packet.regionInfo.x, packet.regionInfo.y);
+
+ //send the content
+ char buffer[PACKET_BUFFER_SIZE];
serialize(&packet, buffer);
network.Send(&packet.meta.srcAddress, buffer, PACKET_BUFFER_SIZE);
}
@@ -1,284 +0,0 @@
diff --git a/server/server_internals.cpp b/server/server_internals.cpp
index 1a96d5b..e1a9cb9 100644
--- a/server/server_internals.cpp
+++ b/server/server_internals.cpp
@@ -1,4 +1,4 @@
-/* Copyright: (c) Kayne Ruse 2013, 2014
+/* 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
@@ -21,7 +21,7 @@
*/
#include "server_application.hpp"
-#include "utility.hpp"
+#include "server_utility.hpp"
#include <stdexcept>
#include <iostream>
@@ -36,8 +36,6 @@ void ServerApplication::Init(int argc, char** argv) {
std::cout << "Beginning startup" << std::endl;
//initial setup
- ClientEntry::uidCounter = 0;
- PlayerEntry::uidCounter = 0;
config.Load("rsc\\config.cfg");
//Init SDL
@@ -109,6 +107,8 @@ void ServerApplication::Proc() {
//we need to go deeper
HandlePacket(packet);
}
+ //update the internals
+ //TODO: update the internals i.e. player positions
//give the computer a break
SDL_Delay(10);
}
@@ -116,6 +116,10 @@ void ServerApplication::Proc() {
void ServerApplication::Quit() {
std::cout << "Shutting down" << std::endl;
+
+ //save the server state
+ //TODO: save the existing players
+
//empty the members
regionPager.UnloadAll();
@@ -125,6 +129,7 @@ void ServerApplication::Quit() {
network.Close();
SDLNet_Quit();
SDL_Quit();
+
std::cout << "Shutdown finished" << std::endl;
}
@@ -140,21 +145,15 @@ void ServerApplication::HandlePacket(SerialPacket packet) {
case SerialPacket::Type::JOIN_REQUEST:
HandleJoinRequest(packet);
break;
- case SerialPacket::Type::DISCONNECT:
- HandleDisconnect(packet);
- break;
case SerialPacket::Type::SYNCHRONIZE:
HandleSynchronize(packet);
break;
+ case SerialPacket::Type::DISCONNECT:
+ HandleDisconnect(packet);
+ break;
case SerialPacket::Type::SHUTDOWN:
HandleShutdown(packet);
break;
- case SerialPacket::Type::PLAYER_NEW:
- HandlePlayerNew(packet);
- break;
- case SerialPacket::Type::PLAYER_DELETE:
- HandlePlayerDelete(packet);
- break;
case SerialPacket::Type::PLAYER_UPDATE:
HandlePlayerUpdate(packet);
break;
@@ -167,202 +166,3 @@ void ServerApplication::HandlePacket(SerialPacket packet) {
break;
}
}
-
-//-------------------------
-//Handle various network input
-//-------------------------
-
-void ServerApplication::HandleBroadcastRequest(SerialPacket packet) {
- //send back the server's metadata
- packet.meta.type = SerialPacket::Type::BROADCAST_RESPONSE;
-
- //pack the data
- snprintf(packet.serverInfo.name, PACKET_STRING_SIZE, "%s", config["server.name"].c_str());
- packet.serverInfo.playerCount = playerMap.size();
- packet.serverInfo.regionWidth = REGION_WIDTH;
- packet.serverInfo.regionHeight = REGION_HEIGHT;
- packet.serverInfo.regionDepth = REGION_DEPTH;
-
- //send the data
- char buffer[PACKET_BUFFER_SIZE];
- serialize(&packet, buffer);
- network.Send(&packet.meta.srcAddress, buffer, PACKET_BUFFER_SIZE);
-}
-
-void ServerApplication::HandleJoinRequest(SerialPacket packet) {
- //register the new client
- ClientEntry newClient;
- newClient.address = packet.meta.srcAddress;
- clientMap[ClientEntry::uidCounter] = newClient;
-
- //send the client their index
- char buffer[PACKET_BUFFER_SIZE];
- packet.meta.type = SerialPacket::Type::JOIN_RESPONSE;
- packet.clientInfo.index = ClientEntry::uidCounter;
- serialize(&packet, buffer);
-
- //bounce this packet
- network.Send(&newClient.address, buffer, PACKET_BUFFER_SIZE);
-
- //finished this routine
- ClientEntry::uidCounter++;
- std::cout << "Connect, total: " << clientMap.size() << std::endl;
-}
-
-void ServerApplication::HandleDisconnect(SerialPacket packet) {
- //TODO: authenticate who is disconnecting/kicking
-
- //disconnect the specified client
- char buffer[PACKET_BUFFER_SIZE];
- serialize(&packet, buffer);
- network.Send(&clientMap[packet.clientInfo.index].address, buffer, PACKET_BUFFER_SIZE);
- clientMap.erase(packet.clientInfo.index);
-
- //prep the delete packet
- SerialPacket delPacket;
- delPacket.meta.type = SerialPacket::Type::PLAYER_DELETE;
-
- //TODO: can this use DeletePlayer() instead?
- //delete server and client side players
- erase_if(playerMap, [&](std::pair<unsigned int, PlayerEntry> it) -> bool {
- //find the internal players to delete
- if (it.second.clientIndex == packet.clientInfo.index) {
- //send the delete player command to all clients
- delPacket.playerInfo.playerIndex = it.first;
- PumpPacket(delPacket);
-
- //delete this player object
- return true;
- }
-
- //don't delete this player object
- return false;
- });
-
- //finished this routine
- std::cout << "Disconnect, total: " << clientMap.size() << std::endl;
-}
-
-void ServerApplication::HandleSynchronize(SerialPacket packet) {
- //TODO: compensate for large distances
-
- //send all the server's data to this client
- SerialPacket newPacket;
- char buffer[PACKET_BUFFER_SIZE];
-
- //players
- newPacket.meta.type = SerialPacket::Type::PLAYER_UPDATE;
- for (auto& it : playerMap) {
- //TODO: update this for the expanded PlayerEntry structure
- newPacket.playerInfo.playerIndex = it.first;
- snprintf(newPacket.playerInfo.handle, PACKET_STRING_SIZE, "%s", it.second.handle.c_str());
- snprintf(newPacket.playerInfo.avatar, PACKET_STRING_SIZE, "%s", it.second.avatar.c_str());
- newPacket.playerInfo.position = it.second.position;
- newPacket.playerInfo.motion = it.second.motion;
- serialize(&newPacket, buffer);
- network.Send(&clientMap[packet.clientInfo.index].address, buffer, PACKET_BUFFER_SIZE);
- }
-}
-
-void ServerApplication::HandleShutdown(SerialPacket packet) {
- //end the server
- running = false;
-
- //disconnect all clients
- packet.meta.type = SerialPacket::Type::DISCONNECT;
- PumpPacket(packet);
-
- //finished this routine
- std::cout << "Shutdown signal accepted" << std::endl;
-}
-
-void ServerApplication::HandlePlayerNew(SerialPacket packet) {
- //register the new PlayerEntry
- //NOTE: assigning each field one-by-one so adding or moving a field doesn't break this code
- PlayerEntry newPlayer;
-
- //metadata
- newPlayer.clientIndex = packet.playerInfo.clientIndex;
- newPlayer.handle = packet.playerInfo.handle;
- newPlayer.avatar = packet.playerInfo.avatar;
-
- //position
- newPlayer.mapIndex = 0;
- newPlayer.position = {0,0};
- newPlayer.motion = {0,0};
- newPlayer.bbox = {0, 0, 0, 0};
-
- //TODO: Add the statistic creation code here
-
- //push this player
- playerMap[PlayerEntry::uidCounter] = newPlayer;
-
- //send the client their info
- packet.playerInfo.playerIndex = PlayerEntry::uidCounter;
- packet.playerInfo.position = newPlayer.position;
- packet.playerInfo.motion = newPlayer.motion;
-
- //actually send to everyone
- PumpPacket(packet);
-
- //finish this routine
- PlayerEntry::uidCounter++;
-}
-
-//TODO: differentiate between delete and unload
-void ServerApplication::HandlePlayerDelete(SerialPacket packet) {
- //TODO: authenticate who is deleting this player
- if (playerMap.find(packet.playerInfo.playerIndex) == playerMap.end()) {
- throw(std::runtime_error("Cannot delete a non-existant player"));
- }
-
- //TODO: remove the deleted player from the database?
-
- //prep the delete packet
- SerialPacket delPacket;
- delPacket.meta.type = SerialPacket::Type::PLAYER_DELETE;
-
- //delete the specified playerEntry
- erase_if(playerMap, [&](std::pair<unsigned int, PlayerEntry> it) -> bool {
- //find the specified PlayerEntry
- if (it.first == packet.playerInfo.playerIndex) {
- //send to all
- delPacket.playerInfo.playerIndex = it.first;
- PumpPacket(delPacket);
-
- //delete this player
- return true;
- }
- //skip this player
- return false;
- });
-}
-
-void ServerApplication::HandlePlayerUpdate(SerialPacket packet) {
- if (playerMap.find(packet.playerInfo.playerIndex) == playerMap.end()) {
- throw(std::runtime_error("Cannot update a non-existant player"));
- }
-
- //TODO: the server needs it's own movement system too
- playerMap[packet.playerInfo.playerIndex].position = packet.playerInfo.position;
- playerMap[packet.playerInfo.playerIndex].motion = packet.playerInfo.motion;
-
- PumpPacket(packet);
-}
-
-void ServerApplication::HandleRegionRequest(SerialPacket packet) {
- char buffer[PACKET_BUFFER_SIZE];
- packet.meta.type = SerialPacket::Type::REGION_CONTENT;
- packet.regionInfo.region = regionPager.GetRegion(packet.regionInfo.x, packet.regionInfo.y);
- serialize(&packet, buffer);
- network.Send(&packet.meta.srcAddress, buffer, PACKET_BUFFER_SIZE);
-}
-
-void ServerApplication::PumpPacket(SerialPacket packet) {
- //NOTE: I don't really like this, but it'll do for now
- char buffer[PACKET_BUFFER_SIZE];
- serialize(&packet, buffer);
- for (auto& it : clientMap) {
- network.Send(&it.second.address, buffer, PACKET_BUFFER_SIZE);
- }
-}
-91
View File
@@ -1,91 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
* /
#include "server_application.hpp"
#include "SDL/SDL.h"
#include <stdexcept>
#include <iostream>
using namespace std;
int main(int argc, char** argv) {
cout << "Beginning server" << endl;
try {
ServerApplication app;
app.Init(argc, argv);
app.Loop();
app.Quit();
}
catch(exception& e) {
cerr << "Fatal error: " << e.what() << endl;
return 1;
}
cout << "Clean exit" << endl;
return 0;
}*/
#include "network_packet.hpp"
#include "serial.hpp"
#include "region.hpp"
#include "map_generator.hpp"
#include <iostream>
using namespace std;
int main(int, char**) {
char buffer[PACKET_BUFFER_SIZE];
Region region(20, 20, 3, 0, 0);
NetworkPacket packet;
packet.meta.type = NetworkPacket::Type::REGION_CONTENT;
packet.regionInfo.region = &region;
for (int i = 0; i < packet.regionInfo.region->GetWidth(); i++) {
for (int j = 0; j < packet.regionInfo.region->GetHeight(); j++) {
for (int k = 0; k < packet.regionInfo.region->GetDepth(); k++) {
packet.regionInfo.region->SetTile(i, j, k, i*20*3 + j*3 +k);
}
}
}
serialize(&packet, buffer);
for (int i = 0; i < PACKET_BUFFER_SIZE; i++) {
cout << ((Region::type_t*)(buffer))[i] << ",";
}
cout << endl << endl;
deserialize(&packet, buffer);
for (int i = 0; i < packet.regionInfo.region->GetWidth(); i++) {
for (int j = 0; j < packet.regionInfo.region->GetHeight(); j++) {
for (int k = 0; k < packet.regionInfo.region->GetDepth(); k++) {
cout << packet.regionInfo.region->GetTile(i, j, k) << ",";
}
}
}
cout << endl;
BlankGenerator().Unload(packet.regionInfo.region);
return 0;
}
-76
View File
@@ -1,76 +0,0 @@
#include <iostream>
#include <cstring>
using namespace std;
union Foo {
enum class Type {
INT,
FLOAT
}type;
struct {
Type type;
int i;
}i;
struct {
Type type;
float f;
}f;
};
void serialize(Foo* f, void* buffer) {
int len = 0;
memcpy((void*)((int)buffer + len), &f->type, sizeof(Foo::Type));
len += sizeof(Foo::Type);
switch(f->type) {
case Foo::Type::INT:
memcpy((void*)((int)buffer + len), &f->i.i, sizeof(int));
len += sizeof(int);
break;
case Foo::Type::FLOAT:
memcpy((void*)((int)buffer + len), &f->f.f, sizeof(float));
len += sizeof(float);
break;
}
}
void deserialize(Foo* f, void* buffer) {
int len = 0;
memcpy(&f->type, (void*)((int)buffer + len), sizeof(Foo::Type));
len += sizeof(Foo::Type);
switch(f->type) {
case Foo::Type::INT:
memcpy(&f->i.i, (void*)((int)buffer + len), sizeof(int));
len += sizeof(int);
break;
case Foo::Type::FLOAT:
memcpy(&f->f.f, (void*)((int)buffer + len), sizeof(float));
len += sizeof(float);
break;
}
}
int main() {
Foo f;
f.type = Foo::Type::FLOAT;
f.f.f = 3.14;
Foo i;
i.type = Foo::Type::INT;
i.i.i = 42;
char buffer[sizeof(Foo)];
serialize(&f, buffer);
deserialize(&i, buffer);
switch(i.type) {
case Foo::Type::INT:
cout << i.i.i << endl;
break;
case Foo::Type::FLOAT:
cout << i.f.f << endl;
break;
}
return 0;
}
@@ -1,12 +0,0 @@
The palette is extracted from the frog images. It's only meant as areference, and can change later. Hot pink (255, 0, 255) is used to fill the gaps.
[blank], mid highlight, high highlight
low base, mid base, high base
[blank], mid shadow, high shadow
inner cheek
tongue outline, tongue shadow, tongue base
leather shadow, leather base, leather hightlight
wood shadow, wood base, wood highlight
sharp shadow, sharp base, [blank]
dull shadow, dull base, [blank]
frog outline, metal outline, wood outline
Binary file not shown.

Before

Width:  |  Height:  |  Size: 997 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 687 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 320 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 838 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 577 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 494 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 363 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

@@ -1,7 +0,0 @@
pay attention to each frog's eyes
frogs are green
bog toad is yellow/orange with spots (gradient?)
princess dress is an ugly pink
frog king wears a gold crown and red cape with gold trimmings
the knight's helmet has a purple plume, and it's wearing boxer shorts with loveheart patterns
Binary file not shown.

Before

Width:  |  Height:  |  Size: 974 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 984 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1004 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 506 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 572 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 524 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 336 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 433 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 231 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 387 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 473 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 869 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 864 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 970 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 981 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 849 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 865 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 856 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 944 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 884 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 968 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

+23
View File
@@ -0,0 +1,23 @@
OUTDIR=out
all: $(OUTDIR)
$(MAKE) -C common
$(MAKE) -C src
debug: export CXXFLAGS+=-g
debug: clean all
$(OUTDIR):
mkdir $(OUTDIR)
clean:
ifeq ($(OS),Windows_NT)
$(RM) *.o *.a *.exe
else ifeq ($(shell uname), Linux)
find . -type f -name '*.o' -exec rm -f -r -v {} \;
find . -type f -name '*.a' -exec rm -f -r -v {} \;
rm -f -v $(OUT)
find . -empty -type d -delete
endif
rebuild: clean all
-390
View File
@@ -1,390 +0,0 @@
<HTML>
<HEAD>
<META name="description"
content="Violet UML Editor cross format document" />
<META name="keywords" content="Violet, UML" />
<META charset="UTF-8" />
<SCRIPT type="text/javascript">
function switchVisibility() {
var obj = document.getElementById("content");
obj.style.display = (obj.style.display == "block") ? "none" : "block";
}
</SCRIPT>
</HEAD>
<BODY>
This file was generated with Violet UML Editor 2.0.1.
&nbsp;&nbsp;(&nbsp;<A href=# onclick="switchVisibility()">View Source</A>&nbsp;/&nbsp;<A href="http://sourceforge.net/projects/violet/files/violetumleditor/" target="_blank">Download Violet</A>&nbsp;)
<BR />
<BR />
<SCRIPT id="content" type="text/xml"><![CDATA[<ClassDiagramGraph id="1">
<nodes id="2">
<ClassNode id="3">
<children id="4"/>
<location class="Point2D.Double" id="5" x="580.0" y="150.0"/>
<id id="6" value="ae1d5b70-0a1c-498b-9df5-ae8a5fdc2922"/>
<revision>1</revision>
<backgroundColor id="7">
<red>255</red>
<green>255</green>
<blue>255</blue>
<alpha>255</alpha>
</backgroundColor>
<borderColor id="8">
<red>0</red>
<green>0</green>
<blue>0</blue>
<alpha>255</alpha>
</borderColor>
<textColor reference="8"/>
<name id="9" justification="1" size="3" underlined="false">
<text>Font</text>
</name>
<attributes id="10" justification="0" size="4" underlined="false">
<text></text>
</attributes>
<methods id="11" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
<ClassNode id="12">
<children id="13"/>
<location class="Point2D.Double" id="14" x="950.0" y="150.0"/>
<id id="15" value="66d346f9-0fd9-4572-b2ac-fff3aa2aaf98"/>
<revision>1</revision>
<backgroundColor reference="7"/>
<borderColor reference="8"/>
<textColor reference="8"/>
<name id="16" justification="1" size="3" underlined="false">
<text>Image</text>
</name>
<attributes id="17" justification="0" size="4" underlined="false">
<text></text>
</attributes>
<methods id="18" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
<ClassNode id="19">
<children id="20"/>
<location class="Point2D.Double" id="21" x="760.0" y="240.0"/>
<id id="22" value="1695ab7e-539a-4428-adfa-d2124507d153"/>
<revision>1</revision>
<backgroundColor reference="7"/>
<borderColor reference="8"/>
<textColor reference="8"/>
<name id="23" justification="1" size="3" underlined="false">
<text>Button</text>
</name>
<attributes id="24" justification="0" size="4" underlined="false">
<text></text>
</attributes>
<methods id="25" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
<ClassNode id="26">
<children id="27"/>
<location class="Point2D.Double" id="28" x="760.0" y="330.0"/>
<id id="29" value="a88251a0-235d-473d-8fb8-ef70cdb00be6"/>
<revision>1</revision>
<backgroundColor reference="7"/>
<borderColor reference="8"/>
<textColor reference="8"/>
<name id="30" justification="1" size="3" underlined="false">
<text>MenuBarEntry</text>
</name>
<attributes id="31" justification="0" size="4" underlined="false">
<text></text>
</attributes>
<methods id="32" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
<ClassNode id="33">
<children id="34"/>
<location class="Point2D.Double" id="35" x="760.0" y="420.0"/>
<id id="36" value="400ee56a-3c60-46c1-a260-6e239b7c1de0"/>
<revision>1</revision>
<backgroundColor reference="7"/>
<borderColor reference="8"/>
<textColor reference="8"/>
<name id="37" justification="1" size="3" underlined="false">
<text>MenuBar</text>
</name>
<attributes id="38" justification="0" size="4" underlined="false">
<text></text>
</attributes>
<methods id="39" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
</nodes>
<edges id="40">
<AggregationEdge id="41">
<start class="ClassNode" reference="3"/>
<end class="ClassNode" reference="12"/>
<startLocation class="Point2D.Double" id="42" x="50.0" y="40.0"/>
<endLocation class="Point2D.Double" id="43" x="70.0" y="40.0"/>
<transitionPoints id="44"/>
<id id="45" value="a0b62c8f-177a-4840-b37e-2d78384f89c6"/>
<revision>1</revision>
<bentStyle id="46" name="AUTO"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</AggregationEdge>
<AggregationEdge id="47">
<start class="ClassNode" reference="19"/>
<end class="ClassNode" reference="26"/>
<startLocation class="Point2D.Double" id="48" x="50.0" y="50.0"/>
<endLocation class="Point2D.Double" id="49" x="60.0" y="20.0"/>
<transitionPoints id="50"/>
<id id="51" value="b9f015fe-bc19-4a80-ae76-f8fe40fa1f2f"/>
<revision>1</revision>
<bentStyle reference="46"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</AggregationEdge>
<AggregationEdge id="52">
<start class="ClassNode" reference="26"/>
<end class="ClassNode" reference="33"/>
<startLocation class="Point2D.Double" id="53" x="30.0" y="40.0"/>
<endLocation class="Point2D.Double" id="54" x="30.0" y="0.0"/>
<transitionPoints id="55"/>
<id id="56" value="71a5ed8a-cbbd-42ae-90b4-bcfa8285f1d4"/>
<revision>1</revision>
<bentStyle reference="46"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</AggregationEdge>
<CompositionEdge id="57">
<start class="ClassNode" reference="19"/>
<end class="ClassNode" reference="3"/>
<startLocation class="Point2D.Double" id="58" x="30.0" y="30.0"/>
<endLocation class="Point2D.Double" id="59" x="50.0" y="40.0"/>
<transitionPoints id="60"/>
<id id="61" value="38bcfcd1-fd42-458b-9518-a7d68f007b7f"/>
<revision>1</revision>
<bentStyle reference="46"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</CompositionEdge>
<CompositionEdge id="62">
<start class="ClassNode" reference="19"/>
<end class="ClassNode" reference="12"/>
<startLocation class="Point2D.Double" id="63" x="90.0" y="30.0"/>
<endLocation class="Point2D.Double" id="64" x="30.0" y="50.0"/>
<transitionPoints id="65"/>
<id id="66" value="3e2710d7-45eb-4a89-9d74-b9eafdda6e2f"/>
<revision>1</revision>
<bentStyle reference="46"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</CompositionEdge>
</edges>
</ClassDiagramGraph>]]></SCRIPT>
<BR />
<BR />
<IMG alt="embedded diagram image" src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0a
HBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIy
MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAFPAdsDASIA
AhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQA
AAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3
ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWm
p6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEA
AwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSEx
BhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElK
U1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3
uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD0PwX4
L8K3XgXw9cXHhrRpp5dMtnkkksImZ2MSkkkrkknnNbn/AAgng/8A6FTQ/wDwXQ//ABNHgT/knnhr
/sFWv/opa6CgDn/+EE8H/wDQqaH/AOC6H/4mj/hBPB//AEKmh/8Aguh/+JroKKAOf/4QTwf/ANCp
of8A4Lof/iaP+EE8H/8AQqaH/wCC6H/4mugooA5//hBPB/8A0Kmh/wDguh/+Jo/4QTwf/wBCpof/
AILof/ia6CigDn/+EE8H/wDQqaH/AOC6H/4mj/hBPB//AEKmh/8Aguh/+JroKKAOf/4QTwf/ANCp
of8A4Lof/iaP+EE8H/8AQqaH/wCC6H/4mugooA4eXTNH8M+PdKk0nR7Gz8/TL1ZBaQJDvxLa4ztH
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
6NtK6CufvP8Akoejf9gq/wD/AEbaUAdBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFF
FFABRRRQAUUUUAc/4h/5DnhP/sKyf+kV1XQVz/iH/kOeE/8AsKyf+kV1XQUAFFFFABRRRQAUUUUA
FFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAV
z95/yUPRv+wVf/8Ao20roK5+8/5KHo3/AGCr/wD9G2lAHQUUUUAFFFFABRXN62dQuvFWlaXaavd6
dBLZXdxK1rHCzO0b26qD5sbgDEr9AO1Sf8I9qn/Q565/35sv/kegDoKK5/8A4R7VP+hz1z/vzZf/
ACPR/wAI9qn/AEOeuf8Afmy/+R6AOgorn/8AhHtU/wChz1z/AL82X/yPR/wj2qf9Dnrn/fmy/wDk
egDoKK5//hHtU/6HPXP+/Nl/8j0f8I9qn/Q565/35sv/AJHoA6Ciuf8A+Ee1T/oc9c/782X/AMj0
f8I9qn/Q565/35sv/kegDoKK5/8A4R7VP+hz1z/vzZf/ACPR/wAI9qn/AEOeuf8Afmy/+R6AOgor
n/8AhHtU/wChz1z/AL82X/yPUng/VZNY8IaNe3E3nXc1hby3D7duXaMFjgADk56cUAblFFFABRRR
QBz/AIh/5DnhP/sKyf8ApFdV0Fc/4h/5DnhP/sKyf+kV1XQUAFFFFABRRRQAUUUUAFFFFABRRRQA
UUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVz95/wAlD0b/
ALBV/wD+jbSugrn7z/koejf9gq//APRtpQB0FFFFABRRRQBz95/yUPRv+wVf/wDo20roK5+8/wCS
h6N/2Cr/AP8ARtpXQUAFFFFABRRRQAUUUUAFFFFABRRRQAVx3wz/AORI0f8A7Btr/wCixXY1x3wz
/wCRI0f/ALBtr/6LFAHY0UUUAFFFFAHP+If+Q54T/wCwrJ/6RXVdBXP+If8AkOeE/wDsKyf+kV1X
QUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRR
QAUUUUAFFFFABRRRQAVz95/yUPRv+wVf/wDo20roKz9T0LR9b8r+1tKsb/yc+X9rt0l2ZxnG4HGc
Dp6CgDQorn/+EE8H/wDQqaH/AOC6H/4mj/hBPB//AEKmh/8Aguh/+JoA6Ciuf/4QTwf/ANCpof8A
4Lof/iaP+EE8H/8AQqaH/wCC6H/4mgAvP+Sh6N/2Cr//ANG2ldBXH2+haPonxD0v+ydKsbDztKvv
M+yW6Rb8S2mM7QM4yevqa7CgAooooAwPFHiG50L+y4rOxivLjUb1bSNZrgwopKs24sEc/wAPp3qn
pXji2uLmWx1aJLG/TUf7NVIZGnill8sSAK+xf4TzuAwRijxz4aufEkGkrb2un3a2V+tzLa37lYpk
CMu0kI/dh1Wucj+H+swTxX9rHpVq1vq8d/b6RBO62sSLEY2Cv5eQWJ3HEYH86I76/wBbf8EJeX9b
/wDAOgm+ImjDUNJtrVLy7j1Iz7JoLSVgvk5DcBCSdwxgDgcnAxlNM+I+iX3h+z1aYXdst48qw25t
JZJWCZJYKiElQuCWGVGcZrI0XwPrekHwvM0unzzaXNfG6USuislw5O5DsOSo/hOM9N3eodG8EeJN
Bt9Hmt/7JmvNNtrix8uS4kWOaKRg4k3CMlWDAAphgR/EKXT+vP8A4H9Jj0v/AF/XmdPfeP8Awxpz
otxqgw8CXIeKGSVBC52rIWRSoXPGScDIz1FdKCCMjkV5VL8LNSi0W9020vrWQS6HFp0ckpZcyrK0
jMQAcL83GCTXqaKVjVT1AAqnb+vVk/1+C/4P3DqKKKQwrjvhn/yJGj/9g21/9FiuxrzT4e+D/DF7
4P0qe78OaRPM9hbO8ktjGzMxjBJJK8knvQB6XRXP/wDCCeD/APoVND/8F0P/AMTR/wAIJ4P/AOhU
0P8A8F0P/wATQB0FFc//AMIJ4P8A+hU0P/wXQ/8AxNH/AAgng/8A6FTQ/wDwXQ//ABNAB4h/5Dnh
P/sKyf8ApFdV0FY9j4T8N6ZeR3lh4f0q0uo87JoLKON1yCDhgMjIJH41sUAFFFFABRRRQAUUUUAF
FFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUU
UUAFFFFABRRRQBz95/yUPRv+wVf/APo20roK5+8/5KHo3/YKv/8A0baV0FABRRRQAUUUUAFFFFAB
RRRQAUUUUAFcd8M/+RI0f/sG2v8A6LFdjXHfDP8A5EjR/wDsG2v/AKLFAHY0UUUAFFFFABRRRQAU
UUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRR
RQAUUUUAFFFFABRRRQAUUUUAFFFFAHL65djTPGWj389tfSWq6fews9pZTXO12ktioIiViMhG6+hp
/wDwnmh/3dX/APBJef8Axqulqp/Zln/zx/8AHj/jQBi/8J5of93V/wDwSXn/AMao/wCE80P+7q//
AIJLz/41W1/Zln/zx/8AHj/jR/Zln/zx/wDHj/jQBi/8J5of93V//BJef/GqP+E80P8Au6v/AOCS
8/8AjVbX9mWf/PH/AMeP+NH9mWf/ADx/8eP+NAGDL8QvD0CB5m1SNSyoGfRrwAsxCqOYupJAA7ki
pP8AhPND/u6v/wCCS8/+NVF4w061TRbcrFg/2ppw+8ehvIR61v8A9mWf/PH/AMeP+NAGL/wnmh/3
dX/8El5/8ao/4TzQ/wC7q/8A4JLz/wCNVtf2ZZ/88f8Ax4/40f2ZZ/8APH/x4/40AYv/AAnmh/3d
X/8ABJef/GqP+E80P+7q/wD4JLz/AONVtf2ZZ/8APH/x4/40f2ZZ/wDPH/x4/wCNAGL/AMJ5of8A
d1f/AMEl5/8AGqr/AA5hlt/B+lwTxvFNHYWyPG6lWVhGAQQehB7V0X9mWf8Azx/8eP8AjUsFrDbb
vKTbu68k0ATUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAU
UUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAHL+
MJri7gh0vTLX7bfpLFfvCsgTYkL+cm5jwvmSRLEMn+JmAYRsK6CwvrfU9Otr+zk8y1uokmhfaRuR
gCpweRkEdax9E/d+I/EMV181+ZYpg/ZrVk2wheu1QyTDaSfnEj4USAUeGvnvNdntvl02TUHECdvM
UBJ2UcbVMquNuMl1kfcwkGADoKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKK
KACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoooo
AKKKKACiiigDD1jWNStdZsdL0vTrS7nuree4Zrq8aBUWJolwNsbkkmYdh0NR/bPGH/QC0P8A8HM3
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
ACiiigAooooA" />
</BODY>
</HTML>
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
-460
View File
@@ -1,460 +0,0 @@
<HTML>
<HEAD>
<META name="description"
content="Violet UML Editor cross format document" />
<META name="keywords" content="Violet, UML" />
<META charset="UTF-8" />
<SCRIPT type="text/javascript">
function switchVisibility() {
var obj = document.getElementById("content");
obj.style.display = (obj.style.display == "block") ? "none" : "block";
}
</SCRIPT>
</HEAD>
<BODY>
This file was generated with Violet UML Editor 2.0.1.
&nbsp;&nbsp;(&nbsp;<A href=# onclick="switchVisibility()">View Source</A>&nbsp;/&nbsp;<A href="http://sourceforge.net/projects/violet/files/violetumleditor/" target="_blank">Download Violet</A>&nbsp;)
<BR />
<BR />
<SCRIPT id="content" type="text/xml"><![CDATA[<ClassDiagramGraph id="1">
<nodes id="2">
<ClassNode id="3">
<children id="4"/>
<location class="Point2D.Double" id="5" x="360.0" y="60.0"/>
<id id="6" value="e434bcf1-a723-46d4-9c95-f02109d9bc3e"/>
<revision>1</revision>
<backgroundColor id="7">
<red>255</red>
<green>255</green>
<blue>255</blue>
<alpha>255</alpha>
</backgroundColor>
<borderColor id="8">
<red>0</red>
<green>0</green>
<blue>0</blue>
<alpha>255</alpha>
</borderColor>
<textColor reference="8"/>
<name id="9" justification="1" size="3" underlined="false">
<text>AccountData</text>
</name>
<attributes id="10" justification="0" size="4" underlined="false">
<text>client index
character index</text>
</attributes>
<methods id="11" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
<ClassNode id="12">
<children id="13"/>
<location class="Point2D.Double" id="14" x="300.0" y="170.0"/>
<id id="15" value="9558a2ab-6e32-4f5f-8740-d1064ab1aaf2"/>
<revision>1</revision>
<backgroundColor reference="7"/>
<borderColor reference="8"/>
<textColor reference="8"/>
<name id="16" justification="1" size="3" underlined="false">
<text>ClientData</text>
</name>
<attributes id="17" justification="0" size="4" underlined="false">
<text></text>
</attributes>
<methods id="18" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
<ClassNode id="19">
<children id="20"/>
<location class="Point2D.Double" id="21" x="420.0" y="170.0"/>
<id id="22" value="09237306-b5be-464e-a5f0-69398fd9473f"/>
<revision>1</revision>
<backgroundColor reference="7"/>
<borderColor reference="8"/>
<textColor reference="8"/>
<name id="23" justification="1" size="3" underlined="false">
<text>CharacterData</text>
</name>
<attributes id="24" justification="0" size="4" underlined="false">
<text></text>
</attributes>
<methods id="25" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
<ClassNode id="26">
<children id="27"/>
<location class="Point2D.Double" id="28" x="620.0" y="80.0"/>
<id id="29" value="fb90ebaa-64c1-4efe-b785-392dad7f7a55"/>
<revision>1</revision>
<backgroundColor reference="7"/>
<borderColor reference="8"/>
<textColor reference="8"/>
<name id="30" justification="1" size="3" underlined="false">
<text>AccountData</text>
</name>
<attributes id="31" justification="0" size="4" underlined="false">
<text></text>
</attributes>
<methods id="32" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
<ClassNode id="33">
<children id="34"/>
<location class="Point2D.Double" id="35" x="560.0" y="170.0"/>
<id id="36" value="4539608c-4e01-4279-a18e-0011f10bf089"/>
<revision>1</revision>
<backgroundColor reference="7"/>
<borderColor reference="8"/>
<textColor reference="8"/>
<name id="37" justification="1" size="3" underlined="false">
<text>ClientData</text>
</name>
<attributes id="38" justification="0" size="4" underlined="false">
<text>account index</text>
</attributes>
<methods id="39" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
<ClassNode id="40">
<children id="41"/>
<location class="Point2D.Double" id="42" x="680.0" y="170.0"/>
<id id="43" value="d362126a-cc20-4b98-a5a5-96acbb29eb2a"/>
<revision>1</revision>
<backgroundColor reference="7"/>
<borderColor reference="8"/>
<textColor reference="8"/>
<name id="44" justification="1" size="3" underlined="false">
<text>CharacterData</text>
</name>
<attributes id="45" justification="0" size="4" underlined="false">
<text>account index</text>
</attributes>
<methods id="46" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
</nodes>
<edges id="47">
<AssociationEdge id="48">
<start class="ClassNode" reference="3"/>
<end class="ClassNode" reference="12"/>
<startLocation class="Point2D.Double" id="49" x="50.0" y="20.0"/>
<endLocation class="Point2D.Double" id="50" x="80.0" y="30.0"/>
<transitionPoints id="51"/>
<id id="52" value="d5f5280c-93bd-4519-8bf1-eb2bda331b6f"/>
<revision>1</revision>
<bentStyle id="53" name="AUTO"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</AssociationEdge>
<AssociationEdge id="54">
<start class="ClassNode" reference="3"/>
<end class="ClassNode" reference="19"/>
<startLocation class="Point2D.Double" id="55" x="60.0" y="40.0"/>
<endLocation class="Point2D.Double" id="56" x="60.0" y="30.0"/>
<transitionPoints id="57"/>
<id id="58" value="1f933164-0a58-4df1-a90f-2f436565e306"/>
<revision>1</revision>
<bentStyle reference="53"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</AssociationEdge>
<AssociationEdge id="59">
<start class="ClassNode" reference="33"/>
<end class="ClassNode" reference="26"/>
<startLocation class="Point2D.Double" id="60" x="30.0" y="30.0"/>
<endLocation class="Point2D.Double" id="61" x="20.0" y="40.0"/>
<transitionPoints id="62"/>
<id id="63" value="1a974bae-848c-4070-a87c-7f65133e255d"/>
<revision>1</revision>
<bentStyle reference="53"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</AssociationEdge>
<AssociationEdge id="64">
<start class="ClassNode" reference="40"/>
<end class="ClassNode" reference="26"/>
<startLocation class="Point2D.Double" id="65" x="20.0" y="20.0"/>
<endLocation class="Point2D.Double" id="66" x="50.0" y="40.0"/>
<transitionPoints id="67"/>
<id id="68" value="2ef69b8d-781f-4c2a-8c71-4511097b71cf"/>
<revision>1</revision>
<bentStyle reference="53"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</AssociationEdge>
</edges>
</ClassDiagramGraph>]]></SCRIPT>
<BR />
<BR />
<IMG alt="embedded diagram image" src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0a
HBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIy
MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCACvAeUDASIA
AhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQA
AAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3
ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWm
p6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEA
AwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSEx
BhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElK
U1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3
uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iii
gAooooAKKKKACuT17SdN1nx1olvqmn2l9AumXzrHdQrKobzbQZAYEZwSM+5rrK5+8/5KHo3/AGCr
/wD9G2lAB/wgng//AKFTQ/8AwXQ//E1naroPw90RrNdR8PaDAbydbeAHTIzvkPQcIcfU4HvXY15j
430jXfFHiW/s7LS0ls7PSXiimupngT7RMc74yI2DsojXjjBPUUm7DSudd/wgng//AKFTQ/8AwXQ/
/E0f8IJ4P/6FTQ//AAXQ/wDxNcJKr6vqFtq3i7w3ql7bz6JEtvbRWMryW90GPnKAozC5O0hyV4A+
YYq6NPhTxlqdxr3h/VL67lubV9Jnggd2hiCqNonU7Ytr7y4Ljdkn5s81bW39b2/4PoTfS/8AW1/+
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
BFBGzsCxVF2jOO+MUUAf" />
</BODY>
</HTML>
-74
View File
@@ -1,74 +0,0 @@
--NOTE: This is the outline for the final combat system
--enumeration
hitType = { MISS = 1, HIT = 2, CRITICAL = 3 }
attackType = { PHYSICAL = 1, MAGICAL = 2 }
function MakeChar()
local t = {}
t.MaxHP = 100
t.HP = t.MaxHP
t.MaxMP = 100
t.MP = t.MaxMP
t.attack = 10
t.defence = 10
t.intelligence = 10
t.resistance = 10
t.accuracy = 0.9
t.evasion = 0.1
t.luck = 0.1
t.level = 1
return t
end
function CheckHit(A, D)
local RNG = math.random(100)
local hitRate = (A.accuracy - A.accuracy * D.evasion) * 100
if RNG <= hitRate * A.luck then
return hitType.CRITICAL
end
if RNG <= hitRate then
return hitType.HIT
end
return hitType.MISS
end
function CalcDamage(A, D, t)
-- if t == attackType.PHYSICAL then
--TODO: test min & max of the rng
--TODO: overall, this needs tweaking for balance
return math.max(1, ( A.attack*3 + A.attack*(math.random(A.luck*100)/10) ) - (D.defence + D.defence*D.evasion))
-- end
-- if t == attackType.MAGICAL then
-- --??
-- end
-- --wtf?
end
A = MakeChar()
D = MakeChar()
dump = io.open("dump.txt", "w")
--top
dump:write("\t\t")
for i = 10, 100, 10 do
dump:write(i, "\t")
end
dump:write("\n\n")
--lines
for j = 10, 100, 10 do
dump:write(j, "\t\t")
for i = 10, 100, 10 do
A.attack = i
D.defence = j
dump:write(CalcDamage(A, D, 0), "\t")
end
dump:write("\n")
end
--bottom
dump:write("\n")
dump:close()
-533
View File
@@ -1,533 +0,0 @@
<HTML>
<HEAD>
<META name="description"
content="Violet UML Editor cross format document" />
<META name="keywords" content="Violet, UML" />
<META charset="UTF-8" />
<SCRIPT type="text/javascript">
function switchVisibility() {
var obj = document.getElementById("content");
obj.style.display = (obj.style.display == "block") ? "none" : "block";
}
</SCRIPT>
</HEAD>
<BODY>
This file was generated with Violet UML Editor 2.0.1.
&nbsp;&nbsp;(&nbsp;<A href=# onclick="switchVisibility()">View Source</A>&nbsp;/&nbsp;<A href="http://sourceforge.net/projects/violet/files/violetumleditor/" target="_blank">Download Violet</A>&nbsp;)
<BR />
<BR />
<SCRIPT id="content" type="text/xml"><![CDATA[<ClassDiagramGraph id="1">
<nodes id="2">
<ClassNode id="3">
<children id="4"/>
<location class="Point2D.Double" id="5" x="240.0" y="120.0"/>
<id id="6" value="150cda2d-f7dc-4f67-80ec-1d92e7985570"/>
<revision>1</revision>
<backgroundColor id="7">
<red>255</red>
<green>255</green>
<blue>255</blue>
<alpha>255</alpha>
</backgroundColor>
<borderColor id="8">
<red>0</red>
<green>0</green>
<blue>0</blue>
<alpha>255</alpha>
</borderColor>
<textColor reference="8"/>
<name id="9" justification="1" size="3" underlined="false">
<text>gameplay</text>
</name>
<attributes id="10" justification="0" size="4" underlined="false">
<text></text>
</attributes>
<methods id="11" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
<ClassNode id="12">
<children id="13"/>
<location class="Point2D.Double" id="14" x="480.0" y="120.0"/>
<id id="15" value="47197ae3-bef7-4cb3-8617-dfef2c1c848a"/>
<revision>1</revision>
<backgroundColor reference="7"/>
<borderColor reference="8"/>
<textColor reference="8"/>
<name id="16" justification="1" size="3" underlined="false">
<text>map</text>
</name>
<attributes id="17" justification="0" size="4" underlined="false">
<text></text>
</attributes>
<methods id="18" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
<ClassNode id="19">
<children id="20"/>
<location class="Point2D.Double" id="21" x="480.0" y="40.0"/>
<id id="22" value="b681a379-61b1-40e9-b8c1-7174f497b26c"/>
<revision>1</revision>
<backgroundColor reference="7"/>
<borderColor reference="8"/>
<textColor reference="8"/>
<name id="23" justification="1" size="3" underlined="false">
<text>utilities</text>
</name>
<attributes id="24" justification="0" size="4" underlined="false">
<text></text>
</attributes>
<methods id="25" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
<ClassNode id="26">
<children id="27"/>
<location class="Point2D.Double" id="28" x="480.0" y="280.0"/>
<id id="29" value="8b90e37a-ccde-4cfa-aba4-2f222cd1657f"/>
<revision>1</revision>
<backgroundColor reference="7"/>
<borderColor reference="8"/>
<textColor reference="8"/>
<name id="30" justification="1" size="3" underlined="false">
<text>ui</text>
</name>
<attributes id="31" justification="0" size="4" underlined="false">
<text></text>
</attributes>
<methods id="32" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
<ClassNode id="33">
<children id="34"/>
<location class="Point2D.Double" id="35" x="480.0" y="200.0"/>
<id id="36" value="e4abf2a3-a13c-41b5-9c6b-274802bc2ce5"/>
<revision>1</revision>
<backgroundColor reference="7"/>
<borderColor reference="8"/>
<textColor reference="8"/>
<name id="37" justification="1" size="3" underlined="false">
<text>graphics</text>
</name>
<attributes id="38" justification="0" size="4" underlined="false">
<text></text>
</attributes>
<methods id="39" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
<ClassNode id="40">
<children id="41"/>
<location class="Point2D.Double" id="42" x="600.0" y="120.0"/>
<id id="43" value="6a8f25f4-da57-45ba-8734-f4632423c463"/>
<revision>1</revision>
<backgroundColor reference="7"/>
<borderColor reference="8"/>
<textColor reference="8"/>
<name id="44" justification="1" size="3" underlined="false">
<text>script</text>
</name>
<attributes id="45" justification="0" size="4" underlined="false">
<text></text>
</attributes>
<methods id="46" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
<ClassNode id="47">
<children id="48"/>
<location class="Point2D.Double" id="49" x="360.0" y="120.0"/>
<id id="50" value="7aa0d4b0-0910-4c57-83f2-b6df19957c13"/>
<revision>1</revision>
<backgroundColor reference="7"/>
<borderColor reference="8"/>
<textColor reference="8"/>
<name id="51" justification="1" size="3" underlined="false">
<text>network</text>
</name>
<attributes id="52" justification="0" size="4" underlined="false">
<text></text>
</attributes>
<methods id="53" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
</nodes>
<edges id="54">
<InheritanceEdge id="55">
<start class="ClassNode" reference="33"/>
<end class="ClassNode" reference="12"/>
<startLocation class="Point2D.Double" id="56" x="70.0" y="40.0"/>
<endLocation class="Point2D.Double" id="57" x="30.0" y="30.0"/>
<transitionPoints id="58"/>
<id id="59" value="ba9a78c0-41cb-4b0e-a145-f73768e527fa"/>
<revision>1</revision>
<bentStyle id="60" name="AUTO"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</InheritanceEdge>
<InheritanceEdge id="61">
<start class="ClassNode" reference="12"/>
<end class="ClassNode" reference="19"/>
<startLocation class="Point2D.Double" id="62" x="80.0" y="10.0"/>
<endLocation class="Point2D.Double" id="63" x="30.0" y="10.0"/>
<transitionPoints id="64"/>
<id id="65" value="83d334bd-774d-4307-acd5-9b0d6da1f13c"/>
<revision>1</revision>
<bentStyle reference="60"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</InheritanceEdge>
<InheritanceEdge id="66">
<start class="ClassNode" reference="47"/>
<end class="ClassNode" reference="3"/>
<startLocation class="Point2D.Double" id="67" x="70.0" y="40.0"/>
<endLocation class="Point2D.Double" id="68" x="50.0" y="20.0"/>
<transitionPoints id="69"/>
<id id="70" value="0f94def3-6d2c-423a-a959-4775a1a43a68"/>
<revision>1</revision>
<bentStyle reference="60"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</InheritanceEdge>
<InheritanceEdge id="71">
<start class="ClassNode" reference="47"/>
<end class="ClassNode" reference="12"/>
<startLocation class="Point2D.Double" id="72" x="50.0" y="40.0"/>
<endLocation class="Point2D.Double" id="73" x="80.0" y="40.0"/>
<transitionPoints id="74"/>
<id id="75" value="0ba32d54-4249-474b-9725-1a3da5304ca6"/>
<revision>1</revision>
<bentStyle reference="60"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</InheritanceEdge>
<InheritanceEdge id="76">
<start class="ClassNode" reference="47"/>
<end class="ClassNode" reference="19"/>
<startLocation class="Point2D.Double" id="77" x="60.0" y="50.0"/>
<endLocation class="Point2D.Double" id="78" x="60.0" y="20.0"/>
<transitionPoints id="79"/>
<id id="80" value="a7b9f455-5d43-4e8f-ac35-04b2588585e6"/>
<revision>1</revision>
<bentStyle id="81" name="VH"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</InheritanceEdge>
<InheritanceEdge id="82">
<start class="ClassNode" reference="40"/>
<end class="ClassNode" reference="12"/>
<startLocation class="Point2D.Double" id="83" x="60.0" y="30.0"/>
<endLocation class="Point2D.Double" id="84" x="70.0" y="20.0"/>
<transitionPoints id="85"/>
<id id="86" value="72b05ba8-a729-4c27-ba19-86b633f759f4"/>
<revision>1</revision>
<bentStyle reference="60"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</InheritanceEdge>
<InheritanceEdge id="87">
<start class="ClassNode" reference="40"/>
<end class="ClassNode" reference="19"/>
<startLocation class="Point2D.Double" id="88" x="60.0" y="30.0"/>
<endLocation class="Point2D.Double" id="89" x="80.0" y="30.0"/>
<transitionPoints id="90"/>
<id id="91" value="8a92da5b-6e31-40ed-9381-461f2a44d4e5"/>
<revision>1</revision>
<bentStyle reference="81"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</InheritanceEdge>
<InheritanceEdge id="92">
<start class="ClassNode" reference="26"/>
<end class="ClassNode" reference="33"/>
<startLocation class="Point2D.Double" id="93" x="40.0" y="20.0"/>
<endLocation class="Point2D.Double" id="94" x="80.0" y="50.0"/>
<transitionPoints id="95"/>
<id id="96" value="d197b0f6-02fe-45ba-911a-565c61555d50"/>
<revision>1</revision>
<bentStyle reference="60"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</InheritanceEdge>
<InheritanceEdge id="97">
<start class="ClassNode" reference="3"/>
<end class="ClassNode" reference="19"/>
<startLocation class="Point2D.Double" id="98" x="60.0" y="30.0"/>
<endLocation class="Point2D.Double" id="99" x="20.0" y="10.0"/>
<transitionPoints id="100"/>
<id id="101" value="d16a12c5-a820-4edb-a86a-1dc642b78fe8"/>
<revision>1</revision>
<bentStyle reference="81"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</InheritanceEdge>
<InheritanceEdge id="102">
<start class="ClassNode" reference="3"/>
<end class="ClassNode" reference="33"/>
<startLocation class="Point2D.Double" id="103" x="70.0" y="20.0"/>
<endLocation class="Point2D.Double" id="104" x="20.0" y="20.0"/>
<transitionPoints id="105"/>
<id id="106" value="cb85fb35-8df6-42f7-88e0-bf1b9fc37441"/>
<revision>1</revision>
<bentStyle reference="81"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</InheritanceEdge>
</edges>
</ClassDiagramGraph>]]></SCRIPT>
<BR />
<BR />
<IMG alt="embedded diagram image" src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0a
HBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIy
MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAExAdEDASIA
AhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQA
AAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3
ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWm
p6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEA
AwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSEx
BhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElK
U1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3
uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iii
gAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKjnn
htbeW4uJY4YIkLySSMFVFAySSeAAOc1JQBwfgvwX4VuvAvh64uPDWjTTy6ZbPJJJYRMzsYlJJJXJ
JPOa3P8AhBPB/wD0Kmh/+C6H/wCJo8Cf8k88Nf8AYKtf/RS10FAHP/8ACCeD/wDoVND/APBdD/8A
E0f8IJ4P/wChU0P/AMF0P/xNdBRQBz//AAgng/8A6FTQ/wDwXQ//ABNH/CCeD/8AoVND/wDBdD/8
TXQUUAc//wAIJ4P/AOhU0P8A8F0P/wATR/wgng//AKFTQ/8AwXQ//E10FFAHP/8ACCeD/wDoVND/
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
P/0L+kf+DiX/AORqADxL/wAjvof/AGDb7/0Za12NcBJJrOq+IrPUNQsbCzhtbS4gC29687O0jwt3
iTAAiPr1rv6ACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKA
CiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigArD8Wtq
f/CPywaTaXdxcXLrA5tJY45YYmOJJEZ3UBwm7acn59uRjNblFAHn8+rXd3PajRPBuqwXWhXcdu0Y
ezjjSJkQyQ8T8r5To6qPl3pFn7pFegVz/h7/AJDniz/sKx/+kVrXQUAFFFFABRRRQAUUUUAFFFFA
BRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAF
FFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBwfgvwX4VuvAvh64uPDWjTTy6ZbPJJJYRMz
sYlJJJXJJPOa3P8AhBPB/wD0Kmh/+C6H/wCJo8Cf8k88Nf8AYKtf/RS10FAHP/8ACCeD/wDoVND/
APBdD/8AE0f8IJ4P/wChU0P/AMF0P/xNdBRQBz//AAgng/8A6FTQ/wDwXQ//ABNH/CCeD/8AoVND
/wDBdD/8TXQUUAc//wAIJ4P/AOhU0P8A8F0P/wATR/wgng//AKFTQ/8AwXQ//E10FFAHP/8ACCeD
/wDoVND/APBdD/8AE0f8IJ4P/wChU0P/AMF0P/xNdBRQBz//AAgng/8A6FTQ/wDwXQ//ABNH/CCe
D/8AoVND/wDBdD/8TXQUUAcPLpmj+GfHulSaTo9jZ+fpl6sgtIEh34ltcZ2jnGT19TXcVx3iX/kd
9D/7Bt9/6Mta7GgAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACi
iigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAOf8Cf8k88Nf9gq
1/8ARS10Fc/4E/5J54a/7BVr/wCilroKACiiigAoorD8WeIv+EX0P+0vsv2n/SIYfL8zZ/rJFTOc
Hpuz0oA3KK4Z/G8lxrttYpbzQBNefS2McyEShYDJuYNGTj2Ug8fexxXc0LVX/rZP9Qejt/Xb9Aoo
ooAKKKKAOO8S/wDI76H/ANg2+/8ARlrXY1x3iX/kd9D/AOwbff8Aoy1rsaACiiigAooooAKKKKAC
iiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKK
KKACiiigAooooAKKKKACiiigAooooA5/wJ/yTzw1/wBgq1/9FLXQVz/gT/knnhr/ALBVr/6KWugo
AKKKKACszxBoVr4k0eXTbxpUidkcSREB0ZWDKwyCMggdQRWnRQBydn4A06zuYblr7ULiePU21QyT
OmXmaPyznCAbcc4GMHpxxXWUUUeQeYUUUUAFFFFAHHeJf+R30P8A7Bt9/wCjLWuxrjvEv/I76H/2
Db7/ANGWtdjQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQ
AUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAHP+BP+SeeGv8AsFWv
/opa6CuH0yXxX4Z8PaVpMmj6LP8AZLSO2Eq6tKu/y0Vd2Ps3GcZxk1P/AMJL4n/6F/SP/BxL/wDI
1AHY0Vx3/CS+J/8AoX9I/wDBxL/8jUf8JL4n/wChf0j/AMHEv/yNQB2NFcd/wkvif/oX9I/8HEv/
AMjUf8JL4n/6F/SP/BxL/wDI1AHY0Vx3/CS+J/8AoX9I/wDBxL/8jUf8JL4n/wChf0j/AMHEv/yN
QB2NFcd/wkvif/oX9I/8HEv/AMjUf8JL4n/6F/SP/BxL/wDI1AHY0Vx3/CS+J/8AoX9I/wDBxL/8
jUf8JL4n/wChf0j/AMHEv/yNQAeJf+R30P8A7Bt9/wCjLWuxrgJJNZ1XxFZ6hqFjYWcNraXEAW3v
XnZ2keFu8SYAER9etd/QAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFF
FFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUU
UAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH" />
</BODY>
</HTML>
-51
View File
@@ -1,51 +0,0 @@
--NOTE: I don't actually remember what this is
function CalcExp(base, mod, level)
return math.floor(base * mod ^ level)
end
function CalcSumExp(base, mod, level)
local ret = CalcExp(base, mod, level)
if (level > 1) then
return ret + CalcSumExp(base, mod, level-1)
else
return ret
end
end
function CalcExpTables(base, mod, levelCap)
local exp = {}
local sum = {}
for i = 1, levelCap do
exp[i] = CalcExp(base, mod, i)
sum[i] = CalcSumExp(base, mod, i)
end
return exp, sum
end
--the variables
base = 1000
mod = 1.14
levelCap = 20
--calc the tables
exp, sum = CalcExpTables(base, mod, levelCap)
--output the data
io.write("Level\t\tExp\t\tTotal\t\tLaps\n")
for i = 1, 60 do io.write("-") end
io.write("\n")
for i = 1, levelCap do
if i % 5 == 0 then
sep = "\t---\t"
else
sep = "\t\t"
end
io.write(i,
sep, exp[i],
sep, sum[i],
sep, math.floor(sum[i] / sum[1] * 10) / 10, --rounded
-- sep, sum[i] / sum[1], --real
"\n")
end
-887
View File
@@ -1,887 +0,0 @@
<HTML>
<HEAD>
<META name="description"
content="Violet UML Editor cross format document" />
<META name="keywords" content="Violet, UML" />
<META charset="UTF-8" />
<SCRIPT type="text/javascript">
function switchVisibility() {
var obj = document.getElementById("content");
obj.style.display = (obj.style.display == "block") ? "none" : "block";
}
</SCRIPT>
</HEAD>
<BODY>
This file was generated with Violet UML Editor 2.0.1.
&nbsp;&nbsp;(&nbsp;<A href=# onclick="switchVisibility()">View Source</A>&nbsp;/&nbsp;<A href="http://sourceforge.net/projects/violet/files/violetumleditor/" target="_blank">Download Violet</A>&nbsp;)
<BR />
<BR />
<SCRIPT id="content" type="text/xml"><![CDATA[<ClassDiagramGraph id="1">
<nodes id="2">
<ClassNode id="3">
<children id="4"/>
<location class="Point2D.Double" id="5" x="350.0" y="170.0"/>
<id id="6" value="ade258a7-467c-45b8-9ee5-dc95b71de6e3"/>
<revision>1</revision>
<backgroundColor id="7">
<red>255</red>
<green>255</green>
<blue>255</blue>
<alpha>255</alpha>
</backgroundColor>
<borderColor id="8">
<red>0</red>
<green>0</green>
<blue>0</blue>
<alpha>255</alpha>
</borderColor>
<textColor reference="8"/>
<name id="9" justification="1" size="3" underlined="false">
<text>Room Manager</text>
</name>
<attributes id="10" justification="0" size="4" underlined="false">
<text></text>
</attributes>
<methods id="11" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
<ClassNode id="12">
<children id="13"/>
<location class="Point2D.Double" id="14" x="530.0" y="170.0"/>
<id id="15" value="e15b382b-ee07-4378-9dc2-bb71324ab00c"/>
<revision>1</revision>
<backgroundColor reference="7"/>
<borderColor reference="8"/>
<textColor reference="8"/>
<name id="16" justification="1" size="3" underlined="false">
<text>Room Manager API</text>
</name>
<attributes id="17" justification="0" size="4" underlined="false">
<text></text>
</attributes>
<methods id="18" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
<ClassNode id="19">
<children id="20"/>
<location class="Point2D.Double" id="21" x="350.0" y="260.0"/>
<id id="22" value="5d366752-e93d-401e-84d7-956765189314"/>
<revision>1</revision>
<backgroundColor reference="7"/>
<borderColor reference="8"/>
<textColor reference="8"/>
<name id="23" justification="1" size="3" underlined="false">
<text>Room</text>
</name>
<attributes id="24" justification="0" size="4" underlined="false">
<text></text>
</attributes>
<methods id="25" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
<ClassNode id="26">
<children id="27"/>
<location class="Point2D.Double" id="28" x="530.0" y="260.0"/>
<id id="29" value="bf4307c3-e4b4-4149-a738-388f83027ef2"/>
<revision>1</revision>
<backgroundColor reference="7"/>
<borderColor reference="8"/>
<textColor reference="8"/>
<name id="30" justification="1" size="3" underlined="false">
<text>Room API</text>
</name>
<attributes id="31" justification="0" size="4" underlined="false">
<text></text>
</attributes>
<methods id="32" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
<ClassNode id="33">
<children id="34"/>
<location class="Point2D.Double" id="35" x="330.0" y="350.0"/>
<id id="36" value="9d0e83ab-6d53-4beb-97dd-7f88794f4740"/>
<revision>1</revision>
<backgroundColor reference="7"/>
<borderColor reference="8"/>
<textColor reference="8"/>
<name id="37" justification="1" size="3" underlined="false">
<text>Region Pager Lua</text>
</name>
<attributes id="38" justification="0" size="4" underlined="false">
<text></text>
</attributes>
<methods id="39" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
<ClassNode id="40">
<children id="41"/>
<location class="Point2D.Double" id="42" x="530.0" y="350.0"/>
<id id="43" value="42ec1576-602f-4815-86bb-f3e8f9631a4c"/>
<revision>1</revision>
<backgroundColor reference="7"/>
<borderColor reference="8"/>
<textColor reference="8"/>
<name id="44" justification="1" size="3" underlined="false">
<text>Region Pager API</text>
</name>
<attributes id="45" justification="0" size="4" underlined="false">
<text></text>
</attributes>
<methods id="46" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
<ClassNode id="47">
<children id="48"/>
<location class="Point2D.Double" id="49" x="350.0" y="440.0"/>
<id id="50" value="0b31e429-cceb-46bd-a8cd-57b6d7504fae"/>
<revision>1</revision>
<backgroundColor reference="7"/>
<borderColor reference="8"/>
<textColor reference="8"/>
<name id="51" justification="1" size="3" underlined="false">
<text>Region</text>
</name>
<attributes id="52" justification="0" size="4" underlined="false">
<text></text>
</attributes>
<methods id="53" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
<ClassNode id="54">
<children id="55"/>
<location class="Point2D.Double" id="56" x="530.0" y="440.0"/>
<id id="57" value="7447dbbb-e6e5-41d3-88e8-5c5a8dca878f"/>
<revision>1</revision>
<backgroundColor reference="7"/>
<borderColor reference="8"/>
<textColor reference="8"/>
<name id="58" justification="1" size="3" underlined="false">
<text>Region API</text>
</name>
<attributes id="59" justification="0" size="4" underlined="false">
<text></text>
</attributes>
<methods id="60" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
<ClassNode id="61">
<children id="62"/>
<location class="Point2D.Double" id="63" x="180.0" y="350.0"/>
<id id="64" value="fe0da63f-c0f7-4c29-8600-f4dfe900a35e"/>
<revision>1</revision>
<backgroundColor reference="7"/>
<borderColor reference="8"/>
<textColor reference="8"/>
<name id="65" justification="1" size="3" underlined="false">
<text>Region Pager Base</text>
</name>
<attributes id="66" justification="0" size="4" underlined="false">
<text></text>
</attributes>
<methods id="67" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
<ClassNode id="68">
<children id="69"/>
<location class="Point2D.Double" id="70" x="670.0" y="80.0"/>
<id id="71" value="504afa54-7c28-4d9c-9df6-637eb31280a2"/>
<revision>1</revision>
<backgroundColor reference="7"/>
<borderColor reference="8"/>
<textColor reference="8"/>
<name id="72" justification="1" size="3" underlined="false">
<text>linit.cpp
</text>
</name>
<attributes id="73" justification="0" size="4" underlined="false">
<text></text>
</attributes>
<methods id="74" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
</nodes>
<edges id="75">
<InheritanceEdge id="76">
<start class="ClassNode" reference="33"/>
<end class="ClassNode" reference="61"/>
<startLocation class="Point2D.Double" id="77" x="40.0" y="40.0"/>
<endLocation class="Point2D.Double" id="78" x="90.0" y="30.0"/>
<transitionPoints id="79"/>
<id id="80" value="b1fd37a2-2a76-4068-baf3-e65cb97169d2"/>
<revision>1</revision>
<bentStyle id="81" name="AUTO"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</InheritanceEdge>
<DependencyEdge id="82">
<start class="ClassNode" reference="54"/>
<end class="ClassNode" reference="47"/>
<startLocation class="Point2D.Double" id="83" x="50.0" y="30.0"/>
<endLocation class="Point2D.Double" id="84" x="60.0" y="30.0"/>
<transitionPoints id="85"/>
<id id="86" value="2ce8bdac-5d02-4db8-aef8-d53fe6fab19b"/>
<revision>1</revision>
<bentStyle reference="81"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</DependencyEdge>
<DependencyEdge id="87">
<start class="ClassNode" reference="40"/>
<end class="ClassNode" reference="33"/>
<startLocation class="Point2D.Double" id="88" x="50.0" y="30.0"/>
<endLocation class="Point2D.Double" id="89" x="80.0" y="40.0"/>
<transitionPoints id="90"/>
<id id="91" value="c885efd2-7ef9-4868-a89d-97fae5975c84"/>
<revision>1</revision>
<bentStyle reference="81"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</DependencyEdge>
<DependencyEdge id="92">
<start class="ClassNode" reference="26"/>
<end class="ClassNode" reference="19"/>
<startLocation class="Point2D.Double" id="93" x="50.0" y="40.0"/>
<endLocation class="Point2D.Double" id="94" x="70.0" y="30.0"/>
<transitionPoints id="95"/>
<id id="96" value="8ea2589c-ef6c-4b98-b1c1-7932da143615"/>
<revision>1</revision>
<bentStyle reference="81"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</DependencyEdge>
<DependencyEdge id="97">
<start class="ClassNode" reference="12"/>
<end class="ClassNode" reference="3"/>
<startLocation class="Point2D.Double" id="98" x="90.0" y="40.0"/>
<endLocation class="Point2D.Double" id="99" x="80.0" y="40.0"/>
<transitionPoints id="100"/>
<id id="101" value="63faf17b-3272-4f1e-84bb-17045f8e2f3d"/>
<revision>1</revision>
<bentStyle reference="81"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</DependencyEdge>
<DependencyEdge id="102">
<start class="ClassNode" reference="3"/>
<end class="ClassNode" reference="26"/>
<startLocation class="Point2D.Double" id="103" x="70.0" y="50.0"/>
<endLocation class="Point2D.Double" id="104" x="10.0" y="10.0"/>
<transitionPoints id="105"/>
<id id="106" value="f0183522-9c9e-4178-9b9e-98c40869584f"/>
<revision>1</revision>
<bentStyle reference="81"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</DependencyEdge>
<DependencyEdge id="107">
<start class="ClassNode" reference="26"/>
<end class="ClassNode" reference="33"/>
<startLocation class="Point2D.Double" id="108" x="60.0" y="40.0"/>
<endLocation class="Point2D.Double" id="109" x="70.0" y="20.0"/>
<transitionPoints id="110"/>
<id id="111" value="be0ab187-3bac-4b41-be4d-21cfc7e4e64c"/>
<revision>1</revision>
<bentStyle reference="81"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</DependencyEdge>
<DependencyEdge id="112">
<start class="ClassNode" reference="68"/>
<end class="ClassNode" reference="12"/>
<startLocation class="Point2D.Double" id="113" x="10.0" y="40.0"/>
<endLocation class="Point2D.Double" id="114" x="70.0" y="40.0"/>
<transitionPoints id="115"/>
<id id="116" value="ccc4f329-daef-44e7-a110-86702b831b23"/>
<revision>1</revision>
<bentStyle id="117" name="VH"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</DependencyEdge>
<DependencyEdge id="118">
<start class="ClassNode" reference="68"/>
<end class="ClassNode" reference="26"/>
<startLocation class="Point2D.Double" id="119" x="20.0" y="50.0"/>
<endLocation class="Point2D.Double" id="120" x="60.0" y="40.0"/>
<transitionPoints id="121"/>
<id id="122" value="06801cdf-84fb-4d20-828f-f675e8df60d6"/>
<revision>1</revision>
<bentStyle reference="117"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</DependencyEdge>
<DependencyEdge id="123">
<start class="ClassNode" reference="68"/>
<end class="ClassNode" reference="40"/>
<startLocation class="Point2D.Double" id="124" x="40.0" y="40.0"/>
<endLocation class="Point2D.Double" id="125" x="90.0" y="20.0"/>
<transitionPoints id="126"/>
<id id="127" value="b8baf414-2eb7-474f-b4ed-3c5fffca1dc7"/>
<revision>1</revision>
<bentStyle reference="117"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</DependencyEdge>
<DependencyEdge id="128">
<start class="ClassNode" reference="68"/>
<end class="ClassNode" reference="54"/>
<startLocation class="Point2D.Double" id="129" x="50.0" y="50.0"/>
<endLocation class="Point2D.Double" id="130" x="70.0" y="20.0"/>
<transitionPoints id="131"/>
<id id="132" value="9b76818a-5771-4ae9-8d08-fe4f682c3999"/>
<revision>1</revision>
<bentStyle reference="117"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</DependencyEdge>
<DependencyEdge id="133">
<start class="ClassNode" reference="61"/>
<end class="ClassNode" reference="47"/>
<startLocation class="Point2D.Double" id="134" x="80.0" y="50.0"/>
<endLocation class="Point2D.Double" id="135" x="40.0" y="40.0"/>
<transitionPoints id="136"/>
<id id="137" value="fb9c82c9-ff40-4889-921a-64c0209b286f"/>
<revision>1</revision>
<bentStyle reference="117"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</DependencyEdge>
<DependencyEdge id="138">
<start class="ClassNode" reference="33"/>
<end class="ClassNode" reference="54"/>
<startLocation class="Point2D.Double" id="139" x="70.0" y="40.0"/>
<endLocation class="Point2D.Double" id="140" x="40.0" y="20.0"/>
<transitionPoints id="141"/>
<id id="142" value="607d6549-e84f-41b7-8950-69d26ffa6c7c"/>
<revision>1</revision>
<bentStyle reference="81"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</DependencyEdge>
</edges>
</ClassDiagramGraph>]]></SCRIPT>
<BR />
<BR />
<IMG alt="embedded diagram image" src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0a
HBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIy
MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAGpAlMDASIA
AhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQA
AAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3
ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWm
p6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEA
AwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSEx
BhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElK
U1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3
uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iii
gAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKA
CiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAK
KKKACuL0/wANaDrPiTxVcapomm3066nGiyXVqkrBfsdscAsCcZJOPc12lc/4e/5Dniz/ALCsf/pF
a0AH/CCeD/8AoVND/wDBdD/8TR/wgng//oVND/8ABdD/APE10FFAHP8A/CCeD/8AoVND/wDBdD/8
TR/wgng//oVND/8ABdD/APE10FFAHP8A/CCeD/8AoVND/wDBdD/8TR/wgng//oVND/8ABdD/APE1
0FFAHP8A/CCeD/8AoVND/wDBdD/8TR/wgng//oVND/8ABdD/APE10FFAHP8A/CCeD/8AoVND/wDB
dD/8TR/wgng//oVND/8ABdD/APE10FFAHP8A/CCeD/8AoVND/wDBdD/8TWJ4q8LeG9H0m2v7Dw9p
VrdQ6np7JLBZxxuv+lwg4YLkZBI/Gu7rmvHn/IsL/wBhLT//AEshoA37Wf7TbpLt27s8Zz3xRUWm
f8g6L8f5migC3RRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFA
BRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAF
FFFABRRRQAUUUUAFFFFABXP+Hv8AkOeLP+wrH/6RWtdBXP8Ah7/kOeLP+wrH/wCkVrQB0FFFFABR
WD411G60jwRreo2MvlXdtZySxSbQ21gpIOCCD+NctB4+vobuS1Sye+uZdTg0+MTXKRIrPbCXcCsW
QueoO48kg9FoWra9Pxdgeiv6/hqej0V5hdfEi+uNNtr+xsjDcSaXqFybaW4UwrJbuFOSI9zdyMFQ
ehHOR0R8VXOlfD2w1zU7dJr6eGBVhhl4lllKqnzFRtyWBPHHOM45Fqr/ANbtfoD0dv60t/mdbRXH
al4u1vSjp1tdeG4hfX9/9iiVNQDQsDGXEgfy92BgggoCMEjPGc+D4j319fWmm2Hh5JNRl+1pPFLf
bEhkt2UMu4RksDuGDgdRkDOQX/r5XD+v0PQaKzPDutweI/D1jrFvG8cd3EJBG5BKHoQcehBFadNq
zswTuFc148/5Fhf+wlp//pZDXS1zXjz/AJFhf+wlp/8A6WQ0gNrTP+QdF+P8zRRpn/IOi/H+ZooA
t0UUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAB
RRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFF
FFABRRRQAVz/AIe/5Dniz/sKx/8ApFa10Fc/4e/5Dniz/sKx/wDpFa0AdBRRRQBQ1vSYNe0S90m6
eRILyFoZGiIDBWGDgkEZ/CsSPwBpUWoJercXnmLfx34BdceYkXlAfd+7t5PfPftXVUULR3B66HIQ
/DjRobeKDz71447a8tQGkXlLlt0mcKOQenp3zUh8B2kulPp13q2rXUH2aKCMSzIPJMTFo5ECoFDg
7RnHIUZB5z1dFC02/rf/ADYPXf8Ar+rHDa14Ev7+bSJIdevppbbUxez3V3MvmKojZAIlWPywQSDj
aAec5qvN8Nnj1vSJtO1S5tra1huxc3QkX7VLLOykvzGUOcHPAxxgcDHoNFH9fhYP6/G5S0nS7XRN
ItNMsUKW1rGIowTk4Hcnue9XaKKbd3dglYK5rx5/yLC/9hLT/wD0shrpa5rx5/yLC/8AYS0//wBL
IaQG1pn/ACDovx/maKNM/wCQdF+P8zRQBbooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKA
CiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAK
KKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigArn/D3/ACHPFn/YVj/9IrWugrk5I/EWianr
l5Zafpd3aX12lyjTahJDIuIIYipUQOOsZOd3Q0AdZRXHf8JL4n/6F/SP/BxL/wDI1Ml8V+IoEDza
JosallQM+syAFmIVRzbdSSAB3JFAHaUVx3/CS+J/+hf0j/wcS/8AyNR/wkvif/oX9I/8HEv/AMjU
AdjRXFp4r8RSvKkeiaK7RNskVdZkJRsBsH/RuDhgcehHrT/+El8T/wDQv6R/4OJf/kagDsaK4S/8
aeItOtknm8O6WytPFAAmryE7pJFjXrbdMsM+2atf8JL4n/6F/SP/AAcS/wDyNQB2NFcd/wAJL4n/
AOhf0j/wcS//ACNVW18aeIry5voI/DulhrOcQSFtXkwWMaScf6N0xIPxzQB3dc148/5Fhf8AsJaf
/wClkNU/+El8T/8AQv6R/wCDiX/5GqhrF74i12yisZ9J0u1h+1207ypqckrBYpklOFMC5JCY6jrQ
B2umf8g6L8f5mijTP+QdF+P8zRQBbooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig
AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAC
iiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKx/Ev2P+yoPt3n+T/aFlt8jG7zPtUXl5z/
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
/wDGq2v7Ms/+eP8A48f8aP7Ms/8Anj/48f8AGgDF/wCE80P+7q//AIJLz/41R/wnmh/3dX/8El5/
8ara/syz/wCeP/jx/wAaP7Ms/wDnj/48f8aAMX/hPND/ALur/wDgkvP/AI1R/wAJ5of93V//AASX
n/xqtr+zLP8A54/+PH/Gj+zLP/nj/wCPH/GgDF/4TzQ/7ur/APgkvP8A41R/wnmh/wB3V/8AwSXn
/wAara/syz/54/8Ajx/xo/syz/54/wDjx/xoA4zxP4n0/WtIhsLCHVHuHv7JwH0m6jUKlzE7Es8Y
UAKpOSe1dnpn/IOi/H+Zo/syz/54/wDjx/xqxFEkMYjjGFHQZoAfRRRQAVl6+80enRGCyjvHN7aA
xvEZAqm4jDPgdCikuD/CVB7VqVl6+k0mnRCC9js3F7aEyPKYwyi4jLJkdS6goB/EWA70AalFFFAG
XpTzNqOuCWyjt0S9URSLEUNwv2eE72P8ZDFkyOyAfw1qVl6Uky6jrhlvY7hHvVMUaylzbr9nhGxh
/ASwZ8Ds4P8AFWpQBl6+k0mnRCC9js3F7aEyPKYwyi4jLJkdS6goB/EWA71qVj+Jfsf9lQfbvP8A
J/tCy2+Rjd5n2qLy85/h37d3fbnHOK2KACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA
KKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigDH
8S/Y/wCyoPt3n+T/AGhZbfIxu8z7VF5ec/w79u7vtzjnFbFZevvNHp0Rgso7xze2gMbxGQKpuIwz
4HQopLg/wlQe1alABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAF
Y/iX7H/ZUH27z/J/tCy2+Rjd5n2qLy85/h37d3fbnHOK2Ky9feaPTojBZR3jm9tAY3iMgVTcRhnw
OhRSXB/hKg9qANSiiigDH0b7H/aviH7N5/nf2gn2rzcbfM+ywY2Y/h2bOvO7d2xWxWXpTzNqOuCW
yjt0S9URSLEUNwv2eE72P8ZDFkyOyAfw1qUAZevvNHp0Rgso7xze2gMbxGQKpuIwz4HQopLg/wAJ
UHtWpWXr6TSadEIL2OzcXtoTI8pjDKLiMsmR1LqCgH8RYDvWpQAUUUUAFFFFABRRRQAUUUUAFFFF
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
iigAooooAKKKKACiiigD" />
</BODY>
</HTML>
-707
View File
@@ -1,707 +0,0 @@
<HTML>
<HEAD>
<META name="description"
content="Violet UML Editor cross format document" />
<META name="keywords" content="Violet, UML" />
<META charset="UTF-8" />
<SCRIPT type="text/javascript">
function switchVisibility() {
var obj = document.getElementById("content");
obj.style.display = (obj.style.display == "block") ? "none" : "block";
}
</SCRIPT>
</HEAD>
<BODY>
This file was generated with Violet UML Editor 2.0.1.
&nbsp;&nbsp;(&nbsp;<A href=# onclick="switchVisibility()">View Source</A>&nbsp;/&nbsp;<A href="http://sourceforge.net/projects/violet/files/violetumleditor/" target="_blank">Download Violet</A>&nbsp;)
<BR />
<BR />
<SCRIPT id="content" type="text/xml"><![CDATA[<ClassDiagramGraph id="1">
<nodes id="2">
<ClassNode id="3">
<children id="4"/>
<location class="Point2D.Double" id="5" x="270.0" y="160.0"/>
<id id="6" value="5b32ec54-9391-435b-b712-b1c61f3065c7"/>
<revision>1</revision>
<backgroundColor id="7">
<red>255</red>
<green>255</green>
<blue>255</blue>
<alpha>255</alpha>
</backgroundColor>
<borderColor id="8">
<red>0</red>
<green>0</green>
<blue>0</blue>
<alpha>255</alpha>
</borderColor>
<textColor reference="8"/>
<name id="9" justification="1" size="3" underlined="false">
<text>SplashScreen</text>
</name>
<attributes id="10" justification="0" size="4" underlined="false">
<text></text>
</attributes>
<methods id="11" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
<ClassNode id="12">
<children id="13"/>
<location class="Point2D.Double" id="14" x="390.0" y="160.0"/>
<id id="15" value="509eabdd-9a4f-4afe-9efa-75352894f2da"/>
<revision>1</revision>
<backgroundColor reference="7"/>
<borderColor reference="8"/>
<textColor reference="8"/>
<name id="16" justification="1" size="3" underlined="false">
<text>MainMenu</text>
</name>
<attributes id="17" justification="0" size="4" underlined="false">
<text></text>
</attributes>
<methods id="18" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
<ClassNode id="19">
<children id="20"/>
<location class="Point2D.Double" id="21" x="390.0" y="80.0"/>
<id id="22" value="f3739b99-649e-42f0-89ad-29fad8851c34"/>
<revision>1</revision>
<backgroundColor reference="7"/>
<borderColor reference="8"/>
<textColor reference="8"/>
<name id="23" justification="1" size="3" underlined="false">
<text>OptionsScreen</text>
</name>
<attributes id="24" justification="0" size="4" underlined="false">
<text></text>
</attributes>
<methods id="25" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
<ClassNode id="26">
<children id="27"/>
<location class="Point2D.Double" id="28" x="510.0" y="160.0"/>
<id id="29" value="24950217-9261-4edd-8957-ea4e04531b0b"/>
<revision>1</revision>
<backgroundColor reference="7"/>
<borderColor reference="8"/>
<textColor reference="8"/>
<name id="30" justification="1" size="3" underlined="false">
<text>LobbyMenu</text>
</name>
<attributes id="31" justification="0" size="4" underlined="false">
<text></text>
</attributes>
<methods id="32" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
<ClassNode id="33">
<children id="34"/>
<location class="Point2D.Double" id="35" x="630.0" y="160.0"/>
<id id="36" value="613be92c-dcd5-48cb-a92f-daa489796507"/>
<revision>1</revision>
<backgroundColor reference="7"/>
<borderColor reference="8"/>
<textColor reference="8"/>
<name id="37" justification="1" size="3" underlined="false">
<text>InWorld</text>
</name>
<attributes id="38" justification="0" size="4" underlined="false">
<text></text>
</attributes>
<methods id="39" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
<ClassNode id="40">
<children id="41"/>
<location class="Point2D.Double" id="42" x="750.0" y="160.0"/>
<id id="43" value="b1444fff-d29d-437c-9af6-a104a8a6e46f"/>
<revision>1</revision>
<backgroundColor reference="7"/>
<borderColor reference="8"/>
<textColor reference="8"/>
<name id="44" justification="1" size="3" underlined="false">
<text>InCombat</text>
</name>
<attributes id="45" justification="0" size="4" underlined="false">
<text></text>
</attributes>
<methods id="46" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
<ClassNode id="47">
<children id="48"/>
<location class="Point2D.Double" id="49" x="390.0" y="240.0"/>
<id id="50" value="48ea5a7a-b90f-42cf-a531-ed968fc32384"/>
<revision>1</revision>
<backgroundColor reference="7"/>
<borderColor reference="8"/>
<textColor reference="8"/>
<name id="51" justification="1" size="3" underlined="false">
<text>Restart</text>
</name>
<attributes id="52" justification="0" size="4" underlined="false">
<text></text>
</attributes>
<methods id="53" justification="0" size="4" underlined="false">
<text></text>
</methods>
</ClassNode>
<NoteNode id="54">
<children id="55"/>
<location class="Point2D.Double" id="56" x="290.0" y="100.0"/>
<id id="57" value="02548e6f-7e1d-4ea1-983b-93c523f4208e"/>
<revision>1</revision>
<backgroundColor reference="7"/>
<borderColor reference="8"/>
<textColor reference="8"/>
<text id="58" justification="0" size="4" underlined="false">
<text>Entry</text>
</text>
<color id="59">
<red>255</red>
<green>228</green>
<blue>181</blue>
<alpha>255</alpha>
</color>
</NoteNode>
<NoteNode id="60">
<children id="61"/>
<location class="Point2D.Double" id="62" x="670.0" y="100.0"/>
<id id="63" value="1ac0e82a-a6c4-4a80-8f47-0462c4019f08"/>
<revision>1</revision>
<backgroundColor reference="7"/>
<borderColor reference="8"/>
<textColor reference="8"/>
<text id="64" justification="0" size="4" underlined="false">
<text>More gameplay scenes
would form a &quot;ring&quot; here.</text>
</text>
<color reference="59"/>
</NoteNode>
</nodes>
<edges id="65">
<InheritanceEdge id="66">
<start class="ClassNode" reference="3"/>
<end class="ClassNode" reference="12"/>
<startLocation class="Point2D.Double" id="67" x="60.0" y="20.0"/>
<endLocation class="Point2D.Double" id="68" x="10.0" y="30.0"/>
<transitionPoints id="69"/>
<id id="70" value="2e77bba5-4f49-4c7e-ae08-5bf30462cad4"/>
<revision>1</revision>
<bentStyle id="71" name="AUTO"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</InheritanceEdge>
<InheritanceEdge id="72">
<start class="ClassNode" reference="12"/>
<end class="ClassNode" reference="19"/>
<startLocation class="Point2D.Double" id="73" x="20.0" y="20.0"/>
<endLocation class="Point2D.Double" id="74" x="40.0" y="50.0"/>
<transitionPoints id="75"/>
<id id="76" value="593faf73-0d04-4044-8190-b51f525934fe"/>
<revision>1</revision>
<bentStyle reference="71"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</InheritanceEdge>
<InheritanceEdge id="77">
<start class="ClassNode" reference="19"/>
<end class="ClassNode" reference="12"/>
<startLocation class="Point2D.Double" id="78" x="60.0" y="40.0"/>
<endLocation class="Point2D.Double" id="79" x="70.0" y="10.0"/>
<transitionPoints id="80"/>
<id id="81" value="d91c37c3-2f3a-41be-b1b0-ba6996009142"/>
<revision>1</revision>
<bentStyle reference="71"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</InheritanceEdge>
<InheritanceEdge id="82">
<start class="ClassNode" reference="12"/>
<end class="ClassNode" reference="26"/>
<startLocation class="Point2D.Double" id="83" x="60.0" y="40.0"/>
<endLocation class="Point2D.Double" id="84" x="30.0" y="30.0"/>
<transitionPoints id="85"/>
<id id="86" value="ab5ccc8e-83c6-415c-9228-62059b5d1be0"/>
<revision>1</revision>
<bentStyle reference="71"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</InheritanceEdge>
<InheritanceEdge id="87">
<start class="ClassNode" reference="26"/>
<end class="ClassNode" reference="12"/>
<startLocation class="Point2D.Double" id="88" x="50.0" y="50.0"/>
<endLocation class="Point2D.Double" id="89" x="60.0" y="50.0"/>
<transitionPoints id="90"/>
<id id="91" value="08339cef-cf59-4e4f-9fd2-d41ff82c6b9d"/>
<revision>1</revision>
<bentStyle reference="71"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</InheritanceEdge>
<InheritanceEdge id="92">
<start class="ClassNode" reference="40"/>
<end class="ClassNode" reference="33"/>
<startLocation class="Point2D.Double" id="93" x="60.0" y="20.0"/>
<endLocation class="Point2D.Double" id="94" x="50.0" y="50.0"/>
<transitionPoints id="95"/>
<id id="96" value="d99e329a-956d-421e-86c8-99edeacdcedf"/>
<revision>1</revision>
<bentStyle reference="71"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</InheritanceEdge>
<InheritanceEdge id="97">
<start class="ClassNode" reference="33"/>
<end class="ClassNode" reference="40"/>
<startLocation class="Point2D.Double" id="98" x="30.0" y="50.0"/>
<endLocation class="Point2D.Double" id="99" x="10.0" y="30.0"/>
<transitionPoints id="100"/>
<id id="101" value="6dc43370-d54d-4a07-be04-4c5acfa5ada4"/>
<revision>1</revision>
<bentStyle reference="71"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</InheritanceEdge>
<InheritanceEdge id="102">
<start class="ClassNode" reference="26"/>
<end class="ClassNode" reference="33"/>
<startLocation class="Point2D.Double" id="103" x="80.0" y="40.0"/>
<endLocation class="Point2D.Double" id="104" x="0.0" y="40.0"/>
<transitionPoints id="105"/>
<id id="106" value="f7871ec1-1a9d-49e8-8fcf-1a02e2820fd2"/>
<revision>1</revision>
<bentStyle reference="71"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</InheritanceEdge>
<InheritanceEdge id="107">
<start class="ClassNode" reference="40"/>
<end class="ClassNode" reference="47"/>
<startLocation class="Point2D.Double" id="108" x="80.0" y="40.0"/>
<endLocation class="Point2D.Double" id="109" x="50.0" y="40.0"/>
<transitionPoints id="110"/>
<id id="111" value="ce83948d-91a0-4828-b072-9556a8d0e299"/>
<revision>1</revision>
<bentStyle id="112" name="VH"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</InheritanceEdge>
<InheritanceEdge id="113">
<start class="ClassNode" reference="47"/>
<end class="ClassNode" reference="12"/>
<startLocation class="Point2D.Double" id="114" x="40.0" y="20.0"/>
<endLocation class="Point2D.Double" id="115" x="40.0" y="40.0"/>
<transitionPoints id="116"/>
<id id="117" value="113fe696-2f24-42ca-a6a8-2cd29ffa548c"/>
<revision>1</revision>
<bentStyle reference="71"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</InheritanceEdge>
<InheritanceEdge id="118">
<start class="ClassNode" reference="33"/>
<end class="ClassNode" reference="47"/>
<startLocation class="Point2D.Double" id="119" x="30.0" y="30.0"/>
<endLocation class="Point2D.Double" id="120" x="70.0" y="30.0"/>
<transitionPoints id="121"/>
<id id="122" value="974b1797-f798-4edb-8591-2784c8f42e5c"/>
<revision>1</revision>
<bentStyle reference="112"/>
<startLabel></startLabel>
<middleLabel></middleLabel>
<endLabel></endLabel>
</InheritanceEdge>
<NoteEdge id="123">
<start class="NoteNode" reference="54"/>
<end class="ClassNode" reference="3"/>
<startLocation class="Point2D.Double" id="124" x="10.0" y="30.0"/>
<endLocation class="Point2D.Double" id="125" x="40.0" y="30.0"/>
<transitionPoints id="126"/>
<id id="127" value="0e21bed1-067a-4bf3-9658-80d1f0b44b79"/>
<revision>1</revision>
</NoteEdge>
<NoteEdge id="128">
<start class="ClassNode" reference="33"/>
<end class="NoteNode" reference="60"/>
<startLocation class="Point2D.Double" id="129" x="40.0" y="40.0"/>
<endLocation class="Point2D.Double" id="130" x="30.0" y="30.0"/>
<transitionPoints id="131"/>
<id id="132" value="e346a6e9-f902-453a-b7f5-09361550a4bf"/>
<revision>1</revision>
</NoteEdge>
<NoteEdge id="133">
<start class="ClassNode" reference="40"/>
<end class="NoteNode" reference="60"/>
<startLocation class="Point2D.Double" id="134" x="50.0" y="30.0"/>
<endLocation class="Point2D.Double" id="135" x="110.0" y="10.0"/>
<transitionPoints id="136"/>
<id id="137" value="647470c0-631c-434a-8bfb-793714950ec0"/>
<revision>1</revision>
</NoteEdge>
</edges>
</ClassDiagramGraph>]]></SCRIPT>
<BR />
<BR />
<IMG alt="embedded diagram image" src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0a
HBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIy
MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCADhAkkDASIA
AhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQA
AAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3
ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWm
p6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEA
AwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSEx
BhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElK
U1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3
uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iii
gAooooAKKKKACiiigAooooAKKKKACiiigArg/BfgvwrdeBfD1xceGtGmnl0y2eSSSwiZnYxKSSSu
SSec13lc/wCBP+SeeGv+wVa/+iloAP8AhBPB/wD0Kmh/+C6H/wCJo/4QTwf/ANCpof8A4Lof/ia6
CigDn/8AhBPB/wD0Kmh/+C6H/wCJo/4QTwf/ANCpof8A4Lof/ia6CigDn/8AhBPB/wD0Kmh/+C6H
/wCJo/4QTwf/ANCpof8A4Lof/ia6CigDn/8AhBPB/wD0Kmh/+C6H/wCJo/4QTwf/ANCpof8A4Lof
/ia6CigDn/8AhBPB/wD0Kmh/+C6H/wCJo/4QTwf/ANCpof8A4Lof/ia6CigDn/8AhBPB/wD0Kmh/
+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
/guh/wDiaAOgorn/APhBPB//AEKmh/8Aguh/+Jo/4QTwf/0Kmh/+C6H/AOJoA6Ciuf8A+EE8H/8A
QqaH/wCC6H/4mj/hBPB//QqaH/4Lof8A4mgDoKK5/wD4QTwf/wBCpof/AILof/iaP+EE8H/9Cpof
/guh/wDiaAOgorn/APhBPB//AEKmh/8Aguh/+Jo/4QTwf/0Kmh/+C6H/AOJoA6Ciuf8A+EE8H/8A
QqaH/wCC6H/4mj/hBPB//QqaH/4Lof8A4mgDoKK5/wD4QTwf/wBCpof/AILof/iaP+EE8H/9Cpof
/guh/wDiaAOgorn/APhBPB//AEKmh/8Aguh/+Jo/4QTwf/0Kmh/+C6H/AOJoA6Ciuf8A+EE8H/8A
QqaH/wCC6H/4mj/hBPB//QqaH/4Lof8A4mgDoKK5/wD4QTwf/wBCpof/AILof/iaP+EE8H/9Cpof
/guh/wDiaAOgorn/APhBPB//AEKmh/8Aguh/+Jo/4QTwf/0Kmh/+C6H/AOJoA6Ciuf8A+EE8H/8A
QqaH/wCC6H/4mj/hBPB//QqaH/4Lof8A4mgDoKK5/wD4QTwf/wBCpof/AILof/iaP+EE8H/9Cpof
/guh/wDiaAOgorn/APhBPB//AEKmh/8Aguh/+Jo/4QTwf/0Kmh/+C6H/AOJoAPD3/Ic8Wf8AYVj/
APSK1roKp6bpOm6Nbtb6Xp9pYwM5do7WFYlLYAyQoAzgAZ9hVygAooooAKKKKACiiigAooooAKKK
KACiiigAooooAKKKKACiiigAooooAK5/wJ/yTzw1/wBgq1/9FLXQVw+mS+K/DPh7StJk0fRZ/slp
HbCVdWlXf5aKu7H2bjOM4yaAO4orjv8AhJfE/wD0L+kf+DiX/wCRqP8AhJfE/wD0L+kf+DiX/wCR
qAOxorjv+El8T/8AQv6R/wCDiX/5Go/4SXxP/wBC/pH/AIOJf/kagDsaK47/AISXxP8A9C/pH/g4
l/8Akaj/AISXxP8A9C/pH/g4l/8AkagDsaK47/hJfE//AEL+kf8Ag4l/+RqP+El8T/8AQv6R/wCD
iX/5GoA7GiuO/wCEl8T/APQv6R/4OJf/AJGo/wCEl8T/APQv6R/4OJf/AJGoA7GuO8S/8jvof/YN
vv8A0Za0f8JL4n/6F/SP/BxL/wDI1UZJNZ1XxFZ6hqFjYWcNraXEAW3vXnZ2keFu8SYAER9etAHf
0UUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABR
RRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFF
FABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUU
AFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQA
UUUUAFFFFABRRRQB" />
</BODY>
</HTML>
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 321 B

+139
View File
@@ -0,0 +1,139 @@
--generate a roguelike map
--[[ DOCS: Game design theory, read more
As a basic starting point, I can create a list of "seed" tiles, which are the
center of rooms. The rooms can be any size, as long as they don't overlap. From
There, a tunnel can be "carved" from each seed tile to the next. Finally, the
map is populated, but that is beyond this exercise.
This specification isn't ironclad, as the current implementation has no overlap
prevention, resulting in some strange dungeon designs.
--]]
print("Beginning generator...")
function newroom(northBound, eastBound, southBound, westBound)
--place the room within proximity of the center, so that they're not too far apart.
local x = math.random(westBound, eastBound)
local y = math.random(northBound, southBound)
local w = math.random(2, 5)
local h = math.random(2, 5)
--return this new room
return {
seedX = x,
seedY = y,
--give it a decent size
north = y - h,
south = y + h,
east = x + w,
west = x - w,
}
end
function newpath(x1, y1, x2, y2)
--NOTE: a path is an ordered list of {x, y} pairs
local path = {}
local step = 0
--vertical
if y1 > y2 then
step = -1
else
step = 1
end
for i = y1, y2, step do
table.insert(path, {x = x1, y = i})
end
--horizontal
if x1 > x2 then
step = -1
else
step = 1
end
for i = x1, x2, step do
table.insert(path, {x = i, y = y2})
end
--NOTE: {x, y} pairs are duplicated at the corners
--TODO: improve the pathing system
return path
end
function buildpaths(roomlist)
local roomcount = #roomlist
local pathlist = {}
--tunnel the shortest paths
for i = 1, roomcount-1 do
table.insert(pathlist, newpath(
roomlist[i].seedX,
roomlist[i].seedY,
roomlist[i+1].seedX,
roomlist[i+1].seedY))
end
--return the new paths
return pathlist
end
print("Populating lists")
math.randomseed(os.time())
roomlist = {}
pathlist = {}
--populate the roomlist
roomcount = math.random(10, 15)
for i = 1, roomcount do
table.insert(roomlist, newroom(-30, 0, 30, -60)) --60x60
end
roomcount = math.random(5, 10)
for i = 1, roomcount do
table.insert(roomlist, newroom(-30, 50, 30, -10)) --60x60
end
print("Building boss room")
--boss room
local bossRoom = {
seedX = math.random(60, 90),
seedY = math.random(-30, 30),
}
bossRoom.north = bossRoom.seedY - 5
bossRoom.south = bossRoom.seedY + 5
bossRoom.east = bossRoom.seedX + 5
bossRoom.west = bossRoom.seedX - 5
table.insert(roomlist, bossRoom)
--paths
pathlist = buildpaths(roomlist)
--pass the data onto the pager
pager = ... --called as a chunk
--create the rooms
for k, iter in next, roomlist do
--for each tile in the room
for i = iter.west, iter.east do
for j = iter.north, iter.south do
--set
region_pager.SetTile(pager, i, j, 0, 14)
end
end
end
--create the paths
iter = nil
for k, path in next, pathlist do --multiple paths in the lsit
for k, iter in next, path do
--for each tile in the path, set
region_pager.SetTile(pager, iter.x, iter.y, 0, 14)
end
end
print("Generator finished")
+80
View File
@@ -0,0 +1,80 @@
--the indeces of tiles from an associated tileset
--this file is intended for use with a generator
--store the tilesheet's format
local format = {
fname = "roguetileset.png",
sheetWidth = 256,
sheetHeight = 256,
tileWidth = 16,
tileHeight = 16,
countX = 16,
countY = 16
}
--define the walls of the simple "walls" set
local walls = {
--concave
nw = format.countX * 0 + 1, n = format.countX * 0 + 2, ne = format.countX * 0 + 3,
w = format.countX * 1 + 1, e = format.countX * 1 + 3,
sw = format.countX * 2 + 1, s = format.countX * 2 + 2, se = format.countX * 2 + 3,
--convex (corner pieces jutting out)
--DOCS: These are named according to the corresponding tile they fit
sec = format.countX * 0 + 7, swc = format.countX * 0 + 9,
nec = format.countX * 2 + 7, nwc = format.countX * 2 + 9
}
--define the corridor pieces
--named for their door locations in the order nesw
local corridors = {
--straight
ns = 10, ew = 11,
--dead ends
s = format.countX * 0 + 8,
w = format.countX * 1 + 9,
n = format.countX * 2 + 8,
e = format.countX * 1 + 7,
--loop (compass)
es = format.countX * 0 + 4, esw = format.countX * 0 + 5, sw = format.countX * 0 + 6,
nes = format.countX * 1 + 4, nesw = format.countX * 1 + 5, nsw = format.countX * 1 + 6,
ne = format.countX * 2 + 4, new = format.countX * 2 + 5, nw = format.countX * 2 + 6
}
--DEBUG: dump the values
--[[
print("walls:")
for k, v in pairs(walls) do
print("", k, v)
end
print("corridors:")
for k, v in pairs(corridors) do
print("", k, v)
end
--]]
--DEBUG: test the values
--[[
local test = {}
for k, v in pairs(walls) do
if test[v] then
print("Error found: ", k)
return
end
test[v] = true
end
for k, v in pairs(corridors) do
if test[v] then
print("Error found: ", k)
return
end
test[v] = true
end
print("No errors detected")
--]]
return {format, walls, corridors}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.
+35
View File
@@ -0,0 +1,35 @@
--args are: userdata RegionPagerLua;
print("Running startup script")
pager = ...
--[[
--DOCS: These lambdas should return true or false, depending on if the operation succeeded or not
--DOCS: No return value given is recognized as a failure
--DOCS: OnCreate() and OnUnload() return values are currently ignored
region_pager.SetOnLoad(pager, function(r)
print("Calling SetOnLoad's lambda")
end)
region_pager.SetOnSave(pager, function(r)
print("Calling SetOnSave's lambda")
end)
region_pager.SetOnCreate(pager, function(r)
print("Calling SetOnCreate's lambda")
end)
region_pager.SetOnUnload(pager, function(r)
print("Calling SetOnUnload's lambda")
end)
--]]
generator, msg = loadfile("../rsc/roguegenerator.lua")
if generator == nil then
print("error: ", msg)
else
generator(pager)
end
print("Finished startup script")
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

+226
View File
@@ -0,0 +1,226 @@
/* Copyright: (c) Kayne Ruse 2015
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "application.hpp"
#include <chrono>
#include <iostream>
#include <sstream>
#include <stdexcept>
void Application::Init(int argc, char* argv[]) {
//create and check the window
window = SDL_CreateWindow(
"Example Caption",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
screenWidth,
screenHeight,
SDL_WINDOW_RESIZABLE);
if (!window) {
std::ostringstream msg;
msg << "Failed to create the window: " << SDL_GetError();
throw(std::runtime_error(msg.str()));
}
else {
std::cout << "Created the window" << std::endl;
}
//create and check the renderer
renderer = SDL_CreateRenderer(window, -1, 0);
if (!renderer) {
std::ostringstream msg;
msg << "Failed to create the renderer: " << SDL_GetError();
throw(std::runtime_error(msg.str()));
}
else {
std::cout << "Created the renderer" << std::endl;
}
//screen scaling
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "best");
SDL_RenderSetLogicalSize(renderer, screenWidth, screenHeight);
//set the hook for the renderer
BaseScene::SetRenderer(renderer);
std::cout << "Initialized screen scaling" << std::endl;
//setting up SDL2_ttf
if (TTF_Init()) {
std::ostringstream msg;
msg << "Failed to initialize SDL2_ttf: " << SDL_GetError();
throw(std::runtime_error(msg.str()));
}
else {
std::cout << "Initialized SDL2_ttf" << std::endl;
}
//setup lua
lua = luaL_newstate();
if (!lua) {
std::ostringstream msg;
msg << "Failed to create the lua state";
throw(std::runtime_error(msg.str()));
}
else {
std::cout << "Initialized lua" << std::endl;
}
luaL_openlibs(lua);
std::cout << "Initialization sucessful" << std::endl;
}
void Application::Proc() {
//load the first scene
ProcessSceneSignal(SceneSignal::FIRST);
//fixed frame rate
typedef std::chrono::steady_clock Clock;
Clock::time_point simTime = Clock::now();
Clock::time_point realTime;
constexpr std::chrono::duration<int, std::milli> frameDelay(16); //~60FPS
//the game loop continues until the scenes signal QUIT
while(activeScene->GetSceneSignal() != SceneSignal::QUIT) {
//switch scenes if necessary
if(activeScene->GetSceneSignal() != SceneSignal::CONTINUE) {
ProcessSceneSignal(activeScene->GetSceneSignal());
continue;
}
//update the current time
realTime = Clock::now();
//simulate the game or give the machine a break
if (simTime < realTime) {
while(simTime < realTime) {
//call the user defined functions
activeScene->FrameStart();
ProcessEvents();
activeScene->Update();
activeScene->FrameEnd();
//step to the next frame
simTime += frameDelay;
}
}
else {
SDL_Delay(1);
}
SDL_RenderClear(renderer);
activeScene->RenderFrame(renderer);
SDL_RenderPresent(renderer);
}
//cleanup
ClearScene();
}
void Application::Quit() {
std::cout << "Closing the APIs" << std::endl;
lua_close(lua);
TTF_Quit();
//clean up after the program
BaseScene::SetRenderer(nullptr);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
}
//-------------------------
//Scene management
//-------------------------
void Application::ProcessEvents() {
SDL_Event event;
while(SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_QUIT:
activeScene->QuitEvent();
break;
case SDL_MOUSEMOTION:
activeScene->MouseMotion(event.motion);
break;
case SDL_MOUSEBUTTONDOWN:
activeScene->MouseButtonDown(event.button);
break;
case SDL_MOUSEBUTTONUP:
activeScene->MouseButtonUp(event.button);
break;
case SDL_MOUSEWHEEL:
activeScene->MouseWheel(event.wheel);
break;
case SDL_KEYDOWN:
activeScene->KeyDown(event.key);
break;
case SDL_KEYUP:
activeScene->KeyUp(event.key);
break;
//TODO: joystick and controller events
//window events are handled internally
case SDL_WINDOWEVENT:
switch(event.window.event) {
case SDL_WINDOWEVENT_RESIZED:
SDL_RenderSetLogicalSize(renderer, event.window.data1, event.window.data2);
break;
}
break;
}
}
}
//Add the custom scene headers here
#include "example_scene.hpp"
void Application::ProcessSceneSignal(SceneSignal signal) {
ClearScene();
switch(signal) {
case SceneSignal::FIRST:
case SceneSignal::EXAMPLE_SCENE:
activeScene = new ExampleScene(lua);
break;
default: {
std::ostringstream msg;
msg << "Failed to recognize the scene signal: " << signal;
throw(std::logic_error(msg.str()));
}
}
}
void Application::ClearScene() {
delete activeScene;
activeScene = nullptr;
}
+58
View File
@@ -0,0 +1,58 @@
/* Copyright: (c) Kayne Ruse 2015
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#pragma once
#include "base_scene.hpp"
#include "scene_signal.hpp"
#include "lua.hpp"
#include "SDL2/SDL.h"
#include "SDL2/SDL_ttf.h"
//TODO: do something with these
constexpr int screenWidth = 800;
constexpr int screenHeight = 600;
//DOCS: The Application class handles scene switching, utilizing only one window
class Application {
public:
Application() = default;
~Application() = default;
void Init(int argc, char* argv[]);
void Proc();
void Quit();
private:
//scene management
void ProcessEvents();
void ProcessSceneSignal(SceneSignal);
void ClearScene();
BaseScene* activeScene = nullptr;
//TODO: build a "window" class?
SDL_Window* window = nullptr;
SDL_Renderer* renderer = nullptr;
lua_State* lua = nullptr;
};
+105
View File
@@ -0,0 +1,105 @@
/* Copyright: (c) Kayne Ruse 2015
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "base_scene.hpp"
SDL_Renderer* BaseScene::rendererHandle = nullptr;
BaseScene::BaseScene() {
//EMPTY
}
BaseScene::~BaseScene() {
//EMPTY
}
void BaseScene::RenderFrame(SDL_Renderer* renderer) {
//EMPTY
}
void BaseScene::SetRenderer(SDL_Renderer* r) {
rendererHandle = r;
}
SDL_Renderer* BaseScene::GetRenderer() {
return rendererHandle;
}
void BaseScene::SetSceneSignal(SceneSignal signal) {
sceneSignal = signal;
}
SceneSignal BaseScene::GetSceneSignal() {
return sceneSignal;
}
//-------------------------
//frame phases
//-------------------------
void BaseScene::FrameStart() {
//EMPTY
}
void BaseScene::Update() {
//EMPTY
}
void BaseScene::FrameEnd() {
//EMPTY
}
//-------------------------
//input events
//-------------------------
void BaseScene::QuitEvent() {
sceneSignal = SceneSignal::QUIT;
}
void BaseScene::MouseMotion(SDL_MouseMotionEvent const& event) {
//EMPTY
}
void BaseScene::MouseButtonDown(SDL_MouseButtonEvent const& event) {
//EMPTY
}
void BaseScene::MouseButtonUp(SDL_MouseButtonEvent const& event) {
//EMPTY
}
void BaseScene::MouseWheel(SDL_MouseWheelEvent const& event) {
//EMPTY
}
void BaseScene::KeyDown(SDL_KeyboardEvent const& event) {
//preference as a default
switch(event.keysym.sym) {
case SDLK_ESCAPE:
QuitEvent();
break;
}
}
void BaseScene::KeyUp(SDL_KeyboardEvent const& event) {
//EMPTY
}
+61
View File
@@ -0,0 +1,61 @@
/* Copyright: (c) Kayne Ruse 2015
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#pragma once
#include "scene_signal.hpp"
#include "SDL2/SDL.h"
class BaseScene {
public:
BaseScene();
virtual ~BaseScene();
virtual void RenderFrame(SDL_Renderer*);
static void SetRenderer(SDL_Renderer*);
SceneSignal GetSceneSignal();
//frame phases
virtual void FrameStart();
virtual void Update();
virtual void FrameEnd();
//input events
virtual void QuitEvent();
virtual void MouseMotion(SDL_MouseMotionEvent const& event);
virtual void MouseButtonDown(SDL_MouseButtonEvent const& event);
virtual void MouseButtonUp(SDL_MouseButtonEvent const& event);
virtual void MouseWheel(SDL_MouseWheelEvent const& event);
virtual void KeyDown(SDL_KeyboardEvent const& event);
virtual void KeyUp(SDL_KeyboardEvent const& event);
//TODO: joystick and controller events
protected:
//control
static SDL_Renderer* GetRenderer();
void SetSceneSignal(SceneSignal);
private:
static SDL_Renderer* rendererHandle;
SceneSignal sceneSignal = SceneSignal::CONTINUE;
};
+221
View File
@@ -0,0 +1,221 @@
/* Copyright: (c) Kayne Ruse 2015
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "example_scene.hpp"
#include <iomanip>
#include <iostream>
#include <sstream>
ExampleScene::ExampleScene(lua_State* L) {
lua = L;
//TODO: non-hardcoded source
tileSheet.Load(GetRenderer(), "../rsc/terrain.png", 32, 32);
//set the pager's hook
regionPager.SetLuaState(lua);
//load the file as a chunk
luaL_loadfile(lua, "../rsc/startup.lua");
//push the pager as an arg
lua_pushlightuserdata(lua, static_cast<void*>(&regionPager));
//run the function
lua_pcall(lua, 1, LUA_MULTRET, 0);
//DEBUG: cam jump
camera.x = -3000;
camera.y = -1500;
camera.scale = 0.25;
//DEBUG: testing buttons
buttonBG.Load(GetRenderer(), "../rsc/button.png");
//Ubuntu: "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"
font = TTF_OpenFont("C:\\Windows\\Fonts\\Arial.ttf", 12);
if (!font) {
std::ostringstream msg;
msg << "Failed to load a font: " << SDL_GetError();
throw(std::runtime_error(msg.str()));
}
button.SetBackgroundTexture(GetRenderer(), buttonBG.GetTexture());
button.SetText(GetRenderer(), font, "BUTTON TEXT", {0, 0, 0, 255});
button.SetX(400);
button.SetY(200);
// {140, 62, 54, 255}
//DEBUG: testing textLine
textBox.PushLine(GetRenderer(), font, "first line", {255, 255, 255, 255});
textBox.PushLine(GetRenderer(), font, "second line", {255, 255, 255, 255});
textBox.PushLine(GetRenderer(), font, "third line", {255, 255, 255, 255});
textBox.PushLine(GetRenderer(), font, "FOURTH LINE!!", {255, 0, 0, 0});
//
blankImage.Create(GetRenderer(), 256, 256);
//
std::cout << "Scene setup finished" << std::endl;
}
ExampleScene::~ExampleScene() {
TTF_CloseFont(font);
}
//-------------------------
//frame phases
//-------------------------
void ExampleScene::FrameStart() {
//
}
void ExampleScene::Update() {
//
}
void ExampleScene::FrameEnd() {
//
}
void ExampleScene::RenderFrame(SDL_Renderer* renderer) {
for (std::list<Region>::iterator it = regionPager.GetContainer()->begin(); it != regionPager.GetContainer()->end(); it++) {
//NOTE: Graphical scaling is done internally
tileSheet.DrawRegionTo(renderer, &(*it), camera.x, camera.y, camera.scale, camera.scale);
}
//DEBUG: testing UI
button.DrawTo(renderer);
textBox.DrawTo(renderer, 0, 550, -12);
blankImage.DrawTo(renderer, 0, 0);
}
//-------------------------
//input events
//-------------------------
void ExampleScene::MouseMotion(SDL_MouseMotionEvent const& event) {
Button::State state = button.MouseMotion(event);
if (state == Button::State::PRESSED) {
//motion while pressed
return;
}
//right mouse button moves the camera
if (event.state & SDL_BUTTON_RMASK) {
camera.x -= event.xrel / camera.scale;
camera.y -= event.yrel / camera.scale;
}
}
void ExampleScene::MouseButtonDown(SDL_MouseButtonEvent const& event) {
Button::State state = button.MouseButtonDown(event);
//catch button input
if (state == Button::State::PRESSED) {
//TODO: do stuff
std::cout << "pressed" << std::endl;
return;
}
switch(event.button) {
case SDL_BUTTON_LEFT: {
//DOCS: broke this down into several lines for clarity
//these are the "real" click positions, relative to the map
//(scaled input is transformed into unscaled tile selection)
int fieldX = event.x / camera.scale + camera.x;
int fieldY = event.y / camera.scale + camera.y;
//these are the x & y indexes of the selected tile
//NOTE: the terniary operator is used to circumvent an error with integer devision
int tileX = (fieldX >= 0 ? fieldX : fieldX - tileSheet.GetTileW()) / tileSheet.GetTileW();
int tileY = (fieldY >= 0 ? fieldY : fieldY - tileSheet.GetTileH()) / tileSheet.GetTileH();
//finally, call the method
regionPager.SetTile(tileX, tileY, layer, selection);
}
break;
}
}
void ExampleScene::MouseButtonUp(SDL_MouseButtonEvent const& event) {
Button::State state = button.MouseButtonUp(event);
//catch button input
if (state == Button::State::RELEASED) {
std::cout << "released" << std::endl;
return;
}
}
void ExampleScene::MouseWheel(SDL_MouseWheelEvent const& event) {
constexpr double scaleMod = 1.2;
constexpr double scaleUpperBound = 3.0;
constexpr double scaleLowerBound = 0.5;
//zoom out
if (event.y < 0) { //downscroll
if (camera.scale / scaleMod <= scaleLowerBound) {
camera.scale = scaleLowerBound;
}
else {
camera.scale /= scaleMod;
}
}
//zoom in
if (event.y > 0) { //upscroll
if (camera.scale * scaleMod >= scaleUpperBound) {
camera.scale = scaleUpperBound;
}
else {
camera.scale *= scaleMod;
}
}
}
void ExampleScene::KeyDown(SDL_KeyboardEvent const& event) {
//preference as a default
switch(event.keysym.sym) {
case SDLK_ESCAPE:
QuitEvent();
break;
case SDLK_r:
SetSceneSignal(SceneSignal::EXAMPLE_SCENE);
break;
case SDLK_SPACE:
camera.scale = 1.0;
break;
case SDLK_RETURN:
textBox.PushLine(GetRenderer(), font, "You pressed enter.", {128, 128, 128, 255});
break;
}
}
void ExampleScene::KeyUp(SDL_KeyboardEvent const& event) {
//
}
+74
View File
@@ -0,0 +1,74 @@
/* Copyright: (c) Kayne Ruse 2015
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#pragma once
#include "base_scene.hpp"
#include "button.hpp"
#include "region_pager_lua.hpp"
#include "text_box.hpp"
#include "tile_sheet.hpp"
#include "lua.hpp"
#include "SDL2/SDL_ttf.h"
class ExampleScene : public BaseScene {
public:
ExampleScene(lua_State* L);
~ExampleScene();
void RenderFrame(SDL_Renderer* renderer) override;
private:
//frame phases
void FrameStart() override;
void Update() override;
void FrameEnd() override;
//input events
void MouseMotion(SDL_MouseMotionEvent const& event) override;
void MouseButtonDown(SDL_MouseButtonEvent const& event) override;
void MouseButtonUp(SDL_MouseButtonEvent const& event) override;
void MouseWheel(SDL_MouseWheelEvent const& event) override;
void KeyDown(SDL_KeyboardEvent const& event) override;
void KeyUp(SDL_KeyboardEvent const& event) override;
//members
lua_State* lua = nullptr;
RegionPagerLua regionPager;
TileSheet tileSheet;
struct {
int x = 0;
int y = 0;
double scale = 1.0;
} camera;
int selection = 1;
int layer = 0;
TTF_Font* font = nullptr;
Image buttonBG;
Button button;
TextBox textBox;
//blank image
Image blankImage;
};
+66
View File
@@ -0,0 +1,66 @@
/*
** $Id: linit.c,v 1.32.1.1 2013/04/12 18:48:47 roberto Exp $
** Initialization of libraries for lua.c and other clients
** See Copyright Notice in lua.h
*/
/*
** 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.hpp"
#include "region_api.hpp"
#include "region_pager_api.hpp"
/*
** these libs are loaded by lua.c and are readily available to any Lua
** program
*/
static const luaL_Reg loadedlibs[] = {
{"_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 stuff
{TORTUGA_REGION_API, openRegionAPI},
{TORTUGA_REGION_PAGER_API, openRegionPagerAPI},
{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 */
}
+43
View File
@@ -0,0 +1,43 @@
/* Copyright: (c) Kayne Ruse 2015
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "application.hpp"
#include "SDL2/SDL.h"
#include <iostream>
#include <stdexcept>
int main(int argc, char** argv) {
std::cout << "Beginning " << argv[0] << std::endl;
try {
Application app;
app.Init(argc, argv);
app.Proc();
app.Quit();
}
catch(std::exception& e) {
std::cerr << "Fatal Error: " << e.what() << std::endl;
return 1;
}
std::cout << "Clean exit from " << argv[0] << std::endl;
return 0;
}
+60
View File
@@ -0,0 +1,60 @@
#include directories
INCLUDES+=. ../common/graphics ../common/map
#libraries
#the order of the $(LIBS) is important, at least for MinGW
LIBS+=../common/libcommon.a
ifeq ($(OS),Windows_NT)
LIBS+=-lmingw32
endif
LIBS+=-lSDL2main -lSDL2 -lSDL2_image -lSDL2_ttf -llua
ifeq ($(shell uname), Linux)
#I don't know what this does, but Ubuntu needs it (dynamic linking for lua)
LIBS+=-ldl
endif
#flags
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
ifeq ($(shell uname), Linux)
#read data about the current install
CXXFLAGS+=$(shell sdl-config --cflags --static-libs)
endif
#source
CXXSRC=$(wildcard *.cpp)
#objects
OBJDIR=obj
OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o))
#output
OUTDIR=../out
OUT=$(addprefix $(OUTDIR)/,map)
#targets
all: $(OBJ) $(OUT)
$(CXX) $(CXXFLAGS) -o $(OUT) $(OBJ) $(LIBS)
$(OBJ): | $(OBJDIR)
$(OUT): | $(OUTDIR)
$(OBJDIR):
mkdir $(OBJDIR)
$(OUTDIR):
mkdir $(OUTDIR)
$(OBJDIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
clean:
ifeq ($(OS),Windows_NT)
$(RM) *.o *.a *.exe
else ifeq ($(shell uname), Linux)
find . -type f -name '*.o' -exec rm -f -r -v {} \;
find . -type f -name '*.a' -exec rm -f -r -v {} \;
rm -f -v $(OUT)
endif
rebuild: clean all
+32
View File
@@ -0,0 +1,32 @@
/* Copyright: (c) Kayne Ruse 2015
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#pragma once
enum SceneSignal {
//reserved members for internal use
QUIT = -1,
CONTINUE = 0,
FIRST = 1,
//custom scenes
EXAMPLE_SCENE
};