爬塔流程设计

爬塔流程设计

武将初始buff

  • 只在爬塔模式生效;
  • 客户端在选将页面显示的武将信息,需要根据配置将buff描述加上;

战令至尊特权

特权1:爬塔体力每日刷新值增加

  • 玩家达到特定的战令至尊等级,在爬塔体力每日刷新时,可在刷新值的基础上再增加相应值;
  • 服务端处理,无需额外交互;客户端根据需要提示特权内容即可;

特权2:爬塔可复活次数

  • 玩家达到特定的战令至尊等级,在爬塔对局失败后,可复活;
  • 一轮中可复活多次,一局中可复活多次,直至次数使用完毕;
  • 对局中死亡,如果可复活则直接复活;
  • 如果没有该至尊特权,死亡时需要提示玩家,是否激活特权;

特权3:专属事件

  • 玩家达到特定的战令至尊等级可操作该事件;
  • 客户端需要根据配置的extremelv字段和战令数据来进行显示处理;

特权4:专属选项

  • 玩家达到特定的战令至尊等级可选择某一选项;
  • 事件选项:客户端需要根据配置的extremelv字段和战令数据来进行显示处理;
  • 升级和奖励选择通知:客户端需要协议中的extremelv字段和战令数据来进行显示处理;

特权5:商店专属商品

  • 根据配置推送专属商品;
  • 专属商品除了只有达到战令至尊可购买,其他没有区别;
  • 客户端需要协议中的extremelv字段和战令数据来进行显示处理;

特权6:专属武将

  • 选将时根据配置推送专属武将;
  • 客户端需要协议中的extremelv字段和战令数据来进行显示处理;

交互协议

  • 修改点查看【3.0】标识

选将通知

  • RoguelikeChrData新增拥有标识
struct RoguelikeChrData
{
    enum emHave
    {
        unusable = 0,  // 不可用
        had = 1, // 拥有(客户端检查正常还是使用)
        free = 2, // 免费
        extreme = 3,  // 战令至尊特权使用 【3.0】
        extreme_lock = 4, // 战令至尊特权锁定不可用【3.0】
    };

    unsigned int chrId;   // 武将id
    unsigned int have;  // 是否拥有武将 emHave
    unsigned int chrStar; // 星级
    unsigned int maxSkinGrade; // 武将的最高皮肤品级
    unsigned int coin; // 初始金币
    unsigned int cardInit; // 初始手牌数
    int cardLimit; // 手牌上限增量值
    unsigned int hpInit; // 初始血量
    unsigned int hpLimit; // 血量上限
    unsigned int sqkUse; // 手气卡每局可使用次数
    unsigned int spellExCnt; // 技能槽数据
    unsigned int param[2];  // 备用
};

ABROAD_ROGUELIKE_SELECT_CHR_NTF = 48549
struct ClientRoguelikeSelectChrNtf : public PacketBase
{
    const static unsigned int sc_max_difficulty_num = 10;
    const static unsigned int sc_max_chr_num = 30;

    unsigned int openCount;
    unsigned int difficultyOpen[sc_max_difficulty_num];   // 开放的困难等级
    unsigned int chrCount;
    RoguelikeChrData chrs[sc_max_chr_num];  // 可选武将列表 【3.0】

    ClientRoguelikeSelectChrNtf() :PacketBase(ABROAD_ROGUELIKE_SELECT_CHR_NTF, sizeof(ClientRoguelikeSelectChrNtf))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientRoguelikeSelectChrNtf));
    }

    friend bostream& operator<<(bostream& bos, const ClientRoguelikeSelectChrNtf& t)
    {
        bos << t.openCount;
        for (unsigned int i = 0; i < t.openCount; i++)
        {
            bos << t.difficultyOpen[i];
            if (i >= ClientRoguelikeSelectChrNtf::sc_max_difficulty_num) break;
        }
        bos << t.chrCount;
        for (unsigned int i = 0; i < t.chrCount; i++)
        {
            bos << t.chrs[i].chrId << t.chrs[i].have << t.chrs[i].chrStar << t.chrs[i].maxSkinGrade << t.chrs[i].coin << t.chrs[i].cardInit
                << t.chrs[i].cardLimit << t.chrs[i].hpInit << t.chrs[i].hpLimit << t.chrs[i].sqkUse << t.chrs[i].spellExCnt
                << t.chrs[i].param[0] << t.chrs[i].param[1];
            if (i >= ClientRoguelikeSelectChrNtf::sc_max_chr_num) break;
        }
        return bos;
    }
};

