EntityDamageByEntityEvent e = new EntityDamageByEntityEvent()
getPluginManager().callEvent(e);
事情是这样的,我想对一个目标造成伤害,LivingEntity里有个damage方法,但是这个方法受攻击冷却影响,这其中可以把目标的受伤间隔调成0然后造成伤害后再改回来,但这个方法显得有些低端而且会扰乱普攻的冷却,所以想到了直接调用上面这个事件,但接下来如何造成伤害却不知道,我想反编译看看源码,但是试了几个反编译工具都反编译失败。
我能想到的是接下来用sethealth对目标造成伤害,但是正确的写法应该是什么,请大神指点,我用的是1.14.4版本。
getPluginManager().callEvent(e);
事情是这样的,我想对一个目标造成伤害,LivingEntity里有个damage方法,但是这个方法受攻击冷却影响,这其中可以把目标的受伤间隔调成0然后造成伤害后再改回来,但这个方法显得有些低端而且会扰乱普攻的冷却,所以想到了直接调用上面这个事件,但接下来如何造成伤害却不知道,我想反编译看看源码,但是试了几个反编译工具都反编译失败。
我能想到的是接下来用sethealth对目标造成伤害,但是正确的写法应该是什么,请大神指点,我用的是1.14.4版本。
第一种方式,使用setHealth,但前提是必须自己触发事件保证对其他插件的兼容,以确保不会出现这个插件无法被控制,无论是不是能造成伤害都造成伤害:
setHealth不会触发事件,因此
setHealth时先触发一次EntityDamageEvent,这样能保证兼容99%的伤害控制等等的插件,假设EntityDamageEvent被setCancelled了,不setHealth即可
但我更推荐第二种方法:
不需要你手动call EntityDamageByEntityEvent
可以被造成伤害的实体都会继承Damageable
先判断是否继承Damageable,如果是则强转
Damageable able=(Damageable)entity;
然后able.damage(你对这个实体造成的伤害值);
即可,该方法也会触发EntityDamageEvent等等事件,兼容性更好
假设你需要指定是谁对这个实体造成的伤害
则是:
able.damage(你对这个实体造成的伤害值,是哪个实体对这个实体造成伤害)
例如:
当一个玩家右键了一个僵尸
able=这个僵尸
player=这个玩家
able.damage(10,player);
则是玩家对这个僵尸造成了10伤害
有伤害来源时,这个方**额外触发EntityDamageByEntity等事件
但Damageable的damage方法造出的伤害不仅会被取消,还会被修改伤害
假设楼主需要写真实伤害等固定伤害不受任何加成,则推荐第一种方法,反之则第二种
setHealth不会触发事件,因此
setHealth时先触发一次EntityDamageEvent,这样能保证兼容99%的伤害控制等等的插件,假设EntityDamageEvent被setCancelled了,不setHealth即可
但我更推荐第二种方法:
不需要你手动call EntityDamageByEntityEvent
可以被造成伤害的实体都会继承Damageable
先判断是否继承Damageable,如果是则强转
Damageable able=(Damageable)entity;
然后able.damage(你对这个实体造成的伤害值);
即可,该方法也会触发EntityDamageEvent等等事件,兼容性更好
假设你需要指定是谁对这个实体造成的伤害
则是:
able.damage(你对这个实体造成的伤害值,是哪个实体对这个实体造成伤害)
例如:
当一个玩家右键了一个僵尸
able=这个僵尸
player=这个玩家
able.damage(10,player);
则是玩家对这个僵尸造成了10伤害
有伤害来源时,这个方**额外触发EntityDamageByEntity等事件
但Damageable的damage方法造出的伤害不仅会被取消,还会被修改伤害
假设楼主需要写真实伤害等固定伤害不受任何加成,则推荐第一种方法,反之则第二种
 本帖最后由 wangmcptr 于 2019-9-19 15:58 编辑 
试了一下第二种方法,还是会受伤害间隔影响,我知道可以设置目标的setNoDamageTicks,但是经过测试,在连续普攻中夹杂这种方式的伤害会使普通次数明显高于正常的攻击次数,所以想问问有什么更好的方法吗,既能随时造成伤害,又不影响普攻给目标带来的短暂无敌时间。
a8105 发表于 2019-9-19 02:22
第一种方式,使用setHealth,但前提是必须自己触发事件保证对其他插件的兼容,以确保不会出现这个插件无法被控 ...
试了一下第二种方法,还是会受伤害间隔影响,我知道可以设置目标的setNoDamageTicks,但是经过测试,在连续普攻中夹杂这种方式的伤害会使普通次数明显高于正常的攻击次数,所以想问问有什么更好的方法吗,既能随时造成伤害,又不影响普攻给目标带来的短暂无敌时间。
wangmcptr 发表于 2019-9-19 13:36
试了一下第二种方法,还是会受伤害间隔影响,我知道可以设置目标的setNoDamageTicks,但是经过测试,在连 ...
换个思路,这时候你就需要做一个针对于该玩家对单一实体造成伤害间隔的检测了
比如判断该实体收到攻击的事件,如果收到伤害的间隔距离上一次小于某个值且攻击者一样那么取消伤害
wangmcptr 发表于 2019-9-19 13:36
试了一下第二种方法,还是会受伤害间隔影响,我知道可以设置目标的setNoDamageTicks,但是经过测试,在连 ...
int a=entity.getNoDamageTicks();
entity.setNoDamageTicks(0);
各种伤害代码,例如
able.damage(.........)
entity.setNoDamageTicks(a);
a8105 发表于 2019-9-19 20:38
int a=entity.getNoDamageTicks();
entity.setNoDamageTicks(0);
就是这么写的,但就是会明显增加普攻次数,不管怎么测试都是这个结果,我开始也想的既然是线程同步不应该出现这种问题,最后也没想明白怎么回事。又试了下第一种方法,又发现了个难以解决的问题,getFinalDamage()本来能获取计算装备后的伤害,但是直接call这个事件再用getFinalDamage()却获取不了,而且给被攻击单位设置了lastDamageCause后死亡信息也只显示某某死了。
wangmcptr 发表于 2019-9-19 22:16
就是这么写的,但就是会明显增加普攻次数,不管怎么测试都是这个结果,我开始也想的既然是线程同步不应该 ...
如果你是监听EntityDamageByEntityEvent等事件的时候,额外able.damage,自然会这样,你都监听这些事件了,event.setDamage即可,或者采用第一种方式
a8105 发表于 2019-9-19 22:20
如果你是监听EntityDamageByEntityEvent等事件的时候,额外able.damage,自然会这样,你都监听这些事件了,ev ...
感谢大佬指点,我好好研究研究