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; }
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; }
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; }
void LiveFire::freeze() { // attempting to freeze a flame causes it to go out death_sound = "sounds/sizzle.ogg"; kill_fall(); }
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; }
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; }
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(); } } }
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; }
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; }
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; }
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; }
bool MrRocket::collision_squished(GameObject& object) { sprite->set_action(dir == LEFT ? "squished-left" : "squished-right"); kill_squished(object); kill_fall(); return true; }
bool Zeekling::collision_squished(Player& player) { sprite->set_action(dir == LEFT ? "squished-left" : "squished-right"); kill_squished(player); kill_fall(); return true; }
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; }
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; }
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; } }
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; }
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; }
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; }
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(); } } }
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; }
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(); } }
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; }
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); }
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(); } } }
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; }
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); } }
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; }
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; }
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; } }