void DSF(TMap const & maze, MapKeyT const & cur, MapKeyT const & prev, Cell const & target, MapT & data, vector<vector<int>> const & bonuses) { bool IsOpposite = GetOppositeDirection(prev.second) == cur.second; double to_add = (IsOpposite ? 3 : 1); if (bonuses[cur.first.m_x][cur.first.m_y] == 1) to_add -= 0.5; bool need_update = data.count(cur) == 0; need_update |= data[cur].first > data[prev].first + to_add; if (need_update) { double prev_dist = data.count(prev) == 0 ? 0 : data[prev].first; data[cur] = {prev_dist + to_add, prev}; } if (cur.first == target) return; if (need_update) { if (CanPass(maze, cur.first, cur.second)) DSF(maze, {cur.first.GetNeibor(cur.second), cur.second}, cur, target, data, bonuses); for (auto const & dir: AllDirections()) if (CanPass(maze, cur.first, dir)) DSF(maze, {cur.first.GetNeibor(dir), dir}, cur, target, data, bonuses); } }
void Atmosphere::ProcessTileMove(size_t x, size_t y, size_t z) { auto tile = map_->GetSquares()[x][y][z]; if (tile->GetTurf()->GetAtmosState() == NON_SIMULATED) { return; } if (tile->GetTurf()->GetAtmosState() == SPACE) { return; } for (size_t d_sh = 0; d_sh < dir_shuffle_.size(); ++d_sh) { Dir dir = dir_shuffle_[d_sh]; auto neighbour = tile->GetNeighbourImpl(dir); if (!( ( neighbour->GetTurf()->GetAtmosState() == NON_SIMULATED && PRESSURE_MOVE_BORDER < tile->GetAtmosHolder()->GetPressure()) || (neighbour->GetAtmosHolder()->GetPressure() + PRESSURE_MOVE_BORDER < tile->GetAtmosHolder()->GetPressure()))) { continue; } if (!CanPass(tile->GetPassable(dir), Passable::AIR)) { tile->BumpByGas(dir, true); continue; } if ( !CanPass(neighbour->GetPassable(D_ALL), Passable::AIR) || !CanPass(neighbour->GetPassable(helpers::revert_dir(dir)), Passable::AIR)) { neighbour->BumpByGas(dir); continue; } if (tile->GetInsideList().size()) { auto i = tile->GetInsideList().rbegin(); while ( (i != tile->GetInsideList().rend()) && ((*i)->passable_level == Passable::EMPTY)) { ++i; } if (i != tile->GetInsideList().rend()) { (*i)->ApplyForce(DirToVDir[dir]); } } } }
void Atmosphere::ProcessTile(size_t x, size_t y, size_t z) { auto tile = map_->GetSquares()[x][y][z]; if (tile->GetTurf()->GetAtmosState() == NON_SIMULATED) { return; } //ShuffleDir(); for (size_t d_sh = 0; d_sh < dir_shuffle_.size(); ++d_sh) { Dir dir = dir_shuffle_[d_sh]; auto neighbour = tile->GetNeighbourImpl(dir); if (!( CanPass(tile->GetPassable(dir), Passable::AIR) && CanPass(neighbour->GetPassable(helpers::revert_dir(dir)), Passable::AIR) && CanPass(neighbour->GetPassable(D_ALL), Passable::AIR)) ) { continue; } if (neighbour->GetTurf()->GetAtmosState() == NON_SIMULATED) { continue; } int p = MAX_GAS_LEVEL / 2; if (!CanPass(tile->GetPassable(D_ALL), Passable::AIR)) { p = 0; } tile->GetAtmosHolder()->Connect( neighbour->GetAtmosHolder(), MAX_GAS_LEVEL, MAX_GAS_LEVEL, p); if (tile->GetTurf()->GetAtmosState() == SPACE) { tile->GetAtmosHolder()->Truncate(); } if (neighbour->GetTurf()->GetAtmosState() == SPACE) { neighbour->GetAtmosHolder()->Truncate(); } } }
bool IMovable::CheckPassable() { PassableLevel loc = GetPassable(dMove); if (loc != Passable::FULL) { SetPassable(dMove, Passable::FULL); } if (!CanPass(owner->GetPassable(dMove), passable_level)) { owner->Bump(GetId()); force_.x = 0; force_.y = 0; force_.z = 0; if (loc != Passable::FULL) { SetPassable(dMove, loc); } return false; } if (loc != Passable::FULL) { SetPassable(dMove, loc); } auto neighbour = owner->GetNeighbour(dMove); if ( !CanPass(neighbour->GetPassable(D_ALL), passable_level) || !CanPass(neighbour->GetPassable(helpers::revert_dir(dMove)), passable_level)) { neighbour->Bump(GetId()); force_.x = 0; force_.y = 0; force_.z = 0; return false; } return true; }
void MapMaster::FillAtmosphere() { for (int z = 0; z < GetDepth(); ++z) for (int x = 0; x < GetWidth(); ++x) for (int y = 0; y < GetHeight(); ++y) if ( squares_[x][y][z]->GetTurf() && squares_[x][y][z]->GetTurf()->GetAtmosState() != SPACE && squares_[x][y][z]->GetTurf()->GetAtmosState() != NON_SIMULATED && CanPass(squares_[x][y][z]->GetPassable(D_ALL), Passable::AIR)) { auto a = squares_[x][y][z]->GetAtmosHolder(); a->AddGase(NYTROGEN, 750); a->AddGase(OXYGEN, 230); a->AddGase(CO2, 1); a->AddEnergy(1000); } }