diff --git a/client/character.hpp b/client/character.hpp index ca2d9a4..bde4268 100644 --- a/client/character.hpp +++ b/client/character.hpp @@ -25,6 +25,7 @@ //components #include "character_defines.hpp" #include "vector2.hpp" +#include "bounding_box.hpp" #include "statistics.hpp" //graphics @@ -64,8 +65,8 @@ public: Vector2 GetOrigin() const { return origin; } Vector2 SetMotion(Vector2 v) { return motion = v; } Vector2 GetMotion() const { return motion; } - Vector2 SetBounds(Vector2 v) { return bounds = v; } - Vector2 GetBounds() const { return bounds; } + BoundingBox SetBounds(BoundingBox b) { return bounds = b; } + BoundingBox GetBounds() { return bounds; } private: //graphics @@ -84,7 +85,7 @@ private: //position Vector2 origin = {0.0,0.0}; Vector2 motion = {0.0,0.0}; - Vector2 bounds = {CHARACTER_BOUNDS_WIDTH,CHARACTER_BOUNDS_HEIGHT}; + BoundingBox bounds; }; //tmp diff --git a/client/makefile b/client/makefile index 97d8949..f318d52 100644 --- a/client/makefile +++ b/client/makefile @@ -1,5 +1,5 @@ #config -INCLUDES+=. scenes ../common/gameplay ../common/graphics ../common/map ../common/network ../common/network/packet ../common/network/serial ../common/ui ../common/utilities +INCLUDES+=. scenes ../common/debugging ../common/gameplay ../common/graphics ../common/map ../common/network ../common/network/packet ../common/network/serial ../common/ui ../common/utilities LIBS+=client.a ../libcommon.a -lSDL_net -lwsock32 -liphlpapi -lmingw32 -lSDLmain -lSDL -llua CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) diff --git a/client/scenes/in_world.cpp b/client/scenes/in_world.cpp index 4f997a0..59f43ba 100644 --- a/client/scenes/in_world.cpp +++ b/client/scenes/in_world.cpp @@ -71,7 +71,8 @@ InWorld::InWorld( //load the tilesheet //TODO: add the tilesheet to the map system? - tileSheet.Load(config["dir.tilesets"] + "terrain.bmp", 12, 15); + //TODO: Tile size and tile sheet should be loaded elsewhere + tileSheet.Load(config["dir.tilesets"] + "terrain.bmp", 32, 32); //request a sync RequestSynchronize(); @@ -105,16 +106,41 @@ void InWorld::Update(double delta) { it.second.Update(delta); } - //TODO: Check collisions here - - //update the camera - if(localCharacter) { - camera.x = localCharacter->GetOrigin().x - camera.marginX; - camera.y = localCharacter->GetOrigin().y - camera.marginY; - } - //check the map UpdateMap(); + + //skip the rest + if (!localCharacter) { + return; + } + + //check for collisions with the map + BoundingBox wallBounds = {0, 0, tileSheet.GetTileW(), tileSheet.GetTileH()}; + const int xCount = localCharacter->GetBounds().w / wallBounds.w + 1; + const int yCount = localCharacter->GetBounds().h / wallBounds.h + 1; + + for (int i = -1; i <= xCount; ++i) { + for (int j = -1; j <= yCount; ++j) { + //set the wall's position + wallBounds.x = wallBounds.w * i + snapToBase((double)wallBounds.w, localCharacter->GetOrigin().x); + wallBounds.y = wallBounds.h * j + snapToBase((double)wallBounds.h, localCharacter->GetOrigin().y); + + if (!regionPager.GetSolid(wallBounds.x / wallBounds.w, wallBounds.y / wallBounds.h)) { + continue; + } + + if ((localCharacter->GetOrigin() + localCharacter->GetBounds()).CheckOverlap(wallBounds)) { + localCharacter->SetOrigin(localCharacter->GetOrigin() - (localCharacter->GetMotion() * delta)); + localCharacter->SetMotion({0,0}); + localCharacter->CorrectSprite(); + SendPlayerUpdate(); + } + } + } + + //update the camera + camera.x = localCharacter->GetOrigin().x - camera.marginX; + camera.y = localCharacter->GetOrigin().y - camera.marginY; } void InWorld::FrameEnd() { @@ -280,6 +306,7 @@ void InWorld::HandleCharacterNew(CharacterPacket* const argPacket) { newCharacter.SetOrigin(argPacket->origin); newCharacter.SetMotion(argPacket->motion); + newCharacter.SetBounds({0, 16, 32, 32}); //TODO: magic numbers, fix this (*newCharacter.GetStats()) = argPacket->stats; diff --git a/client/scenes/main_menu.cpp b/client/scenes/main_menu.cpp index 735e2fb..d722141 100644 --- a/client/scenes/main_menu.cpp +++ b/client/scenes/main_menu.cpp @@ -101,6 +101,7 @@ void MainMenu::MouseButtonDown(SDL_MouseButtonEvent const& button) { } void MainMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) { + //TODO: Buttons should only register as "selected" when the left button is used if (startButton.MouseButtonUp(button) == Button::State::HOVER) { SetNextScene(SceneList::LOBBYMENU); } diff --git a/common/debugging/makefile b/common/debugging/makefile new file mode 100644 index 0000000..9013447 --- /dev/null +++ b/common/debugging/makefile @@ -0,0 +1,37 @@ +#config +INCLUDES+=. +LIBS+= +CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) + +#source +CXXSRC=$(wildcard *.cpp) + +#objects +OBJDIR=obj +OBJ+=$(addprefix $(OBJDIR)/,$(CXXSRC:.cpp=.o)) + +#output +OUTDIR=../.. +OUT=$(addprefix $(OUTDIR)/,libcommon.a) + +#targets +all: $(OBJ) $(OUT) + ar -crs $(OUT) $(OBJ) + +$(OBJ): | $(OBJDIR) + +$(OUT): | $(OUTDIR) + +$(OBJDIR): + mkdir $(OBJDIR) + +$(OUTDIR): + mkdir $(OUTDIR) + +$(OBJDIR)/%.o: %.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +clean: + $(RM) *.o *.a *.exe + +rebuild: clean all diff --git a/common/debugging/timer.cpp b/common/debugging/timer.cpp new file mode 100644 index 0000000..be3636a --- /dev/null +++ b/common/debugging/timer.cpp @@ -0,0 +1,29 @@ +/* Copyright: (c) Kayne Ruse 2014 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. +*/ +#include "timer.hpp" + +std::ostream& operator<<(std::ostream& os, Timer& t) { + os << t.GetName() << ": "; + os << std::chrono::duration_cast(t.GetTime()).count(); + os << "ns"; + return os; +} diff --git a/common/debugging/timer.hpp b/common/debugging/timer.hpp new file mode 100644 index 0000000..7f8f38b --- /dev/null +++ b/common/debugging/timer.hpp @@ -0,0 +1,54 @@ +/* Copyright: (c) Kayne Ruse 2014 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. +*/ +#ifndef TIMER_HPP_ +#define TIMER_HPP_ + +#include +#include +#include + +class Timer { +public: + typedef std::chrono::high_resolution_clock Clock; + + Timer() = default; + Timer(std::string s) : name(s), start(Clock::now()) {}; + ~Timer() = default; + + inline void Start() { start = Clock::now(); } + inline void Stop() { time = Clock::now() - start; } + + //accessors and mutators + Clock::duration GetTime() { return time; } + + std::string SetName(std::string s) { return name = s; } + std::string GetName() { return name; } + +private: + std::string name; + Clock::time_point start; + Clock::duration time; +}; + +std::ostream& operator<<(std::ostream& os, Timer& t); + +#endif diff --git a/common/graphics/makefile b/common/graphics/makefile index afcde11..9013447 100644 --- a/common/graphics/makefile +++ b/common/graphics/makefile @@ -1,5 +1,5 @@ #config -INCLUDES+=. ../map +INCLUDES+=. LIBS+= CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) diff --git a/common/makefile b/common/makefile index b670b7d..bdb1406 100644 --- a/common/makefile +++ b/common/makefile @@ -1,4 +1,5 @@ all: + $(MAKE) -C debugging $(MAKE) -C gameplay $(MAKE) -C graphics $(MAKE) -C map diff --git a/common/map/makefile b/common/map/makefile index 769709e..24e7779 100644 --- a/common/map/makefile +++ b/common/map/makefile @@ -1,5 +1,5 @@ #config -INCLUDES+=. ../utilities +INCLUDES+=. ../graphics ../utilities LIBS+= CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES)) diff --git a/common/map/region_api.cpp b/common/map/region_api.cpp index 014a873..2fd3dbb 100644 --- a/common/map/region_api.cpp +++ b/common/map/region_api.cpp @@ -78,28 +78,27 @@ static int getDepth(lua_State* L) { return 1; } -static int onLoad(lua_State* L) { - //TODO: onLoad() +static int load(lua_State* L) { + //EMPTY lua_pushboolean(L, false); return 1; } -static int onSave(lua_State* L) { - //TODO: onSave() +static int save(lua_State* L) { + //EMPTY return 0; } -static int onCreate(lua_State* L) { - //TODO: onCreate() +static int create(lua_State* L) { + //EMPTY return 0; } -static int onUnload(lua_State* L) { - //TODO: onUnload() +static int unload(lua_State* L) { + //EMPTY return 0; } -//TODO: wrappers for the collision map static const luaL_Reg regionLib[] = { {"SetTile",setTile}, {"GetTile",getTile}, @@ -110,10 +109,10 @@ static const luaL_Reg regionLib[] = { {"GetWidth",getWidth}, {"GetHeight",getHeight}, {"GetDepth",getDepth}, - {"OnLoad",onLoad}, - {"OnSave",onSave}, - {"OnCreate",onCreate}, - {"OnUnload",onUnload}, + {"Load",load}, + {"Save",save}, + {"Create",create}, + {"Unload",unload}, {nullptr, nullptr} }; diff --git a/common/map/region_pager_api.cpp b/common/map/region_pager_api.cpp index 40c4d76..3932421 100644 --- a/common/map/region_pager_api.cpp +++ b/common/map/region_pager_api.cpp @@ -24,10 +24,9 @@ #include "region_pager_lua.hpp" #include "region.hpp" -#include #include -//DOCS: These functions are just wrappers for the RegionPagerLua class +//DOCS: These glue functions simply wrap RegionPagerLua's methods static int setTile(lua_State* L) { RegionPagerLua* pager = reinterpret_cast(lua_touserdata(L, 1)); @@ -64,20 +63,6 @@ static int getRegion(lua_State* L) { return 1; } -static int setDirectory(lua_State* L) { - RegionPagerLua* pager = reinterpret_cast(lua_touserdata(L, 1)); - std::string s = pager->SetDirectory(lua_tostring(L, 2)); - lua_pushstring(L, s.c_str()); - return 1; -} - -static int getDirectory(lua_State* L) { - RegionPagerLua* pager = reinterpret_cast(lua_touserdata(L, 1)); - std::string s = pager->GetDirectory(); - lua_pushstring(L, s.c_str()); - return 1; -} - static int loadRegion(lua_State* L) { RegionPagerLua* pager = reinterpret_cast(lua_touserdata(L, 1)); Region* region = pager->LoadRegion(lua_tointeger(L, 2), lua_tointeger(L, 3)); @@ -105,14 +90,12 @@ static int unloadRegion(lua_State* L) { return 0; } -static const luaL_Reg pagerlib[] = { +static const luaL_Reg regionPagerLib[] = { {"SetTile", setTile}, {"GetTile", getTile}, {"SetSolid", setSolid}, {"GetSolid", getSolid}, {"GetRegion", getRegion}, - {"SetDirectory", setDirectory}, - {"GetDirectory", getDirectory}, {"LoadRegion", loadRegion}, {"SaveRegion", saveRegion}, {"CreateRegion", createRegion}, @@ -121,6 +104,6 @@ static const luaL_Reg pagerlib[] = { }; LUAMOD_API int openRegionPagerAPI(lua_State* L) { - luaL_newlib(L, pagerlib); + luaL_newlib(L, regionPagerLib); return 1; } \ No newline at end of file diff --git a/common/map/region_pager_api.hpp b/common/map/region_pager_api.hpp index 466af61..3636c5a 100644 --- a/common/map/region_pager_api.hpp +++ b/common/map/region_pager_api.hpp @@ -19,8 +19,8 @@ * 3. This notice may not be removed or altered from any source * distribution. */ -#ifndef PAGERAPI_HPP_ -#define PAGERAPI_HPP_ +#ifndef REGIONPAGERAPI_HPP_ +#define REGIONPAGERAPI_HPP_ #include "lua/lua.hpp" diff --git a/common/map/region_pager_base.cpp b/common/map/region_pager_base.cpp index fbe633d..8c31df1 100644 --- a/common/map/region_pager_base.cpp +++ b/common/map/region_pager_base.cpp @@ -47,6 +47,9 @@ bool RegionPagerBase::GetSolid(int x, int y) { } Region* RegionPagerBase::GetRegion(int x, int y) { + x = snapToBase(REGION_WIDTH, x); + y = snapToBase(REGION_HEIGHT, y); + //get the region by various means Region* ptr = nullptr; ptr = FindRegion(x, y); diff --git a/common/map/region_pager_lua.cpp b/common/map/region_pager_lua.cpp index 85ea167..368f950 100644 --- a/common/map/region_pager_lua.cpp +++ b/common/map/region_pager_lua.cpp @@ -32,19 +32,18 @@ Region* RegionPagerLua::LoadRegion(int x, int y) { Region tmpRegion(x, y); //API hook - lua_getglobal(luaState, "Region"); - lua_getfield(luaState, -1, "OnLoad"); - lua_pushlightuserdata(luaState, &tmpRegion); - lua_pushstring(luaState, directory.c_str()); - if (lua_pcall(luaState, 2, 1, 0) != LUA_OK) { - throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) )); + lua_getglobal(lua, "Region"); + lua_getfield(lua, -1, "Load"); + lua_pushlightuserdata(lua, &tmpRegion); + if (lua_pcall(lua, 1, 1, 0) != LUA_OK) { + throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) )); } //success or failure - if (!lua_toboolean(luaState, -1)) { - lua_pop(luaState, 2); + if (!lua_toboolean(lua, -1)) { + lua_pop(lua, 2); return nullptr; } - lua_pop(luaState, 2); + lua_pop(lua, 2); regionList.push_front(tmpRegion); return ®ionList.front(); } @@ -54,14 +53,13 @@ Region* RegionPagerLua::SaveRegion(int x, int y) { Region* ptr = FindRegion(x, y); if (ptr) { //API hook - lua_getglobal(luaState, "Region"); - lua_getfield(luaState, -1, "OnSave"); - lua_pushlightuserdata(luaState, ptr); - lua_pushstring(luaState, directory.c_str()); - if (lua_pcall(luaState, 2, 0, 0) != LUA_OK) { - throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) )); + lua_getglobal(lua, "Region"); + lua_getfield(lua, -1, "Save"); + lua_pushlightuserdata(lua, ptr); + if (lua_pcall(lua, 1, 0, 0) != LUA_OK) { + throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) )); } - lua_pop(luaState, 1); + lua_pop(lua, 1); } return ptr; } @@ -75,30 +73,29 @@ Region* RegionPagerLua::CreateRegion(int x, int y) { Region tmpRegion(x, y); //API hook - lua_getglobal(luaState, "Region"); - lua_getfield(luaState, -1, "OnCreate"); - lua_pushlightuserdata(luaState, &tmpRegion); + lua_getglobal(lua, "Region"); + lua_getfield(lua, -1, "Create"); + lua_pushlightuserdata(lua, &tmpRegion); //TODO: parameters - if (lua_pcall(luaState, 1, 0, 0) != LUA_OK) { - throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) )); + if (lua_pcall(lua, 1, 0, 0) != LUA_OK) { + throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) )); } - lua_pop(luaState, 1); + lua_pop(lua, 1); regionList.push_front(tmpRegion); return ®ionList.front(); } void RegionPagerLua::UnloadRegion(int x, int y) { - lua_getglobal(luaState, "Region"); + lua_getglobal(lua, "Region"); regionList.remove_if([&](Region& region) -> bool { if (region.GetX() == x && region.GetY() == y) { //API hook - lua_getfield(luaState, -1, "OnUnload"); - lua_pushlightuserdata(luaState, ®ion); - lua_pushstring(luaState, directory.c_str()); - if (lua_pcall(luaState, 2, 0, 0) != LUA_OK) { - throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) )); + lua_getfield(lua, -1, "Unload"); + lua_pushlightuserdata(lua, ®ion); + if (lua_pcall(lua, 1, 0, 0) != LUA_OK) { + throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) )); } return true; @@ -106,22 +103,21 @@ void RegionPagerLua::UnloadRegion(int x, int y) { return false; }); - lua_pop(luaState, 1); + lua_pop(lua, 1); } void RegionPagerLua::UnloadAll() { - lua_getglobal(luaState, "Region"); + lua_getglobal(lua, "Region"); for (auto& it : regionList) { //API hook - lua_getfield(luaState, -1, "OnUnload"); - lua_pushlightuserdata(luaState, &it); - lua_pushstring(luaState, directory.c_str()); - if (lua_pcall(luaState, 2, 0, 0) != LUA_OK) { - throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(luaState, -1) )); + lua_getfield(lua, -1, "Unload"); + lua_pushlightuserdata(lua, &it); + if (lua_pcall(lua, 1, 0, 0) != LUA_OK) { + throw(std::runtime_error(std::string() + "Lua error: " + lua_tostring(lua, -1) )); } } - lua_pop(luaState, 1); + lua_pop(lua, 1); regionList.clear(); } \ No newline at end of file diff --git a/common/map/region_pager_lua.hpp b/common/map/region_pager_lua.hpp index 9468a18..8543e2d 100644 --- a/common/map/region_pager_lua.hpp +++ b/common/map/region_pager_lua.hpp @@ -42,14 +42,10 @@ public: void UnloadAll() override; //accessors & mutators - std::string SetDirectory(std::string s) { return directory = s; } - std::string GetDirectory() { return directory; } - - lua_State* SetLuaState(lua_State* L) { return luaState = L; } - lua_State* GetLuaState() { return luaState; } + lua_State* SetLuaState(lua_State* L) { return lua = L; } + lua_State* GetLuaState() { return lua; } protected: - std::string directory; - lua_State* luaState = nullptr; + lua_State* lua = nullptr; }; #endif diff --git a/common/graphics/tile_sheet.cpp b/common/map/tile_sheet.cpp similarity index 73% rename from common/graphics/tile_sheet.cpp rename to common/map/tile_sheet.cpp index bb9a4cb..819d709 100644 --- a/common/graphics/tile_sheet.cpp +++ b/common/map/tile_sheet.cpp @@ -21,24 +21,24 @@ */ #include "tile_sheet.hpp" -void TileSheet::Load(std::string fname, int xc, int yc) { - XCount = xc; - YCount = yc; +void TileSheet::Load(std::string fname, int tileWidth, int tileHeight) { image.LoadSurface(fname); - image.SetClipW(image.GetClipW()/XCount); - image.SetClipH(image.GetClipH()/YCount); + image.SetClipW(tileWidth); + image.SetClipH(tileHeight); + xCount = image.GetSurface()->w / image.GetClipW(); + yCount = image.GetSurface()->h / image.GetClipH(); } void TileSheet::Unload() { image.FreeSurface(); - XCount = YCount = 0; + xCount = yCount = 0; } -void TileSheet::DrawTo(SDL_Surface* const dest, int x, int y, Region::type_t tile) { +void TileSheet::DrawTileTo(SDL_Surface* const dest, int x, int y, Region::type_t tile) { //0 is invisible if (tile == 0) return; - image.SetClipX((tile-1) % XCount * image.GetClipW()); - image.SetClipY((tile-1) / XCount * image.GetClipH()); + image.SetClipX((tile-1) % xCount * image.GetClipW()); + image.SetClipY((tile-1) / xCount * image.GetClipH()); image.DrawTo(dest, x, y); } @@ -50,8 +50,8 @@ void TileSheet::DrawRegionTo(SDL_Surface* const dest, Region* const region, int tile = region->GetTile(i, j, k); //0 is invisible if (tile == 0) continue; - image.SetClipX((tile-1) % XCount * image.GetClipW()); - image.SetClipY((tile-1) / XCount * image.GetClipH()); + image.SetClipX((tile-1) % xCount * image.GetClipW()); + image.SetClipY((tile-1) / xCount * image.GetClipH()); image.DrawTo(dest, (region->GetX() + i) * image.GetClipW() - camX, (region->GetY() + j) * image.GetClipH() - camY); diff --git a/common/graphics/tile_sheet.hpp b/common/map/tile_sheet.hpp similarity index 82% rename from common/graphics/tile_sheet.hpp rename to common/map/tile_sheet.hpp index 368fcec..f9bf8ea 100644 --- a/common/graphics/tile_sheet.hpp +++ b/common/map/tile_sheet.hpp @@ -31,24 +31,24 @@ class TileSheet { public: TileSheet() = default; - TileSheet(std::string f, int x, int y) { Load(f, x, y); } + TileSheet(std::string f, int w, int h) { Load(f, w, h); } ~TileSheet() = default; - void Load(std::string fname, int XCount, int YCount); + void Load(std::string fname, int tileWidth, int tileHeight); void Unload(); - void DrawTo(SDL_Surface* const dest, int x, int y, Region::type_t tile); + void DrawTileTo(SDL_Surface* const dest, int x, int y, Region::type_t tile); void DrawRegionTo(SDL_Surface* const dest, Region* const region, int camX, int camY); //accessors Image* GetImage() { return ℑ } - int GetXCount() { return XCount; } - int GetYCount() { return YCount; } + int GetXCount() { return xCount; } + int GetYCount() { return yCount; } int GetTileW() { return image.GetClipW(); } int GetTileH() { return image.GetClipH(); } private: Image image; - int XCount = 0, YCount = 0; + int xCount = 0, yCount = 0; }; #endif diff --git a/common/map/tile_sheet_api.cpp b/common/map/tile_sheet_api.cpp new file mode 100644 index 0000000..5ee280f --- /dev/null +++ b/common/map/tile_sheet_api.cpp @@ -0,0 +1,75 @@ +/* Copyright: (c) Kayne Ruse 2014 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. +*/ +#include "tile_sheet_api.hpp" + +#include "tile_sheet.hpp" + +static int load(lua_State* L) { + TileSheet* sheet = reinterpret_cast(lua_touserdata(L, 1)); + sheet->Load(lua_tostring(L, 2), lua_tointeger(L, 3), lua_tointeger(L, 4)); + return 0; +} + +static int unload(lua_State* L) { + TileSheet* sheet = reinterpret_cast(lua_touserdata(L, 1)); + sheet->Unload(); + return 0; +} + +static int getXCount(lua_State* L) { + TileSheet* sheet = reinterpret_cast(lua_touserdata(L, 1)); + lua_pushinteger(L, sheet->GetXCount()); + return 1; +} + +static int getYCount(lua_State* L) { + TileSheet* sheet = reinterpret_cast(lua_touserdata(L, 1)); + lua_pushinteger(L, sheet->GetYCount()); + return 1; +} + +static int getTileW(lua_State* L) { + TileSheet* sheet = reinterpret_cast(lua_touserdata(L, 1)); + lua_pushinteger(L, sheet->GetTileW()); + return 1; +} + +static int getTileH(lua_State* L) { + TileSheet* sheet = reinterpret_cast(lua_touserdata(L, 1)); + lua_pushinteger(L, sheet->GetTileH()); + return 1; +} + +static const luaL_Reg tileSheetLib[] = { + {"Load",load}, + {"Unload",unload}, + {"GetXCount",getXCount}, + {"GetYCount",getYCount}, + {"GetTileW",getTileW}, + {"GetTileH",getTileH}, + {nullptr, nullptr} +}; + +LUAMOD_API int openTileSheetAPI(lua_State* L) { + luaL_newlib(L, tileSheetLib); + return 1; +} \ No newline at end of file diff --git a/common/utilities/simple_rng.hpp b/common/map/tile_sheet_api.hpp similarity index 70% rename from common/utilities/simple_rng.hpp rename to common/map/tile_sheet_api.hpp index 52ca91b..0788535 100644 --- a/common/utilities/simple_rng.hpp +++ b/common/map/tile_sheet_api.hpp @@ -19,24 +19,12 @@ * 3. This notice may not be removed or altered from any source * distribution. */ -#ifndef SIMPLERNG_HPP_ -#define SIMPLERNG_HPP_ +#ifndef TILESHEETAPI_HPP_ +#define TILESHEETAPI_HPP_ -//a simple, stateless, random number generator -class SimpleRNG { -public: - SimpleRNG() { SetSeed(8891.0); } - SimpleRNG(double x) { SetSeed(x); } +#include "lua/lua.hpp" - double SetSeed(double s) { return seed = s; } - double GetSeed() { return seed; } +#define TORTUGA_TILE_SHEET_NAME "TileSheet" +LUAMOD_API int openTileSheetAPI(lua_State* L); - double operator()(double x) { - return (x + seed) * 11235.0 + 81321.0; - }; - -private: - double seed; -}; - -#endif \ No newline at end of file +#endif diff --git a/common/utilities/bounding_box.hpp b/common/utilities/bounding_box.hpp new file mode 100644 index 0000000..1d32887 --- /dev/null +++ b/common/utilities/bounding_box.hpp @@ -0,0 +1,77 @@ +/* Copyright: (c) Kayne Ruse 2013, 2014 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. +*/ +#ifndef BOUNDINGBOX_HPP_ +#define BOUNDINGBOX_HPP_ + +#include +#include + +class BoundingBox { +public: + //This is explicitly a POD + int x, y; + int w, h; + + BoundingBox() = default; + BoundingBox(int i, int j, int k, int l): x(i), y(j), w(k), h(l) {}; + ~BoundingBox() = default; + BoundingBox& operator=(BoundingBox const&) = default; + + int Size() { + return std::max(w*h,0); + } + + bool CheckOverlap(BoundingBox rhs) { + return !( + x >= rhs.x + rhs.w || + y >= rhs.y + rhs.h || + rhs.x >= x + w || + rhs.y >= y + h); + } + + BoundingBox CalcOverlap(BoundingBox rhs) { + if (!CheckOverlap(rhs)) { + return {0, 0, 0, 0}; + } + BoundingBox ret; + ret.x = std::max(x, rhs.x); + ret.y = std::max(y, rhs.y); + ret.w = std::min(x+w, rhs.x+rhs.w) - ret.x; + ret.h = std::min(y+h, rhs.y+rhs.h) - ret.y; + return ret; + } +}; + +//This is explicitly a POD +static_assert(std::is_pod::value, "BoundingBox is not a POD"); + +#include "vector2.hpp" + +//operators +inline BoundingBox operator+(BoundingBox b, Vector2 v) { + return {b.x + (int)v.x, b.y + (int)v.y, b.w, b.h}; +} +inline BoundingBox operator+(Vector2 v, BoundingBox b) { + return b + v; +} + +#endif diff --git a/common/utilities/config_utility.cpp b/common/utilities/config_utility.cpp index 02970b1..4b1f797 100644 --- a/common/utilities/config_utility.cpp +++ b/common/utilities/config_utility.cpp @@ -25,25 +25,26 @@ #include #include -using namespace std; - -void ConfigUtility::Load(string fname) { - ifstream is(fname); +void ConfigUtility::Load(std::string fname) { + //TODO: recursive rerouting? + std::ifstream is(fname); if (!is.is_open()) { - throw(runtime_error("Failed to open config file")); + throw(std::runtime_error("Failed to open config file")); } - string key, val; + std::string key, val; - for (;;) { //forever + while(true) { //forever //eat whitespace - while(isspace(is.peek())) + while(isspace(is.peek())) { is.ignore(); + } //end of file - if (is.eof()) + if (is.eof()) { break; + } //skip comment lines if (is.peek() == '#') { @@ -64,7 +65,7 @@ void ConfigUtility::Load(string fname) { while(key.size() && isspace(*(key.end()-1))) key.erase(key.end() - 1); while(val.size() && isspace(*(val.end()-1))) val.erase(val.end() - 1); - //allow empty/wiped values + //disallow empty/wiped values if (key.size() == 0) { continue; } diff --git a/common/utilities/config_utility.hpp b/common/utilities/config_utility.hpp index 6e944ef..3ea8448 100644 --- a/common/utilities/config_utility.hpp +++ b/common/utilities/config_utility.hpp @@ -39,15 +39,9 @@ public: bool Boolean(std::string); //shorthand - std::string& operator[](std::string s) { - return String(s); - } - int Int(std::string s) { - return Integer(s); - } - bool Bool(std::string s) { - return Boolean(s); - } + inline std::string& operator[](std::string s) { return String(s); } + inline int Int(std::string s) { return Integer(s); } + inline bool Bool(std::string s) { return Boolean(s); } //OO breaker std::map* GetMap() { diff --git a/common/utilities/utility.cpp b/common/utilities/utility.cpp index a8a7270..bbba99c 100644 --- a/common/utilities/utility.cpp +++ b/common/utilities/utility.cpp @@ -32,6 +32,10 @@ int snapToBase(int base, int x) { return x / base * base; } +double snapToBase(double base, double x) { + return floor(x / base) * base; +} + std::string truncatePath(std::string pathname) { return std::string( std::find_if( diff --git a/common/utilities/utility.hpp b/common/utilities/utility.hpp index 3589c01..3346136 100644 --- a/common/utilities/utility.hpp +++ b/common/utilities/utility.hpp @@ -25,6 +25,8 @@ #include int snapToBase(int base, int x); +double snapToBase(double base, double x); + std::string truncatePath(std::string pathname); //fixing known bugs in g++ diff --git a/common/utilities/vector2.hpp b/common/utilities/vector2.hpp index 2be3d34..57c716c 100644 --- a/common/utilities/vector2.hpp +++ b/common/utilities/vector2.hpp @@ -43,6 +43,8 @@ public: } void Normalize() { double l = Length(); + if (l == 0) + throw(std::domain_error("Divide by zero")); x /= l; y /= l; } diff --git a/rsc/scripts/setup_server.lua b/rsc/scripts/setup_server.lua index 582cacf..ce07f88 100644 --- a/rsc/scripts/setup_server.lua +++ b/rsc/scripts/setup_server.lua @@ -1,38 +1,39 @@ print("Lua script check") --uber lazy declarations -function square(x) return x*x end -function distance(x, y, i, j) return math.sqrt(square(x - i) + square(y - j)) end +function math.sqr(x) return x*x end +function math.dist(x, y, i, j) return math.sqrt(math.sqr(x - i) + math.sqr(y - j)) end --tile macros, mapped to the tilesheet local base = 14 local shift = 36 -plains = base + shift * 0 -grass = base + shift * 1 -dirt = base + shift * 2 -sand = base + shift * 3 -water = base + shift * 4 +tiles = { + plains = base + shift * 0, + grass = base + shift * 1, + dirt = base + shift * 2, + sand = base + shift * 3, + water = base + shift * 4 +} ---Overwrite the original OnCreate with my own version -Region.hcOnCreate = Region.OnCreate -Region.OnCreate = function(region) - local ret = Region.hcOnCreate(region) --best practices +--could set custom generation systems here, that differ from the global generators, etc. +function Region.Create(region) for i = 1, Region.GetWidth() do for j = 1, Region.GetHeight() do - local dist = distance(0, 0, i + Region.GetX(region) -1, j + Region.GetY(region) -1) + local dist = math.dist(0, 0, i + Region.GetX(region) -1, j + Region.GetY(region) -1) if dist < 10 then - Region.SetTile(region, i, j, 1, plains) + Region.SetTile(region, i, j, 1, tiles.plains) elseif dist < 12 then - Region.SetTile(region, i, j, 1, sand) + Region.SetTile(region, i, j, 1, tiles.sand) else - Region.SetTile(region, i, j, 1, water) + Region.SetTile(region, i, j, 1, tiles.water) + Region.SetSolid(region, i, j, true) end end end - return ret end --Get some regions +--BUG: The server fails without this newRoom = RoomMgr.CreateRoom("overworld") pager = Room.GetPager(newRoom) regionTable = { @@ -42,4 +43,4 @@ regionTable = { RegionPager.GetRegion(pager, Region.GetWidth() *-1, Region.GetHeight() *-1) } -print("Finished the lua script") \ No newline at end of file +print("Finished the lua script") diff --git a/server/linit.cpp b/server/linit.cpp index 1d79c96..072120f 100644 --- a/server/linit.cpp +++ b/server/linit.cpp @@ -38,6 +38,7 @@ #include "region_api.hpp" #include "region_pager_api.hpp" +#include "tile_sheet_api.hpp" #include "room_api.hpp" #include "room_mgr_api.hpp" @@ -58,6 +59,7 @@ static const luaL_Reg loadedlibs[] = { //Tortuga's API {TORTUGA_REGION_NAME, openRegionAPI}, {TORTUGA_REGION_PAGER_NAME, openRegionPagerAPI}, + {TORTUGA_TILE_SHEET_NAME, openTileSheetAPI}, {TORTUGA_ROOM_NAME, openRoomAPI}, {TORTUGA_ROOM_MGR_NAME, openRoomMgrAPI}, diff --git a/server/makefile b/server/makefile index 3d0de76..807cd13 100644 --- a/server/makefile +++ b/server/makefile @@ -1,5 +1,5 @@ #config -INCLUDES+=. accounts characters combat enemies mapgen mapgen/generators rooms ../common/gameplay ../common/map ../common/network ../common/network/packet ../common/network/serial ../common/utilities +INCLUDES+=. accounts characters combat enemies mapgen mapgen/generators rooms ../common/debugging ../common/gameplay ../common/map ../common/network ../common/network/packet ../common/network/serial ../common/utilities LIBS+=server.a ../libcommon.a -lSDL_net -lwsock32 -liphlpapi -lmingw32 -lSDLmain -lSDL -llua -lsqlite3 CXXFLAGS+=-std=c++11 $(addprefix -I,$(INCLUDES))