交互设计

侍灵交互设计

获取侍灵数据信息

  • 新增协议
ABROAD_SERVANT_DATA_REQ=48701
struct ClientServantDataReq : public PacketBase
{
    unsigned int servantId;  // 侍灵id,0表示请求所有侍灵信息

    ClientServantDataReq() :PacketBase(ABROAD_SERVANT_DATA_REQ, sizeof(ClientServantDataReq))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientServantDataReq));
    }
};

// 侍灵数据
struct ServantData
{
    unsigned int id;      // 侍灵id
    unsigned int level;   // 星级
    unsigned int curExp;  // 当前经验值 
    unsigned int nextLvExp;  // 下一星级需要的经验值
    unsigned int flag;    // 拥有标记,0:永久,大于0表示试用结束日期20210706
    BYTE         wakeUp;  // 是否觉醒 0/1 【2.0】
    BYTE         reserve[3]; // 保留字段 【2.0】
    unsigned int param; // 保留字段
};

ABROAD_SERVANT_DATA_REP=48702
struct ClientServantDataRep : public PacketBase
{
    static const unsigned int sc_max_servant_count = 100;

    enum emResult
    {
        ok = 0,
        not_had,
    };

    unsigned int result;
    unsigned int servantId;  // 查询的侍灵id
    unsigned int count;
    ServantData servants[sc_max_servant_count];
    ClientServantDataRep() :PacketBase(ABROAD_SERVANT_DATA_REP, sizeof(ClientServantDataRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientServantDataRep));
    }
};

获取侍灵内丹信息

  • 新增协议
  • 可以主动请求数据;在使用侍灵内丹道具后,服务端主动通知
ABROAD_SERVANT_DAN_INFO_REQ=48703
struct ClientServantDanInfoReq : public PacketBase
{
    unsigned int servantId;

    ClientServantDanInfoReq() : PacketBase(ABROAD_SERVANT_DAN_INFO_REQ, sizeof(ClientServantDanInfoReq))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientServantDanInfoReq));
    }
};

ABROAD_SERVANT_DAN_INFO_REP=48704
struct ClientServantDanInfoRep : public PacketBase
{
    unsigned int servantId;
    unsigned int remainCount;  // 今天还能使用的内丹数目
    ClientServantDanInfoRep() : PacketBase(ABROAD_SERVANT_DAN_INFO_REP, sizeof(ClientServantDanInfoRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientServantDanInfoRep));
    }
};

侍灵出战查询与设置

  • 新增协议
ABROAD_SERVANT_FIGHT_REQ=48705
struct ClientServantFightReq : public PacketBase
{
    bool isQuery;  // 是否是查询,不是查询就是设置出战侍灵
    unsigned int servantId;

    ClientServantFightReq() : PacketBase(ABROAD_SERVANT_FIGHT_REQ, sizeof(ClientServantFightReq))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientServantFightReq));
    }
};

ABROAD_SERVANT_FIGHT_REP=48706
struct ClientServantFightRep : public PacketBase
{
    enum emResult
    {
        ok = 0,
        not_had,   // 没有该侍灵
    };
    unsigned int result;
    unsigned int servantId;
    ClientServantFightRep() : PacketBase(ABROAD_SERVANT_FIGHT_REP, sizeof(ClientServantFightRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientServantFightRep));
    }
};

侍灵内丹使用结果

  • 新增协议
  • 使用侍灵内丹的结果通知
ABROAD_SERVANT_DAN_USE_RESULT=48707
struct ServantDanUseResult : public PacketBase
{
    enum
    {
        ok = 0,
        fail_config = 1,  // 配置错误
        fail_not_enough_goods = 2,  // 道具不足
        fail_gscore_overmax = 3,  // 已经是最大经验值
        fail_daily_limit = 4,  // 每日上限
        fail_not_have_servant = 5,  // 未拥有该侍灵
    };
    unsigned int result;
    unsigned int usedCount;
    unsigned int addValue;

    ServantDanUseResult() : PacketBase(ABROAD_SERVANT_DAN_USE_RESULT, sizeof(ServantDanUseResult))
    {
        PRO_ZERO_MEMORY(this, sizeof(ServantDanUseResult));
    }
};

