Ejemplo n.º 1
0
/**
 * \brief This function is called repeatedly.
 */
void Bomb::update() {

  Detector::update();

  if (is_suspended()) {
    return;
  }

  // check the explosion date
  uint32_t now = System::now();
  if (now >= explosion_date) {
    explode();
  }
  else if (now >= explosion_date - 1500
      && get_sprite().get_current_animation() != "stopped_explosion_soon") {
    get_sprite().set_current_animation("stopped_explosion_soon");
  }

  // destroy the movement once finished
  if (get_movement() != nullptr && get_movement()->is_finished()) {
    clear_movement();
  }

  // check collision with explosions, streams, etc.
  check_collision_with_detectors();
}
Ejemplo n.º 2
0
/**
 * \brief Updates the position.
 */
void PathFindingMovement::update() {

  PathMovement::update();

  if (target != nullptr && target->is_being_removed()) {
    target = nullptr;
  }

  if (is_suspended()) {
    return;
  }

  if (PathMovement::is_finished()) {

    // there was a collision or the path was made
    if (target != nullptr
        && System::now() >= next_recomputation_date
        && get_entity()->is_aligned_to_grid()) {
      recompute_movement();
    }
    else {
      set_path(create_random_path());
    }
  }
}
Ejemplo n.º 3
0
/**
 * \brief Updates the item.
 */
void Destructible::update() {

  MapEntity::update();

  if (is_suspended()) {
    return;
  }

  if (is_being_cut && get_sprite().is_animation_finished()) {

    if (!features[subtype].can_regenerate) {
      // remove the item from the map
      destruction_callback();
      remove_from_map();
    }
    else {
      is_being_cut = false;
      regeneration_date = System::now() + 10000;
    }
  }

  else if (is_disabled() && System::now() >= regeneration_date && !overlaps(get_hero())) {
    get_sprite().set_current_animation("regenerating");
    is_regenerating = true;
    regeneration_date = 0;
    modified_ground = features[subtype].special_ground;
  }
  else if (is_regenerating && get_sprite().is_animation_finished()) {
    get_sprite().set_current_animation("on_ground");
    is_regenerating = false;
  }
}
Ejemplo n.º 4
0
/**
 * \brief Updates this entity.
 */
void Destructible::update() {

  MapEntity::update();

  if (is_suspended()) {
    return;
  }

  if (is_being_cut && get_sprite().is_animation_finished()) {

    if (!get_can_regenerate()) {
      // Remove this destructible from the map.
      remove_from_map();
    }
    else {
      is_being_cut = false;
      regeneration_date = System::now() + 10000;
    }
  }

  else if (is_waiting_for_regeneration()
      && System::now() >= regeneration_date
      && !overlaps(get_hero())) {
    get_sprite().set_current_animation("regenerating");
    is_regenerating = true;
    regeneration_date = 0;
    get_lua_context().destructible_on_regenerating(*this);
  }
  else if (is_regenerating && get_sprite().is_animation_finished()) {
    get_sprite().set_current_animation("on_ground");
    is_regenerating = false;
  }
}
Ejemplo n.º 5
0
/**
 * \brief Updates the chest.
 *
 * This function is called repeatedly by the map.
 * This is a redefinition of MapEntity::update()
 * the handle the chest opening.
 */
void Chest::update() {

  if (is_open() && !is_suspended()) {

    if (!treasure_given && treasure_date != 0 && System::now() >= treasure_date) {

      treasure_date = 0;
      treasure.ensure_obtainable();  // Make the chest empty if the treasure is not allowed.
      if (!treasure.is_empty()) {
        // Give a treasure to the player.

        get_hero().start_treasure(treasure, ScopedLuaRef());
        treasure_given = true;
      }
      else {  // The chest is empty.

        if (treasure.is_saved()) {
          // Mark the treasure as found in the savegame.
          get_savegame().set_boolean(treasure.get_savegame_variable(), true);
        }

        treasure_given = true;

        bool done = get_lua_context().chest_on_empty(*this);
        if (!done) {
          // The script does not define any behavior:
          // by default, do nothing and unfreeze the hero.
          get_hero().start_free();
        }
      }
    }
  }

  MapEntity::update();
}
Ejemplo n.º 6
0
/**
 * \brief Updates this state.
 */
