zoukankan      html  css  js  c++  java
  • 天堂开发笔记(四)

    开发记录

    道具使用

    能够喝药水、使用武器、使用装备、选择箭矢

    [Recv C] C_OPCODE_USEITEM 请求使用道具
    0000: 18 e8 0b 30 13 00 f3 04                            ...0....
    
    [Send C] S_OPCODE_SKILLSOUNDGFX 产生自身动画
    0000: 56 e0 0b 30 13 bf 00 00 00 00 00 00 00 00 00 00    V..0............
    
    [Send C] S_OPCODE_SKILLHASTE 魔法或物品产生的加速效果
    0000: 0b e0 0b 30 13 01 08 07                            ...0....
    
    [Send C] S_OPCODE_ITEMSTATUS 物品状态更新
    0000: 5f e8 0b 30 13 c7 bf bb af d7 d4 ce d2 bc d3 cb    _..0............
    0010: d9 d2 a9 cb ae 20 28 32 39 29 00 1d 00 00 00 00    ..... (29)......
    
    [Send C] S_OPCODE_ITEMSTATUS 物品状态更新
    0000: 5f e8 0b 30 13 c7 bf bb af d7 d4 ce d2 bc d3 cb    _..0............
    0010: d9 d2 a9 cb ae 20 28 32 39 29 00 1d 00 00 00 00    ..... (29)......
    
    [Send C] S_OPCODE_ACTIVESPELLS 激活的符咒
    0000: 64 0a 00 00                                        d...
    
    [Handle] ==end==
    0000: 18 e8 0b 30 13 00 f3 04                            ...0....
    
    [Recv C] C_OPCODE_USEITEM 请求使用道具
    0000: 18 e9 0b 30 13 00 00 00                            ...0....
    
    [Send C] S_OPCODE_SKILLSOUNDGFX 产生自身动画
    0000: 56 e0 0b 30 13 c5 00 00 00 00 00 00 00 00 00 00    V..0............
    
    [Send C] S_OPCODE_SERVERMSG 系統訊息
    0000: 78 4d 00 00                                        xM..
    
    [Send C] S_OPCODE_HPUPDATE 體力與最大體力更新
    0000: 26 10 00 10 00 00 00 00                            &.......
    
    [Send C] S_OPCODE_ITEMSTATUS 物品状态更新
    0000: 5f e9 0b 30 13 b9 c5 b4 fa d6 d5 bc ab cc e5 c1    _..0............
    0010: a6 bb d6 b8 b4 bc c1 20 28 31 39 39 29 00 c7 00    ....... (199)...
    0020: 00 00 00 00                                        ....
    
    [Send C] S_OPCODE_ITEMSTATUS 物品状态更新
    0000: 5f e9 0b 30 13 b9 c5 b4 fa d6 d5 bc ab cc e5 c1    _..0............
    0010: a6 bb d6 b8 b4 bc c1 20 28 31 39 39 29 00 c7 00    ....... (199)...
    0020: 00 00 00                                           ...
    
    [Send C] S_OPCODE_ACTIVESPELLS 激活的符咒
    0000: 64 0a 00 00                                        d...
    
    [Handle] ==end==
    0000: 18 e9 0b 30 13 00 00 00                            ...0....
    
    [Recv C] C_OPCODE_USEITEM 请求使用道具
    0000: 18 02 0c 30 13 00 f3 04                            ...0....
    
    [Send C] S_OPCODE_ITEMNAME 物品名稱
    0000: 6e 02 0c 30 13 c1 d4 c8 cb d6 ae b9 ad 20 28 24    n..0......... ($
    0010: 39 29 00 00                                        9)..
    
    [Send C] S_OPCODE_OWNCHARSTATUS 角色屬性與能力值
    0000: 22 e0 0b 30 13 01 00 00 00 00 14 08 09 0c 0e 0c    "..0............
    0010: 10 00 10 00 01 00 01 00 0a 10 65 99 97 28 00 00    ..........e..(..
    0020: 00 00 00 00 00                                     .....
    
    [Send C] S_OPCODE_CHARVISUALUPDATE 切換物件外觀動作
    0000: 12 e0 0b 30 13 14 00 00                            ...0....
    
    [Handle] ==end==
    0000: 18 02 0c 30 13 00 f3 04                            ...0....
    
    [Recv C] C_OPCODE_USEITEM 请求使用道具
    0000: 18 fa 0b 30 13 00 fd 44                            ...0...D
    
    [Send C] S_OPCODE_SPMR 魔法攻擊力與魔法防禦力
    0000: 53 00 0a 00                                        S...
    
    [Send C] S_OPCODE_SPMR 魔法攻擊力與魔法防禦力
    0000: 53 00 0a 00                                        S...
    
    [Send C] S_OPCODE_ITEMNAME 物品名稱
    0000: 6e fa 0b 30 13 c3 f0 c4 a7 bd e4 d6 b8 20 28 24    n..0......... ($
    0010: 31 31 37 29 00 00 00 00                            117)....
    
    [Send C] S_OPCODE_OWNCHARSTATUS 角色屬性與能力值
    0000: 22 e0 0b 30 13 01 00 00 00 00 14 08 09 0c 0e 0c    "..0............
    0010: 10 00 10 00 01 00 01 00 0a 10 65 99 97 28 00 00    ..........e..(..
    0020: 00 00 00 00 00                                     .....
    
    [Send C] S_OPCODE_OWNCHARATTRDEF 角色屬性值
    0000: 51 0a 00 00 00 00 00 00                            Q.......
    
    [Send C] S_OPCODE_OWNCHARSTATUS 角色屬性與能力值
    0000: 22 e0 0b 30 13 01 00 00 00 00 14 08 09 0c 0e 0c    "..0............
    0010: 10 00 10 00 01 00 01 00 0a 10 65 99 97 28 00 00    ..........e..(..
    0020: 00 00 00 00 00                                     .....
    
    [Send C] S_OPCODE_SPMR 魔法攻擊力與魔法防禦力
    0000: 53 00 0a 00                                        S...
    
    [Handle] ==end==
    0000: 18 fa 0b 30 13 00 fd 44                            ...0...D
    
    [Recv C] C_OPCODE_USEITEM 请求使用道具
    0000: 18 e2 0b 30 13 00 18 45                            ...0...E
    
    [Send C] S_OPCODE_SERVERMSG 系統訊息
    0000: 78 c4 01 01 ba da c9 ab c3 d7 cb f7 c0 f2 bc fd    x...............
    0010: 20 28 31 30 30 30 29 00                             (1000).
    
    [Handle] ==end==
    0000: 18 e2 0b 30 13 00 18 45                            ...0...E
    
    [Recv C] S_OPCODE_CHARRESET 角色重置
    0000: 2b 00 00 00                                        +...
    
    [Handle] ==end==
    0000: 2b 00 00 00                                        +...
    
    [Send C] S_OPCODE_DISCONNECT 立即中斷連線
    0000: 58 f4 01 00 00 00 00 00                            X.......
    

    Java版本的道具使用将所有逻辑都写在了一个函数中,不方便后期添加和调试,于是我重构了下,道具使用分为材料道具使用(etcitem)、武器道具使用(weapon)和防具道具使用(armor)

    C_ItemUse

    道具使用主流程,做一些共性判断,检测玩家当前状态是否能够使用道具,然后根据请求使用的道具类型调用不同类型道具的处理函数C_ArmorItem、C_WeaponItem

    C_ArmorItem

    处理防具使用,先执行判断检测

    • 检测是否存在等级限制
    • 检测是否存在职业限制
    • 检测装备槽是否有空位
    • 检测是否和已经装备的防具有冲突

    然后装备上或脱下道具,并更新玩家状态然后返回更新后的状态到客户端

    EquipmentSlot

    在实现武器/防具的使用前,需要先实现玩家装备槽

    属性:

    • 装备槽所属的角色
    • 当前装备的套装
    • 当前装备的道具

    方法:

    • 穿上道具,并更新角色属性
    • 脱下道具,并更新角色属性

    C_WeaponItem

    处理武器使用,先执行判断检测

    • 检测是否存在等级限制
    • 检测是否存在职业限制
    • 检测是否和已经装备的防具有冲突

    然后装备上或脱下或切换道具,并更新玩家状态然后返回更新后的状态到客户端

    C_EtcItem

    处理材料使用,先执行判断检测

    • 检测是否存在等级限制
    • 特殊类型的道具特殊处理
    • 根据道具模板ID选择对应的道具处理类

    道具处理类

    C_EtcItemBase

    道具处理基类抽象

    属性

    • item_ids:标明当前类能处理的道具种类

    方法

    • 返回禁止使用道具信息到客户端
    • 处理道具的使用

    角色属性计算

    力量、敏捷、体质、智力、精神、魅力

    # 万能药水使用总数
    _elixirStats = 0
    # 力量
    _str = 0
    _trueStr = 0
    _baseStr = 0
    _originalStr = 0
    # 体质
    _con = 0
    _trueCon = 0
    _baseCon = 0
    _originalCon = 0
    # 敏捷
    _dex = 0
    _trueDex = 0
    _baseDex = 0
    _originalDex = 0
    # 魅力
    _cha = 0
    _trueCha = 0
    _baseCha = 0
    _originalCha = 0
    # 智力
    _int = 0
    _trueInt = 0
    _baseInt = 0
    _originalInt = 0
    # 精神
    _wis = 0
    _trueWis = 0
    _baseWis = 0
    _originalWis = 0
    

    为什么每种属性都用四种值表示?
    以力量属性为例,角色力量属性的来源分为:职业的基础属性、创建角色奖励玩家的属性、50级以后的属性奖励、万能药水以及装备/武器的属性。
    现在我们来看看如何描述这些属性来源:

    • _originalStr(下面两项属PcInstance)
      代表职业的基础属性+创建角色奖励玩家的属性,代表原始力量值,这个值只有在C_CreateChar和C_CharReset才会被改变
    • _baseStr
      代表_originalStr+万能药水+50级以后的属性奖励,这个值就是对应Characters的str字段值
    • _trueStr(下面两项属characters)
      代表_baseStr+装备/武器的属性,在装备或使用武器/装备造成的力量变动时候使用
    • _str
      代表角色力量属性有效值,确保_trueStr在[1,127]区间,为什么_str而不直接在_trueStr上设置[1,127]区间呢? 举个例子:假设当前_baseStr=125,准备使用的装备增加i=3点力量,那么_trueStr=_baseStr+i => 128、_str => 127,如果去掉_str,即_trueStr=127,那么当脱下装备的时候,_trueStr -= i => 124,把_baseStr也多扣了1,所以我们需要_trueStr来计算使用或脱下装备造成的属性改动,使用_str来表示力量属性的真正有效值

    命中、伤害

    # 近战伤害
    _dmgup = 0
    _trueDmgup = 0
    _baseDmgup = 0
    _originalDmgup = 0
    _dmgModifierByArmor = 0
    # 远程伤害
    _bowDmgup = 0
    _trueBowDmgup = 0
    _baseBowDmgup = 0
    _originalBowDmgup = 0
    _bowDmgModifierByArmor = 0
    # 近战命中
    _hitup = 0
    _trueHitup = 0
    _baseHitup = 0
    _originalHitup = 0
    _hitModifierByArmor = 0
    # 远程命中
    _bowHitup = 0
    _trueBowHitup = 0
    _baseBowHitup = 0
    _originalBowHitup = 0
    _bowHitModifierByArmor = 0
    # 魔法伤害
    _originalMagicDamge = 0
    # 魔法命中
    _originalMagicHit = 0
    # 魔法暴击
    _originalMagicCritical = 0
    

    和前面的力量属性很类似,这边的命中和伤害用了五种值表示
    以伤害为例(命中同理),伤害加成的来源分为:人物属性值产生的伤害加成、武器产生的伤害加成、人物等级产生的伤害加成、魔法产生的伤害加成

    • _dmgModifierByArmor(下面三项属PcInstance)
      代表装备产生的伤害加成
    • _originalDmgup
      代表人物属性值产生的伤害,在resetOriginalDmgup函数中根据角色的_originalStr属性计算伤害加成
    • _baseDmgup
      代表人物等级产生的伤害加成,在resetBaseDmgup函数中根据角色等级计算伤害加成
    • _trueDmgup(下面两项属characters)
      代表_baseDmgup+魔法产生的伤害加成
    • _dmgup
      代表角色空手时的有效伤害加成和力量属性的_str一个意思
    • _originalMagicHit
      代表人物属性值产生的魔法命中,在resetOriginalMagicHit函数中根据角色的_originalInt属性计算魔法命中
    • _originalMagicCritical
      代表人物属性值产生的魔法暴击,在resetOriginalMagicCritical函数中根据角色的_originalInt属性计算魔法暴击

    和力量属性不同的是,角色最终的伤害加成并不仅仅是简单的_dmgup + _originalDmgup + _dmgModifierByArmor,这个值是在calcPcPcDamage、calcPcNpcDamage、calcNpcPcDamage中动态计算出来的,和角色攻击对象也有关联,需要扣除攻击对象的伤害减免

    防御

    _ac = 0
    _trueAc = 0
    _baseAc = 0
    _originalAc = 0
    

    和前面的力量属性很类似,这边的防御也用了四种值表示
    防御的来源分为:人物属性值产生的防御、装备产生的防御、人物等级产生的防御、魔法产生的防御

    • _originalAc(下面两项属PcInstance)
      代表人物属性值产生的防御,在resetOriginalAc函数中根据角色的_originalDex属性计算防御
    • _baseAc
      代表人物等级产生的防御,在resetBaseAc函数中根据角色等级和敏捷计算防御
    • _trueAc(下面两项属characters)
      代表_baseAc + _originalAc + 装备产生的防御 + 魔法产生的防御
    • _ac
      代表角色防御有效值

    血量、魔量

    # 血量
    _currentHp = 0
    _maxHp = 0
    _trueMaxHp = 0
    _baseMaxHp = 0
    _originalHpup = 0
    _advenHp = 0
    # 魔量
    _currentMp = 0
    _maxMp = 0
    _trueMaxMp = 0
    _baseMaxMp = 0
    _originalMpup = 0
    _advenMp = 0
    

    这些值的概念和防御非常类似

    • _originalHpup(下面两项属PcInstance)
      代表人物属性值产生的血量,在resetOriginalHpup函数中根据角色的_originalCon属性计算血量
    • _baseMaxHp
      代表random(_originalHpup) + 等级产生的血量,这个值就是对应Characters的MaxHp字段值
    • _trueMaxHp(下面三项属characters)
      代表_baseMaxHp + 装备产生的血量 + 魔法产生的血量
    • _maxHp
      代表角色血量上限,即_trueMaxHp的有效值
    • _currentHp
      代表角色当前血量值

    体力回复量、魔力回复量

    # 体力回复量
    _hpr = 0
    _trueHpr = 0
    _originalHpr = 0
    # 魔力回复量
    _mpr = 0
    _trueMpr = 0
    _originalMpr = 0
    

    以体力回复量为例,角色的体力回复量来源分为:人物属性产生的回复量、装备产生的回复量、药水产生的回复量(回血量和等级无关,所以没有_baseHpr)

    • _originalHpr
      代表人物属性值产生的体力回复量,在resetOriginalHpr函数中根据角色的_originalCon属性计算回血量
    • _trueHpr
      代表套装产生的回血量
    • _hpr
      代表角色体力回复量有效值

    魔法防御、魔法攻击

    # 魔防
    _mr = 0
    _trueMr = 0
    _baseMr = 0
    _originalMr = 0
    # 魔攻
    _sp = 0
    

    魔防来源:人物属性产生的魔防、装备产生的魔防、魔法产生的魔防、人物等级产生的魔防

    • _originalMr
      代表人物属性值产生的魔防,在resetOriginalMr函数中根据角色的_originalWis属性计算魔防
    • _baseMr
      代表人物等级产生的魔防,在resetBaseMr函数中根据角色等级和精神计算魔防
    • _trueMr
      代表 _originalMr + _baseMr + 装备和魔法产生的魔防
    • _mr
      代表角色魔防有效值

    魔攻本来也可以这么弄,但是原先的代码没这么设计,后期可以改成和魔防一样

    重量减免、伤害减免、魔法消耗减免

    # 重量减免
    _weightReduction = 0
    _originalStrWeightReduction = 0
    _originalConWeightReduction = 0
    # 伤害减免
    _damageReductionByArmor = 0
    # 魔法消耗减免
    _originalMagicConsumeReduction = 0
    

    负重减免可以提供角色更多的负重量,伤害减免可以使角色受到的伤害值减小,魔法消耗减免可以减少用户使用魔法时的魔量。其中伤害减免的来源:人物等级、防御值、魔法、装备,后期也可以改造成和前面的属性值一样的模式

    属性防御、抗性

    # 属性防御
    _wind = 0
    _trueWind = 0
    _water = 0
    _trueWater = 0
    _fire = 0
    _trueFire = 0
    _earth = 0
    _trueEarth = 0
    # 眩晕抗性
    _registStun = 0
    _trueRegistStun = 0
    # 石化抗性
    _registStone = 0
    _trueRegistStone = 0
    # 睡眠抗性
    _registSleep = 0
    _trueRegistSleep = 0
    # 冰冻抗性
    _registFreeze = 0
    _trueRegistFreeze = 0
    # 支撑抗性
    _registSustain = 0
    _trueRegistSustain = 0
    # 闇暗抗性
    _registBlind = 0
    _trueRegistBlind = 0
    

    属性防御和抗性的来源基本就是装备和魔法

    移速

    # 一段加速
    _moveSpeed
    # 二段加速
    _braveSpeed
    

    一段就是绿色药水,二段就是勇敢药水,只有有和没有两种状态,没有其他特殊计算

    其他属性

    后期补充,目前对属性调整比较重要的就这些,其他的后面补充的时候再添加上

    BUG修复

    描述:灭魔戒子使用只加2点魔防,打印发送和接收数据包的日志,发现"没什么"不同
    解决办法:新增日志打印加密和解密前后的数据包,发现两个数据包是没有发送出去的,仔细分析代码是自己自作聪明在不该填充0字节的时候给特殊数据包填充0字节导致数据包正常发送,导致后面的数据包解析出了问题

  • 相关阅读:
    super().__init__()方法
    so the first day
    left join,right join,inner join,full join之间的区别
    C#中几种常用的集合的用法ArrayList集合HashTable集合List<T>集合Dictionary<K,V>集合及区别
    C#中Dictionary<string,string>的初始化 两种方式不同
    C#中Dictionary的初始化方式
    如何批量修改文件后缀名?cmd命令 ren *.gif *.jpg
    eclipse查看一个方法被谁引用(调用)的快捷键四种方式
    C# 数组集合
    Java-数组和集合简单使用
  • 原文地址:https://www.cnblogs.com/silvermagic/p/7666360.html
Copyright © 2011-2022 走看看