Skip to content

Commit

Permalink
Modifiers are no longer additive instead
Browse files Browse the repository at this point in the history
modifier groupings are
  • Loading branch information
Faithcaio committed Jun 3, 2024
1 parent 7a36c2e commit 2a00155
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
package org.spongepowered.api.event.cause.entity.damage;

import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.api.ResourceKey;
import org.spongepowered.api.entity.Entity;
import org.spongepowered.api.event.Cause;
import org.spongepowered.api.item.ItemTypes;
Expand Down Expand Up @@ -63,6 +64,14 @@ static Builder builder() {
*/
DamageModifierType type();

/**
* Returns the damage modifier group.
* <p>Grouped modifiers calculate their damage independently from each other</p>
*
* @return The damage modifier group
*/
ResourceKey group();

/**
* Gets the cause of this {@link DamageModifier}.
*
Expand Down Expand Up @@ -92,6 +101,7 @@ final class Builder implements org.spongepowered.api.util.Builder<DamageModifier

@Nullable DamageModifierType type;
@Nullable Cause cause;
@Nullable ResourceKey group;
@Nullable ItemStackSnapshot snapshot;

Builder() {
Expand Down Expand Up @@ -121,6 +131,41 @@ public Builder type(final DamageModifierType damageModifierType) {
return this;
}

/**
* The main attack damage calculated for an {@link org.spongepowered.api.event.entity.AttackEntityEvent}
*
* @return This builder, for chaining
*/
public Builder attackDamageGroup() {
this.group = ResourceKey.minecraft("attack_damage");
return this;
}

/**
* The enchantment attack damage calculated for an {@link org.spongepowered.api.event.entity.AttackEntityEvent}
*
* @return This builder, for chaining
*/
public Builder attackEnchantmentGroup() {
this.group = ResourceKey.minecraft("attack_enchantment");
return this;
}

/**
* The damage calculated for an {@link org.spongepowered.api.event.entity.DamageEntityEvent}
*
* @return This builder, for chaining
*/
public Builder damageReductionGroup() {
this.group = ResourceKey.minecraft("damage_reduction");
return this;
}

public Builder group(final ResourceKey group) {
this.group = group;
return this;
}

public Builder item(final ItemStack itemStack) {
this.item(java.util.Objects.requireNonNull(itemStack, "ItemStack").createSnapshot());
return this;
Expand Down Expand Up @@ -179,10 +224,12 @@ private static class ImplementedDamageModifier implements DamageModifier {
private final DamageModifierType type;
private final Cause cause;
@Nullable private final ItemStackSnapshot snapshot;
private final ResourceKey group;

ImplementedDamageModifier(final Builder builder) {
this.type = java.util.Objects.requireNonNull(builder.type, "DamageType is null!");
this.cause = java.util.Objects.requireNonNull(builder.cause, "Cause is null!");
this.group = java.util.Objects.requireNonNull(builder.group, "Group is null!");
this.snapshot = builder.snapshot;
}

Expand All @@ -201,6 +248,10 @@ public Optional<ItemStackSnapshot> contributingItem() {
return Optional.ofNullable(this.snapshot);
}

public ResourceKey group() {
return group;
}

@Override
public int hashCode() {
return Objects.hash(this.type, this.cause);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@
* return damage;
* }</pre></blockquote>
*
* TODO explain groups
* <p>After which, the "final" damage is simply the summation of the
* "base" damage and all "modified damage" for each {@link DamageModifier}
* provided in this event.</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@
* return damage;
* }</pre></blockquote>
*
* TODO explain groups
* <p>After which, the "final" damage is simply the summation of the
* "base" damage and all "modified damage" for each {@link DamageModifier}
* provided in this event.</p>
Expand All @@ -134,6 +135,7 @@
* the provided pairing will be added at the
* "end" of the list for "modifying" the "base" damage.</p>
*
* TODO this is wrong?
* <p>Note that this event is intended for processing incoming damage to
* an {@link Entity} prior to any {@link DamageModifier}s associated with
* the {@link #entity()}. The {@link DamageEntityEvent} is used
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ public final void setOutputDamage(final DamageModifier damageModifier, final Dou
} else {
this.modifierFunctions.add(indexToAddTo, new DamageFunction(damageModifier, function));
}
this.recalculateDamages(this.baseDamage);
this.recalculate(this.baseDamage);
}

@Override
Expand All @@ -138,7 +138,7 @@ public void addDamageModifierBefore(final DamageModifier damageModifier, final D
} else {
this.modifierFunctions.add(indexToAddBefore, new DamageFunction(damageModifier, function));
}
this.recalculateDamages(this.baseDamage);
this.recalculate(this.baseDamage);
}

@Override
Expand All @@ -162,7 +162,7 @@ public void addDamageModifierAfter(final DamageModifier damageModifier, final Do
} else {
this.modifierFunctions.add(indexToAddAfter + 1, new DamageFunction(damageModifier, function));
}
this.recalculateDamages(this.baseDamage);
this.recalculate(this.baseDamage);
}