void Hero::GrabbingState::update() {

  if (is_suspended()) {
    return;
  }

  // the hero is grabbing an obstacle: check the direction pressed

  int wanted_direction8 = get_commands().get_wanted_direction8();
  int sprite_direction8 = get_sprites().get_animation_direction8();

  // release the obstacle
  Hero& hero = get_hero();
  if (!get_commands().is_command_pressed(GameCommands::ACTION)) {
    hero.set_state(new FreeState(hero));
  }

  // push the obstacle
  else if (wanted_direction8 == sprite_direction8) {
    hero.set_state(new PushingState(hero));
  }

  // pull the obstacle
  else if (wanted_direction8 == (sprite_direction8 + 4) % 8) {
    hero.set_state(new PullingState(hero));
  }
}
Ejemplo n.º 7
0
/**
 * @brief Updates the entity.
 */
void Door::update() {

  Detector::update();

  if (!initialized) {
    update_dynamic_tiles();
    initialized = true;
  }

  if (is_closed()
      && get_opening_method() == OPENING_BY_EXPLOSION
      && get_equipment().has_ability("detect_weak_walls")
      && Geometry::get_distance(get_center_point(), get_hero().get_center_point()) < 40
      && !is_suspended()
      && System::now() >= next_hint_sound_date) {
    Sound::play("cane");
    next_hint_sound_date = System::now() + 500;
  }

  if (is_changing() && get_sprite().is_animation_finished()) {
    // Toggle door_open when the changing animation finishes.
    set_open(is_opening());
  }

  if (is_saved() && !is_changing()) {
    bool open_in_savegame = get_savegame().get_boolean(savegame_variable);
    if (open_in_savegame && is_closed()) {
      set_opening();
    }
    else if (!open_in_savegame && is_open()) {
      set_closing();
    }
  }
}
Ejemplo n.º 8
0
/*! Implements the <tt>resume</tt> shell command.
 *
 */
void mpxcmd_resume ( int argc, char *argv[] )
{
	pcb_t		*pcb;

	if ( argc != 2 ){
		printf("ERROR: Wrong number of arguments to resume.\n");
		return;
	}

	if ( strlen(argv[1]) > MAX_ARG_LEN || strlen(argv[1]) < 1 ){
		printf("ERROR: Invalid process name.\n");
		return;
	}

	pcb = find_pcb( argv[1] );
	if ( pcb == NULL ){
		printf("ERROR: Specified process does not exist.\n");
		return;
	}

	if ( ! is_suspended(pcb) ){
		printf("ERROR: Specified process is not suspended.\n");
		return;
	}

	/* Un-suspend PCB, checking for error return. */
	if ( ! resume_pcb(pcb) ){
		printf("ERROR: Unspecified error resuming process.");
		return;
	}

	/* Let the user know that the operation was successful. */
	printf("Success: Process '%s' is no longer suspended.\n", argv[1]);
}
Ejemplo n.º 9
0
/**
 * \brief Updates this state.
 */
void Hero::SwordLoadingState::update() {

  PlayerMovementState::update();

  if (is_suspended() || !is_current_state()) {
    return;
  }

  uint32_t now = System::now();

  // detect when the sword is loaded (i.e. ready for a spin attack)
  if (!sword_loaded && now >= sword_loaded_date) {
    play_load_sound();
    sword_loaded = true;
  }

  if (!get_commands().is_command_pressed(GameCommand::ATTACK)) {
    // the player has just released the sword key

    // stop loading the sword, go to the normal state or make a spin attack
    Hero& hero = get_entity();
    if (!sword_loaded) {
      // the sword was not loaded yet: go to the normal state
      hero.set_state(new FreeState(hero));
    }
    else {
      // the sword is loaded: release a spin attack
      hero.set_state(new SpinAttackState(hero));
    }
  }
}
Ejemplo n.º 10
0
Archivo: Game.cpp Proyecto: ziz/solarus
/**
 * @brief This function is called when a game key is released.
 * @param key a key
 */
