/** * \brief Notifies this state that the hero is activating a jumper. * \param jumper The jumper activated. */ void Hero::RunningState::notify_jumper_activated(Jumper& jumper) { // Jump immediately. get_hero().start_jumping( jumper.get_direction(), jumper.get_jump_length(), true, true, 0); }
/** * \brief Returns whether a jumper is considered as an obstacle in this state * for the hero at the specified position. * \param jumper A jumper. * \param candidate_position Position of the hero to test. * \return \c true if the jumper is an obstacle in this state with this * hero position. */ bool Hero::BaseState::is_jumper_obstacle( const Jumper& jumper, const Rectangle& candidate_position) const { const Hero& hero = get_entity(); if (jumper.overlaps_jumping_region(hero.get_bounding_box(), false)) { // The hero already overlaps the active part of the jumper. // This is authorized if he arrived from another direction // and thus did not activate it. // This can be used to leave water pools for example. return false; } if (!jumper.overlaps_jumping_region(candidate_position, false)) { // The candidate position is in the inactive region: always accept that. return false; } if (!can_take_jumper()) { // If jumpers cannot be used in this state, consider their active region // as obstacles and their inactive region as traversable. // The active region should be an obstacle. return true; } // At this point, we know that the jumper can be activated. const bool hero_in_jump_position = jumper.is_in_jump_position(hero, hero.get_bounding_box(), false); const bool candidate_in_jump_position = jumper.is_in_jump_position(hero, candidate_position, false); if (candidate_in_jump_position) { // Wants to move to a valid jump position: accept. return false; } if (hero_in_jump_position) { // If the hero is already correctly placed (ready to jump), // make the jumper obstacle so that the player has to move in the // jumper's direction during a small delay before jumping. // This also prevents the hero to get inside the jumper's active region. return true; } const bool candidate_in_extended_jump_position = jumper.is_in_jump_position(hero, candidate_position, true); if (candidate_in_extended_jump_position) { // Wants to get inside the active region from an end of the jumper: // don't accept this. return true; } if (!jumper.is_jump_diagonal() && hero.is_moving_towards(jumper.get_direction() / 2)) { // Special case: make the jumper traversable so // that the smooth movement can slide to it. return false; } if (!jumper.is_jump_diagonal() && get_name() == "swimming" && // TODO use inheritance instead hero.is_moving_towards(((jumper.get_direction() / 2) + 2) % 4) ) { // Other special case: trying to enter the jumper the reverse way while // swimming: we accept this to allow the hero to leave water pools. // TODO I'm not sure this behavior is really a good idea. // This may change in a future version. return false; } return true; }