@Override
Expand All @@ -173,7 +173,7 @@ public double baseOutputDamage() {
@Override
public final void setBaseOutputDamage(final double baseDamage) {
this.baseDamage = baseDamage;
this.recalculateDamages(this.baseDamage);
this.recalculate(this.baseDamage);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public final boolean isModifierApplicable(DamageModifier damageModifier) {
@Override
public final double damage(DamageModifier damageModifier) {
if (!this.modifiers.containsKey(Objects.requireNonNull(damageModifier, "Damage Modifier cannot be null!"))) {
throw new IllegalArgumentException("The provided damage modifier is not applicable: " + damageModifier.toString());
throw new IllegalArgumentException("The provided damage modifier is not applicable: " + damageModifier);
}
return this.modifiers.get(Objects.requireNonNull(damageModifier));
}
Expand All @@ -115,7 +115,7 @@ public final void setDamage(DamageModifier damageModifier, DoubleUnaryOperator f
} else {
this.modifierFunctions.add(indexToAddTo, new DamageFunction(damageModifier, function));
}
this.recalculateDamages(this.baseDamage);
this.recalculate(this.baseDamage);
}

@Override
Expand All @@ -139,7 +139,7 @@ public void addDamageModifierBefore(DamageModifier damageModifier, DoubleUnaryOp
} else {
this.modifierFunctions.add(indexToAddBefore, new DamageFunction(damageModifier, function));
}
this.recalculateDamages(this.baseDamage);
this.recalculate(this.baseDamage);
}

@Override
Expand All @@ -163,7 +163,7 @@ public void addModifierAfter(DamageModifier damageModifier, DoubleUnaryOperator
} else {
this.modifierFunctions.add(indexToAddAfter + 1, new DamageFunction(damageModifier, function));
}
this.recalculateDamages(this.baseDamage);
this.recalculate(this.baseDamage);
}