void Game::key_released(GameControls::GameKey key) {

  if (!is_suspended()) {
    // if the game is not suspended, the keys apply to the hero
    hero->key_released(key);
  }
}
Ejemplo n.º 11
0
Archivo: Game.cpp Proyecto: ziz/solarus
/**
 * @brief This function is called when a game key is pressed.
 * @param key a key
 */
void Game::key_pressed(GameControls::GameKey key) {

  if (!is_suspended()) {    

    if (key == GameControls::PAUSE) {
      if (can_pause()) {
        set_paused(true);
      }
    }
    else {
      // when the game is not suspended, all other keys apply to the hero
      hero->key_pressed(key);
    }
  }

  // is a message being shown?
  else if (is_showing_message()) {
    dialog_box->key_pressed(key);
  }

  // is the game paused?
  else if (is_paused()) {
    pause_menu->key_pressed(key);
  }

  // is the game over sequence shown?
  else if (is_showing_gameover()) {
    gameover_sequence->key_pressed(key);
  }
}
Ejemplo n.º 12
0
/**
 * @brief This function is called by the engine when an entity overlaps the chest.
 *
 * This is a redefinition of Detector::notify_collision().
 * If the entity is the hero, and if he is facing north, we allow him to
 * open (or try to open) the chest.
 *
 * @param entity_overlapping the entity overlapping the detector
 * @param collision_mode the collision mode that detected the collision
 */
void Chest::notify_collision(MapEntity &entity_overlapping, CollisionMode collision_mode) {

  if (is_suspended() || !is_visible()) {
    return;
  }

  entity_overlapping.notify_collision_with_chest(*this);
}
Ejemplo n.º 13
0
/**
 * \brief Notifies this state that the game was just suspended or resumed.
 * \param suspended true if the game is suspended
 */
void Hero::SwimmingState::set_suspended(bool suspended) {

  PlayerMovementState::set_suspended(suspended);

  if (!is_suspended() && fast_swimming) {
    end_fast_swim_date += System::now() - get_when_suspended();
  }
}
Ejemplo n.º 14
0
void StraightMovement::set_next_move_date_y(uint32_t next_move_date_y) {
	if(is_suspended()) {
		uint32_t delay = next_move_date_y - System::now();
		this->next_move_date_y = get_when_suspended() + delay;
	} else {
		this->next_move_date_y = next_move_date_y;
	}
}
Ejemplo n.º 15
0
/**
 * @brief Initializes the enemy.
 */
void CustomEnemy::initialize() {

  if (script == NULL) {   // TODO when CustomEnemy is merged with Enemy, make this test in notify_enabled() instead
    script = new EnemyScript(*this);
    script->set_suspended(is_suspended());
    script->event_appear();
  }
}
Ejemplo n.º 16
0
/**
 * @brief Updates the movements: detects the collisions
 * in order to restart the movement.
 */
void PathMovement::update() {

  PixelMovement::update();

  if (!is_suspended() && is_current_elementary_move_finished()) {
    start_next_elementary_move();
  }
}
Ejemplo n.º 17
0
/**
 * \brief Updates the movements: detects the collisions
 * in order to restart the movement.
 */
void PathMovement::update() {

  if (!is_suspended() && is_current_elementary_move_finished()) {
    start_next_elementary_move();
  }

  // Do this at last so that Movement::update() knows whether we are finished.
  PixelMovement::update();
}
Ejemplo n.º 18
0
/**
 * \brief Updates the pickable item.
 *
 * This function is called repeatedly by the map.
 * This is a redefinition of Entity::update() to make
 * the item blink and then disappear after an amount of time.
 */