选择侍灵通知

  • ServantItemData新增觉醒字段 bWake
struct ServantItemData
{
    unsigned int servantId;
    unsigned int level; // 等级
    unsigned int flag;  // 拥有标记,0:永久,大于0表示试用结束日期20210706
    bool bWake; // 是否觉醒 【3.0】
    unsigned int param[2];  // 备用
};

ABROAD_ROGUELIKE_SERVENT_LIST_REP=48551
struct ClientRoguelikeServantListRep : public PacketBase
{
    const static unsigned int sc_max_servant_num = 30;

    unsigned int opType;
    unsigned int chrId;
    unsigned int fightServant;
    unsigned int count;
    ServantItemData servants[sc_max_servant_num];

    ClientRoguelikeServantListRep() :PacketBase(ABROAD_ROGUELIKE_SERVENT_LIST_REP, sizeof(ClientRoguelikeServantListRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientRoguelikeServantListRep));
    }
};

获取武将数据

  • 添加了剩余复活次数字段 reliveCount;
ABROAD_ROGUELIKE_CHR_DATA_REP = 48509,
struct ClientRoguelikeChrDataRep : public PacketBase
{
    enum emResult
    {
        ok = 0,
        failed = 1,
        not_start = 2,  // 未开始
        not_select = 3, // 没有选将
        data_error = 4, // 数据异常,收到该错误请返回模式准备界面
    };

    unsigned int result;
    unsigned int chrId;  // 武将id
    unsigned int skinId; // 武将皮肤
    bool         isDynamic;  // 是否是动态皮肤
    unsigned int skinMaxGrade;  // 武将皮肤拥有的最高品级
    unsigned int chrStar;  // 武将星级
    unsigned int coinNum;  // 金币数
    unsigned int spellNum; // 技能槽数目(额外获得的+武将自带的)
    unsigned int difficulty; // 困难度
    unsigned int playerLevel; // 等级
    unsigned int playerExp; // 当前经验值
    unsigned int playerUpExp; // 升级的经验值 playerExp > playerUpExp表示可升级
    unsigned int initCardNum; // 手牌初始数目
    int limitCardNum; // 手牌上限增量值
    unsigned int initHpNum; // 初始体力
    unsigned int limitHpNum; // 体力上限
    unsigned int useSQKNum; // 可使用手气卡次数
    unsigned int score;  // 积分
    unsigned int reliveCount;  // 还可以复活几次 【3.0】

    ClientRoguelikeChrDataRep() :PacketBase(ABROAD_ROGUELIKE_CHR_DATA_REP, sizeof(ClientRoguelikeChrDataRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientRoguelikeChrDataRep));
    }
};

升级和奖励选择通知

  • EffectItemData 添加了extremeLv字段;
  • 回复结果添加了新错误码;
struct EffectItemData
{
    // 类型,emRoguelikeEffectType
    unsigned int type;

    // 参数值
    // 一般只有value[0]有效
    // type=Effect_Hp,  value[0]为增加上限(需支持负值,至多到0);value[1]为体力,可不配,不配默认和value[0]一致,不可大于value[0]值
    // type=Effect_Spell/Effect_Buff/Effect_Card/Effect_Equip,  value[0]为指定技能id(可不配),value[1]为取特定组随机,配了0就不用管1了
    int value[3];

    unsigned int extremeLv;  // 需要达到的战令至尊等级 【3.0】
};

ABROAD_ROGUELIKE_LEVEL_UP_REP = 48517
struct ClientRoguelikeLevelUpRep : public PacketBase
{
    static const unsigned int sc_effect_max_num = 10;

