关于想要自己定义一套伤害属性体系和公式的一点思考

查看: 308|回复: 16
[复制链接]

枯心听雨 发表于 2018-7-2 10:05:08 | 显示全部楼层

欢迎访问本论坛,注册你的账号并登录,来与我们交流吧!

欢迎 登录 与我们交流!没有帐号?立即注册

x
  因为unitDamaged方法不方便获取伤害来源,所以我使用了unitAttacked和getAttacker这一对,然后添加了如果攻击就unitDamageTarget方法,但是此种方法生效于攻击前摇时,所以可以通过快速S来增加触发次数
  这个时候我不知道如何处理,请指教。
  以下我的解决思路:用一个计时器,这样可以得到单位最后一次发动攻击的时机,两次发动攻击时机间隔如果小于攻击间隔,则不触发,反之则触发。但是我不知道怎么获取一个单位的攻击间隔,请帮忙(尝试了getUnitAttackCoolDown(integer weaponIndex), 但是第一我不知道这到底是不是,第二用了这个方法无法争取启动测试地图 )。
回复

使用道具 举报

nef 发表于 2018-7-2 15:05:58 | 显示全部楼层
可以考虑把地图中的每一个单位都使用脚本添加进地图

然后注册单位进入地图事件,为每一个单位注册受伤事件,这样就可以操作了
回复 支持 反对

使用道具 举报

 楼主| 枯心听雨 发表于 2018-7-2 16:05:41 | 显示全部楼层
nef 发表于 2018-7-2 15:05
可以考虑把地图中的每一个单位都使用脚本添加进地图

然后注册单位进入地图事件,为每一个单位注册受伤事件 ...

受伤事件没有获取伤害来源的简单方式,所以才没有采用。
另外有没有办法方便地获取一个单位的攻击间隔呢?
回复 支持 反对

使用道具 举报

nef 发表于 2018-7-2 16:12:53 | 显示全部楼层
[Jass] 纯文本查看 复制代码
constant native GetEventDamageSource takes nothing returns unit
回复 支持 反对

使用道具 举报

 楼主| 枯心听雨 发表于 2018-7-2 16:25:07 | 显示全部楼层
行,我先按照这个思路去实现以下,因为我之前用的unitDamageTarget,可能会出现循环,所以可能只有ondamage的时候丢个技能啥的,我再看看吧,还是对你深表感谢。
回复 支持 反对

使用道具 举报

 楼主| 枯心听雨 发表于 2018-7-3 12:28:44 | 显示全部楼层

已经根据受伤事件进行了改良,但是伤害结算时是生命值移除,没办法准确地杀死单位,也就无法得到单位的赏金,现在我是通过记录单次伤害值大于目标剩余生命值的方式来判断击杀者,请教一下有没有更好的办法呢?
回复 支持 反对

使用道具 举报

nef 发表于 2018-7-3 16:25:49 | 显示全部楼层
枯心听雨 发表于 2018-7-2 16:25
行,我先按照这个思路去实现以下,因为我之前用的unitDamageTarget,可能会出现循环,所以可能只有ondamage ...

因为不太确定你的需求

出现死循环看上去是因为你在伤害事件的动作里面造成了伤害,如果不全模拟,解决这个问题的方式可以是,使用马甲来造成伤害,然后在伤害事件的条件里面过滤一下即可

还有另外一种方式就是全模拟,比较麻烦但是所有动作可控
1. 平衡性常数里面所有攻击类型对所有防御类型造成0%的伤害
2. 为每一个进入地图的单位注册伤害事件
3. 数值为1的伤害是单位普通攻击(普攻不掉血,但是在伤害事件里面会触发,并且伤害值为1)
4. 自己根据单位属性等因素,使用DamageTarget来造成伤害,但是确保这个伤害值大于等于2即可,因为如果伤害=1,会被判定为“普通攻击”,小于2的伤害直接设置为无伤害
回复 支持 反对