void Pickable::update() {

  // update the animations and the movement
  Detector::update();

  // update the shadow
  if (shadow_sprite != nullptr) {
    shadow_sprite->update();
  }

  shadow_xy.x = get_x();
  if (!is_falling()) {
    shadow_xy.y = get_y();
  }

  if (entity_followed != nullptr && entity_followed->is_being_removed()) {

    if (entity_followed->get_type() == EntityType::BOOMERANG ||
        entity_followed->get_type() == EntityType::HOOKSHOT) {
      // The pickable may have been dropped by the boomerang/hookshot
      // not exactly on the hero so let's fix this.
      if (get_distance(get_hero()) < 16) {
        try_give_item_to_player();
      }
    }
    entity_followed = nullptr;
  }

  check_bad_ground();

  if (!is_suspended()) {

    // check the timer
    uint32_t now = System::now();

    // wait 0.7 second before allowing the hero to take the item
    if (!can_be_picked && now >= allow_pick_date) {
      can_be_picked = true;
      falling_height = FALLING_NONE;
      get_hero().check_collision_with_detectors();
    }
    else {
      // make the item blink and then disappear
      if (will_disappear) {

        if (now >= blink_date && !get_sprite().is_blinking() && entity_followed == nullptr) {
          set_blinking(true);
        }

        if (now >= disappear_date) {
          remove_from_map();
        }
      }
    }
  }
}
Ejemplo n.º 19
0
/**
 * \brief Sets whether this timer should be suspended when the map is suspended.
 * \param suspended_with_map true to suspend this timer with the map.
 */
void Timer::set_suspended_with_map(bool suspended_with_map) {

  if (suspended_with_map != this->suspended_with_map) {
    this->suspended_with_map = suspended_with_map;

    if (is_suspended() && !suspended_with_map) {
      set_suspended(false);
    }
  }
}
Ejemplo n.º 20
0
/**
 * @brief Updates the movements: detects the collisions
 * in order to restart the movement.
 */
void RandomPathMovement::update() {

  PathMovement::update();

  if (!is_suspended() && PathMovement::is_finished()) {

    // there was a collision or the random path is finished: restart with a new random path
    set_path(create_random_path());
  }
}
Ejemplo n.º 21
0
/**
 * \copydoc MapEntity::update
 */
void CustomEntity::update() {

    Detector::update();
    update_ground_observer();

    if (is_suspended() || !is_enabled()) {
        return;
    }

    get_lua_context().entity_on_update(*this);
}
Ejemplo n.º 22
0
/**
 * @brief Updates the fairy movement.
 *
 * This function is called repeatedly by the map.
 * This is a redefinition of Movement::update()
 * to change the fairy's direction sometimes.
 */
void RandomMovement::update() {

    RectilinearMovement::update();

    if (!is_suspended()) {

        uint32_t now = System::now();
        if (now >= next_direction_change_date) {
            set_next_direction();
        }
    }
}
Ejemplo n.º 23
0
/**
 * \brief Updates this transition effect.
 *
 * This function is called repeatedly while the transition exists.
 */
void TransitionScrolling::update() {

  if (!is_started() || is_suspended()) {
    return;
  }

  uint32_t now = System::now();
  while (now >= next_scroll_date && !is_finished()) {
    scroll();
    next_scroll_date += 10;
  }
}
Ejemplo n.º 24
0
/**
 * \brief Updates this state.
 */
void Hero::FreeState::update() {

  PlayerMovementState::update();

  if (!is_suspended()
      && is_current_state()
      && pushing_direction4 != -1                                       // The hero is trying to push
      && get_wanted_movement_direction8() != pushing_direction4 * 2) {  // but his movement direction has changed.

    pushing_direction4 = -1; // stop trying to push
  }
}
Ejemplo n.º 25
0
/**
 * \brief Updates the movements: detects the collisions
 * in order to restart the movement.
 */
