Exemple #1
0
/**
 * @brief Returns whether an entity collides with this detector with respect to a custom rule.
 * @param entity the entity
 * @return true if the entity's collides with this detector with respect to the custom rule
 */
bool DynamicTile::test_collision_custom(MapEntity &entity) {

  // we must test the same coordinates as non-dynamic tiles (see Hero::get_ground_point())
  return overlaps(entity.get_x(), entity.get_y() - 2);
}
Exemple #2
0
/**
 * @brief Notifies this entity that another sprite is overlapping it.
 *
 * This function is called by check_collision(MapEntity*, Sprite*) when another entity's
 * sprite overlaps a sprite of this detector.
 *
 * @param other_entity the entity overlapping this detector
 * @param other_sprite the sprite of other_entity that is overlapping this detector
 * @param this_sprite the sprite of this detector that is overlapping the other entity's sprite
 */
void CrystalSwitch::notify_collision(MapEntity &other_entity, Sprite &other_sprite, Sprite &this_sprite) {
  other_entity.notify_collision_with_crystal_switch(*this, other_sprite);
}
Exemple #3
0
/**
 * @brief This function is called when another entity collides with this crystal switch.
 * @param entity_overlapping the other entity
 * @param collision_mode the collision mode that detected the collision
 */
void CrystalSwitch::notify_collision(MapEntity &entity_overlapping, CollisionMode collision_mode) {
  entity_overlapping.notify_collision_with_crystal_switch(*this, collision_mode);
}
Exemple #4
0
/**
 * \brief Returns whether this entity is an obstacle for another one.
 * \param other another entity
 * \return true if this entity is an obstacle for the other one
 */
bool Sensor::is_obstacle_for(const MapEntity& other) const {

  return other.is_sensor_obstacle(*this);
}
Exemple #5
0
/**
 * \brief Tests whether a point collides with the ground of the map.
 *
 * The ground is the terrain of the point. It is defined by the tiles and
 * by the presence of entities that may change it
 * (like dynamic tiles and destructible items).
 *
 * This method also returns true if the point is outside the map.
 *
 * \param layer Layer of the point.
 * \param x X of the point in pixels.
 * \param y Y of the point in pixels.
 * \param entity_to_check The entity to check (used to decide what grounds are
 * considered as obstacle).
 * \param [out] found_diagonal_wall \c true if the ground under this point was
 * a diagonal wall, unchanged otherwise.
 * Your algorithm may decide to check more points if there is a diagonal wall.
 * \return \c true if this point is on an obstacle.
 */
bool Map::test_collision_with_ground(
    Layer layer,
    int x,
    int y,
    const MapEntity& entity_to_check,
    bool& found_diagonal_wall) const {

  bool on_obstacle = false;
  int x_in_tile, y_in_tile;

  // If the point is outside the map, this is an obstacle.
  if (test_collision_with_border(x, y)) {
    return true;
  }

  // Get the ground property under this point.
  Ground ground = get_ground(layer, x, y);
  switch (ground) {

  case GROUND_EMPTY:
  case GROUND_TRAVERSABLE:
  case GROUND_GRASS:
  case GROUND_ICE:
    // The square is not an obstacle.
    on_obstacle = false;
    break;

  case GROUND_WALL:
    // The square is entirely an obstacle.
    on_obstacle = true;
    break;

  case GROUND_WALL_TOP_RIGHT:
  case GROUND_WALL_TOP_RIGHT_WATER:
    // The upper right half of the square is an obstacle
    // so we have to test the position of the point in the square.
    x_in_tile = x & 7;
    y_in_tile = y & 7;
    on_obstacle = y_in_tile <= x_in_tile;
    found_diagonal_wall = true;
    break;

  case GROUND_WALL_TOP_LEFT:
  case GROUND_WALL_TOP_LEFT_WATER:
    // Same thing.
    x_in_tile = x & 7;
    y_in_tile = y & 7;
    on_obstacle = y_in_tile <= 7 - x_in_tile;
    found_diagonal_wall = true;
    break;

  case GROUND_WALL_BOTTOM_LEFT:
  case GROUND_WALL_BOTTOM_LEFT_WATER:
    x_in_tile = x & 7;
    y_in_tile = y & 7;
    on_obstacle = y_in_tile >= x_in_tile;
    found_diagonal_wall = true;
    break;

  case GROUND_WALL_BOTTOM_RIGHT:
  case GROUND_WALL_BOTTOM_RIGHT_WATER:
    x_in_tile = x & 7;
    y_in_tile = y & 7;
    on_obstacle = y_in_tile >= 7 - x_in_tile;
    found_diagonal_wall = true;
    break;

  case GROUND_LOW_WALL:
    on_obstacle = entity_to_check.is_low_wall_obstacle();
    break;

  case GROUND_SHALLOW_WATER:
    on_obstacle = entity_to_check.is_shallow_water_obstacle();
    break;

  case GROUND_DEEP_WATER:
    on_obstacle = entity_to_check.is_deep_water_obstacle();
    break;

  case GROUND_HOLE:
    on_obstacle = entity_to_check.is_hole_obstacle();
    break;

  case GROUND_LAVA:
    on_obstacle = entity_to_check.is_lava_obstacle();
    break;

  case GROUND_PRICKLE:
    on_obstacle = entity_to_check.is_prickle_obstacle();
    break;

  case GROUND_LADDER:
    on_obstacle = entity_to_check.is_ladder_obstacle();
    break;
  }

  return on_obstacle;
}
Exemple #6
0
/**
 * \copydoc Detector::notify_collision(MapEntity&, Sprite&, Sprite&)
 */
