コード例 #1
0
ファイル: game_character.cpp プロジェクト: Zhek/Player
bool Game_Character::IsPassable(int x, int y, int d) const {
	int new_x = x + (d == RPG::EventPage::Direction_right ? 1 : d == RPG::EventPage::Direction_left ? -1 : 0);
	int new_y = y + (d == RPG::EventPage::Direction_down ? 1 : d == RPG::EventPage::Direction_up ? -1 : 0);

	if (!Game_Map::IsValid(new_x, new_y))
		return false;

	if (through) return true;

	if (!Game_Map::IsPassable(x, y, d, this))
		return false;

	if (!Game_Map::IsPassable(new_x, new_y, (d + 2) % 4))
		return false;

	for (tEventHash::iterator i = Game_Map::GetEvents().begin(); i != Game_Map::GetEvents().end(); i++) {
		Game_Event* evnt = i->second.get();
		if (evnt->GetX() == new_x && evnt->GetY() == new_y) {
			if (!evnt->GetThrough() && evnt->GetPriorityType() == RPG::EventPage::Layers_same) {
				return false;
			}
		}
	}

	if (Main_Data::game_player->GetX() == new_x && Main_Data::game_player->GetY() == new_y) {
		if (!Main_Data::game_player->GetThrough() && !character_name.empty()) {
			return false;
		}
	}

	return true;
}
コード例 #2
0
ファイル: game_map.cpp プロジェクト: cheerjo/Player
bool Game_Map::IsLandable(int x, int y, const Game_Character *self_event)
{
    int tile_id;

    if (self_event) {
        for (tEventHash::iterator i = events.begin(); i != events.end(); ++i) {
            Game_Event* evnt = i->second.get();
            if (evnt != self_event && evnt->GetX() == x && evnt->GetY() == y) {
                if (!evnt->GetThrough()) {
                    if (evnt->GetLayer() == RPG::EventPage::Layers_same) {
                        return false;
                    }
                    else if (evnt->GetTileId() >= 0 && evnt->GetLayer() == RPG::EventPage::Layers_below) {
                        // Event layer Chipset Tile
                        tile_id = i->second->GetTileId();
                        return (passages_up[tile_id] & Passable::Down ||
                                passages_up[tile_id] & Passable::Right ||
                                passages_up[tile_id] & Passable::Left ||
                                passages_up[tile_id] & Passable::Up);
                    }
                }
            }
        }
    }

    int const tile_index = x + y * GetWidth();

    tile_id = map->upper_layer[tile_index] - BLOCK_F;
    tile_id = map_info.upper_tiles[tile_id];

    if ((passages_up[tile_id] & Passable::Down) == 0 &&
        (passages_up[tile_id] & Passable::Right) == 0 &&
        (passages_up[tile_id] & Passable::Left) == 0 &&
        (passages_up[tile_id] & Passable::Up) == 0) {
        return false;
    }

    if ((passages_up[tile_id] & Passable::Above) == 0)
        return true;

    if (map->lower_layer[tile_index] >= BLOCK_E) {
        tile_id = map->lower_layer[tile_index] - BLOCK_E;
        tile_id = map_info.lower_tiles[tile_id];
        tile_id += 18;

        if ((passages_down[tile_id] & Passable::Down) == 0 &&
            (passages_down[tile_id] & Passable::Right) == 0 &&
            (passages_down[tile_id] & Passable::Left) == 0 &&
            (passages_down[tile_id] & Passable::Up) == 0)
            return false;

    } else if (map->lower_layer[tile_index] >= BLOCK_D) {
        tile_id = (map->lower_layer[tile_index] - BLOCK_D) / 50;
        int16_t autotile_id = map->lower_layer[tile_index] - BLOCK_D - tile_id * 50;

        tile_id += 6;

        if (((passages_down[tile_id] & Passable::Wall) != 0) && (
                (autotile_id >= 20 && autotile_id <= 23) ||
                (autotile_id >= 33 && autotile_id <= 37) ||
                autotile_id == 42 ||
                autotile_id == 43 ||
                autotile_id == 45
            ))
            return true;

        if ((passages_down[tile_id] & Passable::Down) == 0 &&
            (passages_down[tile_id] & Passable::Right) == 0 &&
            (passages_down[tile_id] & Passable::Left) == 0 &&
            (passages_down[tile_id] & Passable::Up) == 0)
            return false;

    } else if (map->lower_layer[tile_index] >= BLOCK_C) {
        tile_id = (map->lower_layer[tile_index] - BLOCK_C) / 50 + 3;

        if ((passages_down[tile_id] & Passable::Down) == 0 &&
            (passages_down[tile_id] & Passable::Right) == 0 &&
            (passages_down[tile_id] & Passable::Left) == 0 &&
            (passages_down[tile_id] & Passable::Up) == 0)
            return false;

    } else if (map->lower_layer[tile_index] < BLOCK_C) {
        tile_id = map->lower_layer[tile_index] / 1000;

        if ((passages_down[tile_id] & Passable::Down) == 0 &&
            (passages_down[tile_id] & Passable::Right) == 0 &&
            (passages_down[tile_id] & Passable::Left) == 0 &&
            (passages_down[tile_id] & Passable::Up) == 0)
            return false;
    }

    return true;
}
コード例 #3
0
ファイル: game_map.cpp プロジェクト: Ghabry/easyrpg-player
/**
 * Checks whether a collision occurs between self and other if self
 * moves from (x,y) to (new_x, new_y) in direction d.
 *
 * If other is a tile event, also indicates if the player can use it
 * as a "bridge" to step across without hitting the underlying tile
 * layer.
 */
