diff --git a/src/sago/SagoDataHolder.hpp b/src/sago/SagoDataHolder.hpp index 0abace8..9fbd9cd 100644 --- a/src/sago/SagoDataHolder.hpp +++ b/src/sago/SagoDataHolder.hpp @@ -117,7 +117,7 @@ public: * @return A globally unique number. */ Uint64 getVersion() const; - + ~SagoDataHolder(); private: SagoDataHolder(const SagoDataHolder& base) = delete; diff --git a/src/sago/SagoSpriteHolder.cpp b/src/sago/SagoSpriteHolder.cpp index 1e30d63..94c4c1c 100644 --- a/src/sago/SagoSpriteHolder.cpp +++ b/src/sago/SagoSpriteHolder.cpp @@ -131,6 +131,13 @@ void SagoSpriteHolder::ReadSprites() { } } +void SagoSpriteHolder::ReadSprites(const std::vector& extra_sprites) { + for (std::string item : extra_sprites) { + item+=".sprite"; + ReadSpriteFile(item); + } +} + const sago::SagoSprite& SagoSpriteHolder::GetSprite(const std::string& spritename) const { std::unordered_map>::const_iterator got = data->sprites.find (spritename); if ( got == data->sprites.end() ) { diff --git a/src/sago/SagoSpriteHolder.hpp b/src/sago/SagoSpriteHolder.hpp index 21b093e..be76b51 100644 --- a/src/sago/SagoSpriteHolder.hpp +++ b/src/sago/SagoSpriteHolder.hpp @@ -27,6 +27,7 @@ SOFTWARE. #include "SagoDataHolder.hpp" #include "SagoSprite.hpp" +#include namespace sago { @@ -34,7 +35,14 @@ class SagoSpriteHolder final { public: explicit SagoSpriteHolder(const SagoDataHolder &texHolder); ~SagoSpriteHolder(); + /** + * Reads all the sprites from the "sprites" directory in alphabetical order + **/ void ReadSprites(); + /** + * Reads an additional sprites. Used to append mod data. + **/ + void ReadSprites(const std::vector& extra_sprites); const sago::SagoSprite& GetSprite(const std::string &spritename) const; const SagoDataHolder& GetDataHolder() const; private: diff --git a/src/saland.cpp b/src/saland.cpp index 46644af..cfee652 100644 --- a/src/saland.cpp +++ b/src/saland.cpp @@ -265,6 +265,7 @@ void runGame() { int main(int argc, char* argv[]) { PHYSFS_init(argv[0]); + PHYSFS_addToSearchPath((std::string(PHYSFS_getBaseDir())+"/saland.data").c_str(), 1); PHYSFS_addToSearchPath((std::string(PHYSFS_getBaseDir())+"/data").c_str(), 1); std::string savepath = getPathToSaveFiles(); OsCreateSaveFolder(); diff --git a/src/saland/Game.cpp b/src/saland/Game.cpp index 1ca803a..5c0f169 100644 --- a/src/saland/Game.cpp +++ b/src/saland/Game.cpp @@ -337,7 +337,7 @@ void Game::Draw(SDL_Renderer* target) { int mousebox_y = data->world_mouse_y - data->world_mouse_y % 32 - data->topy; if (data->slot_spell.at(data->slot_selected).type == SpellCursorType::tile) { rectangleRGBA(globalData.screen, mousebox_x, mousebox_y, - mousebox_x + 32, mousebox_y + 32, 255, 255, 0, 255); + mousebox_x + 32, mousebox_y + 32, 255, 255, 0, 255); } } //Draw @@ -367,9 +367,9 @@ void Game::Draw(SDL_Renderer* target) { if (data->world_mouse_x >= 0 && data->world_mouse_y >= 0) { char buffer[200]; snprintf(buffer, sizeof(buffer), "world_x = %d, world_y = %d, layer_info:%s", - data->world_mouse_x/32, data->world_mouse_y/32, - GetLayerInfoForTile(data->gameRegion.world, data->world_mouse_x/32, data->world_mouse_y/32).c_str() - ); + data->world_mouse_x/32, data->world_mouse_y/32, + GetLayerInfoForTile(data->gameRegion.world, data->world_mouse_x/32, data->world_mouse_y/32).c_str() + ); data->bottomField.SetText(buffer); } else { @@ -561,6 +561,11 @@ void Game::Update() { MiscItem* item = dynamic_cast (entity.get()); if (item) { if (item->destructible && item->health <= 0.0f && !item->removeMe) { + if (item->body) { + /*data->gameRegion.physicsBox->DestroyBody(item->body); + item->body = nullptr;*/ + destroyBodyWithFixtures(data->gameRegion.physicsBox.get(), item->body); + } item->removeMe = true; } } @@ -662,7 +667,7 @@ void Game::Update() { int tile_y = data->world_mouse_y/32; int tile = data->slot_spell.at(data->slot_selected).tile; if (sago::tiled::tileInBound(data->gameRegion.world.tm, tile_x, tile_y) - && !(data->gameRegion.world.tile_protected(tile_x, tile_y)) ) { + && !(data->gameRegion.world.tile_protected(tile_x, tile_y)) ) { int layer_number = 2; // Do not hardcode sago::tiled::setTileOnLayerNumber(data->gameRegion.world.tm, layer_number, tile_x, tile_y, tile); data->gameRegion.waterHandler.updateFirstTile(data->gameRegion.world.tm, tile_x, tile_y); @@ -677,7 +682,7 @@ void Game::Update() { int tile_x = data->world_mouse_x/32; int tile_y = data->world_mouse_y/32; if (sago::tiled::tileInBound(data->gameRegion.world.tm, tile_x, tile_y) - && !(data->gameRegion.world.tile_protected(tile_x, tile_y)) ) { + && !(data->gameRegion.world.tile_protected(tile_x, tile_y)) ) { int layer_number = 2; // Do not hardcode uint32_t tile = 0; sago::tiled::setTileOnLayerNumber(data->gameRegion.world.tm, layer_number, tile_x, tile_y, tile); diff --git a/src/saland/GameConsoleCommand.cpp b/src/saland/GameConsoleCommand.cpp index d9de7d4..8f12822 100644 --- a/src/saland/GameConsoleCommand.cpp +++ b/src/saland/GameConsoleCommand.cpp @@ -71,7 +71,7 @@ struct ConsoleCommandQuit : public ConsoleCommand { } virtual std::string run(const std::vector&) override { globalData.isShuttingDown = true; - return "Exiting..."; + return "Exiting..."; } virtual std::string helpMessage() const override { diff --git a/src/saland/GameItems.cpp b/src/saland/GameItems.cpp index c60de9e..cf031d5 100644 --- a/src/saland/GameItems.cpp +++ b/src/saland/GameItems.cpp @@ -26,26 +26,26 @@ https://github.com/sago007/saland static ItemDef itemDef; const ItemDef& getItem(const std::string& itemName) { - itemDef.sprite2 = ""; - itemDef.isDestructible = true; - itemDef.health = 100.0f; - itemDef.itemid = itemName; - if (itemName == "barrel") { - itemDef.radius = 16.0f; - itemDef.sprite = "item_barrel"; - itemDef.isStatic = true; - } - if (itemName == "food_potato") { - itemDef.isDestructible = false; - itemDef.radius = 9.0f; - itemDef.sprite = "item_food_potato"; - itemDef.isStatic = false; - } - if (itemName == "tree_pine") { - itemDef.radius = 20.0f; - itemDef.sprite = "tree_pine_trunk"; - itemDef.sprite2 = "tree_pine_top"; - itemDef.isStatic = true; - } - return itemDef; + itemDef.sprite2 = ""; + itemDef.isDestructible = true; + itemDef.health = 100.0f; + itemDef.itemid = itemName; + if (itemName == "barrel") { + itemDef.radius = 16.0f; + itemDef.sprite = "item_barrel"; + itemDef.isStatic = true; + } + if (itemName == "food_potato") { + itemDef.isDestructible = false; + itemDef.radius = 9.0f; + itemDef.sprite = "item_food_potato"; + itemDef.isStatic = false; + } + if (itemName == "tree_pine") { + itemDef.radius = 20.0f; + itemDef.sprite = "tree_pine_trunk"; + itemDef.sprite2 = "tree_pine_top"; + itemDef.isStatic = true; + } + return itemDef; } \ No newline at end of file diff --git a/src/saland/GameItems.hpp b/src/saland/GameItems.hpp index 03ef9be..0e87c1d 100644 --- a/src/saland/GameItems.hpp +++ b/src/saland/GameItems.hpp @@ -30,7 +30,7 @@ struct ItemDef { float radius = 1.0f; std::string itemid = ""; std::string sprite = ""; - std::string sprite2 = ""; + std::string sprite2 = ""; bool isStatic = true; bool isDestructible = true; float health = 10.0f; diff --git a/src/saland/GameRegion.cpp b/src/saland/GameRegion.cpp index 6ed7676..87782bb 100644 --- a/src/saland/GameRegion.cpp +++ b/src/saland/GameRegion.cpp @@ -91,7 +91,7 @@ void GameRegion::SpawnItem(const ItemDef& def, float destX, float destY) { } } } - + for (std::shared_ptr& target : placeables) { if (target->removeMe) { continue; @@ -161,7 +161,7 @@ void GameRegion::Init(int x, int y, const std::string& worldName, bool forceRese lavaHandler.blockingLayer = world.blockingLayer; lavaHandler.blockingLayer_overlay_1 = world.blockingLayer_overlay_1; lavaHandler.setupTiles(16); - + const std::vector& object_groups = world.tm.object_groups; @@ -199,7 +199,7 @@ void GameRegion::Init(int x, int y, const std::string& worldName, bool forceRese std::string regionType = GetRegionType(region_x, region_y); if (regionType == "forrest" || regionType == "start") { std::cout << "Forrest (or start) region\n"; - + for (int i=0; i<10; ++i) { int x = (rand()%(world.tm.width-3)+1)*32+rand()%32; int y = (rand()%(world.tm.height-3)+1)*32+rand()%32; @@ -219,8 +219,7 @@ void GameRegion::Init(int x, int y, const std::string& worldName, bool forceRese void GameRegion::SaveRegion() { sago::tiled::TileObjectGroup tog; tog.name = "mutableObjects"; - for (const std::shared_ptr& p : placeables) - { + for (const std::shared_ptr& p : placeables) { if (p->isStatic()) { const MiscItem* m = dynamic_cast(p.get()); if (m) { diff --git a/src/saland/model/World.cpp b/src/saland/model/World.cpp index 0c64397..a3b5734 100644 --- a/src/saland/model/World.cpp +++ b/src/saland/model/World.cpp @@ -95,20 +95,31 @@ void fill_blocking_tiles(std::vector& output, const sago::tiled::TileMap& if (gid == 0) { continue; } - output[i+j*tm.width] = true; + output[i+j*tm.width] = true; } } } +void destroyBodyWithFixtures(b2World* world, b2Body*& bodyToDestroy) { + b2Fixture* f = bodyToDestroy->GetFixtureList(); + while (f) { + b2Fixture* next_f = f->GetNext(); + bodyToDestroy->DestroyFixture(f); + f = next_f; + } + world->DestroyBody(bodyToDestroy); +} + void World::init_physics(std::shared_ptr& world) { for (b2Body* b : managed_bodies) { - b2Fixture* f = b->GetFixtureList(); + destroyBodyWithFixtures(world.get(), b); + /*b2Fixture* f = b->GetFixtureList(); while (f) { b2Fixture* next_f = f->GetNext(); b->DestroyFixture(f); f = next_f; } - world->DestroyBody(b); + world->DestroyBody(b);*/ } managed_bodies.clear(); const std::vector& object_groups = tm.object_groups; @@ -172,7 +183,7 @@ void World::init(std::shared_ptr& world, const std::string& mapFileName tm.tileset[i].alternativeSource = &ts.back(); } } - for (size_t i=0;i < tm.layers.size(); ++i) { + for (size_t i=0; i < tm.layers.size(); ++i) { if (tm.layers[i].name == "blocking") { blockingLayer = i; } diff --git a/src/saland/model/World.hpp b/src/saland/model/World.hpp index 263a09a..97e5d33 100644 --- a/src/saland/model/World.hpp +++ b/src/saland/model/World.hpp @@ -48,5 +48,14 @@ public: int blockingLayer_overlay_1 = -1; }; +/** + * Helper function to destroy a body including the attached fixtures + * The body must be given as a reference to a pointer. The pointer will be nulled. + * + * @param world The bod2d physics world that the body is attached to. + * @param bodyToDestroy Reference to a pointer to the body + */ +void destroyBodyWithFixtures(b2World* world, b2Body*& bodyToDestroy); + #endif /* WORLD_HPP */ diff --git a/src/terrain/WaterHandler.cpp b/src/terrain/WaterHandler.cpp index b64e04f..e3b69e9 100644 --- a/src/terrain/WaterHandler.cpp +++ b/src/terrain/WaterHandler.cpp @@ -49,9 +49,10 @@ void WaterHandler::setupTiles(uint32_t start_tile) { tile_map["11010000"] = start_tile+tile_count_width*4+2; tiles = {start_tile, start_tile+1, start_tile+2, start_tile+33, start_tile+34, - start_tile+35, start_tile+64, start_tile+65, start_tile+66, start_tile+96, - start_tile+97, start_tile+98, start_tile+128, start_tile+129, start_tile+130, - start_tile+160, start_tile+161, start_tile+162}; + start_tile+35, start_tile+64, start_tile+65, start_tile+66, start_tile+96, + start_tile+97, start_tile+98, start_tile+128, start_tile+129, start_tile+130, + start_tile+160, start_tile+161, start_tile+162 + }; } uint32_t WaterHandler::getTile(sago::tiled::TileMap& tm, int x, int y, uint32_t& overlay_tile) { @@ -159,7 +160,7 @@ bool WaterHandler::isWater(const sago::tiled::TileMap& tm, int x, int y) const { std::string WaterHandler::stringForTileSurrounding(const sago::tiled::TileMap& tm, int x, int y) const { std::string ret = std::to_string(isWater(tm, x-1, y-1)) + std::to_string(isWater(tm, x, y-1)) + std::to_string(isWater(tm, x+1, y-1)) - + std::to_string(isWater(tm, x-1, y)) + std::to_string(isWater(tm, x+1, y)) - + std::to_string(isWater(tm, x-1, y+1)) + std::to_string(isWater(tm, x, y+1)) + std::to_string(isWater(tm, x+1, y+1)); - return ret; + + std::to_string(isWater(tm, x-1, y)) + std::to_string(isWater(tm, x+1, y)) + + std::to_string(isWater(tm, x-1, y+1)) + std::to_string(isWater(tm, x, y+1)) + std::to_string(isWater(tm, x+1, y+1)); + return ret; }