侍灵升级

  • 使用道具(侍魂、内丹)升级侍灵;
  • 使用原有使用道具协议 CC_USER_USING_GOODS_REQ=20811;
  • 道具使用回包 CC_USER_USING_GOODS_REP=20812 的结果result添加3个返回码
    using_fail_servantscore_max=42,            // 侍灵满级
    using_fail_servantdan_no_enough_goods=43,  // 侍灵内丹数目不足
    using_fail_servantspirit_no_enough_goods=44,  // 侍魂不足
    

侍灵合成与分解

  • 侍灵是否可以合成与分解,根据道具配置决定;
  • 使用原有道具合成与分解协议
CLIENT_DBS_COMPOSE_DECOMPOSE_REQ=20844
struct Client_DBS_Compse_Decompose_Req : public PacketBase
{
    enum OPTYPE
    { 
        DO_COMPOSE = 0,    // 合成
        DO_DECOMPOSE,    // 分解单个
        DO_DECOMPOSEALL_SKIN,// 批量分解皮肤
        DO_DECOMPOSEALL_GENERAL, // 批量分解武将
        DO_DECOMPOSE_MULTI,// 分解多个相同道具  [新增]
    };

    unsigned char    optype;
    unsigned int    goodsbaseid;
    unsigned int    goodscount;            //批量分解时表示客户端预算出分解的朱砂数量

    Client_DBS_Compse_Decompose_Req( ) : PacketBase( CLIENT_DBS_COMPOSE_DECOMPOSE_REQ, sizeof(Client_DBS_Compse_Decompose_Req) )
    {
        optype = DO_COMPOSE;
        goodsbaseid = 0;
        goodscount = 0;
    }
};

DBS_CLIENT_COMPOSE_DECOMPOSE_REP=20845
struct DBS_Client_Compse_Decompose_Rep : public PacketBase
{
    enum ReturnFlag
    {
        SUCCEED = 0,
        FAILED_ERROPTYPE,        // 错误的操作类型
        FAILED_NOTSUPPORT,        // 此道具不能合成或者分解
        FAILED_NOTENOUGHGOODS,    // 分解,道具个数不足
        FAILED_NEEDPASSWD2,        // 需要2级密码
        FAILED_FULLWRAP,        // 包裹已满
        FAILED_REDUCE,            // 降级失败
        FAILED_LASTGENERAL,        // 拥有一个永久武将,不能分解也不能再次合成
        FAILED_ALREADYHAS,        // 已经拥有不允许合成
        FAILED_SKIN_EQUPED,
        FAILED_NO_DEPENDS_GOODS,
        FAILED_COUNT_ERROR,        // 批量分解时客户端与服务端计算朱砂数量不一致.
        FAILED_LAST_SERVANT,        // 拥有一个永久侍灵,不能分解也不能再次合成  [新增]
    };

    unsigned char    optype;
    unsigned char    flag;

    // 合成的时候,表示合成出来的道具
    // 分解的时候,表示分解出来的道具(不是分解掉的道具)
    unsigned int    goodsbaseid;
    unsigned int    goodscnt;

    DBS_Client_Compse_Decompose_Rep( ) : PacketBase( DBS_CLIENT_COMPOSE_DECOMPOSE_REP, sizeof(DBS_Client_Compse_Decompose_Rep) )
    {
        optype    = Client_DBS_Compse_Decompose_Req::DO_COMPOSE;
        flag    = SUCCEED;

        goodsbaseid = 0;
        goodscnt    = 0;
    }
};

获取玩家基础&详细信息

  • 原协议添加侍灵相关字段
struct BaseInfoPatch2
{
    //3.6.4
    unsigned long long user_id;
    //3.6.6b
    char    civi_score; //文明分
    unsigned char    privacy;
    //1.3.0
    unsigned int cardfaceid; // 牌背

    //1.4.7
    unsigned int servantId;  // 出战侍灵
    unsigned int servantLv;  // 出战侍灵等级
    unsigned int servantWake;  // 出战侍灵是否觉醒 0/1  【2.0】
    unsigned int params[3];  // 保留字段 【2.0】
};

CLIENT_USERBASEINFO_REP=21405
struct ClientUserBaseInfoRep_Mobile : public PacketBase

    unsigned int                    nickname_usertempid;                   //这个人的临时id,有可能是无效值
    char                            nickname[sc_max_nickname_len];            //
    TProUserBaseInfo_Mobile            baseinfos;
    TProUserBaseInfoSecond_Mobile    baseinfos2;
    BaseInfoPatch                    patch1;
    BaseInfoPatch2                    patch2;

    ClientUserBaseInfoRep_Mobile() : PacketBase(CLIENT_USERBASEINFO_REP, sizeof(ClientUserBaseInfoRep_Mobile))
    {
        memset(nickname, 0,sizeof(nickname) );
        memset(&baseinfos,0,sizeof(baseinfos) );
        memset(&baseinfos2,0,sizeof(baseinfos2) );
        memset(&patch1,0,sizeof(patch1) );
        memset(&patch2, 0, sizeof(patch2));
        nickname_usertempid = sc_invalid_user_temp_id;
    }
};

CLIENT_USERDETAIL_REP=21403
struct ClientUserDetailRep_Mobile : public PacketBase
{
    unsigned int            nickname_usertempid;    //这个人的临时id,有可能是无效值
    char                    nickname[sc_max_nickname_len];            //

    //基本信息
    TProUserBaseInfo_Mobile            baseinfos;
    TProUserBaseInfoSecond_Mobile    baseinfos2;

    ClientUserDetailRep::TUserDetailShenFenItem     sshenfen;               //身份场信息
    ClientUserDetailRep::TUserDetail3V3Item      s3v3;                   //3v3  
    ClientUserDetailRep::TUserDetail1V1Item      s1v1;                   //1v1 

    ClientUserDetailRep::TTTRankScoreItem        ttrank_shenfen;         //天梯 身份信息
    ClientUserDetailRep::TTTRankScoreItem        ttrank_3v3;             //天梯 3v3
    ClientUserDetailRep::TTTRankScoreItem        ttrank_1v1;             //天梯 1v1
    ClientUserDetailRep::TTTRankScoreItem        ttrank_new1v1;          //天梯 n1v1

    TGuoScoreItem_Mobile                         sguo;                    //国战
    ClientUserDetailRep::TPraiseInfo             praise;
    TUserScoreHappy                                 happy;

    BaseInfoPatch                                patch1;
    BaseInfoPatch2                                patch2;

    ClientUserDetailRep_Mobile() : PacketBase(CLIENT_USERDETAIL_REP, sizeof(ClientUserDetailRep_Mobile) )
    {
        nickname_usertempid = sc_invalid_user_temp_id;
        memset(nickname,  0,sizeof(nickname) );
        memset(&baseinfos,0,sizeof(baseinfos) );
        memset(&baseinfos2,0,sizeof(baseinfos2) );
        memset(&praise,0,sizeof(praise) );
        memset(&ttrank_shenfen, 0, sizeof(ttrank_shenfen));
        memset(&ttrank_3v3, 0, sizeof(ttrank_3v3));
        memset(&ttrank_1v1, 0, sizeof(ttrank_1v1));
        memset(&ttrank_new1v1, 0, sizeof(ttrank_new1v1));
        memset(&happy, 0, sizeof(happy));
        memset(&patch1, 0, sizeof(patch1));
        memset(&patch2, 0, sizeof(patch2));
    }
};

侍灵觉醒

  • 新增协议 【2.0】

ABROAD_SERVANT_WAKEUP_REQ=48709
struct ServantWakeUpReq : public PacketBase
{
    unsigned int    servantId;

    ServantWakeUpReq() : PacketBase(ABROAD_SERVANT_WAKEUP_REQ, sizeof(ServantWakeUpReq))
    {
        PRO_ZERO_MEMORY(this, sizeof(ServantWakeUpReq));
    }
};

ABROAD_SERVANT_WAKEUP_REP=48710
struct ServantWakeUpRep : public PacketBase
{
    enum emResult
    {
        ok = 0,
        fail = 1,
        fail_config = 2,  // 配置错误
        fail_not_enough_goods = 3,  // 道具不足
        fail_wakeup_already = 4,  // 已觉醒
        fail_not_have_servant = 5,  // 未拥有该侍灵
        fail_consume_goods = 6,  // 消耗道具失败
    };

