v1.4.4
This commit is contained in:
commit
9c94d113d3
10260 changed files with 1237388 additions and 0 deletions
80
source/game/StarMicroDungeon.cpp
Normal file
80
source/game/StarMicroDungeon.cpp
Normal file
|
@ -0,0 +1,80 @@
|
|||
#include "StarMicroDungeon.hpp"
|
||||
#include "StarRoot.hpp"
|
||||
#include "StarInterpolation.hpp"
|
||||
#include "StarLogging.hpp"
|
||||
#include "StarDungeonGenerator.hpp"
|
||||
|
||||
namespace Star {
|
||||
|
||||
// Placed on server so it can keep a cacheing system which allows for a quick
|
||||
// scan if a piece fits.
|
||||
|
||||
MicroDungeonFactory::MicroDungeonFactory() {
|
||||
m_generating = false;
|
||||
|
||||
m_placementshifts.push_back(0);
|
||||
for (int i = 1; i < 4; ++i)
|
||||
m_placementshifts.push_back(i);
|
||||
for (int i = 1; i < 4; ++i)
|
||||
m_placementshifts.push_back(-i);
|
||||
}
|
||||
|
||||
Maybe<pair<List<RectI>, Set<Vec2I>>> MicroDungeonFactory::generate(RectI const& bounds,
|
||||
String const& dungeonName,
|
||||
Vec2I const& position,
|
||||
uint64_t seed,
|
||||
float threatLevel,
|
||||
DungeonGeneratorWorldFacadePtr facade,
|
||||
bool forcePlacement) {
|
||||
Dungeon::DungeonGeneratorWriter writer(facade, {}, {});
|
||||
|
||||
if (m_generating)
|
||||
throw DungeonException("Not reentrant.");
|
||||
|
||||
m_generating = true;
|
||||
auto generatingGuard = finally([this]() { m_generating = false; });
|
||||
|
||||
DungeonGenerator dungeonGenerator(dungeonName, seed, threatLevel, BiomeMicroDungeonId);
|
||||
|
||||
try {
|
||||
// don't bother scanning around because its used in a bruteforce manner for now.
|
||||
// try to stay a bit stable generation wise, maybe trash the cache after a sector is done ?
|
||||
|
||||
auto anchorPart = dungeonGenerator.pickAnchor();
|
||||
if (!anchorPart) {
|
||||
Logger::debug("No valid anchor piece found for microdungeon at %s, skipping", position);
|
||||
return {};
|
||||
}
|
||||
|
||||
if (forcePlacement) {
|
||||
return dungeonGenerator.buildDungeon(anchorPart, position - anchorPart->anchorPoint(), &writer, forcePlacement);
|
||||
} else {
|
||||
for (int dy : m_placementshifts) {
|
||||
auto pos = position - anchorPart->anchorPoint() + Vec2I{0, dy};
|
||||
if (!bounds.contains(pos) || !bounds.contains(pos + Vec2I{anchorPart->size()} - Vec2I{1, 1}))
|
||||
continue;
|
||||
|
||||
bool collision = false;
|
||||
anchorPart->forEachTile([&](Vec2I tilePos, Dungeon::Tile const& tile) -> bool {
|
||||
if (tile.usesPlaces()) {
|
||||
if (facade->getDungeonIdAt(pos + tilePos) != NoDungeonId) {
|
||||
collision = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
if (!collision && anchorPart->canPlace(pos, &writer)) {
|
||||
return dungeonGenerator.buildDungeon(anchorPart, pos, &writer, forcePlacement);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (std::exception const& e) {
|
||||
throw DungeonException(strf("Error generating microdungeon named '%s'", dungeonGenerator.definition()->name()), e);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue