爬塔流程设计

爬塔流程设置处理

点将和换将功能

免费次数

  • 与其他模式共用点将和换将的免费次数

星级武将免费点将

点将

  • 点将的将池为爬塔将池;
  • 点将选择成功后,暂不消耗免费次数或道具;
  • 推送待选武将时,如果可以推出点将(点将生效),则消耗免费次数或道具或达到星级免费;
  • 点將选择成功且未推送,则保留点将结果;

换将

  • 是否可以换将判断条件:是否有未推送的且玩家拥有的武将;
  • 一个位置的武将栏只可以换一次将;
  • 换将成功后,消耗免费次数或道具;

武将额外加成

  • 计算推送待选武将或换将时,会根据额外加成条件判断待选武将是否满足,如果满足则更具配置进行加成,否则依据武将配置,计算出武将的基础配置(血量、携带技能与buff);
  • 客户端在展示待选武将信息和战斗boss信息时,血量、携带技能与buff需要根据服务端通知的结果进行展示;【5.0】

协议交互

  • 查看【5.0】

获取爬塔模式数据

  • 添加已选择但未生效的点将信息
ABROAD_ROGUELIKE_MODE_DATA_REP = 48501
struct ClientRoguelikeModeDataRep : public PacketBase
{
    enum emResult
    {
        ok = 0,
        failed = 1,
        not_open = 2, // 活动未开
        data_error = 3, // 数据异常,收到该错误请返回模式准备界面
    };

    unsigned int result;
    unsigned int season;  // 赛季id
    unsigned int power;    // 体力值
    bool hasStart;     // 是否有未完成的章节,是否有继续征程
    bool roundWaitComplete;     // 已有征程是否等待结算
    unsigned int dianJiang;  // 已选择的点将,0表示没有 【5.0】

    ClientRoguelikeModeDataRep() :PacketBase(ABROAD_ROGUELIKE_MODE_DATA_REP, sizeof(ClientRoguelikeModeDataRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientRoguelikeModeDataRep));
    }
};

BOSS数据

  • 数据内容没有增减,但对playerType进行了细分,客户端根据这个进行展示
  • ABROAD_ROGUELIKE_BOSS_DATA_REP=48530 【5.0】
struct RoguelikePlayerData
{
    enum emPlayer 【5.0】
    {
        roguelike_self = 0,                // 玩家自己
        roguelike_enemy = 1,            // 敌方 
        roguelike_friend = 2,            // 队友
        roguelike_enemy_boss = 3,        // 敌方 boss
    };

    unsigned int playerType;  // 玩家类型, emPlayer
    unsigned int chrId;  // 武将id
    unsigned int chrStar;
    unsigned int sqkUse;
    unsigned int level;  // 等级
    unsigned int seatid;
    unsigned int figure;
    unsigned int initCardNum; // 手牌初始数目
    int limitCardNum; // 手牌上限增量值
    unsigned int initHpNum; // 初始体力
    unsigned int limitHpNum; // 体力上限
    unsigned int buffCount;
    unsigned int buffIds[ClientRoguelikeSpellDataRep::sc_max_spell_num];
    unsigned int cardCount;
    unsigned int cardIds[ClientRoguelikeSpellDataRep::sc_max_spell_num];
    unsigned int spellCount;
    unsigned int spellIds[ClientRoguelikeSpellDataRep::sc_max_spell_num];
    unsigned int equipCount;
    unsigned int equipIds[ClientRoguelikeSpellDataRep::sc_max_spell_num];
};

待选武将数据

  • 增减改动较大 【5.0】
  • 涉及协议 ABROAD_ROGUELIKE_SELECT_CHR_NTF=48549、ABROAD_ROGUELIKE_HUAN_JIANG_REP=48566,见下述

struct RoguelikeChrData
{
    const static unsigned int sc_max_spell_num = 20;

    enum emHave
    {
        unusable = 0,  // 不可用
        had = 1, // 拥有(客户端检查正常还是使用)
        free = 2, // 免费
        extreme = 3,  // 战令至尊特权使用
        extreme_lock = 4, // 战令至尊特权锁定不可用
        dian_jiang = 5,  // 点将,可用  【5.0】
    };

    unsigned int chrId;   // 武将id
    unsigned int have;  // 是否拥有武将 emHave
    unsigned int chrStar; // 星级
    unsigned int maxSkinGrade; // 武将的最高皮肤品级
    unsigned int hpInit; // 初始血量 【5.0】
    unsigned int hpLimit; // 血量上限 【5.0】
    bool         canReplace;    // 是否可换将 【5.0】
    unsigned int param[4];  // 备用 【5.0】
    unsigned int spellCnt; // 技能数目  【5.0】
    unsigned int spellIds[sc_max_spell_num];  // 【5.0】
    unsigned int buffCnt; // buff数目  【5.0】
    unsigned int buffIds[sc_max_spell_num];  // 【5.0】

    friend bostream& operator<<(bostream& bos, const RoguelikeChrData& t)
    {
        bos << t.chrId << t.have << t.chrStar << t.maxSkinGrade << t.hpInit << t.hpLimit << t.canReplace;
        for (unsigned int i = 0; i < 4; i++)
        {
            bos << t.param[i];
        }
        bos << t.spellCnt;
        for (unsigned int i = 0; i < t.spellCnt; i++)
        {
            bos << t.spellIds[i];
            if (i >= RoguelikeChrData::sc_max_spell_num) break;
        }
        bos << t.buffCnt;
        for (unsigned int i = 0; i < t.buffCnt; i++)
        {
            bos << t.buffIds[i];
            if (i >= RoguelikeChrData::sc_max_spell_num) break;
        }
        return bos;
    }
};

选将通知

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 param[4];  // 备用 【5.0】
    unsigned int openCount;
    unsigned int difficultyOpen[sc_max_difficulty_num];   // 开放的困难等级
    unsigned int chrCount;
    RoguelikeChrData chrs[sc_max_chr_num];  // 可选武将列表 【5.0】

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

    friend bostream& operator<<(bostream& bos, const ClientRoguelikeSelectChrNtf& t)
    {
        for (unsigned int i = 0; i < 4; i++)
        {
            bos << t.param[i];
        }
        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];
            if (i >= ClientRoguelikeSelectChrNtf::sc_max_chr_num) break;
        }
        return bos;
    }
};

点将

  • 新增协议 【5.0】
ABROAD_ROGUELIKE_DIAN_JIANG_REQ = 48563
struct ClientRoguelikeDianJiangReq : public PacketBase
{
    unsigned int chrId;  // 点将id  0表示取消点将
    unsigned int goodsId;  // 需要的道具id

    ClientRoguelikeDianJiangReq() :PacketBase(ABROAD_ROGUELIKE_DIAN_JIANG_REQ, sizeof(ClientRoguelikeDianJiangReq))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientRoguelikeDianJiangReq));
    }
};

ABROAD_ROGUELIKE_DIAN_JIANG_REP = 48564
struct ClientRoguelikeDianJiangRep : public PacketBase
{
    enum emType
    {
        dian_jiang_select = 0,    // 选择
        dian_jiang_effect = 1,  // 生效
    };

    enum enResult
    {
        ok = 0,
        failed = 1,
        data_error = 2,
        no_config = 3,
        failed_no_item = 4,  // 没有指定道具
        consume_goods_error = 5,  // 道具消耗失败
        chr_not_had = 6,  // 未拥有武将
        not_in_group = 7,  // 不在爬塔将池
    };
    unsigned int result;
    unsigned int type;
    unsigned int chrId;  // 点将id

    ClientRoguelikeDianJiangRep() :PacketBase(ABROAD_ROGUELIKE_DIAN_JIANG_REP, sizeof(ClientRoguelikeDianJiangRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientRoguelikeDianJiangReq));
    }
};

换将

  • 新增协议 【5.0】
ABROAD_ROGUELIKE_HUAN_JIANG_REQ = 48565
struct ClientRoguelikeHuanJiangReq : public PacketBase
{
    unsigned int chrId;    // 被换的武将id
    unsigned int goodsId;  // 需要的道具id

    ClientRoguelikeHuanJiangReq() :PacketBase(ABROAD_ROGUELIKE_HUAN_JIANG_REQ, sizeof(ClientRoguelikeHuanJiangReq))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientRoguelikeHuanJiangReq));
    }
};

ABROAD_ROGUELIKE_HUAN_JIANG_REP = 48566
struct ClientRoguelikeHuanJiangRep : public PacketBase
{
    enum enResult
    {
        ok = 0,
        failed = 1,
        data_error = 2,
        no_config = 3,
        failed_no_item = 4,  // 没有指定道具
        consume_goods_error = 5,  // 道具消耗失败
        no_chr_replace = 6,  // 没有武将可换了
        chr_not_find = 7,  // 没找到被替换的武将
    };
    unsigned int result;
    unsigned int chrId;    // 被换的武将id
    RoguelikeChrData replaceChr;

    ClientRoguelikeHuanJiangRep() :PacketBase(ABROAD_ROGUELIKE_HUAN_JIANG_REP, sizeof(ClientRoguelikeHuanJiangRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientRoguelikeHuanJiangRep));
    }

    friend bostream& operator<<(bostream& bos, const ClientRoguelikeHuanJiangRep& t)
    {
        bos << t.result << t.chrId << t.replaceChr;
        return bos;
    }
};

对局胜利条件展示通知与确认

  • 新增协议 【5.0】
  • 爬塔进入对局后,在发完额外开牌后,通知爬塔者展示对局胜利条件,玩家确认后再继续爬塔对局流程;
ABROAD_ROGUELIKE_GAME_WIN_CONDITION_NTF = 48567
struct ClientRoguelikeGameWinConditionNtf : public PacketBase
{
    unsigned int  gameModel;
    unsigned int  fightId;  // 关卡id
    unsigned int  leftSeconds;  // 剩余时间

    ClientRoguelikeGameWinConditionNtf() : PacketBase(ABROAD_ROGUELIKE_GAME_WIN_CONDITION_NTF, sizeof(ClientRoguelikeGameWinConditionNtf))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientRoguelikeGameWinConditionNtf));
    }
};

ABROAD_ROGUELIKE_GAME_WIN_CONDITION_SURE = 48568
struct ClientRoguelikeGameWinConditionSure : public PacketBase
{
    ClientRoguelikeGameWinConditionSure() : PacketBase(ABROAD_ROGUELIKE_GAME_WIN_CONDITION_SURE, sizeof(ClientRoguelikeGameWinConditionSure))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientRoguelikeGameWinConditionSure));
    }
};