Пример #1
0
HitResponse
BadGuy::collision_player(Player& player, const CollisionHit& )
{
  if (player.is_invincible()) {
    kill_fall();
    return ABORT_MOVE;
  }
  if(player.get_grabbed_object() != nullptr)
  {
      auto badguy = dynamic_cast<BadGuy*>(player.get_grabbed_object());
      if(badguy != nullptr)
      {
        player.get_grabbed_object()->ungrab(player, player.m_dir);
        player.stop_grabbing();
        badguy->kill_fall();
        kill_fall();
        return ABORT_MOVE;
      }
  }

  //TODO: unfreeze timer
  if (m_frozen)
    //unfreeze();
    return FORCE_MOVE;

  player.kill(false);
  return FORCE_MOVE;
}
Пример #2
0
bool
MrIceBlock::collision_squished(GameObject& object)
{
  Player* player = dynamic_cast<Player*>(&object);
  if(player && (player->does_buttjump || player->is_invincible())) {
    player->bounce(*this);
    kill_fall();
    return true;
  }

  switch(ice_state) {
    case ICESTATE_KICKED:
    {
      auto badguy = dynamic_cast<BadGuy*>(&object);
      if (badguy) {
        badguy->kill_fall();
        break;
      }
    }

    // fall through
    case ICESTATE_NORMAL:
    {
      squishcount++;
      if (squishcount >= MAXSQUISHES) {
        kill_fall();
        return true;
      }
    }

    set_state(ICESTATE_FLAT);
    nokick_timer.start(NOKICK_TIME);
    break;
    case ICESTATE_FLAT:
    case ICESTATE_WAKING:
    {
      auto movingobject = dynamic_cast<MovingObject*>(&object);
      if (movingobject && (movingobject->get_pos().x < get_pos().x)) {
        dir = RIGHT;
      } else {
        dir = LEFT;
      }
    }
    if (nokick_timer.check()) set_state(ICESTATE_KICKED);
    break;
    case ICESTATE_GRABBED:
      assert(false);
      break;
  }

  if (player) player->bounce(*this);
  return true;
}
Пример #3
0
bool
Snail::collision_squished(GameObject& object)
{
  if (m_frozen)
    return WalkingBadguy::collision_squished(object);

  Player* player = dynamic_cast<Player*>(&object);
  if (player && (player->m_does_buttjump || player->is_invincible())) {
    kill_fall();
    player->bounce(*this);
    return true;
  }

  switch (state) {

    case STATE_KICKED:
    case STATE_NORMAL:

      // Can't stomp in midair
      if (!on_ground())
        break;

      squishcount++;
      if (squishcount >= MAX_SNAIL_SQUISHES) {
        kill_fall();
        return true;
      }
      SoundManager::current()->play("sounds/stomp.wav", get_pos());
      be_flat();
      break;

    case STATE_FLAT:
      SoundManager::current()->play("sounds/kick.wav", get_pos());
      {
        MovingObject* movingobject = dynamic_cast<MovingObject*>(&object);
        if (movingobject && (movingobject->get_pos().x < get_pos().x)) {
          m_dir = Direction::RIGHT;
        } else {
          m_dir = Direction::LEFT;
        }
      }
      be_kicked();
      break;
    case STATE_GRABBED:
    case STATE_KICKED_DELAY:
      break;

  }

  if (player) player->bounce(*this);
  return true;
}
Пример #4
0
void
LiveFire::freeze()
{
  // attempting to freeze a flame causes it to go out
  death_sound = "sounds/sizzle.ogg";
  kill_fall();
}
Пример #5
0
bool
Haywire::collision_squished(GameObject& object)
{
  Player* player = dynamic_cast<Player*>(&object);
  if (player && player->is_invincible()) {
    player->bounce (*this);
    kill_fall();
    return true;
  }

  if (is_stunned) {
    player->bounce (*this);
    return true;
  }

  if (!is_exploding) {
    set_action ((dir == LEFT) ? "ticking-left" : "ticking-right", /* loops = */ -1);
    walk_left_action = "ticking-left";
    walk_right_action = "ticking-right";
    set_walk_speed (160);
    time_until_explosion = TIME_EXPLOSION;
    is_exploding = true;
  }

  time_stunned = TIME_STUNNED;
  is_stunned = true;

  player->bounce (*this);
  return true;
}
Пример #6
0
bool
MrBomb::collision_squished(GameObject& object)
{
  auto player = dynamic_cast<Player*>(&object);
  if(player && player->is_invincible()) {
    player->bounce(*this);
    kill_fall();
    return true;
  }
  if(is_valid()) {
    auto bomb = std::make_shared<Bomb>(get_pos(), dir, sprite_name);

    // Do not trigger dispenser because we need to wait for
    // the bomb instance to explode.
    if(this->get_parent_dispenser() != NULL)
    {
      bomb->set_parent_dispenser(this->get_parent_dispenser());
      this->set_parent_dispenser(NULL);
    }
    remove_me();
    Sector::current()->add_object(bomb);
  }
  kill_squished(object);
  return true;
}
Пример #7
0
void
BadGuy::collision_tile(uint32_t tile_attributes)
{
  // Don't kill badguys that have already been killed
  if (!is_active()) return;

  if (tile_attributes & Tile::WATER && !is_in_water())
  {
    m_in_water = true;
    SoundManager::current()->play("sounds/splash.ogg", get_pos());
  }
  if (!(tile_attributes & Tile::WATER) && is_in_water())
  {
    m_in_water = false;
  }

  if (tile_attributes & Tile::HURTS && is_hurtable()) {
    if (tile_attributes & Tile::FIRE) {
      if (is_flammable()) ignite();
    }
    else if (tile_attributes & Tile::ICE) {
      if (is_freezable()) freeze();
    }
    else {
      kill_fall();
    }
  }
}
Пример #8
0
bool
GoldBomb::collision_squished(GameObject& object)
{
  Player* player = dynamic_cast<Player*>(&object);
  if(player && player->is_invincible()) {
    player->bounce(*this);
    kill_fall();
    return true;
  }
  if(is_valid() && tstate == STATE_NORMAL) {
    tstate = STATE_TICKING;
    frozen = false;
    set_action(dir == LEFT ? "ticking-left" : "ticking-right", 1);
    physic.set_velocity_x(0);

    if (player)
      player->bounce(*this);

    ticking = SoundManager::current()->create_sound_source("sounds/fizz.wav");
    ticking->set_position(get_pos());
    ticking->set_looping(true);
    ticking->set_gain(2.0);
    ticking->set_reference_distance(32);
    ticking->play();
  }
  return true;
}
Пример #9
0
bool
MrBomb::collision_squished(GameObject& object)
{
  auto player = dynamic_cast<Player*>(&object);
  if (player && player->is_invincible()) {
    player->bounce(*this);
    kill_fall();
    return true;
  }
  if (is_valid()) {
    auto& bomb = Sector::get().add<Bomb>(get_pos(), m_dir, m_sprite_name);

    // Do not trigger dispenser because we need to wait for
    // the bomb instance to explode.
    if (get_parent_dispenser() != nullptr)
    {
      bomb.set_parent_dispenser(get_parent_dispenser());
      set_parent_dispenser(nullptr);
    }

    remove_me();
  }
  kill_squished(object);
  return true;
}
Пример #10
0
bool
Haywire::collision_squished(GameObject& object)
{
  auto player = dynamic_cast<Player*>(&object);
  if (player && player->is_invincible()) {
    player->bounce (*this);
    kill_fall();
    return true;
  }

  if (is_stunned) {
    if (player)
      player->bounce (*this);
    return true;
  }

  if(WalkingBadguy::is_frozen()) {
    WalkingBadguy::unfreeze();
  }

  if (!is_exploding) {
    start_exploding();
  }

  time_stunned = TIME_STUNNED;
  is_stunned = true;
  physic.set_velocity_x(0.f);
  physic.set_acceleration_x(0.f);

  if (player)
    player->bounce (*this);

  return true;
}
Пример #11
0
bool
MrIceBlock::collision_squished(GameObject& object)
{
  switch(ice_state) {
    case ICESTATE_KICKED:
    case ICESTATE_NORMAL:
      squishcount++;
      if(squishcount >= MAXSQUISHES) {
        kill_fall();
        return true;
      }

      set_state(ICESTATE_FLAT);
      nokick_timer.start(NOKICK_TIME);
      break;
    case ICESTATE_FLAT:
      {
	MovingObject* movingobject = dynamic_cast<MovingObject*>(&object);
	if (movingobject && (movingobject->get_pos().x < get_pos().x)) {
	  dir = RIGHT;
	} else {
	  dir = LEFT;
	}
      }
      if (nokick_timer.check()) set_state(ICESTATE_KICKED);
      break;
    case ICESTATE_GRABBED:
      assert(false);
      break;
  }

  Player* player = dynamic_cast<Player*>(&object);
  if (player) player->bounce(*this);
  return true;
}
Пример #12
0
bool
MrRocket::collision_squished(GameObject& object)
{
    sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
    kill_squished(object);
    kill_fall();
    return true;
}
Пример #13
0
bool
Zeekling::collision_squished(Player& player)
{
    sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
    kill_squished(player);
    kill_fall();
    return true;
}
Пример #14
0
HitResponse
BadGuy::collision_player(Player& player, const CollisionHit& )
{
  if(player.is_invincible()) {
    kill_fall();
    return ABORT_MOVE;
  }

  if(frozen)
    unfreeze();
  player.kill(false);
  return FORCE_MOVE;
}
Пример #15
0
bool
Haywire::collision_squished(GameObject& object)
{
  Player* player = dynamic_cast<Player*>(&object);
  if (player && player->is_invincible()) {
    player->bounce (*this);
    kill_fall();
    return true;
  }

  if (is_stunned) {
    if (player)
      player->bounce (*this);
    return true;
  }

  if(WalkingBadguy::is_frozen()) {
    WalkingBadguy::unfreeze();
  }

  if (!is_exploding) {
    set_action ((dir == LEFT) ? "ticking-left" : "ticking-right", /* loops = */ -1);
    walk_left_action = "ticking-left";
    walk_right_action = "ticking-right";
    set_walk_speed (160);
    time_until_explosion = TIME_EXPLOSION;
    is_exploding = true;

    ticking = SoundManager::current()->create_sound_source("sounds/fizz.wav");
    ticking->set_position(get_pos());
    ticking->set_looping(true);
    ticking->set_reference_distance(32);
    ticking->play();
    grunting = SoundManager::current()->create_sound_source("sounds/grunts.ogg");
    grunting->set_position(get_pos());
    grunting->set_looping(true);
    grunting->set_reference_distance(32);
    grunting->play();
  }

  time_stunned = TIME_STUNNED;
  is_stunned = true;
  physic.set_velocity_x (0.0);
  physic.set_acceleration_x (0.0);

  if (player)
    player->bounce (*this);

  return true;
}
Пример #16
0
void
MrIceBlock::collision_solid(const CollisionHit& hit)
{
  update_on_ground_flag(hit);

  if(hit.top || hit.bottom) { // floor or roof
    physic.set_velocity_y(0);
    return;
  }

  // hit left or right
  switch(ice_state) {
    case ICESTATE_NORMAL:
      WalkingBadguy::collision_solid(hit);
      break;
    case ICESTATE_KICKED: {
      if(hit.right && dir == RIGHT) {
        dir = LEFT;
        sound_manager->play("sounds/iceblock_bump.wav", get_pos());
        if(++squishcount >= MAXSQUISHES) { kill_fall(); break; }
        physic.set_velocity_x(-KICKSPEED);
      } else if(hit.left && dir == LEFT) {
        dir = RIGHT;
        sound_manager->play("sounds/iceblock_bump.wav", get_pos());
        if(++squishcount >= MAXSQUISHES) { kill_fall(); break; }
        physic.set_velocity_x(KICKSPEED);
      }
      sprite->set_action(dir == LEFT ? "flat-left" : "flat-right");
      break;
    }
    case ICESTATE_FLAT:
      physic.set_velocity_x(0);
      break;
    case ICESTATE_GRABBED:
      break;
  }
}
Пример #17
0
HitResponse
BadGuy::collision(GameObject& other, const CollisionHit& hit)
{
  if (!is_active()) return ABORT_MOVE;

  auto badguy = dynamic_cast<BadGuy*> (&other);
  if (badguy && badguy->is_active() && badguy->m_col.get_group() == COLGROUP_MOVING) {

    /* Badguys don't let badguys squish other badguys. It's bad. */
#if 0
    // hit from above?
    if (badguy->get_bbox().get_bottom() < (bbox.get_top() + 16)) {
      if (collision_squished(*badguy)) {
        return ABORT_MOVE;
      }
    }
#endif

    return collision_badguy(*badguy, hit);
  }

  auto player = dynamic_cast<Player*> (&other);
  if (player) {

    // hit from above?
    if (player->get_bbox().get_bottom() < (m_col.m_bbox.get_top() + 16)) {
      if (player->is_stone()) {
        kill_fall();
        return FORCE_MOVE;
      }
      if (collision_squished(*player)) {
        return FORCE_MOVE;
      }
    }

    if (player->is_stone()) {
      collision_solid(hit);
      return FORCE_MOVE;
    }

    return collision_player(*player, hit);
  }

  auto bullet = dynamic_cast<Bullet*> (&other);
  if (bullet)
    return collision_bullet(*bullet, hit);

  return FORCE_MOVE;
}
Пример #18
0
bool
Owl::collision_squished(GameObject&)
{
  auto player = Sector::current()->get_nearest_player (bbox);
  if (player)
    player->bounce (*this);

  if (carried_object != NULL) {
    carried_object->ungrab (*this, dir);
    carried_object = NULL;
  }

  kill_fall ();
  return true;
}
Пример #19
0
bool
BadGuy::collision_squished(GameObject& object)
{
  // frozen badguys can be killed with butt-jump
  if (m_frozen)
  {
    auto player = dynamic_cast<Player*>(&object);
    if (player && (player->m_does_buttjump)) {
      player->bounce(*this);
      kill_fall();
      return true;
    }
  }
    return false;
}
Пример #20
0
void
BadGuy::collision_tile(uint32_t tile_attributes)
{
  if(tile_attributes & Tile::HURTS) {
    if (tile_attributes & Tile::FIRE) {
      if (is_flammable()) ignite();
    }
    else if (tile_attributes & Tile::ICE) {
      if (is_freezable()) freeze();
    }
    else {
      kill_fall();
    }
  }
}
Пример #21
0
bool
MrBomb::collision_squished(GameObject& object)
{
  auto player = dynamic_cast<Player*>(&object);
  if(player && player->is_invincible()) {
    player->bounce(*this);
    kill_fall();
    return true;
  }
  if(is_valid()) {
    remove_me();
    Sector::current()->add_object(std::make_shared<Bomb>(get_pos(), dir, sprite_name));
  }
  kill_squished(object);
  return true;
}
Пример #22
0
void
BadGuy::ignite()
{
  if (!is_flammable() || m_ignited) {
    return;
  }

  m_physic.enable_gravity(true);
  m_physic.set_velocity_x(0);
  m_physic.set_velocity_y(0);
  set_group(COLGROUP_MOVING_ONLY_STATIC);
  m_sprite->stop_animation();
  m_ignited = true;

  if (m_sprite->has_action("melting-left")) {

    // melt it!
    if (m_sprite->has_action("ground-melting-left") && on_ground()) {
      m_sprite->set_action(m_dir == Direction::LEFT ? "ground-melting-left" : "ground-melting-right", 1);
      SoundManager::current()->play("sounds/splash.ogg", get_pos());
      set_state(STATE_GROUND_MELTING);
    } else {
      m_sprite->set_action(m_dir == Direction::LEFT ? "melting-left" : "melting-right", 1);
      SoundManager::current()->play("sounds/sizzle.ogg", get_pos());
      set_state(STATE_MELTING);
    }

    run_dead_script();

  } else if (m_sprite->has_action("burning-left")) {
    // burn it!
    m_glowing = true;
    SoundManager::current()->play("sounds/fire.ogg", get_pos());
    m_sprite->set_action(m_dir == Direction::LEFT ? "burning-left" : "burning-right", 1);
    set_state(STATE_BURNING);
    run_dead_script();
  } else if (m_sprite->has_action("inside-melting-left")) {
    // melt it inside!
    SoundManager::current()->play("sounds/splash.ogg", get_pos());
    m_sprite->set_action(m_dir == Direction::LEFT ? "inside-melting-left" : "inside-melting-right", 1);
    set_state(STATE_INSIDE_MELTING);
    run_dead_script();
  } else {
    // Let it fall off the screen then.
    kill_fall();
  }
}
Пример #23
0
HitResponse
HurtingPlatform::collision(GameObject& other, const CollisionHit& )
{
  auto player = dynamic_cast<Player*>(&other);
  if (player) {
    if (player->is_invincible()) {
      return ABORT_MOVE;
    }
    player->kill(false);
  }
  auto badguy = dynamic_cast<BadGuy*>(&other);
  if (badguy) {
    badguy->kill_fall();
  }

  return FORCE_MOVE;
}
Пример #24
0
void
GoldBomb::active_update(float elapsed_time)
{
  if(tstate == STATE_TICKING) {
    ticking->set_position(get_pos());
    if(sprite->animation_done()) {
      kill_fall();
    }
    else if (!grabbed) {
      movement = physic.get_movement(elapsed_time);
    }
    return;
  }
  if(grabbed)
    return;
  WalkingBadguy::active_update(elapsed_time);
}
Пример #25
0
void
BadGuy::collision_tile(uint32_t tile_attributes)
{
  // Don't kill badguys that have already been killed
  if (!is_active()) return;

  if(tile_attributes & Tile::HURTS) {
    if (tile_attributes & Tile::FIRE) {
      if (is_flammable()) ignite();
    }
    else if (tile_attributes & Tile::ICE) {
      if (is_freezable()) freeze();
    }
    else {
      kill_fall();
    }
  }
}
Пример #26
0
HitResponse
Explosion::collision(GameObject& other, const CollisionHit& )
{
  if ((state != STATE_EXPLODING) || !hurt)
    return ABORT_MOVE;

  auto player = dynamic_cast<Player*>(&other);
  if(player != nullptr) {
    player->kill(false);
  }

  auto badguy = dynamic_cast<BadGuy*>(&other);
  if(badguy != nullptr) {
    badguy->kill_fall();
  }

  return ABORT_MOVE;
}
Пример #27
0
void
Haywire::active_update(float elapsed_time)
{
  if (is_exploding) {
    ticking->set_position(get_pos());
    grunting->set_position(get_pos());
    if (elapsed_time >= time_until_explosion) {
      kill_fall ();
      return;
    }
    else
      time_until_explosion -= elapsed_time;
  }

  if (is_stunned) {
    if (time_stunned > elapsed_time) {
      time_stunned -= elapsed_time;
      return;
    }
    else { /* if (time_stunned <= elapsed_time) */
      elapsed_time -= time_stunned;
      time_stunned = 0.0;
      is_stunned = false;
    }
  }

  if (is_exploding) {
    Player *p = this->get_nearest_player ();
    float target_velocity = 0.0;

    if (p) {
      /* Player is on the right */
      if (p->get_pos ().x > this->get_pos ().x)
        target_velocity = walk_speed;
      else /* player in on the left */
        target_velocity = (-1.0) * walk_speed;
    } /* if (player) */

    WalkingBadguy::active_update(elapsed_time, target_velocity);
  }
  else {
    WalkingBadguy::active_update(elapsed_time);
  }
}
Пример #28
0
HitResponse
Block::collision(GameObject& other, const CollisionHit& )
{
  auto player = dynamic_cast<Player*> (&other);
  if(player) {
    if(player->get_bbox().get_top() > bbox.get_bottom() - SHIFT_DELTA) {
      hit(*player);
    }
  }

  // only interact with other objects if...
  //   1) we are bouncing
  //   2) the object is not portable (either never or not currently)
  //   3) the object is being hit from below (baguys don't get killed for activating boxes)
  auto portable = dynamic_cast<Portable*> (&other);
  auto moving_object = dynamic_cast<MovingObject*> (&other);
  auto bomb = dynamic_cast<Bomb*> (&other);
  bool is_portable = ((portable != 0) && portable->is_portable());
  bool is_bomb = (bomb != 0); // bombs need to explode, although they are considered portable
  bool hit_mo_from_below = ((moving_object == 0) || (moving_object->get_bbox().get_bottom() < (bbox.get_top() + SHIFT_DELTA)));
  if(bouncing && (!is_portable || is_bomb) && hit_mo_from_below) {

    // Badguys get killed
    auto badguy = dynamic_cast<BadGuy*> (&other);
    if(badguy) {
      badguy->kill_fall();
    }

    // Coins get collected
    auto coin = dynamic_cast<Coin*> (&other);
    if(coin) {
      coin->collect();
    }

    //Eggs get jumped
    auto growup = dynamic_cast<GrowUp*> (&other);
    if(growup) {
      growup->do_jump();
    }

  }

  return FORCE_MOVE;
}
Пример #29
0
bool
SnowSnail::collision_squished(Player& player)
{
  switch(ice_state) {
    case ICESTATE_KICKED:
    case ICESTATE_NORMAL:
      squishcount++;
      if(squishcount >= MAXSQUISHES) {
        kill_fall();
        return true;
      }

      // flatten
      sound_manager->play("sounds/stomp.wav", get_pos());
      physic.set_velocity_x(0);
      physic.set_velocity_y(0); 
      
      sprite->set_action(dir == LEFT ? "flat-left" : "flat-right");
      sprite->set_fps(64);
      flat_timer.start(4);
      ice_state = ICESTATE_FLAT;
      break;
    case ICESTATE_FLAT:
      // kick
      sound_manager->play("sounds/kick.wav", get_pos());

      if(player.get_pos().x < get_pos().x) {
        dir = RIGHT;
      } else {
        dir = LEFT;
      }
      physic.set_velocity_x(dir == LEFT ? -KICKSPEED : KICKSPEED);
      sprite->set_action(dir == LEFT ? "flat-left" : "flat-right");
      sprite->set_fps(64);
      ice_state = ICESTATE_KICKED;
      break;
  }

  player.bounce(*this);
  return true;
}
Пример #30
0
void
WalkingBadguy::turn_around()
{
  if(frozen)
    return;
  dir = dir == LEFT ? RIGHT : LEFT;
  if (get_state() == STATE_INIT || get_state() == STATE_INACTIVE || get_state() == STATE_ACTIVE) {
    sprite->set_action(dir == LEFT ? walk_left_action : walk_right_action);
  }
  physic.set_velocity_x(-physic.get_velocity_x());
  physic.set_acceleration_x (-physic.get_acceleration_x ());

  // if we get dizzy, we fall off the screen
  if (turn_around_timer.started()) {
    if (turn_around_counter++ > 10) kill_fall();
  } else {
    turn_around_timer.start(1);
    turn_around_counter = 0;
  }

}