Skip to content

Commit 7d679e3

Browse files
committed
fix: populate damage event modifiers on server only
Enchantments can only reference a ServerLevel, so we keep the injection points in Player, but will override their injection points on ServerPlayer. This will still enable the event being thrown on the client, but only add the DamageModifiers on the server (where they belong).
1 parent d019346 commit 7d679e3

File tree

4 files changed

+450
-399
lines changed

4 files changed

+450
-399
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* This file is part of Sponge, licensed under the MIT License (MIT).
3+
*
4+
* Copyright (c) SpongePowered <https://www.spongepowered.org>
5+
* Copyright (c) contributors
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in
15+
* all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
* THE SOFTWARE.
24+
*/
25+
package org.spongepowered.common.mixin.core.server.level;
26+
27+
import net.minecraft.server.level.ServerPlayer;
28+
import net.minecraft.world.entity.Entity;
29+
import net.minecraft.world.entity.player.Player;
30+
import org.spongepowered.asm.mixin.Mixin;
31+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
32+
import org.spongepowered.common.mixin.core.world.entity.player.PlayerMixin_Attack_Impl;
33+
import org.spongepowered.common.util.DamageEventUtil;
34+
35+
import java.util.ArrayList;
36+
37+
@Mixin(value = ServerPlayer.class, priority = 900)
38+
public abstract class ServerPlayerMixin_Attack_impl extends PlayerMixin_Attack_Impl {
39+
40+
@Override
41+
protected void attackImpl$enchanttDamageFunc(Entity $$0, CallbackInfo ci) {
42+
final var weapon = this.attackImpl$attack.weapon();
43+
// this.getEnchantedDamage(targetEntity, damage, damageSource) - damage;
44+
final var functions = DamageEventUtil.createAttackEnchantmentFunction(weapon, this.attackImpl$attack.target(), this.attackImpl$attack.dmgSource());
45+
final var separateFunc = DamageEventUtil.provideSeparateEnchantmentFromBaseDamageFunction(this.attackImpl$attack.baseDamage(), weapon);
46+
// enchantmentDamage *= attackStrength;
47+
final var strengthScaleFunc = DamageEventUtil.provideCooldownEnchantmentStrengthFunction(weapon, this.attackImpl$attack.strengthScale());
48+
49+
this.attackImpl$attack.functions().addAll(functions);
50+
this.attackImpl$attack.functions().add(separateFunc);
51+
this.attackImpl$attack.functions().add(strengthScaleFunc);
52+
}
53+
54+
@Override
55+
protected double attackImpl$beforeSweepHurt(Player instance, Entity sweepTarget) {
56+
final var distanceToSqr = instance.distanceToSqr(sweepTarget);
57+
if (!(distanceToSqr < 9.0)) {
58+
return distanceToSqr; // Too far - no event
59+
}
60+
61+
final var mainAttack = this.attackImpl$attack;
62+
final var mainAttackDamage = this.attackImpl$finalDamageAmounts.getOrDefault("minecraft:attack_damage", 0.0).floatValue();
63+
64+
var sweepAttack = new DamageEventUtil.Attack<>(mainAttack.sourceEntity(), sweepTarget, mainAttack.weapon(), mainAttack.dmgSource(), mainAttack.strengthScale(), 1, new ArrayList<>());
65+
// float sweepBaseDamage = 1.0F + (float)this.getAttributeValue(Attributes.SWEEPING_DAMAGE_RATIO) * attackDamage;
66+
sweepAttack.functions().add(DamageEventUtil.provideSweepingDamageRatioFunction(mainAttack.weapon(), mainAttack.sourceEntity(), mainAttackDamage));
67+
// float sweepFullDamage = this.getEnchantedDamage(sweepTarget, sweepBaseDamage, $$3) * strengthScale;
68+
sweepAttack.functions().addAll(DamageEventUtil.createAttackEnchantmentFunction(mainAttack.weapon(), sweepTarget, mainAttack.dmgSource()));
69+
sweepAttack.functions().add(DamageEventUtil.provideCooldownEnchantmentStrengthFunction(mainAttack.weapon(), mainAttack.strengthScale()));
70+
71+
this.attackImpl$attackEvent = DamageEventUtil.callPlayerAttackEntityEvent(sweepAttack, 1.0F);
72+
if (attackImpl$attackEvent.isCancelled()) {
73+
return Double.MAX_VALUE;
74+
}
75+
76+
return distanceToSqr;
77+
}
78+
}

src/mixins/java/org/spongepowered/common/mixin/core/world/entity/LivingEntityMixin_Attack_Impl.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ public abstract class LivingEntityMixin_Attack_Impl extends EntityMixin implemen
243243
}
244244