使用道具 举报

 楼主| 枯心听雨 发表于 2018-7-3 16:28:58 | 显示全部楼层
nef 发表于 2018-7-3 16:25
因为不太确定你的需求

出现死循环看上去是因为你在伤害事件的动作里面造成了伤害,如果不全模拟,解决这 ...

感谢回答。
回复 支持 反对

使用道具 举报

 楼主| 枯心听雨 发表于 2018-7-3 16:35:22 | 显示全部楼层
nef 发表于 2018-7-3 16:25
因为不太确定你的需求

出现死循环看上去是因为你在伤害事件的动作里面造成了伤害,如果不全模拟,解决这 ...

我是这样做的,首先平衡性常数没有修改(汗),其他实现方式类似于全模拟。但是对于扣血,我是用的直接是设置某单位的当前生命为当前生命减去受到的伤害。关于奖励,我是给每一个单位绑定了一个属性类,通过最后一次的攻击单位来判断最后是谁击杀,击杀之后多种自定义奖励直接归在该角色身上。
回复 支持 反对

使用道具 举报

nef 发表于 2018-7-3 18:14:02 | 显示全部楼层
枯心听雨 发表于 2018-7-3 16:35
我是这样做的,首先平衡性常数没有修改(汗),其他实现方式类似于全模拟。但是对于扣血,我是用的直接是 ...

不推荐使用设置血的方式来造成伤害。

在伤害事件里面使用马甲来造成额外伤害可以实现你的需求吗?
回复 支持 反对

使用道具 举报

 楼主| 枯心听雨 发表于 2018-7-4 11:11:33 | 显示全部楼层
nef 发表于 2018-7-3 18:14
不推荐使用设置血的方式来造成伤害。

在伤害事件里面使用马甲来造成额外伤害可以实现你的需求吗? ...

关于使用马甲单位造成伤害事件晚上我回去试试,可能会比扣血好。
另外提一点疑问哈,可以通过设置单位属性来动态控制单位的生命,魔法上限,生命,魔法的回复速度吗(希望能动态重置单位的基础属性,可能还包括攻击力,攻击速度等)?
回复 支持 反对

使用道具 举报

nef 发表于 2018-7-4 12:30:55 | 显示全部楼层
本帖最后由 nef 于 2018-7-4 13:16 编辑

可以,完全没问题。
生命/魔法上限
  • 物编设置单位的这两个属性为1
  • 在代码里面,写一个表,手动控制所有单位类型的生命/魔法上限属性,例如:

UnitTypeId
生命上限
魔法上限
其他属性
火焰抗性
...
Hmkg10002001230.1...
Hart6507002330.15...
  • 先说山丘之王,因为生命值现在只有1,所以需要用JASS给他添加999点生命值
  • 生命值不是固定的,那么我们要创建10000000000个+HP上限的技能来满足动态添加10000000000生命值吗?当然不
  • 看下面的算术

1
2
4
8
16
11
22
312
44
514
624
7124
88
918
1028
11128
1248
13148
14248
151248
1616
17116
18216
191216
20416
211416
222416
2312416
24816
251816
262816
2712816
284816
2914816
3024816
31124816
  • 以此类推,所以我们可以利用2的幂来组合成任意我们想要的数
  • 2^0 = 1, 2^1 = 2, 2^2 = 4, 2^3 = 8, 2^4 = 16,0~4共计5个数,可以组合成0~31的数,而2^5-1则等于31
  • 比如你的地图中,根据你的需要,最大生命值是9999999
  • 那么,对幂进行逆运算,就是对数,log2(9999999) = 23.25,向上取整得24,所以我们总共需要24个数,即2^0 ~ 2^23,最终我们可以组合出0 ~ 16777215的数
  • 在物编里面创建如下血牌技能

技能编号
生命值
01
12
24
38
416
532
664
7128
8256
9512
101024
112048
124096
138192
1416384
1532768
1665536
17131072
18262144
19524288
201048576
212097152
224194304
238388608
  • 回到一开始的问题,我们要给山丘之王添加999点生命值

