Ejemplo n.º 1
0
void FloorMapLayer::confirm_attack_impl(const npc_t& npc)
{
    auto life = get_tile_prop(npc.gid, "life").asInt();
    auto hun = get_tile_prop(npc.gid, "hun").asInt();
    auto gold = get_tile_prop(npc.gid, "gold").asInt();
    auto defence = get_tile_prop(npc.gid, "defence").asInt();
    auto attack = get_tile_prop(npc.gid, "attack").asInt();

    auto player_info = Player::GetInstance()->get_player_info();
    auto attack_damage = std::max(0, player_info.attack - defence);
    auto damage = std::max(0, attack - player_info.defence);
    if (attack_damage == 0 || (life + attack_damage - 1) / attack_damage * damage >= player_info.hp) // 只要攻击不够无论防御多高都打不过
    {
        auto dict = FileUtils::getInstance()->getValueMapFromFile("chinese.xml");
        auto text = dict["txt7_2"].asString();
        PromptDialog::show(text);
        stop_and_clear();
        return;
    }

    auto blood = (life + attack_damage - 1) / attack_damage * damage;

    auto target_pos = this->convertToNodeSpace(_info_panel->get_node_position_in_world(WarriorInfoPanel::hun));
    target_pos -= Vec2(26.0f, 0);
    pick_up_item_impl(npc, target_pos, [blood, gold, hun]() {
        PlayerDelegate::add_hp(-blood);
        PlayerDelegate::add_gold_hun(gold, hun);
    });

    auto end_pos = Vec2((npc.x + 0.5f) * 75.0f - 50.0f, (npc.y + 0.5f) * 75.0f - 50.0f);
    _warrior->move_to(end_pos, CC_CALLBACK_0(FloorMapLayer::step, this));
    _paths.erase(_paths.begin());
}
Ejemplo n.º 2
0
void FloorMapLayer::confirm_open(OKCancelDialog::RETURN_TYPE type, const npc_t& npc)
{
    if (type == OKCancelDialog::CANCEL)
    {
        stop_and_clear();
    }
    else
    {
        _warrior->stand_auto();
        auto npc_layer = _tiled_map->getLayer("npc");
        auto door = npc_layer->getTileAt(Vec2(npc.x, 11 - npc.y));
        npc_layer->setupTileSprite(door, Vec2(npc.x, 11 - npc.y), npc.gid);
        door->runAction(CCSequence::create(FadeOut::create(0.5f), RemoveSelf::create(),
            CCCallFunc::create(std::bind(&FloorMapLayer::confirm_open_impl, this, npc)), nullptr));

        // 如果是竖门需要将其上方的附加节点一并去除
        auto uplink = get_tile_prop(npc.gid, "uplink").asInt();
        if (1 == uplink)
        {
            auto npc_iter = find(_npcs.begin(), _npcs.end(), npc_t(npc.x, npc.y + 1, 0));
            if (npc_iter != _npcs.end())
            {
                const auto& npc_up = *npc_iter;
                auto door_up = npc_layer->getTileAt(Vec2(npc_up.x, 11 - npc_up.y));
                npc_layer->setupTileSprite(door_up, Vec2(npc_up.x, 11 - npc_up.y), npc_up.gid);
                door_up->runAction(CCSequence::create(FadeOut::create(0.5f), RemoveSelf::create(), nullptr));
            }
        }
    }
}
Ejemplo n.º 3
0
void FloorMapLayer::confirm_open(OKCancelDialog::RETURN_TYPE type, const Floor::npc_t& npc)
{
    if (type == OKCancelDialog::CANCEL)
    {
        stop_and_clear();
    }
    else
    {
        _warrior->stand_auto();
        _warrior->set_lock(true);   // 设置等待开门的过程中不可重新寻路,以免出现计算混乱
        auto npc_layer = _tiled_map->getLayer("npc");
        auto door = npc_layer->getTileAt(Vec2(npc.pos.x, 11 - npc.pos.y));
        npc_layer->setupTileSprite(door, Vec2(npc.pos.x, 11 - npc.pos.y), npc.gid);
        const float OPEN_DURATION = 0.5f;
        door->runAction(CCSequence::create(FadeOut::create(OPEN_DURATION), RemoveSelf::create(),
            CCCallFunc::create(std::bind(&FloorMapLayer::confirm_open_impl, this, npc)), nullptr));

        // 如果是竖门需要将其上方的附加节点一并去除
        auto uplink = get_tile_prop(npc.gid, "uplink").asInt();
        if (1 == uplink)
        {
            auto npc_up = Floor::GetInstance()->get_floor_info(_floor).find_npc_by_pos(Floor::position_t(npc.pos.x, npc.pos.y + 1));
            if (nullptr != npc_up)
            {
                auto door_up = npc_layer->getTileAt(Vec2(npc_up->pos.x, 11 - npc_up->pos.y));
                npc_layer->setupTileSprite(door_up, Vec2(npc_up->pos.x, 11 - npc_up->pos.y), npc_up->gid);
                door_up->runAction(CCSequence::create(FadeOut::create(OPEN_DURATION), RemoveSelf::create(), nullptr));
            }
        }
    }
}
Ejemplo n.º 4
0
void FloorMapLayer::step()
{
    if (_paths.empty())
    {
        return;
    }

    auto current_pos = _warrior->getPosition();
    auto start_pt = _paths[0];
    auto start_pos = Vec2((start_pt.x + 0.5f) * 75.0f - 50.0f, (start_pt.y + 0.5f) * 75.0f - 50.0f);

    // 勇士位置在开始位置正中心时触发拾取操作,如果还没到,代表未到触发时机,如果已走过,代表触发前取消当前操作并改变路径
    if (current_pos.equals(start_pos))
    {
        auto npc = Floor::GetInstance()->get_floor_info(_floor).find_npc_by_pos(start_pt);
        if (nullptr != npc)
            pick_up_item(*npc);
    }
    
    // 未走到路径末尾,继续处理下一步行走
    if (_paths.size() > 1)
    {
        auto end_pt = _paths[1];
        auto end_pos = Vec2((end_pt.x + 0.5f) * 75.0f - 50.0f, (end_pt.y + 0.5f) * 75.0f - 50.0f);

        // 如果需要额外走一段到瓦块中心,仅仅执行这段走路,仅在走到块间时重新改变行走路径时有效
        if (current_pos.distance(end_pos) > start_pos.distance(end_pos))
        {
            _warrior->move_to(start_pos, CC_CALLBACK_0(FloorMapLayer::step, this));
            return;
        }

        // 淡出脚下的路径标识
        auto road_children = _road_node->getChildren();
        auto child = dynamic_cast<Node*>(road_children.at(road_children.size() + 1 - _paths.size()));
        if (nullptr != child)
        {
            child->runAction(FadeOut::create(0.2f));
        }

        bool walk_pause = false;
        auto npc = Floor::GetInstance()->get_floor_info(_floor).find_npc_by_pos(end_pt);
        if (nullptr != npc)
            walk_pause = interact_item(*npc);
        
        if (!walk_pause)
        {
            _warrior->move_to(end_pos, CC_CALLBACK_0(FloorMapLayer::step, this));
            _paths.erase(_paths.begin());
        }
    }
    else // 走到寻路最后一个节点,清理工作
    {
        stop_and_clear();
    }
}
Ejemplo n.º 5
0
void FloorMapLayer::confirm_attack(OKCancelDialog::RETURN_TYPE type, const npc_t& npc)
{
    if (type == OKCancelDialog::CANCEL)
    {
        stop_and_clear();
    }
    else
    {
        static int attack_count = 3;
        attack_count = 3;
        _warrior->fight_auto(3, std::bind(&FloorMapLayer::confirm_attack_impl, this, npc));
    }
}
Ejemplo n.º 6
0
bool FloorMapLayer::interact_item(const npc_t& npc)
{
    bool walk_pause = false;
    auto style = get_tile_prop(npc.gid, "style").asInt();
    switch (style)
    {
    case 1: // 怪物
    {
        walk_pause = true;
        auto end_pos = Vec2((npc.x + 0.5f) * 75.0f - 50.0f, (npc.y + 0.5f) * 75.0f - 50.0f);
        _warrior->turn_to(end_pos);

        if (_paths.size() > 2) // 怪物为行走路径的最后一个节点,不提示对话框,直接开打
        {
            auto dict = FileUtils::getInstance()->getValueMapFromFile("chinese.xml");
            auto text = dict["isAttack"].asString();
            auto name = dict[get_tile_prop(npc.gid, "name").asString()].asString();
            auto info = text + " " + name;
            auto dialog = OKCancelDialog::create("", info);
            dialog->setCallback(std::bind(&FloorMapLayer::confirm_attack, this, std::placeholders::_1, npc));
            ModalDialogManager::GetInstance()->pushDialog(dialog);
        }
        else
        {
            assert(_paths.size() == 2); // 和npc交互时路径肯定还有至少两个节点,一个自己的,一个对方的
            if (_paths.size() == 2)
                confirm_attack(OKCancelDialog::OK, npc);
        }
    }
    break;
    case 3: // 门
        {
            walk_pause = true;
            auto end_pos = Vec2((npc.x + 0.5f) * 75.0f - 50.0f, (npc.y + 0.5f) * 75.0f - 50.0f);
            _warrior->turn_to(end_pos);

            auto color = get_tile_prop(npc.gid, "color").asInt();
            const auto& player = Player::GetInstance()->get_player_info();
            if (1 == color && player.key_red < 1 || 2 == color && player.key_blue < 1 || 3 == color && player.key_yellow < 1)
            {
                auto dict = FileUtils::getInstance()->getValueMapFromFile("chinese.xml");
                auto text = dict["buyKeyTip"].asString();
                PromptDialog::show(text);
                stop_and_clear();
                break;
            }

            auto dict = FileUtils::getInstance()->getValueMapFromFile("chinese.xml");
            auto prefix = dict["open_msg1"].asString();
            auto sufix = dict["open_msg2"].asString();
            auto textkey = 1 == color ? "rKey" : (2 == color ? "bKey" : "yKey");
            auto info = prefix + dict[textkey].asString() + sufix;
            auto dialog = OKCancelDialog::create("", info);
            dialog->setCallback(std::bind(&FloorMapLayer::confirm_open, this, std::placeholders::_1, npc));
            ModalDialogManager::GetInstance()->pushDialog(dialog);
        }
        break;
    case 6: // 楼梯
    {
        walk_pause = false; // 无需停下来,直接切换楼层,切换场景的持续时间的一半让勇士正好走入下一个楼梯格子
        auto next_scene = PromptLayer::scene(_floor == 1 ? 2 : 1);
        auto transition = TransitionFade::create(0.5f, next_scene);
        Director::getInstance()->replaceScene(transition);
    }
    break;
    default:
        break;
    }

    return walk_pause;
}