void Crystal::notify_collision(MapEntity& other_entity, Sprite& /* this_sprite */, Sprite& other_sprite) {
  other_entity.notify_collision_with_crystal(*this, other_sprite);
}
Exemple #7
0
/**
 * \brief Notifies the enemy that a collision was just detected with another entity
 * \param entity_overlapping the other entity
 * \param collision_mode the collision mode that detected the collision
 */
void Enemy::notify_collision(MapEntity &entity_overlapping, CollisionMode collision_mode) {

  entity_overlapping.notify_collision_with_enemy(*this);
}
Exemple #8
0
/**
 * \brief Returns whether this entity is an obstacle for another one.
 * \param other another entity
 * \return true
 */
bool Block::is_obstacle_for(const MapEntity& other) const {

  return other.is_block_obstacle(*this);
}
Exemple #9
0
/**
 * \brief This function is called by the engine when there is a collision with another entity.
 * \param entity_overlapping the entity overlapping the detector
 * \param collision_mode the collision mode that detected the collision
 */
void Block::notify_collision(MapEntity& entity_overlapping, CollisionMode collision_mode) {

  entity_overlapping.notify_collision_with_block(*this);
}
Exemple #10
0
/**
 * @brief Notifies this entity that a pixel-perfect collision was just detected with another sprite.
 *
 * This function is called by check_collision(MapEntity*, Sprite*) when another entity's
 * sprite overlaps a sprite of this detector.
 *
 * @param other_entity the entity overlapping this detector
 * @param other_sprite the sprite of other_entity that is overlapping this detector
 * @param this_sprite the sprite of this detector that is overlapping the other entity's sprite
 */
void Explosion::notify_collision(MapEntity &other_entity, Sprite &other_sprite, Sprite &this_sprite) {

  other_entity.notify_collision_with_explosion(*this, other_sprite);
}
Exemple #11
0
/**
 * \brief Returns whether this entity is an obstacle for another one
 * when it is enabled.
 * \param other another entity
 * \return true if this entity is an obstacle for the other one
 */
bool Wall::is_obstacle_for(MapEntity& other) {

  const auto it = entity_types_stopped.find(other.get_type());
  return it != entity_types_stopped.end();
}
Exemple #12
0
/**
 * \brief This function is called by the engine when an entity overlaps the destructible item.
 *
 * If the entity is the hero, we allow him to lift the item.
 *
 * \param entity_overlapping the entity overlapping the detector
 * \param collision_mode the collision mode that detected the collision
 */
void Destructible::notify_collision(MapEntity &entity_overlapping, CollisionMode collision_mode) {

  entity_overlapping.notify_collision_with_destructible(*this, collision_mode);
}
Exemple #13
0
/**
 * \brief Tests whether an entity's collides with this entity.
 *
 * This custom collision test is used for destructible items that change the ground drawn under the hero.
 *
 * \param entity an entity
 * \return true if the entity's collides with this entity
 */
bool Destructible::test_collision_custom(MapEntity &entity) {
  return overlaps(entity.get_x(), entity.get_y() - 2);
}
Exemple #14
0
/**
 * \brief Returns whether this entity is an obstacle for another one.
 *
 * For a destructible item, this does not depend on the other
 * entity but only on the subtype of destructible item.
 *
 * \param other another entity
 * \return true if this entity is an obstacle for others
 */
