int Game_Map::GetTerrainTag(int x, int y) { // Terrain tag wraps on looping maps x = RoundX(x); y = RoundY(y); if (!Game_Map::IsValid(x, y) || !chipset) return 9; unsigned const chipID = map->lower_layer[x + y * GetWidth()]; unsigned chip_index = (chipID < 3050)? 0 + chipID/1000 : (chipID < 4000)? 4 + (chipID-3050)/50 : (chipID < 5000)? 6 + (chipID-4000)/50 : (chipID < 5144)? 18 + (chipID-5000) : 0; // Apply tile substitution if (chip_index >= 18 && chip_index <= 144) chip_index = map_info.lower_tiles[chip_index - 18] + 18; auto& terrain_data = chipset->terrain_data; if (terrain_data.empty()) { // RPG_RT optimisation: When the terrain is all 1, no terrain data is stored return 1; } assert(chip_index < terrain_data.size()); return terrain_data[chip_index]; }
bool Game_Map::MakeWay(int x, int y, int d, const Game_Character& self, bool force_through) { int new_x = RoundX(x + (d == Game_Character::Right ? 1 : d == Game_Character::Left ? -1 : 0)); int new_y = RoundY(y + (d == Game_Character::Down ? 1 : d == Game_Character::Up ? -1 : 0)); if (!Game_Map::IsValid(new_x, new_y)) return false; if (self.GetThrough() || force_through) return true; // A character can move to a position with an impassable tile by // standing on top of an event below it. These flags track whether // we stepped off an event and therefore don't need to check the // passability of the tile layer below. bool stepped_off_event = false; bool stepped_onto_event = false; for (Game_Event& other : GetEvents()) { CollisionResult result = TestCollisionDuringMove(x, y, new_x, new_y, d, self, other); if (result == Collision) { // Try updating the offending event to give it a chance to move out of the // way and recheck. other.UpdateParallel(); if (TestCollisionDuringMove(x, y, new_x, new_y, d, self, other) == Collision) { return false; } } else if (result == CanStepOffCurrentTile) { stepped_off_event = true; } else if (result == CanStepOntoNewTile) { stepped_onto_event = true; } } if (vehicles[0]->IsInPosition(new_x, new_y) || vehicles[1]->IsInPosition(new_x, new_y)) { return false; } if (Main_Data::game_player->IsInPosition(new_x, new_y) && !Main_Data::game_player->GetThrough() && self.GetLayer() == RPG::EventPage::Layers_same) { // Update the Player to see if they'll move and recheck. Main_Data::game_player->Update(!first_frame); if (Main_Data::game_player->IsInPosition(new_x, new_y)) { return false; } } return (stepped_off_event || IsPassableTile(DirToMask(d), x + y * GetWidth())) && (stepped_onto_event || IsPassableTile(DirToMask(Game_Character::ReverseDir(d)), new_x + new_y * GetWidth())); }
int Game_Map::XwithDirection(int x, int direction) { return RoundX(x + (direction == RPG::EventPage::Direction_right ? 1 : direction == RPG::EventPage::Direction_left ? -1 : 0)); }