commit dba5dfb6
Backport from Block Attack and some physics fixes
Changed files
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<std::string>& 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<std::string,std::shared_ptr<sago::SagoSprite>>::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 <vector>
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<std::string>& 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<MiscItem*> (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<std::string>&) 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<Placeable>& 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<sago::tiled::TileObjectGroup>& 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<Placeable>& p : placeables)
- {
+ for (const std::shared_ptr<Placeable>& p : placeables) {
if (p->isStatic()) {
const MiscItem* m = dynamic_cast<MiscItem*>(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<bool>& 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<b2World>& 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<sago::tiled::TileObjectGroup>& object_groups = tm.object_groups;
@@ -172,7 +183,7 @@ void World::init(std::shared_ptr<b2World>& 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;
}