Skip to content

Commit 18367fa

Browse files
committed
Damage step API improvements
1 parent 4e7c4ed commit 18367fa

File tree

15 files changed

+404
-184
lines changed

15 files changed

+404
-184
lines changed

forge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/LivingEntityMixin_Forge_Damage.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ public abstract class LivingEntityMixin_Forge_Damage implements TrackedDamageBri
5959
return ForgeEventFactory.onShieldBlock(self, source, originalDamage);
6060
}
6161

62-
final SpongeDamageStep step = tracker.newStep(DamageStepTypes.SHIELD, originalDamage, ItemStackUtil.snapshotOf(self.getUseItem()));
63-
float damage = (float) step.applyModifiersBefore();
62+
final SpongeDamageStep step = tracker.newStep(DamageStepTypes.SHIELD, ItemStackUtil.snapshotOf(self.getUseItem()));
63+
float damage = (float) step.applyChildrenBefore(originalDamage);
6464
final ShieldBlockEvent event;
6565
if (step.isSkipped()) {
6666
event = new ShieldBlockEvent(self, source, damage);
@@ -71,7 +71,7 @@ public abstract class LivingEntityMixin_Forge_Damage implements TrackedDamageBri
7171
damage -= event.getBlockedDamage();
7272
}
7373
}
74-
step.applyModifiersAfter(damage);
74+
step.applyChildrenAfter(damage);
7575
return event;
7676
}
7777

neoforge/src/mixins/java/org/spongepowered/neoforge/mixin/core/world/entity/LivingEntityMixin_Neo_Damage.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ public abstract class LivingEntityMixin_Neo_Damage implements TrackedDamageBridg
6666
}
6767

6868
final float originalDamage = container.getNewDamage();
69-
final SpongeDamageStep step = tracker.newStep(DamageStepTypes.SHIELD, originalDamage, ItemStackUtil.snapshotOf(self.getUseItem()));
70-
float damage = (float) step.applyModifiersBefore();
69+
final SpongeDamageStep step = tracker.newStep(DamageStepTypes.SHIELD, ItemStackUtil.snapshotOf(self.getUseItem()));
70+
float damage = (float) step.applyChildrenBefore(originalDamage);
7171
container.setNewDamage(damage);
7272
final LivingShieldBlockEvent event;
7373
if (step.isSkipped()) {
@@ -78,7 +78,7 @@ public abstract class LivingEntityMixin_Neo_Damage implements TrackedDamageBridg
7878
container.setBlockedDamage(event);
7979
damage = container.getNewDamage();
8080
}
81-
step.applyModifiersAfter(damage);
81+
step.applyChildrenAfter(damage);
8282
return event;
8383
}
8484

src/main/java/org/spongepowered/common/event/cause/entity/damage/SpongeAttackTracker.java

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
import org.spongepowered.api.entity.Entity;
3131
import org.spongepowered.api.event.CauseStackManager;
3232
import org.spongepowered.api.event.SpongeEventFactory;
33-
import org.spongepowered.api.event.cause.entity.damage.DamageStep;
33+
import org.spongepowered.api.event.cause.entity.damage.DamageStepTypes;
3434
import org.spongepowered.api.event.entity.AttackEntityEvent;
3535
import org.spongepowered.api.event.entity.DamageCalculationEvent;
3636
import org.spongepowered.api.item.inventory.ItemStackSnapshot;
@@ -39,17 +39,15 @@
3939
import org.spongepowered.common.event.tracking.PhaseTracker;
4040
import org.spongepowered.common.item.util.ItemStackUtil;
4141