    unsigned int oldLevel;  // 原等级
    unsigned int newLevel;  // 升级到的等级
    unsigned int mustCnt; // 升级必得的奖励
    EffectItemData mustEffect[sc_effect_max_num];  //【3.0】
    unsigned int randomGetNum; // 升级可选择的奖励的个数
    unsigned int randomCnt; // 升级可选择的奖励
    EffectItemData randomEffect[sc_effect_max_num];  // 【3.0】

    ClientRoguelikeLevelUpRep() :PacketBase(ABROAD_ROGUELIKE_LEVEL_UP_REP, sizeof(ClientRoguelikeLevelUpRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientRoguelikeLevelUpRep));
    }

    friend bostream& operator<<(bostream& bos, const ClientRoguelikeLevelUpRep& t)
    {
        bos << t.oldLevel << t.newLevel << t.mustCnt;
        for (unsigned int i = 0; i < t.mustCnt; i++)
        {
            bos << t.mustEffect[i].type << t.mustEffect[i].value[0] << t.mustEffect[i].value[1] << t.mustEffect[i].value[2] << t.mustEffect[i].extremeLv;
            if (i >= sc_effect_max_num) break;
        }
        bos << t.randomGetNum << t.randomCnt;
        for (unsigned int i = 0; i < t.randomCnt; i++)
        {
            bos << t.randomEffect[i].type << t.randomEffect[i].value[0] << t.randomEffect[i].value[1] << t.randomEffect[i].value[2] << t.randomEffect[i].extremeLv;
            if (i >= sc_effect_max_num) break;
        }
        return bos;
    }
};

ABROAD_ROGUELIKE_LEVEL_UP_SELECT_REP = 48519
struct ClientRoguelikeLevelUpSelectRep : public PacketBase
{
    enum emResult
    {
        ok = 0,
        failed = 1,
        up_already = 2, // 已升级到该等级
        tolevel_invalid = 3,  // 升级的等级不对
        count_invalid = 4, // 选择的随机奖励数目不对
        select_invalid = 5, // 选择的随机奖励不对
        data_error = 6, // 数据异常,收到该错误请返回模式准备界面
        option_extreme_lock = 7,  // 未达到战令至尊等级,选项未解锁 【3.0】
    };

    unsigned int result;  
    unsigned int toLevel;  // 升级到的等级

    ClientRoguelikeLevelUpSelectRep() :PacketBase(ABROAD_ROGUELIKE_LEVEL_UP_SELECT_REP, sizeof(ClientRoguelikeLevelUpSelectRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientRoguelikeLevelUpSelectRep));
    }
};

ABROAD_ROGUELIKE_EFFECT_SELECT_NTF = 48539
struct ClientRoguelikeEffectSelectNtf : public PacketBase
{
    static const unsigned int sc_effect_max_num = 10;

    unsigned int chapterNo;  
    unsigned int eventNo; 
    unsigned int optionId; 
    unsigned int mustCnt;
    EffectItemData mustEffect[sc_effect_max_num];  // 【3.0】
    unsigned int randomGetNum;  // 等于0不需要做选择请求
    unsigned int randomCnt; 
    EffectItemData randomEffect[sc_effect_max_num];  // 【3.0】

    ClientRoguelikeEffectSelectNtf() :PacketBase(ABROAD_ROGUELIKE_EFFECT_SELECT_NTF, sizeof(ClientRoguelikeEffectSelectNtf))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientRoguelikeEffectSelectNtf));
    }

    friend bostream& operator<<(bostream& bos, const ClientRoguelikeEffectSelectNtf& t)
    {
        bos << t.chapterNo << t.eventNo << t.optionId << t.mustCnt;
        for (unsigned int i = 0; i < t.mustCnt; i++)
        {
            bos << t.mustEffect[i].type << t.mustEffect[i].value[0] << t.mustEffect[i].value[1] << t.mustEffect[i].value[2] << t.mustEffect[i].extremeLv;
            if (i >= sc_effect_max_num) break;
        }
        bos << t.randomGetNum << t.randomCnt;
        for (unsigned int i = 0; i < t.randomCnt; i++)
        {
            bos << t.randomEffect[i].type << t.randomEffect[i].value[0] << t.randomEffect[i].value[1] << t.randomEffect[i].value[2] << t.randomEffect[i].extremeLv;
            if (i >= sc_effect_max_num) break;
        }
        return bos;
    }
};