bool Destructible::is_obstacle_for(const MapEntity& other) const {
  return features[subtype].can_be_lifted && !is_being_cut && other.is_destructible_obstacle(*this);
}
/**
 * @brief Sets the entity to target with this movement.
 */
void PathFindingMovement::set_target(MapEntity& target) {

  this->target = &target;
  target.increment_refcount();
  next_recomputation_date = System::now() + 100;
}
Exemple #16
0
/**
 * \brief Returns whether an entity's rectangle is overlapping the detector's rectangle.
 *
 * This method is called by check_collision(MapEntity*) when the detector's collision
 * mode is COLLISION_RECTANGLE.
 *
 * \param entity the entity
 * \return true if the entity's rectangle is overlapping the detector's rectangle
 */
bool Detector::test_collision_rectangle(MapEntity& entity) {

  return entity.overlaps(*this);
}
Exemple #17
0
/**
 * \brief This function is called by the engine when an entity overlaps this detector.
 * \param entity_overlapping the entity overlapping the detector
 * \param collision_mode the collision mode that detected the collision
 */
void Bomb::notify_collision(MapEntity& entity_overlapping, CollisionMode collision_mode) {

  entity_overlapping.notify_collision_with_bomb(*this, collision_mode);
}
Exemple #18
0
/**
 * \brief Returns whether an entity's rectangle is entirely inside the detector's rectangle.
 *
 * This method is called by check_collision(MapEntity*) when the detector's collision
 * mode is COLLISION_INSIDE.
 *
 * \param entity the entity
 * \return true if the entity's rectangle is entirely inside the detector's rectangle
 */
bool Detector::test_collision_inside(MapEntity& entity) {

  return get_bounding_box().contains(entity.get_bounding_box());
}
Exemple #19
0
/**
 * \brief Makes the enemy receive an attack.
 *
 * He might resist to the attack or get hurt.
 *
 * \param attack type of attack
 * \param source the entity attacking the enemy (often the hero)
 * \param this_sprite the sprite of this enemy that received the attack, or NULL
 * if the attack comes from a non pixel-precise collision test
 */
void Enemy::try_hurt(EnemyAttack attack, MapEntity& source, Sprite* this_sprite) {

  EnemyReaction::Reaction reaction = get_attack_consequence(attack, this_sprite);
  if (invulnerable || reaction.type == EnemyReaction::IGNORED) {
    // ignore the attack
    return;
  }

  invulnerable = true;
  vulnerable_again_date = System::now() + 500;

  switch (reaction.type) {

    case EnemyReaction::PROTECTED:
      // attack failure sound
      Sound::play("sword_tapping");
      break;

    case EnemyReaction::IMMOBILIZED:
      // get immobilized
      hurt(source);
      immobilize();
      notify_hurt(source, attack, 0);
      break;

    case EnemyReaction::CUSTOM:
      // custom attack (defined in the script)
      if (is_in_normal_state()) {
        custom_attack(attack, this_sprite);
      }
      else {
        // no attack was made: notify the source correctly
        reaction.type = EnemyReaction::IGNORED;
        invulnerable = false;
      }
      break;

    case EnemyReaction::HURT:

      if (is_immobilized() && get_sprite().get_current_animation() == "shaking") {
        stop_immobilized();
      }

      // compute the number of health points lost by the enemy

      if (attack == ATTACK_SWORD) {

        // for a sword attack, the damage depends on the sword and the variant of sword attack used
        int damage_multiplicator = ((Hero&) source).get_sword_damage_factor();
        reaction.life_lost *= damage_multiplicator;
      }
      else if (attack == ATTACK_THROWN_ITEM) {
        reaction.life_lost *= ((CarriedItem&) source).get_damage_on_enemies();
      }
      life -= reaction.life_lost;

      hurt(source);
      notify_hurt(source, attack, reaction.life_lost);
      break;

    case EnemyReaction::IGNORED:
    case EnemyReaction::REACTION_NUMBER:
      Debug::die(StringConcat() << "Invalid enemy reaction" << reaction.type);
      break;
  }

  // notify the source
  source.notify_attacked_enemy(attack, *this, reaction, get_life() <= 0);
}
Exemple #20
0
/**
 * \brief Returns whether the facing point of an entity is overlapping the detector's rectangle.
 *
 * This method is called by check_collision(MapEntity*) when the detector's collision
 * mode is COLLISION_FACING_POINT.
 *
 * \param entity the entity
 * \return true if the entity's facing point is overlapping the detector's rectangle
 */