42-
import java.util.List;
43-
4442
public class SpongeAttackTracker extends SpongeDamageTracker {
4543
private final ItemStack weapon;
4644
private final ItemStackSnapshot weaponSnapshot;
4745

4846
private float attackStrength;
4947
private boolean strongSprint = false;
5048

51-
public SpongeAttackTracker(final DamageCalculationEvent.Pre preEvent, final ItemStack weapon) {
52-
super(preEvent);
49+
public SpongeAttackTracker(final DamageCalculationEvent.Pre preEvent, final DamageSource source, final ItemStack weapon) {
50+
super(preEvent, source);
5351
this.weapon = weapon;
5452
this.weaponSnapshot = ItemStackUtil.snapshotOf(weapon);
5553
}
@@ -88,31 +86,39 @@ public void setStrongSprint(final boolean strongSprint) {
8886
this.strongSprint = strongSprint;
8987
}
9088

91-
public boolean callAttackPostEvent(final Entity entity, final DamageSource source, final float finalDamage, final float knockbackModifier) {
92-
final List<DamageStep> steps = this.preparePostEvent();
89+
public boolean callAttackPostEvent(final Entity entity, final DamageSource source, float finalDamage, final float knockbackModifier) {
90+
if (this.postEvent != null) {
91+
throw new IllegalStateException("Post event already fired");
92+
}
93+
94+
finalDamage = (float) this.newStep(DamageStepTypes.END).apply(finalDamage);
9395

94-
try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) {
96+
try (final CauseStackManager.StackFrame frame = PhaseTracker.getInstance().pushCauseFrame()) {
9597
SpongeDamageTracker.generateCauseFor(source, frame);
9698

9799
final AttackEntityEvent.Post event = SpongeEventFactory.createAttackEntityEventPost(frame.currentCause(),
98-
this.preEvent.originalBaseDamage(), this.preEvent.baseDamage(), finalDamage, finalDamage, knockbackModifier, knockbackModifier, entity, steps);
100+
knockbackModifier, knockbackModifier, entity, this, this.preEvent.baseDamage(), finalDamage);
99101

100102
this.postEvent = event;
101103
return SpongeCommon.post(event);
102104
}
103105
}
104106

105107
public static @Nullable SpongeAttackTracker callAttackPreEvent(final Entity entity, final DamageSource source, final float baseDamage, final ItemStack weapon) {
106-
try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) {
108+
final SpongeAttackTracker tracker;
109+
try (final CauseStackManager.StackFrame frame = PhaseTracker.getInstance().pushCauseFrame()) {
107110
SpongeDamageTracker.generateCauseFor(source, frame);
108111

109-
final AttackEntityEvent.Pre event = SpongeEventFactory.createAttackEntityEventPre(frame.currentCause(), baseDamage, baseDamage, entity);
112+
final AttackEntityEvent.Pre event = SpongeEventFactory.createAttackEntityEventPre(frame.currentCause(), entity, baseDamage);
110113
if (SpongeCommon.post(event)) {
111114
return null;
112115
}
113116

114-
return new SpongeAttackTracker(event, weapon);
117+
tracker = new SpongeAttackTracker(event, source, weapon);
115118
}
119+
120+
tracker.newStep(DamageStepTypes.START).apply(baseDamage);
121+
return tracker;
116122
}
117123

118124
public static @Nullable SpongeAttackTracker of(final DamageSource source) {
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
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.event.cause.entity.damage;
26+
27+
import org.checkerframework.checker.nullness.qual.Nullable;
28+
import org.spongepowered.api.event.CauseStackManager;
29+
import org.spongepowered.api.event.cause.entity.damage.DamageModifier;
30+
import org.spongepowered.api.event.cause.entity.damage.DamageStepType;
31+
32+
import java.util.Objects;
33+
import java.util.Optional;
34+
import java.util.function.Consumer;
35+
36+
public record SpongeDamageModifier(DamageStepType type, Optional<Consumer<CauseStackManager.StackFrame>> frame, Optional<Function> damage) implements DamageModifier {
37+
38+
public static class Builder implements DamageModifier.Builder {
39+
private @Nullable DamageStepType type;
40+
private @Nullable Consumer<CauseStackManager.StackFrame> frame;
41+
private Function function;
42+
43+
public Builder() {
44+
this.reset();
45+
}
46+
47+
@Override
48+
public DamageModifier.Builder reset() {
49+
this.type = null;
50+
this.frame = null;
51+
this.function = (step, damage) -> damage;
52+
return this;
53+
}
54+
55+
@Override
56+
public DamageModifier.Builder type(DamageStepType type) {
57+
this.type = Objects.requireNonNull(type, "type");
58+
return this;
59+
}
60+
61+
@Override
62+
public DamageModifier.Builder frame(Consumer<CauseStackManager.StackFrame> frame) {
63+
this.frame = Objects.requireNonNull(frame, "frame");
64+
return this;
65+
}
66+
67+
@Override
68+
public DamageModifier.Builder damage(Function function) {
69+
this.function = Objects.requireNonNull(function, "function");
70+
return this;
71+
}
72+
73+
@Override
74+
public DamageModifier build() {
75+
if (this.type == null) {
76+
throw new IllegalStateException("type must be set");
77+
}
78+
return new SpongeDamageModifier(this.type, Optional.ofNullable(this.frame), Optional.ofNullable(this.function));
79+
}
80+
}
81+
}

0 commit comments

Comments
 (0)