void GoalManager::update() { if (exit_time == 0) { World* world = server->get_world(); PinguHolder* pingus = world->get_pingus(); const PingusLevel& plf = server->get_plf(); if (pingus->get_number_of_allowed() == pingus->get_number_of_released() && pingus->get_number_of_alive() == 0) { goal = GT_NO_PINGUS_IN_WORLD; } else if (pingus->get_number_of_alive() == 0 && world->check_armageddon()) { goal = GT_ARMAGEDDON; } else if (plf.get_time() != -1 && plf.get_time() <= server->get_time()) { goal = GT_OUT_OF_TIME; } } }
void IceBlock::update() { if (is_finished) return; PinguHolder* holder = world->get_pingus(); for (PinguIter pingu = holder->begin(); pingu != holder->end(); ++pingu) { if ((*pingu)->get_x() > pos.x && (*pingu)->get_x() < pos.x + static_cast<float>(block_sur.get_width()) && (*pingu)->get_y() > pos.y - 4 && (*pingu)->get_y() < pos.y + static_cast<float>(block_sur.get_height())) { last_contact = world->get_time(); } } if (last_contact && last_contact + 1000 > world->get_time()) { //log_error("IceBlock: Catched Pingu: " << thickness); thickness -= 0.01f; if (thickness < 0) { is_finished = true; thickness = 0; world->remove(block_sur_cmap, static_cast<int>(pos.x), static_cast<int>(pos.y)); return; } } }
void Exit::update () { sprite.update(); PinguHolder* holder = world->get_pingus(); for (PinguIter pingu = holder->begin(); pingu != holder->end(); ++pingu) { // Make sure this particular exit is allowed for this pingu if ((*pingu)->get_owner() == owner_id) { // Now, make sure the pingu is within range if ( (*pingu)->get_pos().x > pos.x - 1 && (*pingu)->get_pos().x < pos.x + 1 && (*pingu)->get_pos().y > pos.y - 5 && (*pingu)->get_pos().y < pos.y + 5) { // Now, make sure the pingu isn't already exiting, gone, or dead if ( (*pingu)->get_status() != Pingu::PS_EXITED && (*pingu)->get_status() != Pingu::PS_DEAD && (*pingu)->get_action() != ActionName::EXITER) { // Pingu actually exits (*pingu)->set_action(ActionName::EXITER); } } } } }
void Smasher::update () { PinguHolder* holder = world->get_pingus(); for (PinguIter pingu = holder->begin (); pingu != holder->end (); ++pingu) catch_pingu(*pingu); if (smashing) { if (downwards) { if (count >= 5) { // SMASH!!! The thing hitten earth and kills the pingus downwards = false; --count; Sound::PingusSound::play_sound("sounds/tenton.wav", 0.7f); for(int i=0; i < 20; ++i) { world->get_smoke_particle_holder()-> add_particle(pos.x + 20 + float(rand() % 260), pos.y + 180, Math::frand()-0.5f, Math::frand()-0.5f); } for (PinguIter pingu = holder->begin (); pingu != holder->end (); ++pingu) { if ((*pingu)->is_inside(static_cast<int>(pos.x + 30), static_cast<int>(pos.y + 90), static_cast<int>(pos.x + 250), static_cast<int>(pos.y + 190))) { if ((*pingu)->get_action() != ActionName::SPLASHED) (*pingu)->set_action(ActionName::SPLASHED); } } } else { ++count; } } else { if (count <= 0) { count = 0; smashing = false; } else { --count; } } } }
void SmallMap::draw(DrawingContext& gc) { // FIXME: This is potentially dangerous, since we don't know how // long 'gc' will be alive. Should use a DrawingContext for caching. gc_ptr = &gc; World* const& world = server->get_world(); Vector2i of = playfield->get_pos(); Rect view_rect; if (world->get_width() > gc.get_width()) { int rwidth = int(gc.get_width() * rect.get_width() / world->get_width()); view_rect.left = rect.left + (of.x * rect.get_width() / world->get_width()) - rwidth/2; view_rect.right = view_rect.left + rwidth; } else { view_rect.left = rect.left; view_rect.right = rect.left + rect.get_width(); } if (world->get_height() > gc.get_height()) { int rheight = int(gc.get_height() * rect.get_height() / world->get_height()); view_rect.top = rect.top + (of.y * rect.get_height() / world->get_height()) - rheight/2; view_rect.bottom = view_rect.top + rheight; } else { view_rect.top = rect.top; view_rect.bottom = rect.top + rect.get_height(); } gc.draw(image->get_surface(), Vector2i(rect.left, rect.top)); gc.draw_rect(view_rect, Color(0, 255, 0)); server->get_world()->draw_smallmap(this); // Draw Pingus PinguHolder* pingus = world->get_pingus(); for(PinguIter i = pingus->begin(); i != pingus->end(); ++i) { int x = static_cast<int>(static_cast<float>(rect.left) + ((*i)->get_x() * static_cast<float>(rect.get_width()) / static_cast<float>(world->get_width()))); int y = static_cast<int>(static_cast<float>(rect.top) + ((*i)->get_y() * static_cast<float>(rect.get_height()) / static_cast<float>(world->get_height()))); gc.draw_line(Vector2i(x, y), Vector2i(x, y-2), Color(255, 255, 0)); } gc_ptr = 0; }
void Spike::update() { if (killing) surface.update(); PinguHolder* holder = world->get_pingus(); for (PinguIter pingu = holder->begin (); pingu != holder->end (); ++pingu) catch_pingu(*pingu); if (surface.get_current_frame() == surface.get_frame_count() - 1) killing = false; }
void Blocker::update() { if (!standing_on_ground()) { pingu->set_action(Actions::Faller); } else { // FIXME: PinguHolder iterations should be handled otherwise PinguHolder* pingus = WorldObj::get_world()->get_pingus(); for(PinguIter i = pingus->begin(); i != pingus->end(); ++i) { catch_pingu(*i); } } sprite.update(); }
void Teleporter::update () { sprite.update(); if (target) { PinguHolder* holder = world->get_pingus(); for (PinguIter pingu = holder->begin (); pingu != holder->end (); ++pingu) { if ( (*pingu)->get_x() > pos.x - 3 && (*pingu)->get_x() < pos.x + 3 && (*pingu)->get_y() > pos.y - 52 && (*pingu)->get_y() < pos.y) { (*pingu)->set_pos(target->get_pos().x, target->get_pos().y); target->teleporter_used(); sprite.restart(); } } } }
void ConveyorBelt::update () { left_sur.update(); middle_sur.update(); right_sur.update(); PinguHolder* holder = world->get_pingus(); for (PinguIter pingu = holder->begin(); pingu != holder->end(); ++pingu) { if ( (*pingu)->get_pos().x > pos.x && (*pingu)->get_pos().x < pos.x + 15 * static_cast<float>(width + 2) && (*pingu)->get_pos().y > pos.y - 2 && (*pingu)->get_pos().y < pos.y + 10) { Vector3f pos_ = (*pingu)->get_pos(); pos_.x -= speed * 0.025f; (*pingu)->set_pos(pos_); } } }
void Guillotine::update () { // Only have to check one sprite because they update simultaneously if (sprite_kill_left.is_finished()) killing = false; PinguHolder* holder = world->get_pingus(); for (PinguIter pingu = holder->begin (); pingu != holder->end (); ++pingu) catch_pingu(*pingu); if (killing) { // Update both sprites so they finish at the same time. sprite_kill_left.update(); sprite_kill_right.update(); // FIXME: Should be a different sound if (sprite_kill_left.get_current_frame() == 7) WorldObj::get_world()->play_sound("splash", pos); } else { sprite_idle.update(); } }