void Generator::PostProcessTile(Map& map, Tile& tile, std::map<std::pair<unsigned int, unsigned int>, unsigned int>& tiles, unsigned int id) { unsigned int x = tile.GetX(); unsigned int y = tile.GetY(); Tile* tile2 = map.GetTile(x - 1, y); if (tile2 && !tile2->IsBlocked()) { std::map<std::pair<unsigned int, unsigned int>, unsigned int>::iterator itr = tiles.find(std::make_pair(tile2->GetX(), tile2->GetY())); if (itr == tiles.end()) { tiles.insert(std::make_pair(std::make_pair(tile2->GetX(), tile2->GetY()), id)); PostProcessTile(map, *tile2, tiles, id); } } tile2 = map.GetTile(x + 1, y); if (tile2 && !tile2->IsBlocked()) { std::map<std::pair<unsigned int, unsigned int>, unsigned int>::iterator itr = tiles.find(std::make_pair(tile2->GetX(), tile2->GetY())); if (itr == tiles.end()) { tiles.insert(std::make_pair(std::make_pair(tile2->GetX(), tile2->GetY()), id)); PostProcessTile(map, *tile2, tiles, id); } } tile2 = map.GetTile(x, y - 1); if (tile2 && !tile2->IsBlocked()) { std::map<std::pair<unsigned int, unsigned int>, unsigned int>::iterator itr = tiles.find(std::make_pair(tile2->GetX(), tile2->GetY())); if (itr == tiles.end()) { tiles.insert(std::make_pair(std::make_pair(tile2->GetX(), tile2->GetY()), id)); PostProcessTile(map, *tile2, tiles, id); } } tile2 = map.GetTile(x, y + 1); if (tile2 && !tile2->IsBlocked()) { std::map<std::pair<unsigned int, unsigned int>, unsigned int>::iterator itr = tiles.find(std::make_pair(tile2->GetX(), tile2->GetY())); if (itr == tiles.end()) { tiles.insert(std::make_pair(std::make_pair(tile2->GetX(), tile2->GetY()), id)); PostProcessTile(map, *tile2, tiles, id); } } }
//----------------------------------------------------------------------------- Tile* Area::GetTile(int X, int Y) { int MapWidth = MAP_WIDTH * TILE_SIZE; int MapHeight = MAP_HEIGHT * TILE_SIZE; Map* Map = GetMap(X, Y); if(Map == NULL) return NULL; X = X % MapWidth; Y = Y % MapHeight; return Map->GetTile(X, Y); }
void Exit::Init(Map& World){ int x=0; int y=0; bool NotDone = true; while(NotDone){ x = rand()%(int)World.GetSize().x; y = rand()%(int)World.GetSize().y; if(World.GetTile(x,y).isTraversable()){ Loc = V2D(x,y); CurrentLoc = V2D(x,y); NotDone = false; } } }
void Generator::PostProcessMap(Map& map) { // Sort tiles by connectivity std::map<std::pair<unsigned int, unsigned int>, unsigned int> tiles; unsigned int id = 0; for (Map::TileIterator itr = map.GetTilesBegin(); itr != map.GetTilesEnd(); ++itr) { if (!itr->second->IsBlocked()) { std::map<std::pair<unsigned int, unsigned int>, unsigned int>::iterator itr2 = tiles.find(itr->first); if (itr2 == tiles.end()) { tiles.insert(std::make_pair(itr->first, id)); PostProcessTile(map, *itr->second, tiles, id); ++id; } } } // Find largest connected area std::vector<unsigned int> count; for (unsigned int i = 0; i != id; ++i) { count.push_back(0); } for (std::map<std::pair<unsigned int, unsigned int>, unsigned int>::iterator itr = tiles.begin(); itr != tiles.end(); ++itr) { ++count[itr->second]; } unsigned int max = 0; unsigned int max_id = 0; for (unsigned int i = 0; i != id; ++i) { if (count[i] > max) { max = count[i]; max_id = i; } } // Blcok all tiles that aren't connected to the largest connected area for (std::map<std::pair<unsigned int, unsigned int>, unsigned int>::iterator itr = tiles.begin(); itr != tiles.end(); ++itr) { if (itr->second != max_id) { Tile* tile = map.GetTile(itr->first.first, itr->first.second); tile->SetType(TT_FOREST); } } }
void CObstructionThingieDlg::MangleObstructions(Map& map,bool bSetobs,bool bFromorexcept,int nStarttile,int nEndtile,int nLayer) { // If we're mangling based on all layers if (nLayer==nAllLayers) { for (int i=0; i<map.NumLayers(); i++) MangleObstructions(map,bSetobs,bFromorexcept,nStarttile,nEndtile,i); // I'm such a loser return; } if (nLayer>=map.NumLayers()) return; // POOOOOOOOOOOOOOOOOOOOOOOO for (int y=0; y<map.Height(); y++) for (int x=0; x<map.Width(); x++) { int t=map.GetTile(x,y,nLayer); if (t>=nStarttile && t<=nEndtile) map.SetObs(x,y,bSetobs); } }
Unit* PlaceToolInputState::CreateUnitAtScreenCoords( const Vec2f& screenCoords ) { Unit* unit = nullptr; if( mSelectedUnitType ) { if( mSelectedFaction ) { EditorState* owner = GetOwnerDerived(); MapView* mapView = owner->GetMapView(); Map* map = owner->GetMap(); // Get the Tile at the screen coords. Vec2f worldPos = mapView->ScreenToWorldCoords( screenCoords ); Vec2s tilePos = mapView->WorldToTileCoords( worldPos ); Map::Iterator tile = map->GetTile( tilePos ); if( tile.IsValid() && tile->IsEmpty() && mSelectedUnitType->CanMoveAcrossTerrain( tile->GetTerrainType() ) ) { // If the selected UnitType can be placed into the Tile, create a new Unit. DebugPrintf( "Placing Unit at tile (%d,%d)!", tilePos.x, tilePos.y ); unit = map->CreateUnit( mSelectedUnitType, mSelectedFaction, tilePos ); } else { WarnFail( "Cannot place Unit into tile (%d,%d)!", tilePos.x, tilePos.y ); } } else { WarnFail( "Cannot create Unit because no Faction was selected!" ); } } else { WarnFail( "Cannot create Unit because no UnitType was selected!" ); } return unit; }
void UnitAttackAbility::DetermineAvailableActions( const Unit* unit, const Path& movementPath, Actions& result ) const { // Get the UnitType of the Unit. UnitType* unitType = unit->GetUnitType(); if( unitType->HasWeapons() ) { // If this Unit has weapons, determine whether the Unit can wait in the destination square. Map* map = unit->GetMap(); Map::Iterator destinationTile = map->GetTile( movementPath.GetDestination() ); if( unit->CanOccupyTile( destinationTile ) ) { // If the Unit can stop here, get the list of Units in attack range from this location. Map::Units unitsInRange; map->FindUnitsInRange( destinationTile.GetPosition(), unitType->GetAttackRange(), unitsInRange ); for( auto it = unitsInRange.begin(); it != unitsInRange.end(); ++it ) { Unit* target = *it; if( unit->CanAttack( target ) ) { // Add an attack action to the list of actions. UnitAttackAbility::Action* attackAction = new UnitAttackAbility::Action(); attackAction->UnitID = unit->GetID(); attackAction->TargetID = target->GetID(); attackAction->MovementPath = movementPath; result.push_back( attackAction ); } } } } }
Map* Generator::CreateMap(Game& game, unsigned int width, unsigned int height, unsigned int tile_width, unsigned int tile_height) { Map* map = new Map(game, width, height, tile_width, tile_height); // Generate water tiles on the edge of the map noise::module::Perlin perlin; perlin.SetSeed(Random::UInt()); perlin.SetNoiseQuality(noise::QUALITY_BEST); perlin.SetLacunarity(1.0f); Tile* tile; for (unsigned int x = 0; x != width; ++x) { double size = abs(perlin.GetValue(x * .02, 0, 0) * 16.0); for (unsigned int i = 0; i < size + 16; ++i) { tile = map->GetTile(x, i); if (tile) { tile->SetType(TT_WATER); } tile = map->GetTile(x, height - i - 1); if (tile) { tile->SetType(TT_WATER); } } } for (unsigned int y = 0; y != height; ++y) { double size = abs(perlin.GetValue(0, y * .02, 0) * 16.0); for (unsigned int i = 0; i < size + 16; ++i) { tile = map->GetTile(i, y); if (tile) { tile->SetType(TT_WATER); } tile = map->GetTile(width - i - 1, y); if (tile) { tile->SetType(TT_WATER); } } } // Generate forest or grass tiles on remaining tiles perlin.SetSeed(Random::UInt()); perlin.SetNoiseQuality(noise::QUALITY_BEST); perlin.SetLacunarity(1.0f); for (unsigned int x = 1; x != width; ++x) { for (unsigned int y = 1; y != height; ++y) { tile = map->GetTile(x, y); if (tile->GetType() != TT_WATER) { double value = perlin.GetValue(x * .02, y * .02, 0); if (value <= -.3 || value >= .3) { tile->SetType(TT_FOREST); } else { tile->SetType(TT_GRASS); } } } } // Remove unreachable tiles PostProcessMap(*map); return map; }