diff --git a/level.cpp b/level.cpp index 943757352..87c970ebf 100644 --- a/level.cpp +++ b/level.cpp @@ -48,6 +48,7 @@ #include "player_control.h" #include "portals.h" #include "effect_type.h" +#include "content_factory.h" template void Level::serialize(Archive& ar, const unsigned int version) { @@ -81,25 +82,28 @@ void Level::serialize(Archive& ar, const unsigned int version) { } } +static Effects::Chance* getChanceTick(FurnitureTickType& t) { + return t.visit( + [&](auto&) { return nullptr;}, + [&](Effect& effect) { + return effect.effect->visit( + [&](Effects::Chance& c) { + return &c; + }, + [&](auto&) { return nullptr;} + ); + } + ); +} + void Level::updateTickingFurniture() { for (auto v : squares->getBounds()) for (auto layer : ENUM_ALL(FurnitureLayer)) if (auto f = furniture->getBuilt(layer).getReadonly(v)) { if (auto t = f->getTickType()) { - double chance = 1.0; - t->visit( - [&](const auto&) {}, - [&](const Effect& effect) { - effect.effect->visit( - [&](const Effects::Chance& c) { - chance = c.value; - furniture->getBuilt(layer).getWritable(v)->tickType = FurnitureTickType(std::move(*c.effect)); - }, - [&](const auto&) {} - ); - } - ); - tickingFurniture.insert(make_tuple(v, layer, chance)); + if (auto chance = getChanceTick(*t)) + furniture->getBuilt(layer).getWritable(v)->tickType = FurnitureTickType(std::move(*chance->effect)); + tickingFurniture.insert(make_pair(make_pair(v, layer), -1)); } if ((f->getFire() && f->getFire()->isBurning()) || f->hasBlood()) burningFurniture.insert(make_pair(v, layer)); @@ -565,7 +569,7 @@ void Level::addTickingSquare(Vec2 pos) { } void Level::addTickingFurniture(Vec2 pos, FurnitureLayer layer) { - tickingFurniture.insert(make_tuple(pos, layer, 1.0)); + tickingFurniture[make_pair(pos, layer)] = 1.0; } void Level::addBurningFurniture(Vec2 pos, FurnitureLayer layer) { @@ -576,31 +580,18 @@ void Level::tick() { PROFILE_BLOCK("Level::tick"); for (Vec2 pos : tickingSquares) squares->getWritable(pos)->tick(Position(pos, this)); + auto& furnitureFactory = getGame()->getContentFactory()->furniture; for (auto& elem : tickingFurniture) - if (auto f = furniture->getBuilt(std::get<1>(elem)).getWritable(std::get<0>(elem))) { - auto chance = std::get<2>(elem); - if (f->getType() == FurnitureType("UNDERGROUND_WATER")) - chance = 0.002; - if (f->getType() == FurnitureType("ENCHANTED_WATER")) - chance = 0.00002; - if (f->getType() == FurnitureType("MAGMA")) - chance = 0.1; - if (f->getType() == FurnitureType("SWAMPGRASS")) - chance = 0.006; - if (f->getType() == FurnitureType("GHOST_SPAWN")) - chance = 0.002; - if (f->getType() == FurnitureType("CANIF_TREE")) - chance = 0.002; - if (f->getType() == FurnitureType("CHICKEN_COOP")) - chance = 0.05; - if (f->getType() == FurnitureType("PIGSTY")) - chance = 0.05; - if (f->getType() == FurnitureType("COW_PEN")) - chance = 0.05; - if (f->getType() == FurnitureType("HELL_MOUNTAIN")) - chance = 0.0005; + if (auto f = furniture->getBuilt(elem.first.second).getWritable(elem.first.first)) { + auto& chance = elem.second; + if (chance <= 0) + if (auto tickType = furnitureFactory.getData(f->getType()).tickType) + if (auto chanceTick = getChanceTick(*tickType)) + chance = chanceTick->value; + if (chance <= 0) + chance = 1; if (Random.chance(chance)) - f->tick(Position(std::get<0>(elem), this), std::get<1>(elem)); + f->tick(Position(elem.first.first, this), elem.first.second); } for (auto& elem : burningFurniture) if (auto f = furniture->getBuilt(std::get<1>(elem)).getWritable(std::get<0>(elem))) diff --git a/level.h b/level.h index b8b968901..f91304594 100644 --- a/level.h +++ b/level.h @@ -185,7 +185,7 @@ class Level : public OwnedObject { Table SERIAL(unavailable); LandingSquares SERIAL(landingSquares); set SERIAL(tickingSquares); - set> tickingFurniture; + HashMap, double> tickingFurniture; HashSet> burningFurniture; void placeCreature(Creature*, Vec2 pos); void unplaceCreature(Creature*, Vec2 pos);