[Jass] 纯文本查看 复制代码
// 存放24个技能
integer MAXHP_ABILS[];

// 目标值=999
integer amount = 999;
integer i = 0;
while (amount > 0) {
    if (ModuloInteger(amount, 2) == 1) {
        if (GetUnitAbilityLevel(u, MAXHP_ABILS[i]) == 0) {
            UnitAddAbility(u, MAXHP_ABILS[i]);
            UnitMakeAbilityPermanent(u, true, MAXHP_ABILS[i]); // 设置技能为永久,防止变身出问题
        }
    } else {
        if (GetUnitAbilityLevel(u, MAXHP_ABILS[i]) > 0) {
            UnitRemoveAbility(u, MAXHP_ABILS[i]);
        }
    } 
    amount /= 2; 
    i += 1;
}
while (i < 24) {
    if (GetUnitAbilityLevel(u, MAXHP_ABILS[i]) > 0) {
        UnitRemoveAbility(u, MAXHP_ABILS[i]);
    }
    i += 1;
}


相信代码你大概能看懂,你可以用jass写一个你自己的版本
  • 在单位进入地图的时候,根据表,查一下他缺少多少属性,用代码给它添加就可以了

其它
  • 攻击速度可能是负的,添加一个额外的 -2^5 = -32 就能解决问题了,比如 -7 = -32 + 25,-16 = -32 + 16
  • 首次加载的时候会卡顿一下,毕竟一下子为N个单位添加几十个技能不是小事

回复 支持 反对

使用道具 举报

nef 发表于 2018-7-4 13:16:53 | 显示全部楼层
枯心听雨 发表于 2018-7-4 11:11
关于使用马甲单位造成伤害事件晚上我回去试试,可能会比扣血好。
另外提一点疑问哈,可以通过设置单位属 ...

看搂上的回复
回复 支持 反对

使用道具 举报

 楼主| 枯心听雨 发表于 2018-7-4 22:29:37 | 显示全部楼层
nef 发表于 2018-7-4 13:16
看搂上的回复

非常感谢你耐心的解答,能看懂,之前去野外看了某帖子说了血牌,本来想到用wurstScrpit看是否能绕过,看来还是绕不过啊(汗)。
我看到里边有setMaxHP方法,也就是jass里的BlzSetUnitMaxHP方法,结果无效,难受到爆炸。
回复 支持 反对

使用道具 举报

nef 发表于 2018-7-4 23:00:04 | 显示全部楼层
枯心听雨 发表于 2018-7-4 22:29
非常感谢你耐心的解答,能看懂,之前去野外看了某帖子说了血牌,本来想到用wurstScrpit看是否能绕过,看 ...

wurst应该有内置单位属性库的,不过我不是很确定,没用wurst做过东西。

上面我说的方法,自己实现一次,终身受益。

Blz*是1.29的API,你也在用1.29吗?你现在踩的一些坑可以在 https://xywiki.com/p/Common.j 贡献一下。

比如
https://xywiki.com/p/BlzSetSpecialEffectX
https://xywiki.com/p/BlzSetItemExtendedTooltip
就是我踩过的坑
回复 支持 反对

使用道具 举报

 楼主| 枯心听雨 发表于 2018-7-5 17:43:00 | 显示全部楼层
nef 发表于 2018-7-4 23:00
wurst应该有内置单位属性库的,不过我不是很确定,没用wurst做过东西。

上面我说的方法,自己实现一次, ...

好的,我慢慢踩慢慢贡献哈!
回复 支持 反对

使用道具 举报

火凌之鳯 发表于 2018-8-7 17:07:42 | 显示全部楼层
伤害系统可以看看我做的这一个系统
http://zengphoenix.top/zrlog/post/gameDamageSystem
可以结合wurst内置的damageType包来使用

属性系统似乎wurst没有
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表