Skip to content

Commit b128dd0

Browse files
committed
Represents damage steps as trees
This allows capturing and inspecting damage values before and after each modifier.
1 parent 78a3e1b commit b128dd0

File tree

6 files changed

+226
-89
lines changed

6 files changed

+226
-89
lines changed

src/main/java/org/spongepowered/api/event/cause/entity/damage/DamageStep.java

Lines changed: 63 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -27,30 +27,19 @@
2727
import org.spongepowered.api.event.Cause;
2828

2929
import java.util.List;
30+
import java.util.OptionalDouble;
3031

3132
/**
32-
* Represents a step in the damage calculation.
33+
* Represents a tree of steps in the damage calculation.
34+
* A damage calculation is made of multiple trees of steps.
3335
*/
3436
public interface DamageStep {
3537

36-
/**
37-
* Gets the {@link DamageStepType} for this {@link DamageStep}.
38-
*
39-
* @return The damage step type
40-
*/
41-
DamageStepType type();
42-
43-
/**
44-
* Gets the cause of this {@link DamageStep}.
45-
*
46-
* @return The cause of this step
47-
*/
48-
Cause cause();
49-
5038
/**
5139
* Gets whether this step is skipped.
52-
* When skipped, only the step and its side effects are ignored, modifiers are still applied.
53-
* A modifier willing to ignore every previous modifiers should revert the damage to {@link #damageBeforeModifiers()}.
40+
* When skipped, only the step itself and its side effects are ignored, children are still applied.
41+
* A modifier willing to ignore every previous children should revert the damage to {@link #damageBeforeChildren()},
42+
* or call {@link #skip} on each child.
5443
*
5544
* @return Whether this step is skipped
5645
*/
@@ -75,47 +64,88 @@ default void skip() {
7564
}
7665

7766
/**
78-
* The damage just before the modifiers of this step.
67+
* The damage just before the children of this step.
68+
* Returns empty if the value is not known yet.
7969
*
80-
* @return The damage before this step
70+
* @return The damage before the children of this step
8171
*/
82-
double damageBeforeModifiers();
72+
OptionalDouble damageBeforeChildren();
8373

8474
/**
8575
* The damage just before this step.
76+
* Returns empty if the value is not known yet.
8677
*
8778
* @return The damage before this step
88-
* @throws IllegalStateException if called before the "before" modifiers have finished.
8979
*/
90-
double damageBeforeStep();
80+
OptionalDouble damageBeforeSelf();
9181

9282
/**
9383
* The damage just after this step.
84+
* Returns empty if the value is not known yet.
9485
*
9586
* @return The damage after this step
96-
* @throws IllegalStateException if called before this step has finished
9787
*/
98-
double damageAfterStep();
88+
OptionalDouble damageAfterSelf();
9989

10090
/**
101-
* The damage just after the modifiers of this step.
91+
* The damage just after the children of this step.
92+
* Returns empty if the value is not known yet.
10293
*
10394
* @return The damage after this step
104-
* @throws IllegalStateException if called before the modifiers have finished.
10595
*/
106-
double damageAfterModifiers();
96+
OptionalDouble damageAfterChildren();
10797

10898
/**
109-
* Gets an immutable list of all modifiers that applies just before this step.
99+
* Gets an immutable list of all children steps that applies just before this step.
110100
*
111-
* @return The list of modifiers
101+
* @return The list of children steps
112102
*/
113-
List<DamageModifier> modifiersBefore();
103+
List<DamageStep.Child> childrenBefore();
114104

115105
/**
116-
* Gets an immutable list of all modifiers that applies just after this step.
106+
* Gets an immutable list of all children steps that applies just after this step.
117107
*
118-
* @return The list of modifiers
108+
* @return The list of children steps
119109
*/
120-
List<DamageModifier> modifiersAfter();
110+
List<DamageStep.Child> childrenAfter();
111+
112+
/**
113+
* Represents a step made by the platform (vanilla and mods).
114+
*/
115+
interface Root extends DamageStep {
116+
117+
/**
118+
* Gets the {@link DamageStepType} for this step.
119+
*
120+
* @return The damage step type
121+
*/
122+
DamageStepType type();
123+
124+
/**
125+
* Gets the {@link Cause} of this step.
126+
*
127+
* @return The cause of this step
128+
*/
129+
Cause cause();
130+
}
131+
132+
/**
133+
* Represents a step made by a plugin (a modifier).
134+
*/
135+
interface Child extends DamageStep {
136+
137+
/**
138+
* Gets the parent of this step.
139+
*
140+
* @return The parent of this step
141+
*/
142+
DamageStep parent();
143+
144+
/**
145+
* The {@link DamageModifier} function of this step.
146+
*
147+
* @return The damage modifier
148+
*/
149+
DamageModifier modifier();
150+
}
121151
}
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/*
2+
* This file is part of SpongeAPI, 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.api.event.cause.entity.damage;
26+
27+
import org.spongepowered.api.Sponge;
28+
import org.spongepowered.api.event.entity.DamageCalculationEvent;
29+
30+
import java.util.List;
31+
import java.util.Optional;
32+
33+
/**
34+
* Represents the mutable equivalent of a {@link DamageStep}.
35+
* This allows plugins to add and remove modifiers during the {@link DamageCalculationEvent.Pre}.
36+
*/
37+
public interface DamageStepSpec {
38+
39+
/**
40+
* Gets a mutable list of all children steps that applies just before this step.
41+
* Adding a step to this list will raise an error if the step is already the child of another step.
42+
*
43+
* @return The list of children steps
44+
*/
45+
List<DamageStepSpec.Child> childrenBefore();
46+
47+
/**
48+
* Gets a mutable list of all children steps that applies just after this step.
49+
* Adding a step to this list will raise an error if the step is already the child of another step.
50+
*
51+
* @return The list of children steps
52+
*/
53+
List<DamageStepSpec.Child> childrenAfter();
54+
55+
/**
56+
* Represents a step made by the platform (vanilla and mods).
57+
*/
58+
interface Root extends DamageStepSpec {
59+
60+
/**
61+
* Gets the {@link DamageStepType} for this step.
62+
*
63+
* @return The damage step type
64+
*/
65+
DamageStepType type();
66+
67+
static DamageStepSpec.Root of(DamageStepType type) {
68+
return Sponge.game().factoryProvider().provide(Factory.class).of(type);
69+
}
70+
71+
interface Factory {
72+
DamageStepSpec.Root of(DamageStepType type);
73+
}
74+
}
75+
76+
/**
77+
* Represents a step made by a plugin (a modifier).
78+
*/
79+
interface Child extends DamageStepSpec {
80+
81+
/**
82+
* Gets the parent of this step.
83+
*
84+
* @return The parent of this step
85+
*/
86+
Optional<DamageStepSpec> parent();
87+
88+
/**
89+
* The {@link DamageModifier} function of this step.
90+
*
91+
* @return The damage modifier
92+
*/
93+
DamageModifier modifier();
94+
95+
/**
96+
* Creates a new {@link DamageStepSpec.Child} from the given damage modifier.
97+
*
98+
* @param modifier The damage modifier
99+
* @return The child step
100+
*/
101+
static DamageStepSpec.Child of(DamageModifier modifier) {
102+
return DamageStepSpec.Child.builder().modifier(modifier).build();
103+
}
104+
105+
/**
106+
* Creates a new {@link Builder} to create {@link DamageStepSpec.Child}s.
107+
*
108+
* @return The new builder
109+
*/
110+
static Builder builder() {
111+
return Sponge.game().builderProvider().provide(Builder.class);
112+
}
113+
114+
/**
115+
* A builder to create {@link DamageStepSpec.Child}s.
116+
*/
117+
interface Builder extends org.spongepowered.api.util.Builder<DamageStepSpec.Child, Builder> {
118+
119+
/**
120+
* Sets the {@link DamageModifier} function for this step.
121+
*
122+
* @param modifier The damage modifier
123+
* @return this builder for chaining
124+
*/
125+
Builder modifier(DamageModifier modifier);
126+
}
127+
}
128+
}

src/main/java/org/spongepowered/api/event/cause/entity/damage/DamageStepType.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,11 @@
2424
*/
2525
package org.spongepowered.api.event.cause.entity.damage;
2626

27-
import org.spongepowered.api.event.Cause;
2827
import org.spongepowered.api.registry.DefaultedRegistryValue;
2928
import org.spongepowered.api.util.annotation.CatalogedBy;
3029

3130
/**
32-
* A type of {@link DamageStep} that can apply a "grouping" so to speak
33-
* for the damage modifier. The use case is being able to differentiate between
34-
* various {@link DamageStep}s based on the {@link DamageStepType}
35-
* without digging through the {@link Cause} provided by
36-
* {@link DamageStep#cause()}.
31+
* Represents a type of {@link DamageStep.Root}.
3732
*/
3833
@CatalogedBy(DamageStepTypes.class)
3934
public interface DamageStepType extends DefaultedRegistryValue {

0 commit comments

Comments
 (0)