bool Detector::test_collision_facing_point(MapEntity& entity) {

  return entity.is_facing_point_in(get_bounding_box());
}
Exemple #21
0
/**
 * \brief Notifies this enemy that a pixel-precise collision was just detected with another sprite.
 *
 * This function is called by check_collision(MapEntity*, Sprite*) when another entity's
 * sprite overlaps a sprite of this enemy.
 *
 * \param other_entity the entity overlapping this detector
 * \param other_sprite the sprite of other_entity that is overlapping this detector
 * \param this_sprite the sprite of this detector that is overlapping the other entity's sprite
 */
void Enemy::notify_collision(MapEntity &other_entity, Sprite &other_sprite, Sprite &this_sprite) {

  other_entity.notify_collision_with_enemy(*this, this_sprite, other_sprite);
}
Exemple #22
0
/**
 * \brief Returns whether the center point of an entity is overlapping the detector's rectangle.
 *
 * This method is called by check_collision(MapEntity*) when the detector's collision
 * mode is COLLISION_CENTER.
 *
 * \param entity the entity
 * \return true if the entity's center is overlapping the detector's rectangle
 */
bool Detector::test_collision_center(MapEntity& entity) {

  return entity.is_center_in(get_bounding_box());
}
Exemple #23
0
/**
 * \brief This function is called by the engine when an entity overlaps this sensor.
 * \param entity_overlapping the entity overlapping the detector
 * \param collision_mode the collision mode that detected the collision
 */
void Sensor::notify_collision(MapEntity& entity_overlapping, CollisionMode collision_mode) {

  entity_overlapping.notify_collision_with_sensor(*this, collision_mode);
}
Exemple #24
0
/**
 * \brief Makes the camera move towards an entity.
 *
 * The camera will be centered on the entity's center point.
 * If there was already a movement, the new one replaces it.
 * Note that the camera will not update its movement if the entity moves.
 *
 * \param entity the target entity
 */
void Camera::move(MapEntity& entity) {

  const Rectangle& center = entity.get_center_point();
  move(center.get_x(), center.get_y());
}
Exemple #25
0
void Chest::notify_collision(MapEntity& entity_overlapping, CollisionMode collision_mode) {
	entity_overlapping.notify_collision_with_chest(*this);
}
Exemple #26
0
/**
 * @brief Notifies this detector that a pixel-perfect collision was just detected with another sprite.
 *
 * This function is called by check_collision(MapEntity&, Sprite&) when another entity's
 * sprite overlaps a sprite of this detector.
 *
 * @param other_entity the entity overlapping this detector
 * @param other_sprite the sprite of other_entity that is overlapping this detector
 * @param this_sprite the sprite of this detector that is overlapping the other entity's sprite
 */
void Door::notify_collision(MapEntity& other_entity, Sprite& other_sprite, Sprite& this_sprite) {

  if (other_entity.get_type() == EXPLOSION) {
    notify_collision_with_explosion(static_cast<Explosion&>(other_entity), other_sprite);
  }
}
Exemple #27
0
/**
 * @brief Returns whether this entity is an obstacle for another one.
 * @param other another entity
 * @return true if this entity is an obstacle for the other one 
 */
bool CrystalSwitch::is_obstacle_for(MapEntity &other) {
  return other.is_crystal_switch_obstacle(*this);
}
Exemple #28
0
/**
 * @brief Notifies this entity that a pixel-precise collision was just detected with another sprite.
 *
 * This function is called by check_collision(MapEntity*, Sprite*) when another entity's
 * sprite overlaps a sprite of this detector.
 *
 * @param other_entity the entity overlapping this detector
 * @param other_sprite the sprite of other_entity that is overlapping this detector
 * @param this_sprite the sprite of this detector that is overlapping the other entity's sprite
 */
void Fire::notify_collision(MapEntity& other_entity, Sprite& other_sprite, Sprite& this_sprite) {

  other_entity.notify_collision_with_fire(*this, other_sprite);
}
Exemple #29
0
/**
 * \brief Returns whether this entity is an obstacle for another one
 * when it is enabled.
 * \param other another entity
 * \return true if this entity is an obstacle for the other one
 */
bool Stairs::is_obstacle_for(MapEntity& other) {

  return other.is_stairs_obstacle(*this);
}
/**
 * @brief This function is called by the engine when an entity overlaps the teletransporter.
 * @param entity_overlapping the entity overlapping the detector
 * @param collision_mode the collision mode that detected the collision
 */
void Teletransporter::notify_collision(MapEntity& entity_overlapping, CollisionMode collision_mode) {

  entity_overlapping.notify_collision_with_teletransporter(*this, collision_mode);
}