    unsigned int    result;
    unsigned int    servantId;

    ServantWakeUpRep() : PacketBase(ABROAD_SERVANT_WAKEUP_REP, sizeof(ServantWakeUpRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ServantWakeUpRep));
    }
};

获取侍灵种田信息

  • 新增协议 【2.0】
ABROAD_SERVANT_TRIP_DATA_REQ=48711
struct ServantTripDataReq : public PacketBase
{
    enum emReqType
    {
        req_all = 0,
        req_one,
    };

    unsigned int    reqType;
    unsigned int    boxId;

    ServantTripDataReq() : PacketBase(ABROAD_SERVANT_TRIP_DATA_REQ, sizeof(ServantTripDataReq))
    {
        PRO_ZERO_MEMORY(this, sizeof(ServantTripDataReq));
    }
};

ABROAD_SERVANT_TRIP_DATA_REP=48712
struct ServantTripDataRep : public PacketBase
{
    const static unsigned int sc_max_produce_count = 50;
    const static unsigned int sc_max_box_count = 20;

    enum emResult
    {
        ok = 0,
        fail = 1,
        data_not_load = 2,
        config_error = 3,
    };

    struct BoxProduce
    {
        unsigned int goodsId;
        unsigned int goodsCount;

        friend bostream& operator<<(bostream& bos, const BoxProduce& t)
        {
            bos << t.goodsId << t.goodsCount;
            return bos;
        }
    };

    struct TripBoxItem
    {
        unsigned int boxId;
        bool         bUnlock;      // 是否解锁
        unsigned int servantId;    // 在里面的侍灵
        unsigned int servantLv;    // 在里面的侍灵的等级
        unsigned int servantWake;          // 在里面的侍灵是否觉醒
        unsigned int leftTm;       // 剩余时间 秒
        unsigned int count;
        BoxProduce   produce[sc_max_produce_count];

        friend bostream& operator<<(bostream& bos, const TripBoxItem& t)
        {
            bos << t.boxId << t.bUnlock << t.servantId << t.servantLv << t.servantWake << t.leftTm << t.count;
            for (unsigned int i = 0; i < t.count; i++)
            {
                bos << t.produce[i];
                if (i >= sc_max_produce_count) break;
            }
            return bos;
        }
    };

    unsigned int    result;
    unsigned int    reqType;
    unsigned int    boxId;
    unsigned int    count;
    TripBoxItem     boxs[sc_max_box_count];

    ServantTripDataRep() : PacketBase(ABROAD_SERVANT_TRIP_DATA_REP, sizeof(ServantTripDataRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ServantTripDataRep));
    }

    friend bostream& operator<<(bostream& bos, const ServantTripDataRep& t)
    {
        bos << t.result << t.reqType << t.boxId << t.count;
        for (unsigned int i = 0; i < t.count; i++)
        {
            bos << t.boxs[i];
            if (i >= sc_max_box_count) break;
        }
        return bos;
    }
};

侍灵种田解锁

  • 新增协议 【2.0】
ABROAD_SERVANT_TRIP_UNLOCK_REQ=48713
struct ServantTripUnlockReq : public PacketBase
{
    unsigned int    boxId;

    ServantTripUnlockReq() : PacketBase(ABROAD_SERVANT_TRIP_UNLOCK_REQ, sizeof(ServantTripUnlockReq))
    {
        PRO_ZERO_MEMORY(this, sizeof(ServantTripUnlockReq));
    }
};

ABROAD_SERVANT_TRIP_UNLOCK_REP=48714
struct ServantTripUnlockRep : public PacketBase
{
    enum emResult
    {
        ok = 0,
        fail = 1,
        data_not_load = 2,
        config_error = 3, // 配置错误
        unlock_already = 4, // 已解锁
        goods_not_enough = 5, // 解锁需要的道具(元宝)不够
        consume_error = 6, // 道具(元宝)消耗失败
        fail_unlock_condition = 7, // 没达到解锁条件
    };

    unsigned int    result;
    unsigned int    boxId;