ABROAD_ROGUELIKE_EFFECT_SELECT_REP = 48541
struct ClientRoguelikeEffectSelectRep : public PacketBase
{
    enum emResult
    {
        ok = 0,
        failed = 1,
        data_error = 2,
        event_invalid = 3,
        event_not_find = 4,
        select_invalid = 5,
        option_extreme_lock = 6,  // 未达到战令至尊等级,选项未解锁 【3.0】
    };

    unsigned int result;
    unsigned int chapterNo;
    unsigned int eventNo;
    unsigned int optionId;
    ClientRoguelikeEffectSelectRep() :PacketBase(ABROAD_ROGUELIKE_EFFECT_SELECT_REP, sizeof(ClientRoguelikeEffectSelectRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientRoguelikeEffectSelectRep));
    }
};

获取商城数据

  • 商品信息添加extremeLv字段;
ABROAD_ROGUELIKE_SHOP_DATA_REP = 48528
struct ClientRoguelikeShopDataRep : public PacketBase
{
    static const unsigned int sc_max_shoptab_num = 4;
    static const unsigned int sc_max_shopitem_num = 10;

    enum emResult
    {
        ok = 0,
        failed = 1,
        not_start = 2, // 未开始
        eventno_invalid = 3,
        data_error = 4, // 数据异常,收到该错误请返回模式准备界面
    };

    struct ShopItem
    {
        unsigned int id;
        unsigned int price;
        unsigned int extremeLv; // 该商品需要达到指定的战令至尊等级才可以购买,0表示不限制 【3.0】
    };

    struct ShopTab
    {
        unsigned int tab;   // 分页类型
        unsigned int buyCnt; // 购买次数
        unsigned int premium; // 单次购买溢价
        bool buffValid;  // 免溢价buff是否生效
        unsigned int count; // 商品数目
        ShopItem items[sc_max_shopitem_num]; // 商品信息
    };

    unsigned int result;
    unsigned int chapterNo;  // 当前第几个章节
    unsigned int eventNo; // 第几个事件
    unsigned int eventId; 
    unsigned int tabCount;  // 有几个分页
    ShopTab tabs[sc_max_shoptab_num]; // 分页数据

    ClientRoguelikeShopDataRep() :PacketBase(ABROAD_ROGUELIKE_SHOP_DATA_REP, sizeof(ClientRoguelikeShopDataRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientRoguelikeShopDataRep));
    }

    friend bostream& operator<<(bostream& bos, const ClientRoguelikeShopDataRep& t)
    {
        bos << t.result << t.chapterNo << t.eventNo << t.eventId << t.tabCount;
        for (unsigned int i = 0; i < t.tabCount; i++)
        {
            bos << t.tabs[i].tab << t.tabs[i].buyCnt << t.tabs[i].premium << t.tabs[i].buffValid << t.tabs[i].count;
            auto &item = t.tabs[i].items;
            for (unsigned int k = 0; k < t.tabs[i].count; k++)
            {
                bos << item[k].id << item[k].price << item[k].extremeLv;
                if (k >= sc_max_shopitem_num) break;
            }
            if (i >= sc_max_shoptab_num) break;
        }
        return bos;
    }
};

事件操作

  • 结果新增错误码
ABROAD_ROGUELIKE_EVENT_OP_REP = 48523
struct ClientRoguelikeEventOpRep : public PacketBase
{
    enum emResult
    {
        ok = 0,
        failed = 1,
        event_invalid = 2, // 事件非法
        event_not_find = 3, // 事件找不到
        select_invlid = 4,  // 选择非法
        fight_data_get_failed = 5, // 战斗数据获取失败
        chapter_over = 6, // 本章节已结束
        data_error = 7, // 数据异常,收到该错误请返回模式准备界面
        no_spell_pos_fill = 8, // 无法选择技能,没有额外技能槽
        qa_select_err = 9, // 回答错误
        event_extreme_lock = 10,  // 未达到战令至尊等级,事件未解锁 【3.0】
        option_extreme_lock = 11,  // 未达到战令至尊等级,选项未解锁【3.0】
    };

