Ejemplo n.º 1
0
Area* World::move(Player *player,
                  int clip_x, int clip_y, int clip_w, int clip_h)
{
    Area *result = 0;

    if (!player->is_morphing()) {
        result = player->get_warp();
    }

    player->move(m_map);

    int window_width = clip_w - clip_x;
    if (m_lock_x) {
        m_map->set_x(m_lock_x, window_width);
    }
    else {
        int map_x = player->get_x() - window_width / 2 + m_offset_x;
        if (map_x < 0) {
            map_x = 0;
        }
        m_map->set_x(map_x, window_width);
    }

    int window_height = clip_h - clip_y;
    if (m_lock_y) {
        m_map->set_y(m_lock_y, window_height);
    }
    else {
        int map_y = player->get_y() - window_height / 2 + m_offset_y;
        if (map_y < 0) {
            map_y = 0;
        }
        m_map->set_y(map_y, window_height);
    }

    std::vector<Object*> perished;

    for (std::list<Object*>::iterator it = m_objects.begin();
         it != m_objects.end();
         ++it) {
        Object *object = *it;

        if (object->get_visible(m_map, clip_x, clip_y, clip_w, clip_h)) {
            Object::Type object_type = object->get_type();

            // Handle area objects
            if (object_type == Object::TypeArea) {
                Area *area = (Area *) object;

                if (area->is_over(player)) {

                    if (area->is_locked()) {

                        // Check if the player has the key
                        Status *status = m_db->get_status();
                        Item *item = status->check_item(area->get_data());
                        if (item) {
                            if (area->unlock(this, item)) {
                                status->remove_item(item);
                            }
                        }
                    }
                    else {
                        area->move(m_map);

                        if (area->is_open()) {
                            result = area;
                        }
                    }
                }
            }

            // Handle monster object
            else if (object_type == Object::TypeMonster) {
                Monster *monster = (Monster *) object;

                monster->move(m_map);
                monster->set_reference(player->get_front(), player->get_y());
                if (player->check_collision(monster) ||
                    monster->attack_object(player)) {
                    if (!monster->get_invisible()) {
                        player->set_hit(monster, m_db->get_status());
                    }
                }
                if (player->attack_object(monster)) {
                    monster->set_hit(player, m_db->get_status());
                }
                if (monster->get_action() == Actor::HitPerished) {
                    perished.push_back(monster);
                }
            }

            // Handle item objects
            else if (object_type == Object::TypeItem) {
                Item *item = (Item *) object;

                item->move(m_map);

                // Check if player picked up item
                if (player->check_collision(item)) {
                    Status *status = m_db->get_status();
                    status->aquire_item(item);
                    item->aquire(this);
                    item->set_reused(true);
                    perished.push_back(item);
                }
            }

            // Handle collectable objects
            else if (object_type == Object::TypeCollectable) {
                Collectable *collectable = (Collectable *) object;

                collectable->move(m_map);

                // Check if player picked up the collectable
                if (player->check_collision(collectable)) {
                    Status *status = m_db->get_status();
                    status->aquire_collectable(collectable);
                    perished.push_back(collectable);
                }
            }

            // Handle curse objects
            else if (object_type == Object::TypeCurse) {
                Curse *curse = (Curse *) object;

                curse->move(m_map);
                if (player->check_collision(curse)) {
                    player->set_morph(new Morph("human_to_salamander.xml",
                                                m_media,
                                                player->get_x(),
                                                player->get_y(),
                                                player->get_dir()));
                    player->set_warp(new Area(curse));
                    perished.push_back(curse);
                }
            }

            // Handle chest objects
            else if (object_type == Object::TypeChest) {
                Chest *chest = (Chest *) object;
                if (chest->is_open(player)) {
                    Object *released_object = chest->release_object();
                    if (released_object) {
                        released_object->set_x(chest->get_x());
                        released_object->set_y(chest->get_y());
                        released_object->set_reference(player->get_front(),
                                                       player->get_y());
                        m_objects.push_back(released_object);
                    }
                }
            }
        }
    }

    // Remove all perished objects
    for (int i = 0; i < perished.size(); i++) {

        // If monster drop object
        if (perished[i]->get_type() == Object::TypeMonster) {
            Monster *monster = (Monster *) perished[i];
            Object *released_object = monster->release_object();
            if (released_object) {
                released_object->set_x(monster->get_x());
                released_object->set_y(monster->get_y());
                released_object->set_reference(player->get_front(),
                                               player->get_y());
                m_objects.push_back(released_object);
            }
        }
        m_objects.remove(perished[i]);

        if (!perished[i]->get_reused()) {
            delete perished[i];
        }
    }

    return result;
}