    ServantTripUnlockRep() : PacketBase(ABROAD_SERVANT_TRIP_UNLOCK_REP, sizeof(ServantTripUnlockRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ServantTripUnlockRep));
    }
};

侍灵进入退出种田

  • 新增协议 【2.0】
ABROAD_SERVANT_TRIP_ENTER_QUIT_REQ=48715
struct ServantTripEnterQuitReq : public PacketBase
{
    bool            bEnter;
    unsigned int    boxId;
    unsigned int    servantId;

    ServantTripEnterQuitReq() : PacketBase(ABROAD_SERVANT_TRIP_ENTER_QUIT_REQ, sizeof(ServantTripEnterQuitReq))
    {
        PRO_ZERO_MEMORY(this, sizeof(ServantTripEnterQuitReq));
    }
};

ABROAD_SERVANT_TRIP_ENTER_QUIT_REP=48716
struct ServantTripEnterQuitRep : public PacketBase
{
    enum emResult
    {
        ok = 0,
        fail = 1,
        data_not_load = 2,
        config_error = 3, // 配置错误
        already_enter = 4, // 已进入
        servant_notin_box = 5, // 侍灵不在该box中
        servant_not_have = 6, // 侍灵未拥有
        box_lock = 7, // box未解锁
        had_other_servant = 8,  // 有其他侍灵在里面
        product_award_error = 9,  // 产出奖励失败
    };

    unsigned int    result;
    bool            bEnter;
    unsigned int    boxId;
    unsigned int    servantId;

    ServantTripEnterQuitRep() : PacketBase(ABROAD_SERVANT_TRIP_ENTER_QUIT_REP, sizeof(ServantTripEnterQuitRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ServantTripEnterQuitRep));
    }
};

侍灵种田产出领取

  • 新增协议 【2.0】
ABROAD_SERVANT_TRIP_TAKE_PRODUCE_REQ=48717
struct ServantTripTakeProduceReq : public PacketBase
{
    unsigned int  boxId;

    ServantTripTakeProduceReq() : PacketBase(ABROAD_SERVANT_TRIP_TAKE_PRODUCE_REQ, sizeof(ServantTripTakeProduceReq))
    {
        PRO_ZERO_MEMORY(this, sizeof(ServantTripTakeProduceReq));
    }
};

ABROAD_SERVANT_TRIP_TAKE_PRODUCE_REP=48718
struct ServantTripTakeProduceRep : public PacketBase
{
    enum emResult
    {
        ok = 0,
        fail = 1,
        data_not_load = 2,
        config_error = 3, // 配置错误
        no_produce = 4, // 没有产出
        no_servant = 5, // 该box中没有侍灵
        product_award_error = 6,  // 产出奖励失败
    };

    unsigned int    result;
    unsigned int    boxId;

    ServantTripTakeProduceRep() : PacketBase(ABROAD_SERVANT_TRIP_TAKE_PRODUCE_REP, sizeof(ServantTripTakeProduceRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ServantTripTakeProduceRep));
    }
};

侍灵种田到期通知

  • 新增协议 【2.0】
ABROAD_SERVANT_TRIP_TIMEOVER_NTF=48720
struct ServantTripTimeOverNtf : public PacketBase
{
    unsigned int  count;
    unsigned int  boxIds[ServantTripDataRep::sc_max_box_count];

    ServantTripTimeOverNtf() : PacketBase(ABROAD_SERVANT_TRIP_TIMEOVER_NTF, sizeof(ServantTripTimeOverNtf))
    {
        PRO_ZERO_MEMORY(this, sizeof(ServantTripTimeOverNtf));
    }
};

侍灵种田产出通知

  • 新增协议 【2.0】
ABROAD_SERVANT_TRIP_PRODUCE_NTF=48719
struct ServantTripProduceNtf : public PacketBase
{
    unsigned int  count;
    unsigned int  boxIds[ServantTripDataRep::sc_max_box_count];

    ServantTripProduceNtf() : PacketBase(ABROAD_SERVANT_TRIP_PRODUCE_NTF, sizeof(ServantTripProduceNtf))
    {
        PRO_ZERO_MEMORY(this, sizeof(ServantTripProduceNtf));
    }
};