    unsigned int result;  
    unsigned int chapterNo;
    unsigned int eventNo;
    unsigned int eventId;
    unsigned int eventType;
    unsigned int opType;
    unsigned int select;

    ClientRoguelikeEventOpRep() :PacketBase(ABROAD_ROGUELIKE_EVENT_OP_REP, sizeof(ClientRoguelikeEventOpRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientRoguelikeEventOpRep));
    }
};

商品购买

  • 结果新增错误码
ABROAD_ROGUELIKE_SHOP_BUY_REP = 48525
struct ClientRoguelikeShopBuyRep : public PacketBase
{
    enum emResult
    {
        ok = 0,
        failed = 1,
        event_invalid = 2, // 事件非法
        event_not_find = 3, // 事件找不到
        tab_invalid = 4, // 分页非法
        buyid_not_find = 5, // 物品找不到
        coin_not_enough = 6, // 金币不够
        chapter_over = 7,  // 本章节已结束
        data_error = 8, // 数据异常,收到该错误请返回模式准备界面
        no_spell_pos_fill = 9, // 无法选择技能,没有额外技能槽
        had_already = 10, // 已拥有
        option_extreme_lock = 11,  // 未达到战令至尊等级,选项未解锁 【3.0】
    };

    unsigned int result;
    unsigned int chapterNo;
    unsigned int eventNo;
    unsigned int tab;
    unsigned int buyId;

    ClientRoguelikeShopBuyRep() :PacketBase(ABROAD_ROGUELIKE_SHOP_BUY_REP, sizeof(ClientRoguelikeShopBuyRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientRoguelikeShopBuyRep));
    }
};

获取boss数据

  • 结果新增错误码
ABROAD_ROGUELIKE_BOSS_DATA_REP = 48530
struct ClientRoguelikeBossDataRep : public PacketBase
{
    static const unsigned int sc_max_player_count = 8;

    enum emResult
    {
        ok = 0,
        failed = 1,
        event_invalid = 2, 
        data_error = 3, // 数据异常,收到该错误请返回模式准备界面
        not_in_roguelike_game = 4, // 不在爬塔游戏对局中
        seat_not_boss = 5, // 该位置不是boss
        event_extreme_lock = 6,  // 未达到战令至尊等级,事件未解锁 【3.0】
    };

    unsigned int result;
    bool inGame;
    unsigned int seatId;
    unsigned int chapterNo;
    unsigned int eventNo;
    unsigned int eventId;
    unsigned int optionId;
    unsigned int count;
    RoguelikePlayerData player[sc_max_player_count];

    ClientRoguelikeBossDataRep() :PacketBase(ABROAD_ROGUELIKE_BOSS_DATA_REP, sizeof(ClientRoguelikeBossDataRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientRoguelikeBossDataRep));
    }

    friend bostream& operator<<(bostream& bos, const ClientRoguelikeBossDataRep& t)
    {
        bos << t.result << t.inGame << t.seatId << t.chapterNo << t.eventNo << t.eventId << t.optionId << t.count;
        for (unsigned int i = 0; i < t.count; i++)
        {
            bos << t.player[i].playerType << t.player[i].chrId << t.player[i].chrStar << t.player[i].sqkUse << t.player[i].level << t.player[i].seatid
                << t.player[i].figure << t.player[i].initCardNum << t.player[i].limitCardNum << t.player[i].initHpNum << t.player[i].limitHpNum
                << t.player[i].buffCount;
            for (unsigned int x = 0; x < t.player[i].buffCount; x++)
            {
                bos << t.player[i].buffIds[x];
                if (x >= ClientRoguelikeSpellDataRep::sc_max_spell_num) break;
            }
            bos << t.player[i].cardCount;
            for (unsigned int x = 0; x < t.player[i].cardCount; x++)
            {
                bos << t.player[i].cardIds[x];
                if (x >= ClientRoguelikeSpellDataRep::sc_max_spell_num) break;
            }
            bos << t.player[i].spellCount;
            for (unsigned int x = 0; x < t.player[i].spellCount; x++)
            {
                bos << t.player[i].spellIds[x];
                if (x >= ClientRoguelikeSpellDataRep::sc_max_spell_num) break;
            }
            bos << t.player[i].equipCount;
            for (unsigned int x = 0; x < t.player[i].equipCount; x++)
            {
                bos << t.player[i].equipIds[x];
                if (x >= ClientRoguelikeSpellDataRep::sc_max_spell_num) break;
            }
            if (i >= sc_max_player_count) break;
        }
        return bos;
    }
};

