Merge branch 'develop', read more

The trigger system has been fully implemented, as well as a few other
tweaks as the occasional thought came to mind.

Multiple rooms are now fully functional, mostly as a way to test the
triggers. Although there are still no real generation algorithms, a
utility for creating door pairs between given rooms is included in the
scripts directory.

Other changes in this merge include:

* Network updates via lua
* Entity types can be determined in lua
* Database columns are now order independant

It should be noted that only two types of userdata will work as far as
entity names are concerned: Characters and Monsters. I tried getting it to
work for all objects passed to lua, but it proved to be too obtuse.

In theory, I could create a teleport puzzle using what I've written here.
That might be a side project, or a way to test saving & loading systems. I
don't see any reason to delay monsters any longer; hopefully, I can get
them going soon too.
This commit is contained in:
Kayne Ruse
2015-03-13 21:28:05 +11:00
70 changed files with 1010 additions and 868 deletions
+1 -1
View File
@@ -24,7 +24,7 @@
#include "config_utility.hpp" #include "config_utility.hpp"
void BaseMonster::CorrectSprite() { void BaseMonster::CorrectSprite() {
//TODO: (9) empty //TODO: (9) BaseMonster::CorrectSprite()
} }
std::string BaseMonster::SetHandle(std::string s) { std::string BaseMonster::SetHandle(std::string s) {
+28 -14
View File
@@ -67,25 +67,35 @@ void World::hCharacterCreate(CharacterPacket* const argPacket) {
BaseCharacter* character = &characterMap[argPacket->characterIndex]; BaseCharacter* character = &characterMap[argPacket->characterIndex];
//fill the character's info //fill the character's info
character->SetOrigin(argPacket->origin);
character->SetMotion(argPacket->motion);
character->SetBounds({CHARACTER_BOUNDS_X, CHARACTER_BOUNDS_Y, CHARACTER_BOUNDS_WIDTH, CHARACTER_BOUNDS_HEIGHT}); //TODO: (1) send the bounds from the server
character->SetHandle(argPacket->handle); character->SetHandle(argPacket->handle);
character->SetAvatar(argPacket->avatar); character->SetAvatar(argPacket->avatar);
character->SetOwner(argPacket->accountIndex); character->SetOwner(argPacket->accountIndex);
character->SetOrigin(argPacket->origin);
character->SetMotion(argPacket->motion);
character->SetBounds(argPacket->bounds);
character->CorrectSprite(); character->CorrectSprite();
//check for this player's character //check for this player's character
if (character->GetOwner() == accountIndex) { if (character->GetOwner() == accountIndex) {
localCharacter = static_cast<LocalCharacter*>(character); localCharacter = static_cast<LocalCharacter*>(character);
//focus the camera on this character //focus the camera on this character's sprite
camera.marginX = (camera.width / 2 - localCharacter->GetSprite()->GetImage()->GetClipW() / 2); camera.marginX = (camera.width / 2 - localCharacter->GetSprite()->GetImage()->GetClipW() / 2);
camera.marginY = (camera.height/ 2 - localCharacter->GetSprite()->GetImage()->GetClipH() / 2); camera.marginY = (camera.height/ 2 - localCharacter->GetSprite()->GetImage()->GetClipH() / 2);
//focus on this character's info //focus on this character's info
characterIndex = argPacket->characterIndex; characterIndex = argPacket->characterIndex;
roomIndex = argPacket->roomIndex; roomIndex = argPacket->roomIndex;
//query the world state (room)
CharacterPacket newPacket;
memset(&newPacket, 0, MAX_PACKET_SIZE);
newPacket.type = SerialPacketType::QUERY_CHARACTER_EXISTS;
newPacket.roomIndex = roomIndex;
network.SendTo(Channels::SERVER, &newPacket);
newPacket.type = SerialPacketType::QUERY_MONSTER_EXISTS;
network.SendTo(Channels::SERVER, &newPacket);
} }
//debug //debug
@@ -109,10 +119,14 @@ void World::hCharacterDelete(CharacterPacket* const argPacket) {
//clear the room //clear the room
roomIndex = -1; roomIndex = -1;
regionPager.UnloadAll();
characterMap.clear();
monsterMap.clear();
}
else {
//remove this character
characterMap.erase(characterIt);
} }
//remove this character
characterMap.erase(characterIt);
//debug //debug
std::cout << "Character Delete, total: " << characterMap.size() << std::endl; std::cout << "Character Delete, total: " << characterMap.size() << std::endl;
@@ -120,9 +134,9 @@ void World::hCharacterDelete(CharacterPacket* const argPacket) {
void World::hQueryCharacterExists(CharacterPacket* const argPacket) { void World::hQueryCharacterExists(CharacterPacket* const argPacket) {
//prevent a double message about this player's character //prevent a double message about this player's character
if (argPacket->accountIndex == accountIndex) { // if (argPacket->accountIndex == accountIndex) {
return; // return;
} // }
//ignore characters in a different room (sub-optimal) //ignore characters in a different room (sub-optimal)
if (argPacket->roomIndex != roomIndex) { if (argPacket->roomIndex != roomIndex) {
@@ -146,11 +160,11 @@ void World::hQueryCharacterExists(CharacterPacket* const argPacket) {
} }
void World::hQueryCharacterStats(CharacterPacket* const argPacket) { void World::hQueryCharacterStats(CharacterPacket* const argPacket) {
//TODO: (9) empty //TODO: (9) World::hQueryCharacterStats()
} }
void World::hQueryCharacterLocation(CharacterPacket* const argPacket) { void World::hQueryCharacterLocation(CharacterPacket* const argPacket) {
//TODO: (9) empty //TODO: (9) World::hQueryCharacterLocation()
} }
void World::hCharacterMovement(CharacterPacket* const argPacket) { void World::hCharacterMovement(CharacterPacket* const argPacket) {
@@ -170,11 +184,11 @@ void World::hCharacterMovement(CharacterPacket* const argPacket) {
} }
void World::hCharacterAttack(CharacterPacket* const argPacket) { void World::hCharacterAttack(CharacterPacket* const argPacket) {
//TODO: (9) empty //TODO: (9) World::hCharacterAttack()
} }
void World::hCharacterDamage(CharacterPacket* const argPacket) { void World::hCharacterDamage(CharacterPacket* const argPacket) {
//TODO: (9) empty //TODO: (9) World::hCharacterDamage()
} }
//------------------------- //-------------------------
+3 -3
View File
@@ -26,14 +26,14 @@
//------------------------- //-------------------------
void World::hTextBroadcast(TextPacket* const argPacket) { void World::hTextBroadcast(TextPacket* const argPacket) {
//TODO: (9) empty //TODO: (9) World::hTextBroadcast()
} }
void World::hTextSpeech(TextPacket* const argPacket) { void World::hTextSpeech(TextPacket* const argPacket) {
//TODO: (9) empty //TODO: (9) World::hTextSpeech()
} }
void World::hTextWhisper(TextPacket* const argPacket) { void World::hTextWhisper(TextPacket* const argPacket) {
//TODO: (9) empty //TODO: (9) World::hTextWhisper()
} }
+1 -2
View File
@@ -91,10 +91,9 @@ void World::SendDisconnectRequest() {
} }
void World::SendAdminDisconnectForced() { void World::SendAdminDisconnectForced() {
//TODO: (9) empty //TODO: (9) World::SendAdminDisconnectForced()
} }
void World::SendAdminShutdownRequest() { void World::SendAdminShutdownRequest() {
ClientPacket newPacket; ClientPacket newPacket;
+2 -9
View File
@@ -60,7 +60,7 @@ World::World(int* const argClientIndex, int* const argAccountIndex):
shutDownButton.SetText("Shut Down"); shutDownButton.SetText("Shut Down");
//load the tilesheet //load the tilesheet
//TODO: (1) Tile size and tile sheet should be loaded elsewhere //TODO: (2) Tile size and tile sheet should be loaded elsewhere
tileSheet.Load(config["dir.tilesets"] + "overworld.bmp", 32, 32); tileSheet.Load(config["dir.tilesets"] + "overworld.bmp", 32, 32);
//Send the character data //Send the character data
@@ -71,13 +71,6 @@ World::World(int* const argClientIndex, int* const argAccountIndex):
newPacket.accountIndex = accountIndex; newPacket.accountIndex = accountIndex;
network.SendTo(Channels::SERVER, &newPacket); network.SendTo(Channels::SERVER, &newPacket);
//query the world state
memset(&newPacket, 0, MAX_PACKET_SIZE);
newPacket.type = SerialPacketType::QUERY_CHARACTER_EXISTS;
network.SendTo(Channels::SERVER, &newPacket);
newPacket.type = SerialPacketType::QUERY_MONSTER_EXISTS;
network.SendTo(Channels::SERVER, &newPacket);
//set the camera's values //set the camera's values
camera.width = GetScreen()->w; camera.width = GetScreen()->w;
camera.height = GetScreen()->h; camera.height = GetScreen()->h;
@@ -221,7 +214,7 @@ void World::KeyDown(SDL_KeyboardEvent const& key) {
//hotkeys //hotkeys
switch(key.keysym.sym) { switch(key.keysym.sym) {
case SDLK_ESCAPE: case SDLK_ESCAPE:
//TODO: (1) the escape key should actually control menus and stuff //TODO: (3) the escape key should actually control menus and stuff
SendLogoutRequest(); SendLogoutRequest();
return; return;
} }
+4 -4
View File
@@ -99,11 +99,11 @@ void World::hQueryMonsterExists(MonsterPacket* const argPacket) {
} }
void World::hQueryMonsterStats(MonsterPacket* const argPacket) { void World::hQueryMonsterStats(MonsterPacket* const argPacket) {
//TODO: (9) empty //TODO: (9) World::hQueryMonsterStats()
} }
void World::hQueryMonsterLocation(MonsterPacket* const argPacket) { void World::hQueryMonsterLocation(MonsterPacket* const argPacket) {
//TODO: (9) empty //TODO: (9) World::hQueryMonsterLocation()
} }
void World::hMonsterMovement(MonsterPacket* const argPacket) { void World::hMonsterMovement(MonsterPacket* const argPacket) {
@@ -118,9 +118,9 @@ void World::hMonsterMovement(MonsterPacket* const argPacket) {
} }
void World::hMonsterAttack(MonsterPacket* const argPacket) { void World::hMonsterAttack(MonsterPacket* const argPacket) {
//TODO: (9) empty //TODO: (9) World::hMonsterAttack()
} }
void World::hMonsterDamage(MonsterPacket* const argPacket) { void World::hMonsterDamage(MonsterPacket* const argPacket) {
//TODO: (9) empty //TODO: (9) World::hMonsterDamage()
} }
+4 -3
View File
@@ -107,7 +107,8 @@ void LobbyMenu::Render(SDL_Surface* const screen) {
join.DrawTo(screen); join.DrawTo(screen);
back.DrawTo(screen); back.DrawTo(screen);
//TODO: (1) draw headers for the server list //TODO: (3) draw headers for the server list
//TODO: (3) ping/delay displayed in the server list
for (int i = 0; i < serverInfo.size(); i++) { for (int i = 0; i < serverInfo.size(); i++) {
//draw the selected server's highlight //draw the selected server's highlight
if (selection == &serverInfo[i]) { if (selection == &serverInfo[i]) {
@@ -252,11 +253,11 @@ void LobbyMenu::HandleLoginResponse(ClientPacket* const argPacket) {
} }
void LobbyMenu::HandleJoinRejection(TextPacket* const argPacket) { void LobbyMenu::HandleJoinRejection(TextPacket* const argPacket) {
//TODO: (9) empty //TODO: (9) LobbyMenu::HandleJoinRejection()
} }
void LobbyMenu::HandleLoginRejection(TextPacket* const argPacket) { void LobbyMenu::HandleLoginRejection(TextPacket* const argPacket) {
//TODO: (9) empty //TODO: (9) LobbyMenu::HandleLoginRejection
} }
//------------------------- //-------------------------
-55
View File
@@ -1,55 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013-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 "map_system_api.hpp"
//all map API headers
#include "region_api.hpp"
#include "region_pager_api.hpp"
//useful "globals"
//...
//This mimics linit.c to create a nested collection of all map modules.
static const luaL_Reg funcs[] = {
{nullptr, nullptr}
};
static const luaL_Reg libs[] = {
{"Region", openRegionAPI},
{"RegionPager", openRegionPagerAPI},
{nullptr, nullptr}
};
int openMapSystemAPI(lua_State* L) {
//create the table
luaL_newlibtable(L, libs);
//push the "global" functions
luaL_setfuncs(L, funcs, 0);
//push the substable
for (const luaL_Reg* lib = libs; lib->func; lib++) {
lib->func(L);
lua_setfield(L, -2, lib->name);
}
return 1;
}
-30
View File
@@ -1,30 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013-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.
*/
#ifndef MAPSYSTEMAPI_HPP_
#define MAPSYSTEMAPI_APP_
#include "lua.hpp"
#define TORTUGA_MAP_SYSTEM_API "map_system"
LUAMOD_API int openMapSystemAPI(lua_State* L);
#endif
+1 -1
View File
@@ -24,7 +24,7 @@
#include "lua.hpp" #include "lua.hpp"
#define TORTUGA_REGION_NAME "region" #define TORTUGA_REGION_API "region"
LUAMOD_API int openRegionAPI(lua_State* L); LUAMOD_API int openRegionAPI(lua_State* L);
#endif #endif
+1
View File
@@ -25,6 +25,7 @@
#include "region.hpp" #include "region.hpp"
//DOCS: These glue functions simply wrap RegionPagerLua's methods //DOCS: These glue functions simply wrap RegionPagerLua's methods
//NOTE: zero indexing is used here, but not in the region API
static int setTile(lua_State* L) { static int setTile(lua_State* L) {
RegionPagerLua* pager = reinterpret_cast<RegionPagerLua*>(lua_touserdata(L, 1)); RegionPagerLua* pager = reinterpret_cast<RegionPagerLua*>(lua_touserdata(L, 1));
+1 -1
View File
@@ -24,7 +24,7 @@
#include "lua.hpp" #include "lua.hpp"
#define TORTUGA_REGION_PAGER_NAME "region_pager" #define TORTUGA_REGION_PAGER_API "region_pager"
LUAMOD_API int openRegionPagerAPI(lua_State* L); LUAMOD_API int openRegionPagerAPI(lua_State* L);
#endif #endif
@@ -36,11 +36,18 @@ void serializeCharacter(void* buffer, CharacterPacket* packet) {
//location //location
serialCopy(&buffer, &packet->roomIndex, sizeof(int)); serialCopy(&buffer, &packet->roomIndex, sizeof(int));
serialCopy(&buffer, &packet->origin.x, sizeof(double)); serialCopy(&buffer, &packet->origin.x, sizeof(double));
serialCopy(&buffer, &packet->origin.y, sizeof(double)); serialCopy(&buffer, &packet->origin.y, sizeof(double));
serialCopy(&buffer, &packet->motion.x, sizeof(double)); serialCopy(&buffer, &packet->motion.x, sizeof(double));
serialCopy(&buffer, &packet->motion.y, sizeof(double)); serialCopy(&buffer, &packet->motion.y, sizeof(double));
serialCopy(&buffer, &packet->bounds.x, sizeof(int));
serialCopy(&buffer, &packet->bounds.y, sizeof(int));
serialCopy(&buffer, &packet->bounds.w, sizeof(int));
serialCopy(&buffer, &packet->bounds.h, sizeof(int));
//gameplay components: equipment, items, buffs, debuffs... //gameplay components: equipment, items, buffs, debuffs...
} }
@@ -57,10 +64,17 @@ void deserializeCharacter(void* buffer, CharacterPacket* packet) {
//location //location
deserialCopy(&buffer, &packet->roomIndex, sizeof(int)); deserialCopy(&buffer, &packet->roomIndex, sizeof(int));
deserialCopy(&buffer, &packet->origin.x, sizeof(double)); deserialCopy(&buffer, &packet->origin.x, sizeof(double));
deserialCopy(&buffer, &packet->origin.y, sizeof(double)); deserialCopy(&buffer, &packet->origin.y, sizeof(double));
deserialCopy(&buffer, &packet->motion.x, sizeof(double)); deserialCopy(&buffer, &packet->motion.x, sizeof(double));
deserialCopy(&buffer, &packet->motion.y, sizeof(double)); deserialCopy(&buffer, &packet->motion.y, sizeof(double));
deserialCopy(&buffer, &packet->bounds.x, sizeof(int));
deserialCopy(&buffer, &packet->bounds.y, sizeof(int));
deserialCopy(&buffer, &packet->bounds.w, sizeof(int));
deserialCopy(&buffer, &packet->bounds.h, sizeof(int));
//gameplay components: equipment, items, buffs, debuffs... //gameplay components: equipment, items, buffs, debuffs...
} }
@@ -24,6 +24,7 @@
#include "serial_packet_base.hpp" #include "serial_packet_base.hpp"
#include "bounding_box.hpp"
#include "vector2.hpp" #include "vector2.hpp"
struct CharacterPacket : SerialPacketBase { struct CharacterPacket : SerialPacketBase {
@@ -39,6 +40,7 @@ struct CharacterPacket : SerialPacketBase {
int roomIndex; int roomIndex;
Vector2 origin; Vector2 origin;
Vector2 motion; Vector2 motion;
BoundingBox bounds;
}; };
void serializeCharacter(void* buffer, CharacterPacket* packet); void serializeCharacter(void* buffer, CharacterPacket* packet);
@@ -28,7 +28,7 @@ struct ClientPacket : SerialPacketBase {
int clientIndex; int clientIndex;
int accountIndex; int accountIndex;
char username[PACKET_STRING_SIZE]; char username[PACKET_STRING_SIZE];
//TODO: (9) password, auth token //TODO: (3) password, auth token
}; };
void serializeClient(void* buffer, ClientPacket* packet); void serializeClient(void* buffer, ClientPacket* packet);
+1 -1
View File
@@ -34,7 +34,7 @@
typedef SerialPacketBase SerialPacket; typedef SerialPacketBase SerialPacket;
//DOCS: NETWORK_VERSION is used to discern compatible servers and clients //DOCS: NETWORK_VERSION is used to discern compatible servers and clients
constexpr int NETWORK_VERSION = 20150221; constexpr int NETWORK_VERSION = 20150304;
union MaxPacket { union MaxPacket {
CharacterPacket a; CharacterPacket a;
+63
View File
@@ -0,0 +1,63 @@
local doorUtility = {}
roomAPI = require("room")
regionPagerAPI = require("region_pager")
triggerAPI = require("trigger")
triggerManagerAPI = require("trigger_manager")
entityAPI = require("entity")
characterAPI = require("character")
networkAPI = require("network")
function doorUtility.createTrigger(handle, room, x, y, script)
local pager = roomAPI.GetPager(room)
--place the indicator tile
regionPagerAPI.SetTile(pager, x / 32, y / 32, 0, mapMaker.dirt)
regionPagerAPI.SetTile(pager, x / 32, y / 32, 1, mapMaker.blank)
regionPagerAPI.SetTile(pager, x / 32, y / 32, 2, mapMaker.blank)
--create the trigger object
triggerManagerAPI.Create(
roomAPI.GetTriggerMgr(room), handle, x, y,
0, 0, 32, 32, --size of the tiles
script
)
end
function doorUtility.createDoorPair(handle, roomOne, Xone, Yone, roomTwo, Xtwo, Ytwo)
--create the scripts
local function scriptOne(entity)
if entityAPI.GetType(entity) ~= "character" then return end
--move the character
characterAPI.SetRoom(entity, roomTwo)
characterAPI.SetOrigin(entity, Xtwo, Ytwo-16)
networkAPI.PumpCharacterUpdate(entity)
--disable the other trigger
local triggerTwo = triggerManagerAPI.GetTrigger(roomAPI.GetTriggerMgr(roomTwo), handle)
triggerAPI.PushExclusionEntity(triggerTwo, entity)
end
local function scriptTwo(entity)
if entityAPI.GetType(entity) ~= "character" then return end
--move the character
characterAPI.SetRoom(entity, roomOne)
characterAPI.SetOrigin(entity, Xone, Yone-16) --NOTE: the 16 pixel margin for presentation
networkAPI.PumpCharacterUpdate(entity)
--disable the other trigger
local triggerOne = triggerManagerAPI.GetTrigger(roomAPI.GetTriggerMgr(roomOne), handle)
triggerAPI.PushExclusionEntity(triggerOne, entity)
end
--create the triggers proper
doorUtility.createTrigger(handle, roomOne, Xone, Yone, scriptOne)
doorUtility.createTrigger(handle, roomTwo, Xtwo, Ytwo, scriptTwo)
end
return doorUtility
+39 -25
View File
@@ -1,4 +1,4 @@
local Region = require("map_system").Region local regionAPI = require("region")
local mapMaker = {} local mapMaker = {}
@@ -7,6 +7,7 @@ function mapMaker.Sqr(x) return x*x end
function mapMaker.Dist(x, y, i, j) return math.sqrt(mapMaker.Sqr(x - i) + mapMaker.Sqr(y - j)) end function mapMaker.Dist(x, y, i, j) return math.sqrt(mapMaker.Sqr(x - i) + mapMaker.Sqr(y - j)) end
--tile macros, mapped to the tilesheet "overworld.bmp" --tile macros, mapped to the tilesheet "overworld.bmp"
mapMaker.blank = 0
mapMaker.water = 18 + 3 * 0 mapMaker.water = 18 + 3 * 0
mapMaker.sand = 18 + 3 * 1 mapMaker.sand = 18 + 3 * 1
mapMaker.plains = 18 + 3 * 2 mapMaker.plains = 18 + 3 * 2
@@ -20,42 +21,43 @@ mapMaker.edges.south = 16
mapMaker.edges.east = 1 mapMaker.edges.east = 1
mapMaker.edges.west = -1 mapMaker.edges.west = -1
--TODO: (1) path system
--use these macros (mapped to "overworld.bmp" for now) to smooth the region's edges --use these macros (mapped to "overworld.bmp" for now) to smooth the region's edges
function mapMaker.SmoothEdgesSimple(r) function mapMaker.SmoothEdgesSimple(r)
--make and pad an array to use --make and pad an array to use
local shiftArray = {} local shiftArray = {}
for i = 1, Region.GetWidth(r) do for i = 1, regionAPI.GetWidth(r) do
shiftArray[i] = {} shiftArray[i] = {}
for j = 1, Region.GetHeight(r) do for j = 1, regionAPI.GetHeight(r) do
shiftArray[i][j] = 0 shiftArray[i][j] = 0
end end
end end
--build the array --build the array
for i = 1, Region.GetWidth(r) do for i = 1, regionAPI.GetWidth(r) do
for j = 1, Region.GetHeight(r) do for j = 1, regionAPI.GetHeight(r) do
--if (not region edge) and (west tile < this tile), etc. --if (not regionAPI edge) and (west tile < this tile), etc.
if i > 1 and Region.GetTile(r, i - 1, j, 1) < Region.GetTile(r, i, j, 1) then if i > 1 and regionAPI.GetTile(r, i - 1, j, 1) < regionAPI.GetTile(r, i, j, 1) then
shiftArray[i][j] = shiftArray[i][j] + mapMaker.edges.west shiftArray[i][j] = shiftArray[i][j] + mapMaker.edges.west
end end
if j > 1 and Region.GetTile(r, i, j - 1, 1) < Region.GetTile(r, i, j, 1) then if j > 1 and regionAPI.GetTile(r, i, j - 1, 1) < regionAPI.GetTile(r, i, j, 1) then
shiftArray[i][j] = shiftArray[i][j] + mapMaker.edges.north shiftArray[i][j] = shiftArray[i][j] + mapMaker.edges.north
end end
if i < Region.GetWidth(r) and Region.GetTile(r, i + 1, j, 1) < Region.GetTile(r, i, j, 1) then if i < regionAPI.GetWidth(r) and regionAPI.GetTile(r, i + 1, j, 1) < regionAPI.GetTile(r, i, j, 1) then
shiftArray[i][j] = shiftArray[i][j] + mapMaker.edges.east shiftArray[i][j] = shiftArray[i][j] + mapMaker.edges.east
end end
if j < Region.GetHeight(r) and Region.GetTile(r, i, j + 1, 1) < Region.GetTile(r, i, j, 1) then if j < regionAPI.GetHeight(r) and regionAPI.GetTile(r, i, j + 1, 1) < regionAPI.GetTile(r, i, j, 1) then
shiftArray[i][j] = shiftArray[i][j] + mapMaker.edges.south shiftArray[i][j] = shiftArray[i][j] + mapMaker.edges.south
end end
end end
end end
--finally apply this --finally apply this
for i = 1, Region.GetWidth(r) do for i = 1, regionAPI.GetWidth(r) do
for j = 1, Region.GetHeight(r) do for j = 1, regionAPI.GetHeight(r) do
if shiftArray[i][j] ~= 0 then if shiftArray[i][j] ~= 0 then
Region.SetTile(r, i, j, 2, Region.GetTile(r, i, j, 1) + shiftArray[i][j]) regionAPI.SetTile(r, i, j, 2, regionAPI.GetTile(r, i, j, 1) + shiftArray[i][j])
Region.SetTile(r, i, j, 1, Region.GetTile(r, i, j, 1) - 3) regionAPI.SetTile(r, i, j, 1, regionAPI.GetTile(r, i, j, 1) - 3)
end end
end end
end end
@@ -64,27 +66,27 @@ end
--custom generation systems here --custom generation systems here
function mapMaker.DebugIsland(r) function mapMaker.DebugIsland(r)
--basic distance check for each tile, placing an island around the world origin --basic distance check for each tile, placing an island around the world origin
for i = 1, Region.GetWidth(r) do for i = 1, regionAPI.GetWidth(r) do
for j = 1, Region.GetHeight(r) do for j = 1, regionAPI.GetHeight(r) do
local dist = mapMaker.Dist(0, 0, i + Region.GetX(r) -1, j + Region.GetY(r) -1) local dist = mapMaker.Dist(0, 0, i + regionAPI.GetX(r) -1, j + regionAPI.GetY(r) -1)
if dist < 10 then if dist < 10 then
Region.SetTile(r, i, j, 1, mapMaker.plains) regionAPI.SetTile(r, i, j, 1, mapMaker.plains)
elseif dist < 12 then elseif dist < 12 then
Region.SetTile(r, i, j, 1, mapMaker.sand) regionAPI.SetTile(r, i, j, 1, mapMaker.sand)
else else
Region.SetTile(r, i, j, 1, mapMaker.water) regionAPI.SetTile(r, i, j, 1, mapMaker.water)
Region.SetSolid(r, i, j, true) regionAPI.SetSolid(r, i, j, true)
end end
end end
end end
--examples of the smoothing function NOT working correctly --examples of the smoothing function NOT working correctly
--[[ --[[
for j = 1, Region.GetHeight(r) do for j = 1, regionAPI.GetHeight(r) do
Region.SetTile(r, 3, j, 1, mapMaker.dirt) regionAPI.SetTile(r, 3, j, 1, mapMaker.dirt)
Region.SetTile(r, 4, j, 1, mapMaker.dirt) regionAPI.SetTile(r, 4, j, 1, mapMaker.dirt)
Region.SetTile(r, 10, j, 1, mapMaker.dirt) regionAPI.SetTile(r, 10, j, 1, mapMaker.dirt)
end end
--]] --]]
@@ -92,4 +94,16 @@ function mapMaker.DebugIsland(r)
mapMaker.SmoothEdgesSimple(r) mapMaker.SmoothEdgesSimple(r)
end end
function mapMaker.DebugGrassland(r)
--all dirt
for i = 1, regionAPI.GetWidth(r) do
for j = 1, regionAPI.GetHeight(r) do
regionAPI.SetTile(r, i, j, 1, mapMaker.grass)
end
end
--A generic edge system
-- mapMaker.SmoothEdgesSimple(r)
end
return mapMaker return mapMaker
+4 -4
View File
@@ -1,15 +1,15 @@
local Region = require("map_system").Region local region = require("region")
local mapSaver = {} local mapSaver = {}
function mapSaver.Load(r) function mapSaver.Load(r)
--empty --empty
io.write("map_saver:Load(", Region.GetX(r), ", ", Region.GetY(r), ")\n") io.write("map_saver:Load(", region.GetX(r), ", ", region.GetY(r), ")\n")
end end
function mapSaver.Save(r) function mapSaver.Save(r)
--empty --empty
io.write("map_saver:Save(", Region.GetX(r), ", ", Region.GetY(r), ")\n") io.write("map_saver:Save(", region.GetX(r), ", ", region.GetY(r), ")\n")
end end
--TODO: (9) create a flexible saving & loading system --TODO: (3) create a flexible saving & loading system
return mapSaver return mapSaver
+20 -30
View File
@@ -1,46 +1,36 @@
print("Lua script check") print("Lua script check")
--requirements
roomManagerAPI = require("room_manager")
roomAPI = require("room")
mapMaker = require("map_maker") mapMaker = require("map_maker")
mapSaver = require("map_saver") mapSaver = require("map_saver")
roomSystem = require("room_system")
characterSystem = require("character_system")
networkSystem = require("network")
local function dumpTable(t) doorUtility = require("door_utility")
print(t)
for k, v in pairs(t) do
print("",k,v)
end
end
--test the room hooks --test the room hooks
roomSystem.RoomManager.SetOnCreate(function(room, index) roomManagerAPI.SetOnCreate(function(room, index)
print("", "Creating room: ", roomSystem.Room.GetName(room), index) print("", "Creating room: ", roomAPI.GetName(room), index)
--called ~60 times per second roomAPI.SetOnTick(room, function(room)
roomSystem.Room.SetOnTick(room, function(room) roomAPI.ForEachCharacter(room, function(character)
--[[ --
local character = characterSystem.CharacterManager.GetCharacter("handle") end)
if character ~= nil then
--debugging
local originX, originY = characterSystem.Character.GetOrigin(character)
local motionX, motionY = characterSystem.Character.GetMotion(character)
if motionY < 0 then
characterSystem.Character.SetMotion(character, motionX, 0)
networkSystem.PumpCharacterUpdate(character)
print("Sending: ", motionX, motionY)
end
end
--]]
end) end)
end) end)
roomSystem.RoomManager.SetOnUnload(function(room, index) roomManagerAPI.SetOnUnload(function(room, index)
print("", "Unloading room: ", roomSystem.Room.GetName(room), index) print("", "Unloading room: ", roomAPI.GetName(room), index)
end) end)
--NOTE: room 0 is the first that the client asks for, therefore it must exist --NOTE: room 0 is the first that the client asks for, therefore it must exist
local overworld, uid = roomSystem.RoomManager.CreateRoom("overworld", "overworld.bmp") local overworld, uidOne = roomManagerAPI.CreateRoom("overworld", "overworld.bmp")
roomSystem.Room.Initialize(overworld, mapSaver.Load, mapSaver.Save, mapMaker.DebugIsland, mapSaver.Save) roomAPI.Initialize(overworld, mapSaver.Load, mapSaver.Save, mapMaker.DebugIsland, mapSaver.Save)
local underworld, uidTwo = roomManagerAPI.CreateRoom("underworld", "overworld.bmp")
roomAPI.Initialize(underworld, mapSaver.Load, mapSaver.Save, mapMaker.DebugGrassland, mapSaver.Save)
--call the monstrosity
doorUtility.createDoorPair("pair 1", overworld, 0, -64, underworld, 0, 0)
print("Finished the lua script") print("Finished the lua script")
+7 -3
View File
@@ -1,8 +1,8 @@
--TODO: (9) An archive table of all dead characters --TODO: (3) An archive table of all dead characters
CREATE TABLE IF NOT EXISTS Accounts ( CREATE TABLE IF NOT EXISTS Accounts (
uid INTEGER PRIMARY KEY AUTOINCREMENT, uid INTEGER PRIMARY KEY AUTOINCREMENT,
username varchar(100) UNIQUE, --TODO: (9) Swap username for email address username varchar(100) UNIQUE, --TODO: (3) Swap username for email address
--server-client security --server-client security
-- passhash varchar(100), -- passhash varchar(100),
@@ -24,10 +24,14 @@ CREATE TABLE IF NOT EXISTS Characters (
avatar varchar(100), avatar varchar(100),
birth timestamp NOT NULL DEFAULT (datetime()), birth timestamp NOT NULL DEFAULT (datetime()),
--position in the world --physically exists in the world
roomIndex INTEGER DEFAULT 0, roomIndex INTEGER DEFAULT 0,
originX INTEGER DEFAULT 0, originX INTEGER DEFAULT 0,
originY INTEGER DEFAULT 0, originY INTEGER DEFAULT 0,
boundsX INTEGER DEFAULT 0,
boundsY INTEGER DEFAULT 0,
boundsW INTEGER DEFAULT 0,
boundsH INTEGER DEFAULT 0,
--statistics --statistics
baseStats INTEGER REFERENCES StatisticSets(uid), baseStats INTEGER REFERENCES StatisticSets(uid),
+23 -7
View File
@@ -28,15 +28,31 @@
//------------------------- //-------------------------
static const char* CREATE_USER_ACCOUNT = "INSERT INTO Accounts (username) VALUES (?);"; static const char* CREATE_USER_ACCOUNT = "INSERT INTO Accounts (username) VALUES (?);";
static const char* LOAD_USER_ACCOUNT = "SELECT * FROM Accounts WHERE username = ?;";
static const char* SAVE_USER_ACCOUNT = "UPDATE OR FAIL Accounts SET blacklisted = ?2, whitelisted = ?3, mod = ?4, admin = ?5 WHERE uid = ?1;"; static const char* LOAD_USER_ACCOUNT = "SELECT "
"uid, "
"blacklisted, "
"whitelisted, "
"mod, "
"admin "
" FROM Accounts WHERE username = ?;";
static const char* SAVE_USER_ACCOUNT = "UPDATE OR FAIL Accounts SET "
"blacklisted = ?2, "
"whitelisted = ?3, "
"mod = ?4, "
"admin = ?5 "
"WHERE uid = ?1;";
static const char* DELETE_USER_ACCOUNT = "DELETE FROM Accounts WHERE uid = ?;"; static const char* DELETE_USER_ACCOUNT = "DELETE FROM Accounts WHERE uid = ?;";
static const char* COUNT_USER_ACCOUNT_RECORDS = "SELECT COUNT(*) FROM Accounts;"; static const char* COUNT_USER_ACCOUNT_RECORDS = "SELECT COUNT(*) FROM Accounts;";
//------------------------- //-------------------------
//Define the public methods //Define the public methods
//------------------------- //-------------------------
//TODO: (1) block blacklisted accounts
int AccountManager::Create(std::string username, int clientIndex) { int AccountManager::Create(std::string username, int clientIndex) {
//create this user account, failing if it exists, leave this account in memory //create this user account, failing if it exists, leave this account in memory
sqlite3_stmt* statement = nullptr; sqlite3_stmt* statement = nullptr;
@@ -94,11 +110,11 @@ int AccountManager::Load(std::string username, int clientIndex) {
//extract the data into memory //extract the data into memory
AccountData& newAccount = elementMap[uid]; AccountData& newAccount = elementMap[uid];
newAccount.username = reinterpret_cast<const char*>(sqlite3_column_text(statement, 1)); newAccount.username = username;
newAccount.blackListed = sqlite3_column_int(statement, 2); newAccount.blackListed = sqlite3_column_int(statement, 1);
newAccount.whiteListed = sqlite3_column_int(statement, 3); newAccount.whiteListed = sqlite3_column_int(statement, 2);
newAccount.mod = sqlite3_column_int(statement, 4); newAccount.mod = sqlite3_column_int(statement, 3);
newAccount.admin = sqlite3_column_int(statement, 5); newAccount.admin = sqlite3_column_int(statement, 4);
newAccount.clientIndex = clientIndex; newAccount.clientIndex = clientIndex;
//finish the routine //finish the routine
+58 -7
View File
@@ -22,8 +22,58 @@
#include "character_api.hpp" #include "character_api.hpp"
#include "character_data.hpp" #include "character_data.hpp"
#include "character_manager.hpp"
#include "entity_api.hpp" #include "entity_api.hpp"
#include "room_manager.hpp"
#include "server_utilities.hpp"
#include <stdexcept>
static int setRoom(lua_State* L) {
//reverse engineer the character index
int characterIndex = -1;
CharacterData* character = static_cast<CharacterData*>(lua_touserdata(L, 1));
CharacterManager& characterMgr = CharacterManager::GetSingleton();
for (auto& it : *characterMgr.GetContainer()) {
if (character == &it.second) {
characterIndex = it.first;
break;
}
}
//error checking
if (characterIndex == -1) {
throw(std::runtime_error("Lua Error: Failed to find character index by reference"));
}
//get the room index, depending on the parameter type
int roomIndex = -1;
RoomManager& roomMgr = RoomManager::GetSingleton();
switch(lua_type(L, 2)) {
case LUA_TNUMBER:
roomIndex = lua_tointeger(L, 2);
break;
case LUA_TLIGHTUSERDATA:
//reverse engineer the room index
for (auto& it : *roomMgr.GetContainer()) {
if (lua_touserdata(L, 2) == &it.second) {
roomIndex = it.first;
break;
}
}
break;
}
//error checking
if (roomIndex == -1) {
throw(std::runtime_error("Lua Error: Failed to find room index by reference"));
}
//send the delete & create messages
pumpAndChangeRooms(character, roomIndex, characterIndex);
return 0;
}
static int getOwner(lua_State* L) { static int getOwner(lua_State* L) {
CharacterData* character = static_cast<CharacterData*>(lua_touserdata(L, 1)); CharacterData* character = static_cast<CharacterData*>(lua_touserdata(L, 1));
@@ -44,6 +94,7 @@ static int getAvatar(lua_State* L) {
} }
static const luaL_Reg characterLib[] = { static const luaL_Reg characterLib[] = {
{"SetRoom", setRoom},
// {"GetOwner", getOwner}, //unusable without account API // {"GetOwner", getOwner}, //unusable without account API
{"GetHandle", getHandle}, {"GetHandle", getHandle},
{"GetAvatar", getAvatar}, {"GetAvatar", getAvatar},
@@ -51,27 +102,27 @@ static const luaL_Reg characterLib[] = {
}; };
LUAMOD_API int openCharacterAPI(lua_State* L) { LUAMOD_API int openCharacterAPI(lua_State* L) {
//the local table
luaL_newlib(L, characterLib);
//get the parent table //get the parent table
luaL_requiref(L, TORTUGA_ENTITY_API, openEntityAPI, false); luaL_requiref(L, TORTUGA_ENTITY_API, openEntityAPI, false);
//clone the parent table into the local table //the local table
luaL_newlib(L, characterLib);
//merge the local table into the parent table
lua_pushnil(L); //first key lua_pushnil(L); //first key
while(lua_next(L, -2)) { while(lua_next(L, -2)) {
//copy the key-value pair //copy the key-value pair
lua_pushvalue(L, -2); lua_pushvalue(L, -2);
lua_pushvalue(L, -2); lua_pushvalue(L, -2);
//push the copy to the local table //push the copy to the parent table
lua_settable(L, -6); lua_settable(L, -6);
//pop the original value before continuing //pop the original value before continuing
lua_pop(L, 1); lua_pop(L, 1);
} }
//remove the parent table, leaving the expanded child table //remove the local table, leaving the expanded parent table
lua_pop(L, 1); lua_pop(L, 1);
return 1; return 1;
+4
View File
@@ -21,6 +21,10 @@
*/ */
#include "character_data.hpp" #include "character_data.hpp"
CharacterData::CharacterData(): Entity("character") {
//EMPTY
}
int CharacterData::GetOwner() { int CharacterData::GetOwner() {
return owner; return owner;
} }
+2 -2
View File
@@ -32,7 +32,7 @@
class CharacterData: public Entity { class CharacterData: public Entity {
public: public:
CharacterData() = default; CharacterData();
~CharacterData() = default; ~CharacterData() = default;
//database stuff //database stuff
@@ -43,7 +43,7 @@ public:
private: private:
friend class CharacterManager; friend class CharacterManager;
int owner; int owner = -1;
std::string handle; std::string handle;
std::string avatar; std::string avatar;
}; };
+56 -6
View File
@@ -23,6 +23,8 @@
#include "sqlite3.h" #include "sqlite3.h"
#include "character_defines.hpp"
#include <algorithm> #include <algorithm>
#include <stdexcept> #include <stdexcept>
@@ -30,10 +32,45 @@
//Define the queries //Define the queries
//------------------------- //-------------------------
static const char* CREATE_CHARACTER = "INSERT INTO Characters (owner, handle, avatar) VALUES (?, ?, ?);"; //NOTE: Programmer set variables are NOT zero-indexed
static const char* LOAD_CHARACTER = "SELECT * FROM Characters WHERE handle = ?;"; //NOTE: SQLite3 returned variables (i.e. loading) ARE zero-indexed
static const char* SAVE_CHARACTER = "UPDATE OR FAIL Characters SET roomIndex = ?2, originX = ?3, originY = ?4 WHERE uid = ?1;";
static const char* CREATE_CHARACTER = "INSERT INTO Characters ("
"owner, "
"handle, "
"avatar, "
"boundsX, "
"boundsY, "
"boundsW, "
"boundsH"
") VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7);";
static const char* LOAD_CHARACTER = "SELECT "
"uid, "
"owner, "
"handle, "
"avatar, "
"roomIndex, "
"originX, "
"originY, "
"boundsX, "
"boundsY, "
"boundsW, "
"boundsH "
"FROM Characters WHERE handle = ?;";
static const char* SAVE_CHARACTER = "UPDATE OR FAIL Characters SET "
"roomIndex = ?2, "
"originX = ?3, "
"originY = ?4, "
"boundsX = ?5, "
"boundsY = ?6, "
"boundsW = ?7, "
"boundsH = ?8 "
"WHERE uid = ?1;";
static const char* DELETE_CHARACTER = "DELETE FROM Characters WHERE uid = ?;"; static const char* DELETE_CHARACTER = "DELETE FROM Characters WHERE uid = ?;";
static const char* COUNT_CHARACTER_RECORDS = "SELECT COUNT(*) FROM Characters;"; static const char* COUNT_CHARACTER_RECORDS = "SELECT COUNT(*) FROM Characters;";
//------------------------- //-------------------------
@@ -55,6 +92,10 @@ int CharacterManager::Create(int owner, std::string handle, std::string avatar)
ret |= sqlite3_bind_int(statement, 1, owner); ret |= sqlite3_bind_int(statement, 1, owner);
ret |= sqlite3_bind_text(statement, 2, handle.c_str(), handle.size() + 1, SQLITE_STATIC); ret |= sqlite3_bind_text(statement, 2, handle.c_str(), handle.size() + 1, SQLITE_STATIC);
ret |= sqlite3_bind_text(statement, 3, avatar.c_str(), avatar.size() + 1, SQLITE_STATIC); ret |= sqlite3_bind_text(statement, 3, avatar.c_str(), avatar.size() + 1, SQLITE_STATIC);
ret |= sqlite3_bind_int(statement, 4, CHARACTER_BOUNDS_X);
ret |= sqlite3_bind_int(statement, 5, CHARACTER_BOUNDS_Y);
ret |= sqlite3_bind_int(statement, 6, CHARACTER_BOUNDS_WIDTH);
ret |= sqlite3_bind_int(statement, 7, CHARACTER_BOUNDS_HEIGHT);
//check for binding errors //check for binding errors
if (ret) { if (ret) {
@@ -121,9 +162,14 @@ int CharacterManager::Load(int owner, std::string handle, std::string avatar) {
//Don't cache the birth //Don't cache the birth
//world origin //world origin
newChar.roomIndex = sqlite3_column_int(statement, 5); newChar.roomIndex = sqlite3_column_int(statement, 4);
newChar.origin.x = (double)sqlite3_column_int(statement, 6); newChar.origin.x = (double)sqlite3_column_int(statement, 5);
newChar.origin.y = (double)sqlite3_column_int(statement, 7); newChar.origin.y = (double)sqlite3_column_int(statement, 6);
//bounds
newChar.bounds.x = (int)sqlite3_column_int(statement, 7);
newChar.bounds.y = (int)sqlite3_column_int(statement, 8);
newChar.bounds.w = (int)sqlite3_column_int(statement, 9);
newChar.bounds.h = (int)sqlite3_column_int(statement, 10);
//gameplay components: equipment, items, buffs, debuffs... //gameplay components: equipment, items, buffs, debuffs...
@@ -165,6 +211,10 @@ int CharacterManager::Save(int uid) {
ret |= sqlite3_bind_int(statement, 2, character.roomIndex) != SQLITE_OK; ret |= sqlite3_bind_int(statement, 2, character.roomIndex) != SQLITE_OK;
ret |= sqlite3_bind_int(statement, 3, (int)character.origin.x) != SQLITE_OK; ret |= sqlite3_bind_int(statement, 3, (int)character.origin.x) != SQLITE_OK;
ret |= sqlite3_bind_int(statement, 4, (int)character.origin.y) != SQLITE_OK; ret |= sqlite3_bind_int(statement, 4, (int)character.origin.y) != SQLITE_OK;
ret |= sqlite3_bind_int(statement, 5, character.bounds.x) != SQLITE_OK;
ret |= sqlite3_bind_int(statement, 6, character.bounds.y) != SQLITE_OK;
ret |= sqlite3_bind_int(statement, 7, character.bounds.w) != SQLITE_OK;
ret |= sqlite3_bind_int(statement, 8, character.bounds.h) != SQLITE_OK;
//gameplay components: equipment, items, buffs, debuffs... //gameplay components: equipment, items, buffs, debuffs...
+25 -7
View File
@@ -23,24 +23,29 @@
#include "character_manager.hpp" #include "character_manager.hpp"
#include <sstream>
#include <stdexcept>
//TODO: (1) character hooks?
static int setOnCreate(lua_State* L) { static int setOnCreate(lua_State* L) {
//TODO: (9) empty //TODO: (9) setOnCreate()
} }
static int setOnLoad(lua_State* L) { static int setOnLoad(lua_State* L) {
//TODO: (9) empty //TODO: (9) setOnLoad()
} }
static int setOnSave(lua_State* L) { static int setOnSave(lua_State* L) {
//TODO: (9) empty //TODO: (9) setOnSave()
} }
static int setOnUnload(lua_State* L) { static int setOnUnload(lua_State* L) {
//TODO: (9) empty //TODO: (9) setOnUnload()
} }
static int setOnDelete(lua_State* L) { static int setOnDelete(lua_State* L) {
//TODO: (9) empty //TODO: (9) setOnDelete()
} }
static int getCharacter(lua_State* L) { static int getCharacter(lua_State* L) {
@@ -75,7 +80,20 @@ static int getLoadedCount(lua_State* L) {
} }
static int forEach(lua_State* L) { static int forEach(lua_State* L) {
//TODO: (1) find a way to update the clients when a script alters a character's data CharacterManager& characterMgr = CharacterManager::GetSingleton();
//pass each character to the given function
for (auto& it : *characterMgr.GetContainer()) {
lua_pushvalue(L, -1);
lua_pushlightuserdata(L, static_cast<void*>(&it.second));
//call each iteration, throwing an exception if something happened
if (lua_pcall(L, 1, 0, 0) != LUA_OK) {
std::ostringstream os;
os << "Lua error: ";
os << lua_tostring(L, -1);
throw(std::runtime_error(os.str()));
}
}
return 0;
} }
static const luaL_Reg characterManagerLib[] = { static const luaL_Reg characterManagerLib[] = {
@@ -86,7 +104,7 @@ static const luaL_Reg characterManagerLib[] = {
// {"SetOnDelete", setOnDelete}, // {"SetOnDelete", setOnDelete},
{"GetCharacter", getCharacter}, {"GetCharacter", getCharacter},
{"GetLoadedCount", getLoadedCount}, {"GetLoadedCount", getLoadedCount},
// {"ForEach", forEach}, {"ForEach", forEach},
{nullptr, nullptr} {nullptr, nullptr}
}; };
@@ -1,55 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013-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 "character_system_api.hpp"
//all character API headers
#include "character_api.hpp"
#include "character_manager_api.hpp"
//useful "globals"
//...
//This mimics linit.c to create a nested collection of all character modules.
static const luaL_Reg funcs[] = {
{nullptr, nullptr}
};
static const luaL_Reg libs[] = {
{"Character", openCharacterAPI},
{"CharacterManager", openCharacterManagerAPI},
{nullptr, nullptr}
};
int openCharacterSystemAPI(lua_State* L) {
//create the table
luaL_newlibtable(L, libs);
//push the "global" functions
luaL_setfuncs(L, funcs, 0);
//push the substable
for (const luaL_Reg* lib = libs; lib->func; lib++) {
lib->func(L);
lua_setfield(L, -2, lib->name);
}
return 1;
}
@@ -1,30 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013-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.
*/
#ifndef CHARACTERSYSTEMAPI_HPP_
#define CHARACTERSYSTEMAPI_HPP_
#include "lua.hpp"
#define TORTUGA_CHARACTER_SYSTEM_API "character_system"
LUAMOD_API int openCharacterSystemAPI(lua_State* L);
#endif
+1 -1
View File
@@ -1,5 +1,5 @@
#config #config
INCLUDES+=. ../entities ../server_utilities ../../common/gameplay ../../common/utilities INCLUDES+=. ../entities ../monsters ../rooms ../server_utilities ../triggers ../../common/gameplay ../../common/map ../../common/network ../../common/network/packet_types ../../common/utilities
LIBS+= LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
+20
View File
@@ -21,6 +21,14 @@
*/ */
#include "entity.hpp" #include "entity.hpp"
Entity::Entity(const char* _type): type(_type) {
//EMPTY
}
void Entity::Update() {
origin += motion;
}
int Entity::SetRoomIndex(int i) { int Entity::SetRoomIndex(int i) {
return roomIndex = i; return roomIndex = i;
} }
@@ -33,6 +41,10 @@ Vector2 Entity::SetMotion(Vector2 v) {
return motion = v; return motion = v;
} }
BoundingBox Entity::SetBounds(BoundingBox b) {
return bounds = b;
}
int Entity::GetRoomIndex() const { int Entity::GetRoomIndex() const {
return roomIndex; return roomIndex;
} }
@@ -43,4 +55,12 @@ Vector2 Entity::GetOrigin() const {
Vector2 Entity::GetMotion() const { Vector2 Entity::GetMotion() const {
return motion; return motion;
}
BoundingBox Entity::GetBounds() const {
return bounds;
}
const char* Entity::GetType() const {
return type;
} }
+14 -3
View File
@@ -22,27 +22,38 @@
#ifndef ENTITY_HPP_ #ifndef ENTITY_HPP_
#define ENTITY_HPP_ #define ENTITY_HPP_
#include "bounding_box.hpp"
#include "vector2.hpp" #include "vector2.hpp"
#include <string>
//The base class for all objects in the world //The base class for all objects in the world
class Entity { class Entity {
public: public:
virtual void Update();
//accessors & mutators //accessors & mutators
int SetRoomIndex(int i); int SetRoomIndex(int i);
Vector2 SetOrigin(Vector2 v); Vector2 SetOrigin(Vector2 v);
Vector2 SetMotion(Vector2 v); Vector2 SetMotion(Vector2 v);
BoundingBox SetBounds(BoundingBox b);
int GetRoomIndex() const; int GetRoomIndex() const;
Vector2 GetOrigin() const; Vector2 GetOrigin() const;
Vector2 GetMotion() const; Vector2 GetMotion() const;
BoundingBox GetBounds() const;
const char* GetType() const;
protected: protected:
Entity() = default; Entity(const char*);
virtual ~Entity() = default; virtual ~Entity() = default;
int roomIndex = -1; int roomIndex = -1;
Vector2 origin; Vector2 origin = {0, 0};
Vector2 motion; Vector2 motion = {0, 0};
BoundingBox bounds = {0, 0, 0, 0};
const char* type;
}; };
#endif #endif
+29
View File
@@ -41,6 +41,17 @@ static int setMotion(lua_State* L) {
return 0; return 0;
} }
static int setBounds(lua_State* L) {
Entity* entity = static_cast<Entity*>(lua_touserdata(L, 1));
entity->SetBounds({
lua_tointeger(L, 2),
lua_tointeger(L, 3),
lua_tointeger(L, 4),
lua_tointeger(L, 5)
});
return 0;
}
static int getRoomIndex(lua_State* L) { static int getRoomIndex(lua_State* L) {
Entity* entity = static_cast<Entity*>(lua_touserdata(L, 1)); Entity* entity = static_cast<Entity*>(lua_touserdata(L, 1));
lua_pushinteger(L, entity->GetRoomIndex()); lua_pushinteger(L, entity->GetRoomIndex());
@@ -61,13 +72,31 @@ static int getMotion(lua_State* L) {
return 2; return 2;
} }
static int getBounds(lua_State* L) {
Entity* entity = static_cast<Entity*>(lua_touserdata(L, 1));
lua_pushinteger(L, entity->GetBounds().x);
lua_pushinteger(L, entity->GetBounds().y);
lua_pushinteger(L, entity->GetBounds().w);
lua_pushinteger(L, entity->GetBounds().h);
return 4;
}
static int getType(lua_State* L) {
Entity* entity = static_cast<Entity*>(lua_touserdata(L, 1));
lua_pushstring(L, entity->GetType());
return 1;
}
static const luaL_Reg entityLib[] = { static const luaL_Reg entityLib[] = {
{"SetRoomIndex", setRoomIndex}, {"SetRoomIndex", setRoomIndex},
{"SetOrigin", setOrigin}, {"SetOrigin", setOrigin},
{"SetMotion", setMotion}, {"SetMotion", setMotion},
{"SetBounds", setBounds},
{"GetRoomIndex", getRoomIndex}, {"GetRoomIndex", getRoomIndex},
{"GetOrigin", getOrigin}, {"GetOrigin", getOrigin},
{"GetMotion", getMotion}, {"GetMotion", getMotion},
{"GetBounds", getBounds},
{"GetType", getType},
{nullptr, nullptr} {nullptr, nullptr}
}; };
+20 -10
View File
@@ -37,12 +37,17 @@
#include "lua.hpp" #include "lua.hpp"
#include "entity_api.hpp" #include "entity_api.hpp"
#include "character_system_api.hpp" #include "character_api.hpp"
#include "map_system_api.hpp" #include "character_manager_api.hpp"
#include "monster_system_api.hpp" #include "region_api.hpp"
#include "region_pager_api.hpp"
#include "monster_api.hpp"
#include "monster_manager_api.hpp"
#include "network_api.hpp" #include "network_api.hpp"
#include "room_system_api.hpp" #include "room_api.hpp"
#include "waypoint_system_api.hpp" #include "room_manager_api.hpp"
#include "trigger_api.hpp"
#include "trigger_manager_api.hpp"
//these libs are loaded by lua.c and are readily available to any Lua program //these libs are loaded by lua.c and are readily available to any Lua program
static const luaL_Reg loadedlibs[] = { static const luaL_Reg loadedlibs[] = {
@@ -63,12 +68,17 @@ static const luaL_Reg loadedlibs[] = {
//these libs are preloaded and must be required before used //these libs are preloaded and must be required before used
static const luaL_Reg preloadedlibs[] = { static const luaL_Reg preloadedlibs[] = {
{TORTUGA_ENTITY_API, openEntityAPI}, //required by derived classes {TORTUGA_ENTITY_API, openEntityAPI}, //required by derived classes
{TORTUGA_CHARACTER_SYSTEM_API, openCharacterSystemAPI}, {TORTUGA_CHARACTER_API, openCharacterAPI},
{TORTUGA_MAP_SYSTEM_API, openMapSystemAPI}, {TORTUGA_CHARACTER_MANAGER_API, openCharacterManagerAPI},
{TORTUGA_MONSTER_SYSTEM_API, openMonsterSystemAPI}, {TORTUGA_MONSTER_API, openMonsterAPI},
{TORTUGA_MONSTER_MANAGER_API, openMonsterManagerAPI},
{TORTUGA_NETWORK_API, openNetworkAPI}, {TORTUGA_NETWORK_API, openNetworkAPI},
{TORTUGA_ROOM_SYSTEM_API, openRoomSystemAPI}, {TORTUGA_REGION_API, openRegionAPI},
{TORTUGA_WAYPOINT_SYSTEM_API, openWaypointSystemAPI}, {TORTUGA_REGION_PAGER_API, openRegionPagerAPI},
{TORTUGA_ROOM_API, openRoomAPI},
{TORTUGA_ROOM_MANAGER_API, openRoomManagerAPI},
{TORTUGA_TRIGGER_API, openTriggerAPI},
{TORTUGA_TRIGGER_MANAGER_API, openTriggerManagerAPI},
{NULL, NULL} {NULL, NULL}
}; };
-1
View File
@@ -28,7 +28,6 @@
#include "config_utility.hpp" #include "config_utility.hpp"
#include "room_manager.hpp" #include "room_manager.hpp"
#include "udp_network_utility.hpp" #include "udp_network_utility.hpp"
#include "waypoint_manager.hpp"
#include <stdexcept> #include <stdexcept>
#include <iostream> #include <iostream>
+2 -2
View File
@@ -1,5 +1,5 @@
#include directories #include directories
INCLUDES+=. accounts characters clients entities monsters rooms server_utilities waypoints ../common/debugging ../common/gameplay ../common/map ../common/network ../common/network/packet_types ../common/utilities INCLUDES+=. accounts characters clients entities monsters rooms server_utilities triggers ../common/debugging ../common/gameplay ../common/map ../common/network ../common/network/packet_types ../common/utilities
#libraries #libraries
#the order of the $(LIBS) is important, at least for MinGW #the order of the $(LIBS) is important, at least for MinGW
@@ -32,7 +32,7 @@ all: $(OBJ) $(OUT)
$(MAKE) -C monsters $(MAKE) -C monsters
$(MAKE) -C rooms $(MAKE) -C rooms
$(MAKE) -C server_utilities $(MAKE) -C server_utilities
$(MAKE) -C waypoints $(MAKE) -C triggers
$(CXX) $(CXXFLAGS) -o $(OUT) $(OBJ) $(LIBS) $(CXX) $(CXXFLAGS) -o $(OUT) $(OBJ) $(LIBS)
$(OBJ): | $(OBJDIR) $(OBJ): | $(OBJDIR)
+6 -6
View File
@@ -61,27 +61,27 @@ static const luaL_Reg monsterLib[] = {
}; };
LUAMOD_API int openMonsterAPI(lua_State* L) { LUAMOD_API int openMonsterAPI(lua_State* L) {
//the local table
luaL_newlib(L, monsterLib);
//get the parent table //get the parent table
luaL_requiref(L, TORTUGA_ENTITY_API, openEntityAPI, false); luaL_requiref(L, TORTUGA_ENTITY_API, openEntityAPI, false);
//clone the parent table into the local table //the local table
luaL_newlib(L, monsterLib);
//merge the local table into the parent table
lua_pushnil(L); //first key lua_pushnil(L); //first key
while(lua_next(L, -2)) { while(lua_next(L, -2)) {
//copy the key-value pair //copy the key-value pair
lua_pushvalue(L, -2); lua_pushvalue(L, -2);
lua_pushvalue(L, -2); lua_pushvalue(L, -2);
//push the copy to the local table //push the copy to the parent table
lua_settable(L, -6); lua_settable(L, -6);
//pop the original value before continuing //pop the original value before continuing
lua_pop(L, 1); lua_pop(L, 1);
} }
//remove the parent table, leaving the expanded child table //remove the local table, leaving the expanded parent table
lua_pop(L, 1); lua_pop(L, 1);
return 1; return 1;
+4
View File
@@ -21,6 +21,10 @@
*/ */
#include "monster_data.hpp" #include "monster_data.hpp"
MonsterData::MonsterData(): Entity("monster") {
//EMPTY
}
std::string MonsterData::SetAvatar(std::string s) { std::string MonsterData::SetAvatar(std::string s) {
return avatar = s; return avatar = s;
} }
+4 -2
View File
@@ -24,11 +24,13 @@
#include "entity.hpp" #include "entity.hpp"
#include "lua.hpp"
#include <string> #include <string>
class MonsterData: public Entity { class MonsterData: public Entity {
public: public:
MonsterData() = default; MonsterData();
~MonsterData() = default; ~MonsterData() = default;
std::string SetAvatar(std::string); std::string SetAvatar(std::string);
@@ -41,7 +43,7 @@ private:
friend class MonsterManager; friend class MonsterManager;
std::string avatar; std::string avatar;
int scriptRef; int scriptRef = LUA_NOREF;
}; };
#endif #endif
+11 -11
View File
@@ -30,45 +30,45 @@ MonsterManager::~MonsterManager() {
} }
int MonsterManager::Create(std::string) { int MonsterManager::Create(std::string) {
//Create //TODO: (9) MonsterManager::Create()
} }
void MonsterManager::Unload(int uid) { void MonsterManager::Unload(int uid) {
//Unload //TODO: (9) MonsterManager::Unload()
} }
void MonsterManager::UnloadAll() { void MonsterManager::UnloadAll() {
//UnloadAll //TODO: (9) MonsterManager::UnloadAll()
} }
void MonsterManager::UnloadIf(std::function<bool(std::pair<const int, MonsterData const&>)> fn) { void MonsterManager::UnloadIf(std::function<bool(std::pair<const int, MonsterData const&>)> fn) {
//UnloadIf //TODO: (9) MonsterManager::UnloadIf()
} }
MonsterData* MonsterManager::Get(int uid) { MonsterData* MonsterManager::Get(int uid) {
//Get //TODO: (9) MonsterManager::Get()
} }
int MonsterManager::GetLoadedCount() { int MonsterManager::GetLoadedCount() {
//GetLoadedCount //TODO: (9) MonsterManager::GetLoadedCount()
} }
std::map<int, MonsterData>* MonsterManager::GetContainer() { std::map<int, MonsterData>* MonsterManager::GetContainer() {
//GetContainer //TODO: (9) MonsterManager::GetContainer()
} }
lua_State* MonsterManager::SetLuaState(lua_State* L) { lua_State* MonsterManager::SetLuaState(lua_State* L) {
//SetLuaState //TODO: (9) MonsterManager::SetLuaState()
} }
lua_State* MonsterManager::GetLuaState() { lua_State* MonsterManager::GetLuaState() {
//GetLuaState //TODO: (9) MonsterManager::GetLuaState()
} }
sqlite3* MonsterManager::SetDatabase(sqlite3* db) { sqlite3* MonsterManager::SetDatabase(sqlite3* db) {
//SetDatabase //TODO: (9) MonsterManager::SetDatabase()
} }
sqlite3* MonsterManager::GetDatabase() { sqlite3* MonsterManager::GetDatabase() {
//GetDatabase //TODO: (9) MonsterManager::GetDatabase()
} }
-55
View File
@@ -1,55 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013-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 "monster_system_api.hpp"
//all monster API headers
#include "monster_api.hpp"
#include "monster_manager_api.hpp"
//useful "globals"
//...
//This mimics linit.c to create a nested collection of all monster modules.
static const luaL_Reg funcs[] = {
{nullptr, nullptr}
};
static const luaL_Reg libs[] = {
{"Monster", openMonsterAPI},
{"MonsterManager", openMonsterManagerAPI},
{nullptr, nullptr}
};
int openMonsterSystemAPI(lua_State* L) {
//create the table
luaL_newlibtable(L, libs);
//push the "global" functions
luaL_setfuncs(L, funcs, 0);
//push the substable
for (const luaL_Reg* lib = libs; lib->func; lib++) {
lib->func(L);
lua_setfield(L, -2, lib->name);
}
return 1;
}
-30
View File
@@ -1,30 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013-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.
*/
#ifndef MONSTERSYSTEMAPI_HPP_
#define MONSTERSYSTEMAPI_HPP_
#include "lua.hpp"
#define TORTUGA_MONSTER_SYSTEM_API "monster_system"
LUAMOD_API int openMonsterSystemAPI(lua_State* L);
#endif
+1 -1
View File
@@ -1,5 +1,5 @@
#config #config
INCLUDES+=. ../characters ../entities ../monsters ../server_utilities ../waypoints ../../common/gameplay ../../common/map ../../common/utilities INCLUDES+=. ../characters ../entities ../monsters ../server_utilities ../triggers ../../common/gameplay ../../common/map ../../common/utilities
LIBS+= LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
+32 -3
View File
@@ -23,6 +23,9 @@
#include "room_data.hpp" #include "room_data.hpp"
#include <sstream>
#include <stdexcept>
static int setRoomName(lua_State* L) { static int setRoomName(lua_State* L) {
RoomData* room = reinterpret_cast<RoomData*>(lua_touserdata(L, 1)); RoomData* room = reinterpret_cast<RoomData*>(lua_touserdata(L, 1));
room->SetName(lua_tostring(L, 2)); room->SetName(lua_tostring(L, 2));
@@ -59,14 +62,31 @@ static int getMonsterMgr(lua_State* L) {
return 1; return 1;
} }
static int getWaypointMgr(lua_State* L) { static int getTriggerMgr(lua_State* L) {
RoomData* room = reinterpret_cast<RoomData*>(lua_touserdata(L, 1)); RoomData* room = reinterpret_cast<RoomData*>(lua_touserdata(L, 1));
lua_pushlightuserdata(L, reinterpret_cast<void*>(room->GetWaypointMgr()) ); lua_pushlightuserdata(L, reinterpret_cast<void*>(room->GetTriggerMgr()) );
return 1; return 1;
} }
//TODO: character list //TODO: character list
static int forEachCharacter(lua_State* L) {
RoomData* room = reinterpret_cast<RoomData*>(lua_touserdata(L, 1));
//pass each character to the given function
for (auto& it : *room->GetCharacterList()) {
lua_pushvalue(L, -1);
lua_pushlightuserdata(L, static_cast<void*>(it));
//call each iteration, throwing an exception if something happened
if (lua_pcall(L, 1, 0, 0) != LUA_OK) {
std::ostringstream os;
os << "Lua error: ";
os << lua_tostring(L, -1);
throw(std::runtime_error(os.str()));
}
}
return 0;
}
static int setOnTick(lua_State* L) { static int setOnTick(lua_State* L) {
RoomData* room = reinterpret_cast<RoomData*>(lua_touserdata(L, 1)); RoomData* room = reinterpret_cast<RoomData*>(lua_touserdata(L, 1));
luaL_unref(L, LUA_REGISTRYINDEX, room->GetTickReference()); luaL_unref(L, LUA_REGISTRYINDEX, room->GetTickReference());
@@ -74,6 +94,12 @@ static int setOnTick(lua_State* L) {
return 0; return 0;
} }
static int getOnTick(lua_State* L) {
RoomData* room = reinterpret_cast<RoomData*>(lua_touserdata(L, 1));
lua_rawgeti(L, LUA_REGISTRYINDEX, room->GetTickReference());
return 1;
}
static int initialize(lua_State* L) { static int initialize(lua_State* L) {
RoomData* room = static_cast<RoomData*>(lua_touserdata(L, 1)); RoomData* room = static_cast<RoomData*>(lua_touserdata(L, 1));
@@ -95,9 +121,12 @@ static const luaL_Reg roomLib[] = {
{"GetPager",getPager}, {"GetPager",getPager},
{"GetMonsterMgr",getMonsterMgr}, {"GetMonsterMgr",getMonsterMgr},
{"GetWaypointMgr",getWaypointMgr}, {"GetTriggerMgr",getTriggerMgr},
{"ForEachCharacter", forEachCharacter},
{"SetOnTick", setOnTick}, {"SetOnTick", setOnTick},
{"GetOnTick", getOnTick},
{"Initialize", initialize}, {"Initialize", initialize},
{nullptr, nullptr} {nullptr, nullptr}
+73 -9
View File
@@ -21,19 +21,83 @@
*/ */
#include "room_data.hpp" #include "room_data.hpp"
#include <algorithm>
#include <iostream>
#include <stack>
#include <stdexcept>
void RoomData::RunFrame() { void RoomData::RunFrame() {
//get the hook //get the hook
lua_rawgeti(lua, LUA_REGISTRYINDEX, tickRef); lua_rawgeti(lua, LUA_REGISTRYINDEX, tickRef);
if (lua_isnil(lua, -1)) { if (!lua_isnil(lua, -1)) {
//call the tick function, with this as a parameter
lua_pushlightuserdata(lua, this);
if (lua_pcall(lua, 1, 0, 0) != LUA_OK) {
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) ));
}
}
else {
lua_pop(lua, 1); lua_pop(lua, 1);
return;
} }
//call the tick function, with this as a parameter //update the entities in the room
lua_pushlightuserdata(lua, this); for (auto& it : characterList) {
if (lua_pcall(lua, 1, 0, 0) != LUA_OK) { it->Update();
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) )); }
//TODO: (3) iterate through the monster map
//TODO: (3) trigger script for monsters
//build a list of game entities
std::stack<Entity*> entityStack;
for (auto& it : characterList) {
entityStack.push(it);
}
//TODO: (3) push the monster entities
//compare the triggers to the entities, using their real hitboxes
//NOTE: this stack solution should prevent problems when modifying the various lists
while(entityStack.size()) {
//get the entity & hitbox
Entity* entity = entityStack.top();
BoundingBox entityBox = entity->GetBounds() + entity->GetOrigin();
//get the trigger pair & hitbox
for (auto& triggerPair : *triggerMgr.GetContainer()) {
BoundingBox triggerBox = triggerPair.second.GetBoundingBox() + triggerPair.second.GetOrigin();
//find all collisions
if (entityBox.CheckOverlap(triggerBox)) {
//skip members of the exclusion list
if (std::any_of(triggerPair.second.GetExclusionList()->begin(), triggerPair.second.GetExclusionList()->end(), [entity](Entity* ptr) -> bool {
return entity == ptr;
})) {
continue;
}
//run the trigger script
lua_rawgeti(lua, LUA_REGISTRYINDEX, triggerPair.second.GetScriptReference());
lua_pushlightuserdata(lua, entity);
if (lua_pcall(lua, 1, 0, 0) != LUA_OK) {
//error
throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) ));
}
//push to the exclusion list
triggerPair.second.GetExclusionList()->push_back(entity);
}
else {
//remove members of the exclusion list
//NOTE: characters in different rooms won't be removed, but that shouldn't be a problem
triggerPair.second.GetExclusionList()->remove_if([entity](Entity* ptr) -> bool {
return entity == ptr;
});
}
}
//next
entityStack.pop();
} }
} }
@@ -61,8 +125,8 @@ MonsterManager* RoomData::GetMonsterMgr() {
return &monsterMgr; return &monsterMgr;
} }
WaypointManager* RoomData::GetWaypointMgr() { TriggerManager* RoomData::GetTriggerMgr() {
return &waypointMgr; return &triggerMgr;
} }
std::list<CharacterData*>* RoomData::GetCharacterList() { std::list<CharacterData*>* RoomData::GetCharacterList() {
@@ -73,7 +137,7 @@ lua_State* RoomData::SetLuaState(lua_State* L) {
lua = L; lua = L;
pager.SetLuaState(lua); pager.SetLuaState(lua);
monsterMgr.SetLuaState(lua); monsterMgr.SetLuaState(lua);
waypointMgr.SetLuaState(lua); triggerMgr.SetLuaState(lua);
return lua; return lua;
} }
+3 -3
View File
@@ -25,7 +25,7 @@
#include "character_data.hpp" #include "character_data.hpp"
#include "monster_manager.hpp" #include "monster_manager.hpp"
#include "region_pager_lua.hpp" #include "region_pager_lua.hpp"
#include "waypoint_manager.hpp" #include "trigger_manager.hpp"
#include "lua.hpp" #include "lua.hpp"
@@ -48,7 +48,7 @@ public:
RegionPagerLua* GetPager(); RegionPagerLua* GetPager();
MonsterManager* GetMonsterMgr(); MonsterManager* GetMonsterMgr();
WaypointManager* GetWaypointMgr(); TriggerManager* GetTriggerMgr();
std::list<CharacterData*>* GetCharacterList(); std::list<CharacterData*>* GetCharacterList();
//API interfaces //API interfaces
@@ -70,7 +70,7 @@ private:
//members //members
RegionPagerLua pager; RegionPagerLua pager;
MonsterManager monsterMgr; MonsterManager monsterMgr;
WaypointManager waypointMgr; TriggerManager triggerMgr;
std::list<CharacterData*> characterList; std::list<CharacterData*> characterList;
//API //API
-55
View File
@@ -1,55 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013-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 "room_system_api.hpp"
//all room API headers
#include "room_api.hpp"
#include "room_manager_api.hpp"
//useful "globals"
//...
//This mimics linit.c to create a nested collection of all room modules.
static const luaL_Reg funcs[] = {
{nullptr, nullptr}
};
static const luaL_Reg libs[] = {
{"Room", openRoomAPI},
{"RoomManager", openRoomManagerAPI},
{nullptr, nullptr}
};
int openRoomSystemAPI(lua_State* L) {
//create the table
luaL_newlibtable(L, libs);
//push the "global" functions
luaL_setfuncs(L, funcs, 0);
//push the substable
for (const luaL_Reg* lib = libs; lib->func; lib++) {
lib->func(L);
lua_setfield(L, -2, lib->name);
}
return 1;
}
+8 -17
View File
@@ -205,28 +205,19 @@ void ServerApplication::hCharacterMovement(CharacterPacket* const argPacket) {
//check if allowed //check if allowed
if (characterData->GetOwner() != argPacket->accountIndex && !accountData->GetModerator() && !accountData->GetAdministrator()) { if (characterData->GetOwner() != argPacket->accountIndex && !accountData->GetModerator() && !accountData->GetAdministrator()) {
//TODO: (2) send to the client? //TODO: (3) send to the client?
std::cerr << "Failed to set character motion due to lack of permissions targeting uid(" << argPacket->characterIndex << ")" << std::endl; std::cerr << "Failed to set character motion due to lack of permissions targeting uid(" << argPacket->characterIndex << ")" << std::endl;
return; return;
} }
//check if moving rooms //check if moving rooms
if (characterData->GetRoomIndex() != argPacket->roomIndex) { if (characterData->GetRoomIndex() != argPacket->roomIndex) {
//delete from the old room //set the character's origin and motion
CharacterPacket newPacket; characterData->SetOrigin(argPacket->origin);
copyCharacterToPacket(&newPacket, argPacket->characterIndex); characterData->SetMotion(argPacket->motion);
newPacket.type = SerialPacketType::CHARACTER_DELETE;
pumpPacketProximity(&newPacket, characterData->GetRoomIndex());
//move the character between rooms //send the delete & create messages
roomMgr.PopCharacter(characterData); pumpAndChangeRooms(characterData, argPacket->roomIndex, argPacket->characterIndex);
characterData->SetRoomIndex(argPacket->roomIndex);
roomMgr.PushCharacter(characterData);
//create in the new room
copyCharacterToPacket(&newPacket, argPacket->characterIndex);
newPacket.type = SerialPacketType::CHARACTER_CREATE;
pumpPacketProximity(&newPacket, characterData->GetRoomIndex());
} }
//if not moving between rooms //if not moving between rooms
else { else {
@@ -243,9 +234,9 @@ void ServerApplication::hCharacterMovement(CharacterPacket* const argPacket) {
} }
void ServerApplication::hCharacterAttack(CharacterPacket* const argPacket) { void ServerApplication::hCharacterAttack(CharacterPacket* const argPacket) {
//TODO: (9) empty //TODO: (9) ServerApplication::hCharacterAttack()
} }
void ServerApplication::hCharacterDamage(CharacterPacket* const argPacket) { void ServerApplication::hCharacterDamage(CharacterPacket* const argPacket) {
//TODO: (9) empty //TODO: (9) ServerApplication::hCharacterDamage()
} }
+3 -3
View File
@@ -22,13 +22,13 @@
#include "server_application.hpp" #include "server_application.hpp"
void ServerApplication::hTextBroadcast(TextPacket* const argPacket) { void ServerApplication::hTextBroadcast(TextPacket* const argPacket) {
//TODO: (9) empty //TODO: (9) ServerApplication::hTextBroadcast()
} }
void ServerApplication::hTextSpeech(TextPacket* const argPacket) { void ServerApplication::hTextSpeech(TextPacket* const argPacket) {
//TODO: (9) empty //TODO: (9) ServerApplication::hTextSpeech()
} }
void ServerApplication::hTextWhisper(TextPacket* const argPacket) { void ServerApplication::hTextWhisper(TextPacket* const argPacket) {
//TODO: (9) empty //TODO: (9) ServerApplication::hTextWhisper()
} }
+5 -5
View File
@@ -76,21 +76,21 @@ void ServerApplication::hQueryCharacterExists(CharacterPacket* const argPacket)
} }
void ServerApplication::hQueryCharacterStats(CharacterPacket* const argPacket) { void ServerApplication::hQueryCharacterStats(CharacterPacket* const argPacket) {
//TODO: (9) empty //TODO: (9) ServerApplication::hQueryCharacterStats()
} }
void ServerApplication::hQueryCharacterLocation(CharacterPacket* const argPacket) { void ServerApplication::hQueryCharacterLocation(CharacterPacket* const argPacket) {
//TODO: (9) empty //TODO: (9) ServerApplication::hQueryCharacterLocation()
} }
void ServerApplication::hQueryMonsterExists(MonsterPacket* const argPacket) { void ServerApplication::hQueryMonsterExists(MonsterPacket* const argPacket) {
//TODO: (9) empty //TODO: (9) ServerApplication::hQueryMonsterExists()
} }
void ServerApplication::hQueryMonsterStats(MonsterPacket* const argPacket) { void ServerApplication::hQueryMonsterStats(MonsterPacket* const argPacket) {
//TODO: (9) empty //TODO: (9) ServerApplication::hQueryMonsterStats()
} }
void ServerApplication::hQueryMonsterLocation(MonsterPacket* const argPacket) { void ServerApplication::hQueryMonsterLocation(MonsterPacket* const argPacket) {
//TODO: (9) empty //TODO: (9) ServerApplication::hQueryMonsterLocation()
} }
+2 -2
View File
@@ -30,7 +30,7 @@
//------------------------- //-------------------------
void ServerApplication::hAdminDisconnectForced(ClientPacket* const argPacket) { void ServerApplication::hAdminDisconnectForced(ClientPacket* const argPacket) {
//TODO: (9) empty //TODO: (9) ServerApplication::hAdminDisconnectForced()
} }
void ServerApplication::hAdminShutdownRequest(ClientPacket* const argPacket) { void ServerApplication::hAdminShutdownRequest(ClientPacket* const argPacket) {
@@ -85,5 +85,5 @@ void ServerApplication::hAdminShutdownRequest(ClientPacket* const argPacket) {
} }
void ServerApplication::SaveServerState() { void ServerApplication::SaveServerState() {
//TODO: (9) empty //TODO: (3) Periodic mass server saves
} }
+1 -1
View File
@@ -22,5 +22,5 @@
#include "server_application.hpp" #include "server_application.hpp"
void ServerApplication::hMonsterDamage(MonsterPacket* const argPacket) { void ServerApplication::hMonsterDamage(MonsterPacket* const argPacket) {
//TODO: (9) empty //TODO: (9) ServerApplication::hMonsterDamage()
} }
+1 -1
View File
@@ -1,5 +1,5 @@
#config #config
INCLUDES+=. ../accounts ../characters ../clients ../entities ../monsters ../rooms ../waypoints ../../common/gameplay ../../common/map ../../common/network ../../common/network/packet_types ../../common/utilities INCLUDES+=. ../accounts ../characters ../clients ../entities ../monsters ../rooms ../triggers ../../common/gameplay ../../common/map ../../common/network ../../common/network/packet_types ../../common/utilities
LIBS+= LIBS+=
CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))
@@ -140,6 +140,10 @@ void copyCharacterToPacket(CharacterPacket* const packet, int characterIndex) {
throw(std::runtime_error("Failed to copy a character to a packet")); throw(std::runtime_error("Failed to copy a character to a packet"));
} }
copyCharacterToPacket(packet, characterData, characterIndex);
}
void copyCharacterToPacket(CharacterPacket* const packet, CharacterData* const characterData, int characterIndex) {
//NOTE: keep this up to date when the character changes //NOTE: keep this up to date when the character changes
packet->characterIndex = characterIndex; packet->characterIndex = characterIndex;
strncpy(packet->handle, characterData->GetHandle().c_str(), PACKET_STRING_SIZE); strncpy(packet->handle, characterData->GetHandle().c_str(), PACKET_STRING_SIZE);
@@ -148,4 +152,31 @@ void copyCharacterToPacket(CharacterPacket* const packet, int characterIndex) {
packet->roomIndex = characterData->GetRoomIndex(); packet->roomIndex = characterData->GetRoomIndex();
packet->origin = characterData->GetOrigin(); packet->origin = characterData->GetOrigin();
packet->motion = characterData->GetMotion(); packet->motion = characterData->GetMotion();
packet->bounds = characterData->GetBounds();
} }
void pumpAndChangeRooms(int characterIndex, int newRoomIndex) {
//get the character object
CharacterData* character = CharacterManager::GetSingleton().Get(characterIndex);
//pass ownwards
pumpAndChangeRooms(character, newRoomIndex, characterIndex);
}
void pumpAndChangeRooms(CharacterData* const characterData, int newRoomIndex, int characterIndex) {
//delete from the old room
CharacterPacket newPacket;
copyCharacterToPacket(&newPacket, characterData, characterIndex);
newPacket.type = SerialPacketType::CHARACTER_DELETE;
pumpPacketProximity(&newPacket, characterData->GetRoomIndex());
//move the character between rooms
RoomManager::GetSingleton().PopCharacter(characterData);
characterData->SetRoomIndex(newRoomIndex);
RoomManager::GetSingleton().PushCharacter(characterData);
//create in the new room
copyCharacterToPacket(&newPacket, characterData, characterIndex);
newPacket.type = SerialPacketType::CHARACTER_CREATE;
pumpPacketProximity(&newPacket, characterData->GetRoomIndex());
}
@@ -22,14 +22,20 @@
#ifndef SERVERUTILITIES_HPP_ #ifndef SERVERUTILITIES_HPP_
#define SERVERUTILITIES_HPP_ #define SERVERUTILITIES_HPP_
#include "character_data.hpp"
#include "serial_packet.hpp" #include "serial_packet.hpp"
#include "vector2.hpp" #include "vector2.hpp"
void fullClientUnload(int index); void fullClientUnload(int index);
void fullAccountUnload(int index); void fullAccountUnload(int index);
void fullCharacterUnload(int index); void fullCharacterUnload(int index);
void pumpPacket(SerialPacket* const argPacket); void pumpPacket(SerialPacket* const argPacket);
void pumpPacketProximity(SerialPacket* const argPacket, int roomIndex, Vector2 position = {0, 0}, int distance = -1); void pumpPacketProximity(SerialPacket* const argPacket, int roomIndex, Vector2 position = {0, 0}, int distance = -1);
void copyCharacterToPacket(CharacterPacket* const packet, int characterIndex); void copyCharacterToPacket(CharacterPacket* const packet, int characterIndex);
void copyCharacterToPacket(CharacterPacket* const packet, CharacterData* const characterData, int characterIndex);
void pumpAndChangeRooms(int characterIndex, int newRoomIndex);
void pumpAndChangeRooms(CharacterData* const characterData, int newRoomIndex, int characterIndex);
#endif #endif
+126
View File
@@ -0,0 +1,126 @@
/* Copyright: (c) Kayne Ruse 2013-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 "trigger_api.hpp"
#include "trigger_data.hpp"
//hamdle
static int setHandle(lua_State* L) {
TriggerData* trigger = static_cast<TriggerData*>(lua_touserdata(L, 1));
trigger->SetHandle(lua_tostring(L, 2));
return 0;
}
static int getHandle(lua_State* L) {
TriggerData* trigger = static_cast<TriggerData*>(lua_touserdata(L, 1));
lua_pushstring(L, trigger->GetHandle().c_str());
return 1;
}
//origin
static int setOrigin(lua_State* L) {
TriggerData* trigger = static_cast<TriggerData*>(lua_touserdata(L, 1));
trigger->SetOrigin(Vector2(lua_tonumber(L, 2), lua_tonumber(L, 3)));
return 0;
}
static int getOrigin(lua_State* L) {
TriggerData* trigger = static_cast<TriggerData*>(lua_touserdata(L, 1));
lua_pushnumber(L, trigger->GetOrigin().x);
lua_pushnumber(L, trigger->GetOrigin().y);
return 2;
}
//bounds
static int setBoundingBox(lua_State* L) {
TriggerData* trigger = static_cast<TriggerData*>(lua_touserdata(L, 1));
trigger->SetBoundingBox(BoundingBox(
lua_tonumber(L, 2),
lua_tonumber(L, 3),
lua_tonumber(L, 4),
lua_tonumber(L, 5)
));
return 0;
}
static int getBoundingBox(lua_State* L) {
TriggerData* trigger = static_cast<TriggerData*>(lua_touserdata(L, 1));
lua_pushinteger(L, trigger->GetBoundingBox().x);
lua_pushinteger(L, trigger->GetBoundingBox().y);
lua_pushinteger(L, trigger->GetBoundingBox().w);
lua_pushinteger(L, trigger->GetBoundingBox().h);
return 4;
}
//triggers
static int setReference(lua_State* L) {
TriggerData* trigger = static_cast<TriggerData*>(lua_touserdata(L, 1));
luaL_unref(L, LUA_REGISTRYINDEX, trigger->GetScriptReference());
trigger->SetScriptReference(luaL_ref(L, LUA_REGISTRYINDEX));
return 0;
}
static int getReference(lua_State* L) {
TriggerData* trigger = static_cast<TriggerData*>(lua_touserdata(L, 1));
lua_pushinteger(L, trigger->GetScriptReference());
lua_gettable(L, LUA_REGISTRYINDEX);
return 1;
}
static int pushExclusionEntity(lua_State* L) {
TriggerData* trigger = static_cast<TriggerData*>(lua_touserdata(L, 1));
trigger->GetExclusionList()->push_back(static_cast<Entity*>(lua_touserdata(L, 2)));
return 0;
}
static int removeExclusionEntity(lua_State* L) {
TriggerData* trigger = static_cast<TriggerData*>(lua_touserdata(L, 1));
Entity* entity = static_cast<Entity*>(lua_touserdata(L, 2));
trigger->GetExclusionList()->remove_if([entity](Entity* ptr){
return entity == ptr;
});
return 0;
}
static const luaL_Reg triggerLib[] = {
{"SetHandle", setHandle},
{"GetHandle", getHandle},
{"SetOrigin",setOrigin},
{"GetOrigin",getOrigin},
{"SetBounds",setBoundingBox},
{"GetBounds",getBoundingBox},
{"SetScript",setReference},
{"GetScript",getReference},
{"PushExclusionEntity", pushExclusionEntity},
{"RemoveExclusionEntity", removeExclusionEntity},
{nullptr, nullptr}
};
LUAMOD_API int openTriggerAPI(lua_State* L) {
luaL_newlib(L, triggerLib);
return 1;
}
@@ -19,12 +19,12 @@
* 3. This notice may not be removed or altered from any source * 3. This notice may not be removed or altered from any source
* distribution. * distribution.
*/ */
#ifndef WAYPOINTAPI_HPP_ #ifndef TRIGGERAPI_HPP_
#define WAYPOINTAPI_HPP_ #define TRIGGERAPI_HPP_
#include "lua.hpp" #include "lua.hpp"
#define TORTUGA_WAYPOINT_API "waypoint" #define TORTUGA_TRIGGER_API "trigger"
LUAMOD_API int openWaypointAPI(lua_State* L); LUAMOD_API int openTriggerAPI(lua_State* L);
#endif #endif
@@ -19,28 +19,40 @@
* 3. This notice may not be removed or altered from any source * 3. This notice may not be removed or altered from any source
* distribution. * distribution.
*/ */
#include "waypoint_data.hpp" #include "trigger_data.hpp"
int WaypointData::SetTriggerReference(int i) { std::string TriggerData::SetHandle(std::string s) {
return triggerRef = i; return handle = s;
} }
int WaypointData::GetTriggerReference() { std::string TriggerData::GetHandle() const {
return triggerRef; return handle;
} }
BoundingBox WaypointData::SetBoundingBox(BoundingBox b) { Vector2 TriggerData::SetOrigin(Vector2 v) {
return bounds = b;
}
BoundingBox WaypointData::GetBoundingBox() {
return bounds;
}
Vector2 WaypointData::SetOrigin(Vector2 v) {
return origin = v; return origin = v;
} }
Vector2 WaypointData::GetOrigin() { Vector2 TriggerData::GetOrigin() {
return origin; return origin;
} }
BoundingBox TriggerData::SetBoundingBox(BoundingBox b) {
return bounds = b;
}
BoundingBox TriggerData::GetBoundingBox() {
return bounds;
}
int TriggerData::SetScriptReference(int i) {
return scriptRef = i;
}
int TriggerData::GetScriptReference() {
return scriptRef;
}
std::list<Entity*>* TriggerData::GetExclusionList() {
return &exclusionList;
}
@@ -19,20 +19,25 @@
* 3. This notice may not be removed or altered from any source * 3. This notice may not be removed or altered from any source
* distribution. * distribution.
*/ */
#ifndef WAYPOINTDATA_HPP_ #ifndef TRIGGERDATA_HPP_
#define WAYPOINTDATA_HPP_ #define TRIGGERDATA_HPP_
#include "bounding_box.hpp" #include "bounding_box.hpp"
#include "entity.hpp"
#include "vector2.hpp" #include "vector2.hpp"
#include "lua.hpp" #include "lua.hpp"
#include <list>
#include <string> #include <string>
class WaypointData { class TriggerData {
public: public:
WaypointData() = default; TriggerData() = default;
~WaypointData() = default; ~TriggerData() = default;
std::string SetHandle(std::string);
std::string GetHandle() const;
Vector2 SetOrigin(Vector2 v); Vector2 SetOrigin(Vector2 v);
Vector2 GetOrigin(); Vector2 GetOrigin();
@@ -40,15 +45,17 @@ public:
BoundingBox SetBoundingBox(BoundingBox b); BoundingBox SetBoundingBox(BoundingBox b);
BoundingBox GetBoundingBox(); BoundingBox GetBoundingBox();
int SetTriggerReference(int i); int SetScriptReference(int i);
int GetTriggerReference(); int GetScriptReference();
std::list<Entity*>* GetExclusionList();
private: private:
friend class WaypointManager; std::string handle;
Vector2 origin; Vector2 origin;
BoundingBox bounds; BoundingBox bounds;
int triggerRef = LUA_NOREF; int scriptRef = LUA_NOREF;
std::list<Entity*> exclusionList;
}; };
#endif #endif
@@ -19,47 +19,36 @@
* 3. This notice may not be removed or altered from any source * 3. This notice may not be removed or altered from any source
* distribution. * distribution.
*/ */
#include "waypoint_manager.hpp" #include "trigger_manager.hpp"
WaypointManager::WaypointManager() { TriggerManager::TriggerManager() {
//EMPTY //EMPTY
} }
WaypointManager::~WaypointManager() { TriggerManager::~TriggerManager() {
UnloadAll(); UnloadAll();
} }
int WaypointManager::Create() { int TriggerManager::Create(std::string handle) {
//implicitly creates the element //implicitly creates the element
WaypointData& waypointData = elementMap[counter]; TriggerData& triggerData = elementMap[counter];
//no real values set triggerData.SetHandle(handle);
waypointData.origin = {0, 0};
waypointData.bounds = {0, 0, 0, 0};
return counter++; return counter++;
} }
int WaypointManager::Create(Vector2 origin, BoundingBox bounds) { void TriggerManager::Unload(int uid) {
//implicitly creates the element
WaypointData& waypointData = elementMap[counter];
waypointData.origin = origin;
waypointData.bounds = bounds;
return counter++;
}
void WaypointManager::Unload(int uid) {
elementMap.erase(uid); elementMap.erase(uid);
} }
void WaypointManager::UnloadAll() { void TriggerManager::UnloadAll() {
//TODO: save?
elementMap.clear(); elementMap.clear();
} }
void WaypointManager::UnloadIf(std::function<bool(std::pair<const int, WaypointData const&>)> fn) { void TriggerManager::UnloadIf(std::function<bool(std::pair<const int, TriggerData const&>)> fn) {
std::map<int, WaypointData>::iterator it = elementMap.begin(); std::map<int, TriggerData>::iterator it = elementMap.begin();
while (it != elementMap.end()) { while (it != elementMap.end()) {
if (fn(*it)) { if (fn(*it)) {
it = elementMap.erase(it); it = elementMap.erase(it);
@@ -70,8 +59,8 @@ void WaypointManager::UnloadIf(std::function<bool(std::pair<const int, WaypointD
} }
} }
WaypointData* WaypointManager::Get(int uid) { TriggerData* TriggerManager::Get(int uid) {
std::map<int, WaypointData>::iterator it = elementMap.find(uid); std::map<int, TriggerData>::iterator it = elementMap.find(uid);
if (it == elementMap.end()) { if (it == elementMap.end()) {
return nullptr; return nullptr;
@@ -80,19 +69,28 @@ WaypointData* WaypointManager::Get(int uid) {
return &it->second; return &it->second;
} }
int WaypointManager::GetLoadedCount() { TriggerData* TriggerManager::Get(std::string handle) {
for (std::map<int, TriggerData>::iterator it = elementMap.begin(); it != elementMap.end(); ++it) {
if (it->second.GetHandle() == handle) {
return &it->second;
}
}
return nullptr;
}
int TriggerManager::GetLoadedCount() {
return elementMap.size(); return elementMap.size();
} }
std::map<int, WaypointData>* WaypointManager::GetContainer() { std::map<int, TriggerData>* TriggerManager::GetContainer() {
return &elementMap; return &elementMap;
} }
//hooks //hooks
lua_State* WaypointManager::SetLuaState(lua_State* L) { lua_State* TriggerManager::SetLuaState(lua_State* L) {
return lua = L; return lua = L;
} }
lua_State* WaypointManager::GetLuaState() { lua_State* TriggerManager::GetLuaState() {
return lua; return lua;
} }
@@ -19,12 +19,12 @@
* 3. This notice may not be removed or altered from any source * 3. This notice may not be removed or altered from any source
* distribution. * distribution.
*/ */
#ifndef WAYPOINTMANAGER_HPP_ #ifndef TRIGGERMANAGER_HPP_
#define WAYPOINTMANAGER_HPP_ #define TRIGGERMANAGER_HPP_
#include "bounding_box.hpp" #include "bounding_box.hpp"
#include "vector2.hpp" #include "vector2.hpp"
#include "waypoint_data.hpp" #include "trigger_data.hpp"
#include "lua.hpp" #include "lua.hpp"
@@ -32,23 +32,23 @@
#include <map> #include <map>
#include <string> #include <string>
class WaypointManager { class TriggerManager {
public: public:
WaypointManager(); TriggerManager();
~WaypointManager(); ~TriggerManager();
//common public methods //common public methods
int Create(); int Create(std::string handle);
int Create(Vector2 origin, BoundingBox bounds);
void Unload(int uid); void Unload(int uid);
void UnloadAll(); void UnloadAll();
void UnloadIf(std::function<bool(std::pair<const int, WaypointData const&>)> fn); void UnloadIf(std::function<bool(std::pair<const int, TriggerData const&>)> fn);
//accessors & mutators //accessors & mutators
WaypointData* Get(int uid); TriggerData* Get(int uid);
TriggerData* Get(std::string handle);
int GetLoadedCount(); int GetLoadedCount();
std::map<int, WaypointData>* GetContainer(); std::map<int, TriggerData>* GetContainer();
//hooks //hooks
lua_State* SetLuaState(lua_State* L); lua_State* SetLuaState(lua_State* L);
@@ -56,7 +56,7 @@ public:
private: private:
//members //members
std::map<int, WaypointData> elementMap; std::map<int, TriggerData> elementMap;
lua_State* lua = nullptr; lua_State* lua = nullptr;
int counter = 0; int counter = 0;
}; };
+148
View File
@@ -0,0 +1,148 @@
/* Copyright: (c) Kayne Ruse 2013-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 "trigger_manager_api.hpp"
#include "trigger_manager.hpp"
static int create(lua_State* L) {
//DOCS: params: create(triggerMgr, name[, originX, originY[, boundsX, boundsY, boundsW, boundsH]][, script])
//get the trigger manager
TriggerManager* mgr = static_cast<TriggerManager*>(lua_touserdata(L, 1));
//create the trigger
int index = mgr->Create(lua_tostring(L, 2));
TriggerData* triggerData = mgr->Get(index);
//origin
if (lua_gettop(L) >= 4) {
triggerData->SetOrigin({lua_tonumber(L, 3), lua_tonumber(L, 4)}); //vectorX, vectorY
}
//bounds
if (lua_gettop(L) >= 8) {
triggerData->SetBoundingBox({
lua_tointeger(L, 5), //boundsX
lua_tointeger(L, 6), //boundsY
lua_tointeger(L, 7), //boundsW
lua_tointeger(L, 8) //boundsH
});
}
//if the parameter list isn't capped with a script, append a nil instead
if (lua_type(L, -1) != LUA_TFUNCTION) {
lua_pushnil(L);
}
//set the script reference (may be nil)
triggerData->SetScriptReference(luaL_ref(L, LUA_REGISTRYINDEX));
//push to the scipts
lua_pushlightuserdata(L, static_cast<void*>(triggerData));
lua_pushinteger(L, index);
return 2;
}
static int unload(lua_State* L) {
TriggerManager* mgr = static_cast<TriggerManager*>(lua_touserdata(L, 1));
int count = 0; //the number removed
//based on the type
switch(lua_type(L, 2)) {
//unload this index
case LUA_TNUMBER:
mgr->UnloadIf([L, &count](std::pair<int, TriggerData const&> it) -> bool {
if (it.first == lua_tointeger(L, 2)) {
count++;
return true;
}
else {
return false;
}
});
break;
//unload this name
case LUA_TSTRING:
mgr->UnloadIf([L, &count](std::pair<int, TriggerData const&> it) -> bool {
if (it.second.GetHandle() == lua_tostring(L, 2)) {
count++;
return true;
}
else {
return false;
}
});
break;
}
//return the number removed
lua_pushinteger(L, count);
return 1;
}
static int getTrigger(lua_State* L) {
TriggerManager* mgr = static_cast<TriggerManager*>(lua_touserdata(L, 1));
TriggerData* triggerData = nullptr;
switch(lua_type(L, 2)) {
case LUA_TNUMBER:
triggerData = mgr->Get(lua_tointeger(L, 2));
break;
case LUA_TSTRING:
triggerData = mgr->Get(lua_tostring(L, 2));
break;
}
if (triggerData) {
lua_pushlightuserdata(L, static_cast<void*>(triggerData));
}
else {
lua_pushnil(L);
}
return 1;
}
static int forEach(lua_State* L) {
//TODO: (9) forEach()
}
static int getLoadedCount(lua_State* L) {
TriggerManager* mgr = static_cast<TriggerManager*>(lua_touserdata(L, 1));
lua_pushinteger(L, mgr->GetLoadedCount());
return 1;
}
static const luaL_Reg triggerManagerLib[] = {
{"Create",create},
{"Unload",unload},
{"GetTrigger",getTrigger},
{"GetCount",getLoadedCount},
{nullptr, nullptr}
};
LUAMOD_API int openTriggerManagerAPI(lua_State* L) {
luaL_newlib(L, triggerManagerLib);
return 1;
}
@@ -19,12 +19,12 @@
* 3. This notice may not be removed or altered from any source * 3. This notice may not be removed or altered from any source
* distribution. * distribution.
*/ */
#ifndef ROOMSYSTEMAPI_HPP_ #ifndef TRIGGERMANAGERAPI_HPP_
#define ROOMSYSTEMAPI_HPP_ #define TRIGGERMANAGERAPI_HPP_
#include "lua.hpp" #include "lua.hpp"
#define TORTUGA_ROOM_SYSTEM_API "room_system" #define TORTUGA_TRIGGER_MANAGER_API "trigger_manager"
LUAMOD_API int openRoomSystemAPI(lua_State* L); LUAMOD_API int openTriggerManagerAPI(lua_State* L);
#endif #endif
-91
View File
@@ -1,91 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013-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 "waypoint_api.hpp"
#include "waypoint_data.hpp"
//origin
static int setOrigin(lua_State* L) {
WaypointData* waypoint = static_cast<WaypointData*>(lua_touserdata(L, 1));
waypoint->SetOrigin(Vector2(lua_tonumber(L, 2), lua_tonumber(L, 3)));
return 0;
}
static int getOrigin(lua_State* L) {
WaypointData* waypoint = static_cast<WaypointData*>(lua_touserdata(L, 1));
lua_pushnumber(L, waypoint->GetOrigin().x);
lua_pushnumber(L, waypoint->GetOrigin().y);
return 2;
}
//bounds
static int setBoundingBox(lua_State* L) {
WaypointData* waypoint = static_cast<WaypointData*>(lua_touserdata(L, 1));
waypoint->SetBoundingBox(BoundingBox(
lua_tonumber(L, 2),
lua_tonumber(L, 3),
lua_tonumber(L, 4),
lua_tonumber(L, 5)
));
return 0;
}
static int getBoundingBox(lua_State* L) {
WaypointData* waypoint = static_cast<WaypointData*>(lua_touserdata(L, 1));
lua_pushnumber(L, waypoint->GetBoundingBox().x);
lua_pushnumber(L, waypoint->GetBoundingBox().y);
lua_pushnumber(L, waypoint->GetBoundingBox().w);
lua_pushnumber(L, waypoint->GetBoundingBox().h);
return 4;
}
//triggers
static int setTriggerReference(lua_State* L) {
WaypointData* waypoint = static_cast<WaypointData*>(lua_touserdata(L, 1));
luaL_unref(L, LUA_REGISTRYINDEX, waypoint->GetTriggerReference());
waypoint->SetTriggerReference(luaL_ref(L, LUA_REGISTRYINDEX));
return 0;
}
static int getTriggerReference(lua_State* L) {
WaypointData* waypoint = static_cast<WaypointData*>(lua_touserdata(L, 1));
lua_pushinteger(L, waypoint->GetTriggerReference());
lua_gettable(L, LUA_REGISTRYINDEX);
return 1;
}
static const luaL_Reg waypointLib[] = {
{"SetOrigin",setOrigin},
{"GetOrigin",getOrigin},
{"SetBounds",setBoundingBox},
{"GetBounds",getBoundingBox},
{"SetTrigger",setTriggerReference},
{"GetTrigger",getTriggerReference},
{nullptr, nullptr}
};
LUAMOD_API int openWaypointAPI(lua_State* L) {
luaL_newlib(L, waypointLib);
return 1;
}
-59
View File
@@ -1,59 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013-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 "waypoint_manager_api.hpp"
#include "waypoint_manager.hpp"
//TODO: figure out a way to iterate through elements of managers from lua
static int create(lua_State* L) {
WaypointManager* mgr = static_cast<WaypointManager*>(lua_touserdata(L, 1));
}
static int unload(lua_State* L) {
WaypointManager* mgr = static_cast<WaypointManager*>(lua_touserdata(L, 1));
}
static int getWaypoint(lua_State* L) {
WaypointManager* mgr = static_cast<WaypointManager*>(lua_touserdata(L, 1));
lua_pushlightuserdata(L, mgr->Get(lua_tointeger(L, 2)));
return 1;
}
static int getLoadedCount(lua_State* L) {
WaypointManager* mgr = static_cast<WaypointManager*>(lua_touserdata(L, 1));
lua_pushinteger(L, mgr->GetLoadedCount());
return 1;
}
static const luaL_Reg waypointManagerLib[] = {
{"Create",create},
{"Unload",unload},
{"GetWaypoint",getWaypoint},
{"GetCount",getLoadedCount},
{nullptr, nullptr}
};
LUAMOD_API int openWaypointManagerAPI(lua_State* L) {
luaL_newlib(L, waypointManagerLib);
return 1;
}
-30
View File
@@ -1,30 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013-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.
*/
#ifndef WAYPOINTMANAGERAPI_HPP_
#define WAYPOINTMANAGERAPI_HPP_
#include "lua.hpp"
#define TORTUGA_WAYPOINT_MANAGER_API "waypoint_manager"
LUAMOD_API int openWaypointManagerAPI(lua_State* L);
#endif
-55
View File
@@ -1,55 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013-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 "waypoint_system_api.hpp"
//all waypoint API headers
#include "waypoint_api.hpp"
#include "waypoint_manager_api.hpp"
//useful "globals"
//...
//This mimics linit.c to create a nested collection of all waypoint modules.
static const luaL_Reg funcs[] = {
{nullptr, nullptr}
};
static const luaL_Reg libs[] = {
{"Waypoint", openWaypointAPI},
{"WaypointManager", openWaypointManagerAPI},
{nullptr, nullptr}
};
int openWaypointSystemAPI(lua_State* L) {
//create the table
luaL_newlibtable(L, libs);
//push the "global" functions
luaL_setfuncs(L, funcs, 0);
//push the substable
for (const luaL_Reg* lib = libs; lib->func; lib++) {
lib->func(L);
lua_setfield(L, -2, lib->name);
}
return 1;
}
-30
View File
@@ -1,30 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013-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.
*/
#ifndef WAYPOINTSYSTEMAPI_HPP_
#define WAYPOINTSYSTEMAPI_HPP_
#include "lua.hpp"
#define TORTUGA_WAYPOINT_SYSTEM_API "waypoint_system"
LUAMOD_API int openWaypointSystemAPI(lua_State* L);
#endif
+4 -8
View File
@@ -1,21 +1,19 @@
TODO: upgrade to lua 5.3 TODO: upgrade to lua 5.3
TODO: Split config.cfg in two, one for the server and the client TODO: Split config.cfg in two, one for the server and the client
TODO: Consistency for bounds names
TODO: In need of script APIs (list)
* Characters
TODO: Account passwords (list) TODO: Account passwords (list)
* backbone account server OR * backbone account server OR
* social network login OR * social network login OR
* ... * ...
* salts & hashes * salts & hashes
* login screen prompting for username & password
TODO: Features TODO: Features
* Make sure login errors are sent to the client * Make sure login errors are sent to the client
* Add the "home" parameter to the server's config file * Add the "home" parameter to the server's config file
* Waypoints, with positions and trigger zones (collision areas) for doors, monster spawns, etc. * Waypoints, with positions and trigger zones (collision areas) for doors, monster spawns, etc. (trigger system)
* Fix shoddy movement * Fix shoddy movement
* Periodic mass server saves
* Remove the big "Shut Down" button (currently broken...) * Remove the big "Shut Down" button (currently broken...)
* Make a way for the server owner to control the server directly * Make a way for the server owner to control the server directly
* The TileSheet class should implement the surface itself * The TileSheet class should implement the surface itself
@@ -24,6 +22,4 @@ TODO: Features
* Fix the const-ness of accessors * Fix the const-ness of accessors
* Add a screenshot of the game to README.md * Add a screenshot of the game to README.md
* joystick/gamepad support * joystick/gamepad support
* add the tilesheet to the map system * add the tilesheet to the map system
* ping/delay displayed in the lobby
* login screen prompting for username & password