@Override
Expand All @@ -190,7 +190,7 @@ public double baseDamage() {
@Override
public final void setBaseDamage(double baseDamage) {
this.baseDamage = baseDamage;
this.recalculateDamages(this.baseDamage);
this.recalculate(this.baseDamage);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
*/
package org.spongepowered.api.event.impl.entity;

import org.spongepowered.api.ResourceKey;
import org.spongepowered.api.event.cause.entity.damage.DamageModifier;
import org.spongepowered.api.event.cause.entity.damage.ModifierFunction;
import org.spongepowered.api.event.entity.DamageEntityEvent;
import org.spongepowered.api.event.impl.AbstractEvent;
Expand All @@ -49,54 +51,43 @@ public abstract class AbstractModifierEvent<T extends ModifierFunction<M>, M> ex
protected final LinkedHashMap<M, Double> modifiers = new LinkedHashMap<>();
protected final List<T> modifierFunctions = new ArrayList<>();

protected List<T> init(double originalValue, List<T> originalFunctions) {
final List<Tuple<M, Double>> modifierMapBuilder = new ArrayList<>(originalFunctions.size());
final List<T> functionListBuilder = new ArrayList<>(originalFunctions.size());
final Map<M, Double> mapBuilder = new HashMap<>(originalFunctions.size());
double finalDamage = originalValue;
for (T tuple : originalFunctions) {
this.modifierFunctions.add(this.convertTuple(tuple.modifier(), tuple.function()));
final double tempDamage = tuple.function().applyAsDouble(finalDamage);
finalDamage += tempDamage;
modifierMapBuilder.add(new Tuple<>(tuple.modifier(), tempDamage));
mapBuilder.put(tuple.modifier(), tempDamage);
this.modifiers.put(tuple.modifier(), tempDamage);
functionListBuilder.add(this.convertTuple(tuple.modifier(), tuple.function()));
}
this.originalFinalAmount = finalDamage;
this.originalModifiers = List.copyOf(modifierMapBuilder);
this.originalModifierMap = Map.copyOf(mapBuilder);
return List.copyOf(functionListBuilder);
protected List<T> init(double baseAmount, List<T> functions) {
functions.stream().map(entry -> this.convertTuple(entry.modifier(), entry.function())).forEach(this.modifierFunctions::add);
this.originalFinalAmount = this.recalculate(baseAmount);
this.originalModifiers = this.modifiers.entrySet().stream().map(e -> new Tuple<>(e.getKey(), e.getValue())).toList();
this.originalModifierMap = Map.copyOf(this.modifiers);
return functions.stream().map(entry -> this.convertTuple(entry.modifier(), entry.function())).toList();
}

protected abstract T convertTuple(M obj, DoubleUnaryOperator function);

protected void recalculateDamages(final double baseAmount) {
double tempAmount = baseAmount;
this.modifiers.clear();
for (T entry : this.modifierFunctions) {
final double modifierAmount = entry.function().applyAsDouble(tempAmount);
if (this.modifiers.containsKey(entry.modifier())) {
final double oldAmount = this.modifiers.get(entry.modifier());
final double difference = oldAmount - modifierAmount;
if (oldAmount > 0) {
this.modifiers.put(entry.modifier(), Math.max(0, oldAmount - difference));
} else {
this.modifiers.put(entry.modifier(), Math.min(0, oldAmount - difference));
}
} else {
this.modifiers.put(entry.modifier(), modifierAmount);
protected double recalculate(final double baseAmount) {
final var amounts = AbstractModifierEvent.recalculate(this.modifierFunctions, baseAmount, this.modifiers);
return amounts.values().stream().mapToDouble(Double::doubleValue).sum();
}

private static <T extends ModifierFunction<M>, M> Map<ResourceKey, Double> recalculate(final List<T> functions, final double baseAmount, final Map<M, Double> into) {
into.clear();
final var defaultGroup = ResourceKey.sponge("default");
final Map<ResourceKey, Double> amounts = new HashMap<>();
for (T func : functions) {
var group = defaultGroup;
if (func.modifier() instanceof DamageModifier damageModifier) {
group = damageModifier.group();
}
tempAmount += modifierAmount;
var amount = amounts.compute(group, (k, v) -> func.function().applyAsDouble(v == null ? baseAmount : v));
into.put(func.modifier(), amount);
}
return amounts;
}

protected double finalAmount(final double baseAmount) {
double damage = baseAmount;
for (final T entry : this.modifierFunctions) {
damage += entry.function().applyAsDouble(damage);
}
return damage;
final var amounts = AbstractModifierEvent.finalAmounts(baseAmount, this.modifierFunctions);
return amounts.values().stream().mapToDouble(Double::doubleValue).sum();
}

public static <T extends ModifierFunction<M>, M> Map<ResourceKey, Double> finalAmounts(final double baseAmount, final List<T> modifiers) {
return AbstractModifierEvent.recalculate(modifiers, baseAmount, new LinkedHashMap<>());
}

/**
Expand Down

0 comments on commit 2a00155

Please sign in to comment.