void PathMovement::update() {

  while (!is_suspended()
      && is_current_elementary_move_finished()
      && !PathMovement::is_finished()
      && get_entity() != NULL) {
    start_next_elementary_move();
    PixelMovement::update();
  }

  // Do this at last so that Movement::update() knows whether we are finished.
  PixelMovement::update();
}
Ejemplo n.º 26
0
void StraightMovement::update() {
	Movement::update();
	
	if(!is_suspended()) {
		uint32_t now = System::now();
		bool current_move_y = move_y != 0 && now >= next_move_date_y;
		bool current_move_x = move_x != 0 && now >= next_move_date_x;

		while(current_move_x || current_move_y) {
			// save current coordinates.
			Rectangle old_xy(get_x(), get_y());

			if(current_move_x) {	// time to move in x direction.
				if(current_move_y) {	// time to move in y direction.
					if(next_move_date_x <= next_move_date_y) {	//	we first move in x direction.
						update_x();
						if(now >= next_move_date_y) {
							update_y();
						}
					} else {
						update_y();								// we first move in y direciton.
						if(now >= next_move_date_x) {
							update_x();
						}
					}
				} else {	// we only move in x direction.
					update_x();
				}
			} else {	// we only move in y direction.
				update_y();
			}

			if(get_entity() != NULL && !finished) {
				// movement is successful old coordinates have changed.
				bool success = (get_x() != old_xy.get_x() || get_y() != old_xy.get_y()
					&& (move_x != 0 || move_y != 0));

				// no movement notify obstacle.
				if(!success) {
					notify_obstacle_reached();
					set_finished();
				}
			}

			// check if we continue wit movement.
			now = System::now();
			current_move_x = move_x != 0 && now >= next_move_date_x;
			current_move_y = move_y != 0 && now >= next_move_date_y;
		}
	}
}
Ejemplo n.º 27
0
/**
 * \brief Updates this state.
 */
void Hero::LiftingState::update() {

  State::update();

  lifted_item->update();

  if (!is_suspended() && !lifted_item->is_being_lifted()) { // the item has finished being lifted

    Hero& hero = get_hero();
    std::shared_ptr<CarriedItem> carried_item = lifted_item;
    lifted_item = nullptr; // we do not take care of the carried item from this state anymore
    hero.set_state(new CarryingState(hero, carried_item));
  }
}
Ejemplo n.º 28
0
/**
 * \brief Starts this state.
 * \param previous_state the previous state
 */
void Hero::VictoryState::start(const HeroState* previous_state) {

  HeroState::start(previous_state);

  get_sprites().set_animation_victory();
  get_sprites().set_ignore_suspend(true);
  Sound::play("victory");

  // compute the date when the victory state is considered as finished,
  // but the game may be currently suspended
  uint32_t start_victory_date = is_suspended() ?
      get_when_suspended() : System::now();
  end_victory_date = start_victory_date + 1500;
}
Ejemplo n.º 29
0
/**
 * \brief Updates this state.
 */
void Hero::LiftingState::update() {

  State::update();

  lifted_item->update();

  // See if the item has finished being lifted.
  Hero& hero = get_entity();
  const bool lift_finished = !lifted_item->is_being_lifted() || hero.is_animation_finished();
  if (!is_suspended() && lift_finished) {

    std::shared_ptr<CarriedItem> carried_item = lifted_item;
    lifted_item = nullptr; // we do not take care of the carried item from this state anymore
    hero.set_state(new CarryingState(hero, carried_item));
  }
}
Ejemplo n.º 30
0
/**
 * \brief Updates this transition effect.
 *
 * This function should be called repeatedly while the transition exists.
 */
void TransitionFade::update() {

  if (!is_started() || is_suspended()) {
    return;
  }

  uint32_t now = System::now();

  // update the transition effect if needed
  while (now >= next_frame_date && !finished) {
    alpha += alpha_increment;
    next_frame_date += delay; // 20 ms between two frame updates

    finished = (alpha == alpha_limit);
  }
}