爬塔结果通知

  • 新增爬塔总结数据;
ABROAD_ROGUELIKE_RESULT_NTF = 48532
struct ClientRoguelikeResultNtf : public PacketBase
{
    static const unsigned int sc_max_enemy_count = 8;
    static const unsigned int sc_max_reward_count = 20;

    struct RewardGood
    {
        unsigned int goodsId;
        unsigned int goodsCount;
    };

    unsigned int season;
    unsigned int times;  // 第几次闯关【3.0】
    unsigned int difficulty;  // 困难度【3.0】
    bool isWin;
    unsigned int score;  // 本轮计算积分【3.0】
    unsigned int coinCost;  // 本轮消耗金币【3.0】
    unsigned int equipPrice;  // 本轮装备价值【3.0】
    unsigned int fightCount;   // 本轮对局数【3.0】
    unsigned int fightTm;   // 本轮所有对局总时长【3.0】
    unsigned int roundTm;   // 本轮闯关时长【3.0】
    unsigned int overEventId;  // 最后一个事件id【3.0】
    unsigned int count;  // 奖励数目
    RewardGood reward[sc_max_reward_count];  // 奖励

    ClientRoguelikeResultNtf() :PacketBase(ABROAD_ROGUELIKE_RESULT_NTF, sizeof(ClientRoguelikeResultNtf))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientRoguelikeResultNtf));
    }

    friend bostream& operator<<(bostream& bos, const ClientRoguelikeResultNtf& t)
    {
        bos << t.season << t.times << t.difficulty << t.isWin << t.score << t.coinCost << t.equipPrice << t.fightCount
            << t.fightTm << t.roundTm << t.overEventId << t.count;
        for (unsigned int i = 0; i < t.count; i++)
        {
            bos << t.reward[i].goodsId << t.reward[i].goodsCount;
            if (i >= sc_max_reward_count) break;
        }
        return bos;
    }
};

获取问答事件数据

  • 结果新增错误码
ABROAD_ROGUELIKE_QA_EVENT_REP = 48543
struct ClientRoguelikeQaEventRep : public PacketBase
{
    enum emResult
    {
        ok = 0,
        failed = 1,
        data_error = 2,
        event_invalid = 3,
        event_not_find = 4,
        event_extreme_lock = 5,  // 未达到战令至尊等级,事件未解锁 【3.0】
    };
    unsigned int result;
    unsigned int chapterNo;
    unsigned int eventNo;
    unsigned int eventId;
    unsigned int qaId;  // 题库id
    unsigned int excludeIdx;  // buff 排除的错误答案序号
    unsigned int randoms[4]; // 答案序号1234的随机排序  
    ClientRoguelikeQaEventRep() :PacketBase(ABROAD_ROGUELIKE_QA_EVENT_REP, sizeof(ClientRoguelikeQaEventRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientRoguelikeQaEventRep));
    }
};

复活操作通知

  • 【3.0】 新增
  • 爬塔对局中,如果挑战者死亡,则进行复活判定:
  • (1)有复活次数可使用,则直接使用并复活;
  • (2)没有复活次数但可以通过激活至尊等级以获取复活次数,则通知玩家去激活(客户端根据battlePassLv和自己的战令等级以及配置计算如何激活),游戏暂停(倒计时80s);
  • (3)1和2以上都不满足,则直接判定死亡,对局结束
