Skip to content

Commit

Permalink
修复新伤害计算流程
Browse files Browse the repository at this point in the history
  • Loading branch information
wode490390 committed Feb 15, 2024
1 parent f4bb3e3 commit 40825e6
Show file tree
Hide file tree
Showing 16 changed files with 170 additions and 128 deletions.
82 changes: 23 additions & 59 deletions src/main/java/cn/nukkit/Player.java
Original file line number Diff line number Diff line change
Expand Up @@ -4783,18 +4783,16 @@ public boolean attack(EntityDamageEvent source) {
if (!this.isAlive()) {
return false;
}

if (this.isCreativeLike()
// && source.getCause() != DamageCause.SUICIDE
// && source.getCause() != DamageCause.VOID
) {
if (this.isCreativeLike()) {
source.setCancelled();
return false;
} else if (this.getAdventureSettings().get(Type.ALLOW_FLIGHT) && source.getCause() == DamageCause.FALL) {
}
if (this.getAdventureSettings().get(Type.ALLOW_FLIGHT) && source.getCause() == DamageCause.FALL) {
//source.setCancelled();
return false;
} else if (source.getCause() == DamageCause.FALL) {
if (this.getLevel().getBlock(this.getPosition().floor().add(0.5, -1, 0.5)).getId() == Block.SLIME) {
}
if (source.getCause() == DamageCause.FALL) {
if (this.getLevel().getBlock(floor().add(0.5, -1, 0.5)).getId() == Block.SLIME) {
if (!this.isSneaking()) {
//source.setCancelled();
this.resetFallDistance();
Expand All @@ -4807,66 +4805,39 @@ public boolean attack(EntityDamageEvent source) {
return false;
}

boolean add = false;
boolean doubleCritical = false;
if (source instanceof EntityDamageByEntityEvent && source.getCause() == DamageCause.ENTITY_ATTACK) {
Entity damager = ((EntityDamageByEntityEvent) source).getDamager();
if (damager instanceof Player) {
((Player) damager).getFoodData().updateFoodExpLevel(0.1);
boolean critical = false;
if (source instanceof EntityDamageByEntityEvent event && source.getCause() == DamageCause.ENTITY_ATTACK) {
Entity damager = event.getDamager();
if (damager instanceof Player player) {
player.getFoodData().updateFoodExpLevel(0.1);
}

//Critical hit

if (!damager.onGround && damager instanceof Player) {
if (((Player) damager).speed != null && ((Player) damager).speed.y > 0) {
//((Player) damager).sendMessage("speed = " + ((Player) damager).speed.y);
if (((Player) damager).attackCriticalThisJump <= 0) {
add = true;
} else if (((Player) damager).getLoginChainData().getCurrentInputMode() != ClientChainData.INPUT_MOUSE) { // 键鼠不允许叠刀
doubleCritical = true;
if (!damager.onGround && damager instanceof Player player) {
if (player.speed != null && player.speed.y > 0) {
if (player.attackCriticalThisJump <= 0) {
critical = true;
source.setDamage(source.getDamage() * 1.3f);
}
}
}

if (add) {
source.setDamage((float) (source.getDamage() * 1.3));
}

/*if (doubleCritical) {
//正在叠刀
Player damagerPlayer = (Player)((EntityDamageByEntityEvent) source).getDamager();
if (damagerPlayer.attackCriticalThisJump < 2) {
this.nextAllowAttack = 0;
// this.attackTime = 0;
source.setDamage((float) (source.getDamage() * 0.2));
}
damagerPlayer.sendPopup("叠刀 × " + damagerPlayer.attackCriticalThisJump);
AnimatePacket animate = new AnimatePacket();
animate.action = AnimatePacket.Action.CRITICAL_HIT;
animate.eid = getId();
damagerPlayer.dataPacket(animate);
this.getLevel().addLevelSoundEvent(this, LevelSoundEventPacket.SOUND_ATTACK_STRONG, new Player[]{damagerPlayer});
}*/
}

if (super.attack(source)) { //!source.isCancelled()
this.stopSleep();

if (this.getLastDamageCause() == source && this.spawned) {
EntityEventPacket pk = new EntityEventPacket();
pk.eid = this.id;
pk.eid = this.getId();
pk.event = EntityEventPacket.HURT_ANIMATION;
// 这边只发给自己,因为广播给他人的已经在EntityLiving中发送了
this.dataPacket(pk);
if (add) {
if (((EntityDamageByEntityEvent) source).getDamager() instanceof Player) {
/*if (((Player) ((EntityDamageByEntityEvent) source).getDamager()).getLoginChainData().getDeviceOS() == 7) //win10
(((EntityDamageByEntityEvent) source).getDamager()).addEffect(Effect.getEffect(Effect.SLOWNESS).setDuration(10).setAmplifier(1).setVisible(false));*/
((Player)(((EntityDamageByEntityEvent) source).getDamager())).attackCriticalThisJump++;

if (critical) {
if (((EntityDamageByEntityEvent) source).getDamager() instanceof Player player) {
player.attackCriticalThisJump++;
}

// 在这里发送暴击,因为事件可能被取消
AnimatePacket animate = new AnimatePacket();
animate.action = AnimatePacket.Action.CRITICAL_HIT;
Expand All @@ -4875,17 +4846,10 @@ public boolean attack(EntityDamageEvent source) {

this.getLevel().addLevelSoundEvent(this, LevelSoundEventPacket.SOUND_ATTACK_STRONG);
}
/*if (doubleCritical) {
if (((EntityDamageByEntityEvent) source).getDamager() instanceof Player) {
Player damagerPlayer = (Player)((EntityDamageByEntityEvent) source).getDamager();
damagerPlayer.attackCriticalThisJump++;
}
}*/
}
return true;
} else {
return false;
}
return false;
}

protected boolean isDamageBlocked(EntityDamageEvent source) {
Expand Down
38 changes: 31 additions & 7 deletions src/main/java/cn/nukkit/entity/Entity.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import cn.nukkit.event.player.PlayerInteractEvent.Action;
import cn.nukkit.event.player.PlayerTeleportEvent;
import cn.nukkit.item.Item;
import cn.nukkit.item.enchantment.Enchantment;
import cn.nukkit.level.GameRule;
import cn.nukkit.level.Level;
import cn.nukkit.level.Location;
Expand Down Expand Up @@ -1078,23 +1079,46 @@ public void despawnFrom(Player player) {
}
}

public boolean isInvulnerableTo(EntityDamageEvent damageSource) {
return this.isClosed() || this.invulnerable && damageSource.getCause() != DamageCause.VOID && !(damageSource.getEntity() instanceof Player player && player.isCreativeLike());
}

public boolean attack(EntityDamageEvent source) {
if (this.isInvulnerableTo(source)) {
if ((source.getCause() == DamageCause.FIRE || source.getCause() == DamageCause.FIRE_TICK
|| source.getCause() == DamageCause.LAVA || source.getCause() == DamageCause.MAGMA)
&& (fireProof || hasEffect(Effect.FIRE_RESISTANCE))) {
return false;
} else {
// this.markHurt(); // Java Edition
}

getServer().getPluginManager().callEvent(source);
if (source.isCancelled()) {
return false;
}

if (source.getCause() != DamageCause.SUICIDE) {
// Make fire aspect to set the target in fire before dealing any damage so the target is in fire on death even if killed by the first hit
if (source instanceof EntityDamageByEntityEvent) {
Enchantment[] enchantments = ((EntityDamageByEntityEvent) source).getWeaponEnchantments();
if (enchantments != null) {
for (Enchantment enchantment : enchantments) {
enchantment.doAttack(((EntityDamageByEntityEvent) source).getDamager(), this);
}
}
}

if (this.absorption > 0) { // Damage Absorption
this.setAbsorption(Math.max(0, this.getAbsorption() + source.getDamage(EntityDamageEvent.DamageModifier.ABSORPTION)));
}
}

setLastDamageCause(source);
setHealth(getHealth() - source.getFinalDamage());
return true;
}

public boolean attack(float damage) {
return this.attack(new EntityDamageEvent(this, DamageCause.CUSTOM, damage));
}

protected void onAttackSuccess(EntityDamageByEntityEvent source) {
}

public void heal(EntityRegainHealthEvent source) {
this.server.getPluginManager().callEvent(source);
if (source.isCancelled()) {
Expand Down
13 changes: 2 additions & 11 deletions src/main/java/cn/nukkit/entity/EntityHumanType.java
Original file line number Diff line number Diff line change
Expand Up @@ -241,21 +241,12 @@ protected boolean damageEntity0(EntityDamageEvent source) {
}
}

@Override
public boolean attack(EntityDamageEvent source) {
if (this.isClosed() || !this.isAlive()) {
return false;
}

return super.attack(source);
}

protected double calculateEnchantmentProtectionFactor(Item item, EntityDamageEvent source) {
protected int calculateEnchantmentProtectionFactor(Item item, EntityDamageEvent source) {
if (!item.hasEnchantments()) {
return 0;
}

double epf = 0;
int epf = 0;

for (Enchantment ench : item.getEnchantments()) {
epf += ench.getProtectionFactor(source);
Expand Down
61 changes: 27 additions & 34 deletions src/main/java/cn/nukkit/entity/EntityLiving.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package cn.nukkit.entity;

import cn.nukkit.Player;
import cn.nukkit.Server;
import cn.nukkit.block.Block;
import cn.nukkit.block.BlockID;
Expand Down Expand Up @@ -53,8 +54,6 @@ protected float getDrag() {
return 0.02f;
}

@Deprecated
protected int attackTime = 0;
protected long nextAllowAttack = 0; // EC优化,在低TPS时也确保正确的攻击冷却时间
protected float lastHurt;

Expand Down Expand Up @@ -122,13 +121,19 @@ public void collidingWith(Entity ent) { // can override (IronGolem|Bats)
ent.applyEntityCollision(this);
}

protected boolean isInvulnerableTo(EntityDamageEvent source) {
return this.invulnerable && source.getCause() != DamageCause.VOID && !(source.getEntity() instanceof Player player && player.isCreativeLike());
}

@Override
public boolean attack(EntityDamageEvent source) {
if (this.isInvulnerableTo(source)) {
if (this.isClosed() || !this.isAlive()) {
return false;
} else if (this.isClosed() || !this.isAlive()) {
}
if (this.isInvulnerableTo(source)) {
return false;
} else if (source.getCause() == DamageCause.FIRE_TICK || source.getCause() == DamageCause.LAVA || source.getCause() == DamageCause.FIRE) {
}
if (source.getCause() == DamageCause.FIRE_TICK || source.getCause() == DamageCause.LAVA || source.getCause() == DamageCause.FIRE) {
if (this.hasEffect(EffectID.FIRE_RESISTANCE)) {
return false;
}
Expand All @@ -146,8 +151,9 @@ public boolean attack(EntityDamageEvent source) {
float damage = source.getDamage();
boolean hurtAffect = true;
if (source.getCause() != DamageCause.SUICIDE) {
long time = System.currentTimeMillis();
// 冷却中
if (System.currentTimeMillis() < this.nextAllowAttack) {
if (time < this.nextAllowAttack) {
if (damage <= this.lastHurt) {
return false;
}
Expand All @@ -164,43 +170,30 @@ public boolean attack(EntityDamageEvent source) {
}
this.lastHurt = damage;
// EC优化,在低TPS时也确保正确的攻击冷却时间
this.nextAllowAttack = System.currentTimeMillis() + source.getAttackCooldown() * 50L;
this.nextAllowAttack = time + source.getAttackCooldown() * 50L;
}
}
if (hurtAffect) {
// 变红效果和音效
this.onHurt(source);
// 击退
if (source instanceof EntityDamageByEntityEvent ev && ev.hasKnockBack()) {
double deltaX = this.x - ev.getDamager().x;
double deltaZ = this.z - ev.getDamager().z;
this.knockBack(ev.getDamager(), damage, deltaX, deltaZ, ((EntityDamageByEntityEvent) source).getKnockBackH(), ((EntityDamageByEntityEvent) source).getKnockBackV());
}
}
return hurtAffect;

/*if (super.attack(source)) {
if (source instanceof EntityDamageByEntityEvent) {
Entity e = ((EntityDamageByEntityEvent) source).getDamager();
*//*if (source instanceof EntityDamageByChildEntityEvent) {
e = ((EntityDamageByChildEntityEvent) source).getChild();
}*//*
if (source instanceof EntityDamageByEntityEvent ev) {
Entity damager = ev.getDamager();
/*if (source instanceof EntityDamageByChildEntityEvent event) {
damager = event.getChild();
}*/

if (e.isOnFire() && !(e instanceof Player)) {
this.setOnFire(2 * this.server.getDifficulty());
damager.onAttackSuccess(ev);

// 击退
if (ev.hasKnockBack()) {
double deltaX = this.x - damager.x;
double deltaZ = this.z - damager.z;
this.knockBack(damager, damage, deltaX, deltaZ, ev.getKnockBackH(), ev.getKnockBackV());
}
}
onHurt(source);
// this.attackTime = source.getAttackCooldown();
// this.nextAllowAttack 在super.attack中已经设置
// this.nextAllowAttack = System.currentTimeMillis() + source.getAttackCooldown() * 50L; // EC优化,在低TPS时也确保正确的攻击冷却时间
return true;
} else {
return false;
}*/
}
return hurtAffect;
}

/**
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/cn/nukkit/entity/mob/EntityDrowned.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import cn.nukkit.Player;
import cn.nukkit.entity.EntityID;
import cn.nukkit.entity.EntitySmite;
import cn.nukkit.event.entity.EntityDamageByEntityEvent;
import cn.nukkit.item.Item;
import cn.nukkit.level.format.FullChunk;
import cn.nukkit.nbt.tag.CompoundTag;
Expand Down Expand Up @@ -69,4 +70,17 @@ public void spawnTo(Player player) {
public float getRidingOffset() {
return -0.5f;
}

@Override
protected void onAttackSuccess(EntityDamageByEntityEvent source) {
if (!isOnFire()) {
return;
}
int difficulty = server.getDifficulty();
ThreadLocalRandom random = ThreadLocalRandom.current();
if (random.nextInt(10) >= difficulty * 3) {
return;
}
source.getEntity().setOnFire(2 * difficulty);
}
}
14 changes: 14 additions & 0 deletions src/main/java/cn/nukkit/entity/mob/EntityHusk.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import cn.nukkit.Player;
import cn.nukkit.entity.EntityID;
import cn.nukkit.entity.EntitySmite;
import cn.nukkit.event.entity.EntityDamageByEntityEvent;
import cn.nukkit.item.Item;
import cn.nukkit.level.format.FullChunk;
import cn.nukkit.nbt.tag.CompoundTag;
Expand Down Expand Up @@ -69,4 +70,17 @@ public void spawnTo(Player player) {
public float getRidingOffset() {
return -0.5f;
}

@Override
protected void onAttackSuccess(EntityDamageByEntityEvent source) {
if (!isOnFire()) {
return;
}
int difficulty = server.getDifficulty();
ThreadLocalRandom random = ThreadLocalRandom.current();
if (random.nextInt(10) >= difficulty * 3) {
return;
}
source.getEntity().setOnFire(2 * difficulty);
}
}
14 changes: 14 additions & 0 deletions src/main/java/cn/nukkit/entity/mob/EntityZombie.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import cn.nukkit.Player;
import cn.nukkit.entity.EntityID;
import cn.nukkit.entity.EntitySmite;
import cn.nukkit.event.entity.EntityDamageByEntityEvent;
import cn.nukkit.item.Item;
import cn.nukkit.level.format.FullChunk;
import cn.nukkit.nbt.tag.CompoundTag;
Expand Down Expand Up @@ -69,4 +70,17 @@ public void spawnTo(Player player) {
public float getRidingOffset() {
return -0.5f;
}

@Override
protected void onAttackSuccess(EntityDamageByEntityEvent source) {
if (!isOnFire()) {
return;
}
int difficulty = server.getDifficulty();
ThreadLocalRandom random = ThreadLocalRandom.current();
if (random.nextInt(10) >= difficulty * 3) {
return;
}
source.getEntity().setOnFire(2 * difficulty);
}
}
Loading

0 comments on commit 40825e6

Please sign in to comment.