refactor(mummy): generalitza el filtre de cruces a isBlockedAheadInDir
This commit is contained in:
1 parent
11a909b58d
commit
9ac0c0cb74
2 files changed
+30
-21
No files matched your search
@@ -261,7 +261,7 @@ void Mummy::step(float delta_time) {
|
||||
// TODO(refactor): mateixa cascada a `decideAtIntersection` amb la
|
||||
// variant "afegir recta a Nivell 1". Factoritzable
|
||||
// quan tinga sentit (3+ callsites).
|
||||
auto pools = collectDirectionPools(speed_ * delta_time, /*avoid_decals=*/true);
|
||||
auto pools = collectDirectionPools(speed_ * delta_time, /*avoid_blocked=*/true);
|
||||
const std::vector<Direction>* chosen = nullptr;
|
||||
if (!pools.perp.empty()) {
|
||||
chosen = &pools.perp;
|
||||
@@ -270,7 +270,7 @@ void Mummy::step(float delta_time) {
|
||||
}
|
||||
DirectionPools pools_unfiltered;
|
||||
if (chosen == nullptr) {
|
||||
pools_unfiltered = collectDirectionPools(speed_ * delta_time, /*avoid_decals=*/false);
|
||||
pools_unfiltered = collectDirectionPools(speed_ * delta_time, /*avoid_blocked=*/false);
|
||||
if (!pools_unfiltered.perp.empty()) {
|
||||
chosen = &pools_unfiltered.perp;
|
||||
} else if (!pools_unfiltered.uturn.empty()) {
|
||||
@@ -350,13 +350,13 @@ void Mummy::decideAtIntersection(float step_px) {
|
||||
// permetia mai en creuaments, però és preferible recular que caure al
|
||||
// forat quan totes les altres surten a decal.
|
||||
// TODO(refactor): cascada paral·lela a la branca de bloqueig de `step`.
|
||||
auto pools = collectDirectionPools(step_px, /*avoid_decals=*/true);
|
||||
auto pools = collectDirectionPools(step_px, /*avoid_blocked=*/true);
|
||||
|
||||
// Nivell 1: perpendiculars (filtrades) + recta si lliure i sense decal.
|
||||
std::vector<Direction> level1 = std::move(pools.perp);
|
||||
const auto STRAIGHT_BOX = candidateBox(dir_x_ * step_px, dir_y_ * step_px);
|
||||
const bool STRAIGHT_OPEN = Map::insidePlayfield(STRAIGHT_BOX) && !Map::collides(STRAIGHT_BOX);
|
||||
if (STRAIGHT_OPEN && !isDecalAheadInDir(dir_x_, dir_y_)) {
|
||||
if (STRAIGHT_OPEN && !isBlockedAheadInDir(dir_x_, dir_y_)) {
|
||||
level1.push_back(currentDirection());
|
||||
}
|
||||
|
||||
@@ -376,7 +376,7 @@ void Mummy::decideAtIntersection(float step_px) {
|
||||
DirectionPools pools_unfiltered;
|
||||
std::vector<Direction> level3;
|
||||
if (chosen == nullptr) {
|
||||
pools_unfiltered = collectDirectionPools(step_px, /*avoid_decals=*/false);
|
||||
pools_unfiltered = collectDirectionPools(step_px, /*avoid_blocked=*/false);
|
||||
level3 = std::move(pools_unfiltered.perp);
|
||||
if (STRAIGHT_OPEN) { level3.push_back(currentDirection()); }
|
||||
if (!level3.empty()) {
|
||||
@@ -390,7 +390,7 @@ void Mummy::decideAtIntersection(float step_px) {
|
||||
applyChoice(chooseDirection(*chosen));
|
||||
}
|
||||
|
||||
auto Mummy::collectDirectionPools(float step, bool avoid_decals) const -> DirectionPools {
|
||||
auto Mummy::collectDirectionPools(float step, bool avoid_blocked) const -> DirectionPools {
|
||||
struct Candidate {
|
||||
float dx;
|
||||
float dy;
|
||||
@@ -412,9 +412,9 @@ auto Mummy::collectDirectionPools(float step, bool avoid_decals) const -> Direct
|
||||
if (!Map::insidePlayfield(TEST) || Map::collides(TEST)) { continue; }
|
||||
// Filtre de decals (Hole i futurs decals trigger): comprova el
|
||||
// tile cardinal contigu; si conté un trigger, descartem la
|
||||
// direcció. El caller pot demanar `avoid_decals=false` com a
|
||||
// direcció. El caller pot demanar `avoid_blocked=false` com a
|
||||
// fallback quan totes les filtrades estan bloquejades.
|
||||
if (avoid_decals && isDecalAheadInDir(c.dx, c.dy)) { continue; }
|
||||
if (avoid_blocked && isBlockedAheadInDir(c.dx, c.dy)) { continue; }
|
||||
const bool IS_UTURN = (c.dx * dir_x_ < 0.0F) || (c.dy * dir_y_ < 0.0F);
|
||||
if (IS_UTURN) {
|
||||
pools.uturn.push_back(c.dir);
|
||||
@@ -425,10 +425,7 @@ auto Mummy::collectDirectionPools(float step, bool avoid_decals) const -> Direct
|
||||
return pools;
|
||||
}
|
||||
|
||||
auto Mummy::isDecalAheadInDir(float dx_signed, float dy_signed) const -> bool {
|
||||
// Sense manager injectat (smoke tests sense `EntityManager::add`), el
|
||||
// filtre és no-op: la mòmia es comporta exactament com abans del feature.
|
||||
if (entity_manager_ == nullptr) { return false; }
|
||||
auto Mummy::isBlockedAheadInDir(float dx_signed, float dy_signed) const -> bool {
|
||||
if (dx_signed == 0.0F && dy_signed == 0.0F) { return false; }
|
||||
// El rect a consultar és el AABB del tile cardinal contigu (mida
|
||||
// `Map::tile_size`), ancorat al tile actual de la mòmia. Calculem el
|
||||
@@ -457,7 +454,13 @@ auto Mummy::isDecalAheadInDir(float dx_signed, float dy_signed) const -> bool {
|
||||
.w = TS,
|
||||
.h = TS,
|
||||
};
|
||||
return entity_manager_->findFloorTriggerAt(NEXT) != nullptr;
|
||||
// Ordre per cost creixent: comparació de coordenades, després iteració
|
||||
// sobre sarcs i porta, i finalment cerca a l'index d'entitats. Sense
|
||||
// manager (smoke tests) saltem només l'últim filtre.
|
||||
if (!Map::insidePlayfield(NEXT)) { return true; }
|
||||
if (Map::collides(NEXT)) { return true; }
|
||||
if (entity_manager_ != nullptr && entity_manager_->findFloorTriggerAt(NEXT) != nullptr) { return true; }
|
||||
return false;
|
||||
}
|
||||
|
||||
void Mummy::applyChoice(Direction dir) {
|
||||
|
||||
Reference in new issue
Block a user