245245
@Inject(method = "actuallyHurt", at = @At(value = "INVOKE",target = "Lnet/minecraft/world/entity/LivingEntity;getDamageAfterArmorAbsorb(Lnet/minecraft/world/damagesource/DamageSource;F)F"))
246-
public void attackImpl$startActuallyHurt(DamageSource damageSource, float originalDamage, CallbackInfo ci) {
246+
protected void attackImpl$startActuallyHurt(DamageSource damageSource, float originalDamage, CallbackInfo ci) {
247247
// TODO check for direct call?
248248
this.attackImpl$actuallyHurt = new DamageEventUtil.ActuallyHurt((LivingEntity) (Object) this, new ArrayList<>(), damageSource, originalDamage);
249249
}
@@ -254,7 +254,7 @@ public abstract class LivingEntityMixin_Attack_Impl extends EntityMixin implemen
254254
*/
255255
@Redirect(method = "getDamageAfterArmorAbsorb",
256256
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;hurtArmor(Lnet/minecraft/world/damagesource/DamageSource;F)V"))
257-
public void attackImpl$onDamageAfterArmorAbsorb(final LivingEntity instance, final DamageSource $$0, final float $$1) {
257+
protected void attackImpl$onDamageAfterArmorAbsorb(final LivingEntity instance, final DamageSource $$0, final float $$1) {
258258
if (this.attackImpl$actuallyHurt != null) {
259259
// prevents this.hurtArmor($$0, $$1);
260260
// $$1 = CombatRules.getDamageAfterAbsorb(this, $$1, $$0, (float)this.getArmorValue(), (float)this.getAttributeValue(Attributes.ARMOR_TOUGHNESS));
@@ -268,7 +268,7 @@ public abstract class LivingEntityMixin_Attack_Impl extends EntityMixin implemen
268268
*/
269269
@Inject(method = "getDamageAfterMagicAbsorb",
270270
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;getEffect(Lnet/minecraft/core/Holder;)Lnet/minecraft/world/effect/MobEffectInstance;"))
271-
public void attackImpl$onDamageAfterMagicAbsorb(final DamageSource $$0, final float $$1, final CallbackInfoReturnable<Float> cir) {
271+
protected void attackImpl$onDamageAfterMagicAbsorb(final DamageSource $$0, final float $$1, final CallbackInfoReturnable<Float> cir) {
272272
if (this.attackImpl$actuallyHurt != null) {
273273
var func = DamageEventUtil.createResistanceModifier(this.attackImpl$actuallyHurt.entity());
274274
this.attackImpl$actuallyHurt.functions().add(func);
@@ -281,7 +281,7 @@ public abstract class LivingEntityMixin_Attack_Impl extends EntityMixin implemen
281281
*/
282282
@Redirect(method = "getDamageAfterMagicAbsorb",
283283
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/damagesource/CombatRules;getDamageAfterMagicAbsorb(FF)F"))
284-
public float attackImpl$onDetDamageProtection(final float damage, final float protection) {
284+
protected float attackImpl$onDetDamageProtection(final float damage, final float protection) {
285285
if (this.attackImpl$actuallyHurt != null) {
286286
var func = DamageEventUtil.createEnchantmentModifiers(this.attackImpl$actuallyHurt.entity(), protection);
287287
this.attackImpl$actuallyHurt.functions().add(func);
@@ -295,7 +295,7 @@ public abstract class LivingEntityMixin_Attack_Impl extends EntityMixin implemen
295295
* Then calls the DamageEntityEvent
296296
*/
297297
@Inject(method = "setAbsorptionAmount", cancellable = true, at = @At("HEAD"))
298-
public void attackImpl$onSetAbsorptionAmount(final float newAmount, final CallbackInfo ci) {
298+
protected void attackImpl$onSetAbsorptionAmount(final float newAmount, final CallbackInfo ci) {
299299
if (this.attackImpl$actuallyHurt != null) {
300300
ci.cancel(); // Always cancel this
301301
var oldAmount = this.shadow$getAbsorptionAmount();
@@ -331,7 +331,7 @@ public abstract class LivingEntityMixin_Attack_Impl extends EntityMixin implemen
331331
@ModifyVariable(method = "actuallyHurt", ordinal = 0,
332332
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;setAbsorptionAmount(F)V",
333333
ordinal = 0, shift = At.Shift.AFTER), argsOnly = true)
334-
public float attackImpl$setFinalDamage(final float value) {
334+
protected float attackImpl$setFinalDamage(final float value) {
335335
if (this.attackImpl$actuallyHurtResult.event().isCancelled()) {
336336
return 0;
337337
}
@@ -388,7 +388,7 @@ public abstract class LivingEntityMixin_Attack_Impl extends EntityMixin implemen
388388
* also reverts {@link #attackImpl$beforeActuallyHurt}
389389
*/
390390
@Inject(method = "actuallyHurt", at = @At("RETURN"))
391-
public void attackImpl$cleanupActuallyHurt(final DamageSource $$0, final float $$1, final CallbackInfo ci) {
391+
protected void attackImpl$cleanupActuallyHurt(final DamageSource $$0, final float $$1, final CallbackInfo ci) {
392392
this.attackImpl$handlePostDamage();
393393
this.attackImpl$actuallyHurt = null;
394394
this.attackImpl$actuallyHurtResult = null;

0 commit comments

Comments
 (0)