static CollisionResult TestCollisionDuringMove(
	int x,
	int y,
	int new_x,
	int new_y,
	int d,
	const Game_Character& self,
	const Game_Event& other
) {
	if (!other.GetActive()) {
		return NoCollision;
	}

	if (&self == &other) {
		return NoCollision;
	}

	if (other.GetThrough()) {
		return NoCollision;
	}

	if (!other.IsInPosition(x, y) && !other.IsInPosition(new_x, new_y)) {
		return NoCollision;
	}

	if (&self != Main_Data::game_player.get()) {
		if (other.IsInPosition(new_x, new_y) && (self.IsOverlapForbidden() || other.IsOverlapForbidden())) {
			return Collision;
		}
	}

	if (other.IsInPosition(new_x, new_y) && self.GetLayer() == other.GetLayer()) {
		return Collision;
	}

	if (other.GetLayer() == RPG::EventPage::Layers_below) {
		int tile_id = other.GetTileId();
		if ((passages_up[tile_id] & Passable::Above) != 0) {
			return NoCollision;
		}
		if (other.IsInPosition(x,y) && (passages_up[tile_id] & DirToMask(d)) != 0) {
			return CanStepOffCurrentTile;
		}
		else if (other.IsInPosition(new_x, new_y) && (passages_up[tile_id] & DirToMask(Game_Character::ReverseDir(d))) != 0) {
			return CanStepOntoNewTile;
		} else {
			return Collision;
		}
	}

	return NoCollision;
}
コード例 #4
0
ファイル: game_map.cpp プロジェクト: joewagenbrenner/Player
bool Game_Map::IsPassable(int x, int y, int d, const Game_Character* self_event) {
	if (!Game_Map::IsValid(x, y)) return false;

	uint8_t bit = 0;
	switch (d)
	{
		case RPG::EventPage::Direction_down:
			bit = Passable::Down;
			break;

		case RPG::EventPage::Direction_up:
			bit = Passable::Up;
			break;

		case RPG::EventPage::Direction_left:
			bit = Passable::Left;
			break;

		case RPG::EventPage::Direction_right:
			bit = Passable::Right;
			break;

		default:
			assert(false);
	}

	int tile_id;

	if (self_event) {
		bool pass = false;
		for (tEventHash::iterator i = events.begin(); i != events.end(); ++i) {
			Game_Event* evnt = i->second.get();
			if (evnt != self_event && evnt->GetX() == x && evnt->GetY() == y) {
				if (!evnt->GetThrough()) {
					if (evnt->GetLayer() == self_event->GetLayer()) {
						if (self_event->GetX() == x && self_event->GetY() == y)
							pass = true;
						else
							return false;
					}
					else if (evnt->GetTileId() > 0 && evnt->GetLayer() == RPG::EventPage::Layers_below) {
						// Event layer Chipset Tile
						tile_id = evnt->GetTileId();
						if ((passages_up[tile_id] & Passable::Above) != 0)
							if ((passages_down[tile_id] & bit) == 0)
								return false;
						if ((passages_up[tile_id] & bit) != 0)
							pass = true;
						else
							return false;
					}
				}
			}
		}
		if (pass) // All events here are passable
			return true;
	}

	int const tile_index = x + y * GetWidth();

	tile_id = map->upper_layer[tile_index] - BLOCK_F;
	tile_id = map_info.upper_tiles[tile_id];

	if ((passages_up[tile_id] & bit) == 0) {
		return false;
	}

	if ((passages_up[tile_id] & Passable::Above) == 0)
		return true;

	if (map->lower_layer[tile_index] >= BLOCK_E) {
		tile_id = map->lower_layer[tile_index] - BLOCK_E;
		tile_id = map_info.lower_tiles[tile_id];
		tile_id += 18;

		if ((passages_down[tile_id] & bit) == 0)
			return false;

	} else if (map->lower_layer[tile_index] >= BLOCK_D) {
		tile_id = (map->lower_layer[tile_index] - BLOCK_D) / 50;
		int16_t autotile_id = map->lower_layer[tile_index] - BLOCK_D - tile_id * 50;

		tile_id += 6;

		if (((passages_down[tile_id] & Passable::Wall) != 0) && (
				(autotile_id >= 20 && autotile_id <= 23) ||
				(autotile_id >= 33 && autotile_id <= 37) ||
				autotile_id == 42 ||
				autotile_id == 43 ||
				autotile_id == 45
			))
			return true;

		if ((passages_down[tile_id] & bit) == 0)
			return false;

	} else if (map->lower_layer[tile_index] >= BLOCK_C) {
		tile_id = (map->lower_layer[tile_index] - BLOCK_C) / 50 + 3;

		if ((passages_down[tile_id] & bit) == 0)
			return false;

	} else if (map->lower_layer[tile_index] < BLOCK_C) {
		tile_id = map->lower_layer[tile_index] / 1000;

		if ((passages_down[tile_id] & bit) == 0)
			return false;
	}

	return true;
}