ABROAD_ROGUELIKE_RELIVE_OP_NTF=48555
struct ClientRoguelikeReliveOpNtf : public PacketBase
{
    enum emOpType
    {
        Relive_Info = 0,  // 信息通知
        Relive_Ask,  // 询问是否激活至尊等级以获取复活次数
        Relive_Use, // 使用复活次数
    };
    unsigned int opType;
    unsigned int reliveCount = 0;            // 可复活次数
    unsigned int battlePassLv = 0;           // 战令至尊等级, reliveCount=0且battlePassLv>0时,表示可以激活战令至尊来获得复活次数
    unsigned int opTime = 0;                 // ask等待时间 秒

    ClientRoguelikeReliveOpNtf() : PacketBase(ABROAD_ROGUELIKE_RELIVE_OP_NTF, sizeof(ClientRoguelikeReliveOpNtf))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientRoguelikeReliveOpNtf));
    }
};

放弃复活

  • 【3.0】 新增
  • 客户端收到服务端询问是否进行复活操作时,选择放弃或者获取复活次数失败需要主动通知服务端,以恢复游戏对局流程;
ABROAD_ROGUELIKE_RELIVE_CANCEL=48556
struct ClientRoguelikeReliveCancel : public PacketBase
{
    ClientRoguelikeReliveCancel() : PacketBase(ABROAD_ROGUELIKE_RELIVE_CANCEL, sizeof(ClientRoguelikeReliveCancel))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientRoguelikeReliveCancel));
    }
};

技能触发通知与选择

  • 【3.0】 新增
  • 目前只有一个司道触发,通知客户端选一张牌
  • 注意:司道只在爬塔对局外触发一次,且只在选择的武将带有这个技能时才触发,其他途径获取的司道不会触发;在爬塔对局内不触发,在其他模式对局内正常触发;
// 通知
ABROAD_ROGUELIKE_SPELL_TRIGGER_NTF=48557
struct ClientRoguelikeSpellTriggerNtf : public PacketBase
{
    static const unsigned int sc_param_max_num = 20;

    enum emOpType
    {
        ntf_trigger = 0,           // 通知技能触发
        ntf_select_card = 1,       // 通知选择卡牌
    };

    unsigned int opType;   // 操作类型
    unsigned int spellId;  // 触发的技能id
    bool isBuff;  // 是否是buff
    unsigned int selectCount;  // 选择几个
    unsigned int count;  // 选项数目
    unsigned int param[sc_param_max_num];

    ClientRoguelikeSpellTriggerNtf() :PacketBase(ABROAD_ROGUELIKE_SPELL_TRIGGER_NTF, sizeof(ClientRoguelikeSpellTriggerNtf))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientRoguelikeSpellTriggerNtf));
    }
};

// 选择
ABROAD_ROGUELIKE_SPELL_TRIGGER_OP_REQ=48558
struct ClientRoguelikeSpellTriggerOpReq : public PacketBase
{
    static const unsigned int sc_param_max_num = 20;

    unsigned int opType;
    unsigned int spellId;
    unsigned int count;
    unsigned int param[sc_param_max_num];

    ClientRoguelikeSpellTriggerOpReq() :PacketBase(ABROAD_ROGUELIKE_SPELL_TRIGGER_OP_REQ, sizeof(ClientRoguelikeSpellTriggerOpReq))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientRoguelikeSpellTriggerOpReq));
    }
};

ABROAD_ROGUELIKE_SPELL_TRIGGER_OP_REP=48559
struct ClientRoguelikeSpellTriggerOpRep : public PacketBase
{
    enum enResult
    {
        ok = 0,
        fail,
        data_error,
        no_card_config,
        card_exist,
    };

    unsigned int result;
    unsigned int opType;
    unsigned int spellId;

    ClientRoguelikeSpellTriggerOpRep() :PacketBase(ABROAD_ROGUELIKE_SPELL_TRIGGER_OP_REP, sizeof(ClientRoguelikeSpellTriggerOpRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientRoguelikeSpellTriggerOpRep));
    }
};