public interface AttackEntityEvent extends TargetEntityEvent, Cancellable
Entity is being "attacked".
The uniqueness of this event is that all DamageSources can deal
varying amounts of damage with varying modifiers based on various reasons.
Due to this ambiguous variety of information that is possible to provide,
the AttackEntityEvent can be summarized as so:
An Arrow,
that was shot by a Skeleton,
with an enchanted ItemTypes.BOW ItemStack,
when the World Difficulty was set to
Difficulties.HARD,
will deal possibly "5" damage to any Entity it hits.
The issue with representing this type of "logic flow" is that a
particular amount of damage from a DamageSource, even if specified
to a particular DamageType, has no static finalized amount of damage
to deal to a particular Entity. To properly represent this,
a DamageSource has various "states" such as:
DamageSource.isAbsolute(), or DamageSource.isBypassingArmor().
Quite simply, the DamageSource will always be the "first" element
within a Cause that can be retrieved from Event.getCause().
Next, any additional "aides" in attacking the Entity will
be included in order of "priority of relation" to "attacking" the entity. In
short, if another Entity is considered a "team member" to the
attacking Entity, the "team member" may be a second element within
the Cause. The same can be said if an Arrow was shot from
a Dispenser that was triggered by a Player flipping a
switch.
Continuing with the notion of "modifiers" to damage, the "base" damage
is modified or added onto after various unknown methods are called or
processed on the damage. Optimally, these modifiers can be traced to a
particular object, be it an ItemStack, Difficulty, or
simply an an attribute. The interesting part is that these "modifiers"
do not just define a static value to add to the "base" damage, they
are usually a loose form of a Function that are applied to
the "base" damage. Given that Cause has a unique capability of
storing any and every Object willing to be passed into it, we
can easily represent these "sources" of "modifiers" in a Cause.
Now, knowing the "source" will not provide enough information, so a
DamageModifierType is provided with a DamageModifier to
paint the fullest picture of "explaining" the DamageModifier as to
why it is present, and why it is "modifying" the "base" damage. Finally,
we can associate a DamageModifier with a Function that is
passed the current "damage" into Function.apply(Object), being added
to the current "damage". After all DamageModifier Functions
are "applied", the overall "damage" is now the final damage to actually
throw a AttackEntityEvent.
Note that due to the mechanics of the game, DamageModifiers
are always ordered in the order of which they apply their modifier onto
the "base" damage. The implementation for getFinalOutputDamage() can
be exemplified like so:
double damage = this.baseDamage;
for (Map.Entry<DamageModifier, Function<? super Double, Double>>
entry : this.modifierFunctions.entrySet()) {
damage += checkNotNull(entry.getValue().apply(damage));
}
return damage;
After which, the "final" damage is simply the summation of the
"base" damage and all "modified damage" for each DamageModifier
provided in this event.
Coming forward, it is possible to further customize not only the "base"
damage, but override pre-existing DamageModifier Functions
by calling setOutputDamage(DamageModifier, DoubleUnaryOperator) at which point the
end result may be undefined. However, if a custom DamageModifier
that aims to alter the "final" damage based on some custom circumstances,
calling setOutputDamage(DamageModifier, DoubleUnaryOperator) on a new
DamageModifier instance, easily created from the
DamageModifier.Builder,
the provided pairing will be added at the
"end" of the list for "modifying" the "base" damage.
Note that this event is intended for processing incoming damage to
an Entity prior to any DamageModifiers associated with
the TargetEntityEvent.getTargetEntity(). The AttackEntityEvent is used
to process the various DamageModifiers of which originate or are
associated with the targeted Entity.
| Modifier and Type | Field and Description |
|---|---|
static String |
ABSORPTION
For use with a
DamageModifier where it's type is a
DamageModifierTypes.ABSORPTION and the Cause contains
a PotionEffect. |
static String |
BOOTS
For use with a
DamageModifier where it's type is a
DamageModifierTypes.ARMOR and the Cause contains
an ItemStackSnapshot for "boots". |
static String |
CHESTPLATE
For use with a
DamageModifier where it's type is a
DamageModifierTypes.ARMOR and the Cause contains
an ItemStackSnapshot for a "chestplate". |
static String |
CREATOR
For use with a
DamageModifier where the root cause is "created"
by an object, usually the Entity or Living entity. |
static String |
GENERAL_ARMOR
For use with a
DamageModifier where it's type is a
DamageModifierTypes.ARMOR and the Cause contains
an ItemStackSnapshot. |
static String |
HARD_HAT_ARMOR
For use with a
DamageModifier where it's type is a
DamageModifierTypes.HARD_HAT and the Cause contains
an ItemStackSnapshot, usually a helmet. |
static String |
HELMET
For use with a
DamageModifier where it's type is a
DamageModifierTypes.ARMOR and the Cause contains
an ItemStackSnapshot for a "helmet". |
static String |
LEGGINGS
For use with a
DamageModifier where it's type is a
DamageModifierTypes.ARMOR and the Cause contains
an ItemStackSnapshot for "leggings". |
static String |
NOTIFIER
For use with a
DamageSource where it is either a
BlockDamageSource or EntityDamageSource such that
it was last "notified" by the object represented in the cause. |
static String |
RESISTANCE
For use with a
DamageModifier where it's type is a
DamageModifierTypes.HARD_HAT and the Cause contains
a PotionEffect. |
static String |
SHIELD
or use with a
DamageModifier where its type is a
DamageModifierTypes.SHIELD and the Cause contains
an ItemStackSnapshot (in Vanilla, a shield). |
static String |
SOURCE
For use with the
DamageSource that is known as the "source"
of the damage. |
| Modifier and Type | Method and Description |
|---|---|
void |
addDamageModifierAfter(DamageModifier damageModifier,
DoubleUnaryOperator function,
Set<DamageModifierType> after)
Adds the provided
DamageModifier and Function to the list
of modifiers, such that the modifier will appear in order after any
current modifiers whose type are included in the provided Set
of DamageModifierTypes. |
void |
addDamageModifierBefore(DamageModifier damageModifier,
DoubleUnaryOperator function,
Set<DamageModifierType> before)
Adds the provided
DamageModifier and Function to the
list of modifiers, such that the Set containing
DamageModifierTypes provided in before will appear
after the provided damage modifier. |
double |
getBaseOutputDamage()
Gets the "base" damage to deal to the targeted
Entity. |
double |
getFinalOutputDamage()
Gets the final damage that will be passed into the proceeding
AttackEntityEvent. |
int |
getKnockbackModifier()
Gets the knock back modifier.
|
List<DamageFunction> |
getModifiers()
|
double |
getOriginalDamage()
Gets the original "raw" amount of damage to deal to the targeted
Entity. |
Map<DamageModifier,Double> |
getOriginalDamages()
Gets an
ImmutableMap of all original DamageModifiers
and their associated "modified" damage. |
double |
getOriginalFinalDamage()
Gets the original "final" amount of damage after all original
DamageModifiers are applied to getOriginalDamage(). |
List<ModifierFunction<DamageModifier>> |
getOriginalFunctions()
|
double |
getOriginalModifierDamage(DamageModifier damageModifier)
Gets the original damage for the provided
DamageModifier. |
double |
getOutputDamage(DamageModifier damageModifier)
Gets the damage for the provided
DamageModifier. |
boolean |
isModifierApplicable(DamageModifier damageModifier)
Checks whether the provided
DamageModifier is applicable to the
current available DamageModifiers. |
void |
setBaseOutputDamage(double baseDamage)
Sets the "base" damage to deal to the targeted
Entity. |
void |
setKnockbackModifier(int modifier)
Sets the knock back modifier.
|
void |
setOutputDamage(DamageModifier damageModifier,
DoubleUnaryOperator function)
Sets the provided
Function to be used for the given
DamageModifier. |
getTargetEntitygetCause, getContext, getSourceisCancelled, setCancelledstatic final String SOURCE
DamageSource that is known as the "source"
of the damage.static final String HARD_HAT_ARMOR
DamageModifier where it's type is a
DamageModifierTypes.HARD_HAT and the Cause contains
an ItemStackSnapshot, usually a helmet.static final String SHIELD
DamageModifier where its type is a
DamageModifierTypes.SHIELD and the Cause contains
an ItemStackSnapshot (in Vanilla, a shield).static final String GENERAL_ARMOR
DamageModifier where it's type is a
DamageModifierTypes.ARMOR and the Cause contains
an ItemStackSnapshot. Separate from hard hat but still
considered as "armor" where it will absorb a certain amount of damage
before dealing damage to the wearer.static final String HELMET
DamageModifier where it's type is a
DamageModifierTypes.ARMOR and the Cause contains
an ItemStackSnapshot for a "helmet".static final String CHESTPLATE
DamageModifier where it's type is a
DamageModifierTypes.ARMOR and the Cause contains
an ItemStackSnapshot for a "chestplate".static final String LEGGINGS
DamageModifier where it's type is a
DamageModifierTypes.ARMOR and the Cause contains
an ItemStackSnapshot for "leggings".static final String BOOTS
DamageModifier where it's type is a
DamageModifierTypes.ARMOR and the Cause contains
an ItemStackSnapshot for "boots".static final String RESISTANCE
DamageModifier where it's type is a
DamageModifierTypes.HARD_HAT and the Cause contains
a PotionEffect.static final String ABSORPTION
DamageModifier where it's type is a
DamageModifierTypes.ABSORPTION and the Cause contains
a PotionEffect.static final String CREATOR
DamageModifier where the root cause is "created"
by an object, usually the Entity or Living entity.static final String NOTIFIER
DamageSource where it is either a
BlockDamageSource or EntityDamageSource such that
it was last "notified" by the object represented in the cause.
Usually this is used where a Player interacted with the
now DamageSource such that they
double getOriginalDamage()
Entity.double getOriginalFinalDamage()
DamageModifiers are applied to getOriginalDamage().
The "final" damage is considered the amount of health being lost by
the Entity, if health is tracked.Map<DamageModifier,Double> getOriginalDamages()
ImmutableMap of all original DamageModifiers
and their associated "modified" damage. Note that ordering is not
retained.double getOriginalModifierDamage(DamageModifier damageModifier)
DamageModifier. If
the provided DamageModifier was not included in
getOriginalDamages(), an IllegalArgumentException is
thrown.damageModifier - The original damage modifierList<ModifierFunction<DamageModifier>> getOriginalFunctions()
double getBaseOutputDamage()
Entity. The
"base" damage is the original value before passing along the chain of
Functions for all known DamageModifiers.void setBaseOutputDamage(double baseDamage)
Entity. The
"base" damage is the original value before passing along the chain of
Functions for all known DamageModifiers.baseDamage - The base damagedouble getFinalOutputDamage()
AttackEntityEvent. The final damage is the end result of the
getBaseOutputDamage() being applied in Function.apply(Object)
available from all the Tuples of DamageModifier to
Function in getOriginalFunctions().boolean isModifierApplicable(DamageModifier damageModifier)
DamageModifier is applicable to the
current available DamageModifiers.damageModifier - The damage modifier to checkdouble getOutputDamage(DamageModifier damageModifier)
DamageModifier. Providing that
isModifierApplicable(DamageModifier) returns true,
the cached "damage" for the DamageModifier is returned.damageModifier - The damage modifier to get the damage forvoid setOutputDamage(DamageModifier damageModifier, DoubleUnaryOperator function)
Function to be used for the given
DamageModifier. If the DamageModifier is already
included in getModifiers(), the Function replaces
the existing function. If there is no Tuple for the
DamageModifier, a new one is created and added to the end
of the list of Functions to be applied to the
getBaseOutputDamage().
If needing to create a custom DamageModifier is required,
usage of the
DamageModifier.Builder
is recommended.
damageModifier - The damage modifierfunction - The function to map to the modifiervoid addDamageModifierBefore(DamageModifier damageModifier, DoubleUnaryOperator function, Set<DamageModifierType> before)
DamageModifier and Function to the
list of modifiers, such that the Set containing
DamageModifierTypes provided in before will appear
after the provided damage modifier.damageModifier - The damage modifier to addfunction - The associated functionbefore - The set containing the modifier types to come after
the provided modifiervoid addDamageModifierAfter(DamageModifier damageModifier, DoubleUnaryOperator function, Set<DamageModifierType> after)
DamageModifier and Function to the list
of modifiers, such that the modifier will appear in order after any
current modifiers whose type are included in the provided Set
of DamageModifierTypes.damageModifier - The damage modifier to addfunction - The associated functionafter - The set of modifier types to come before the new modifierList<DamageFunction> getModifiers()
Tuples of DamageModifier keyed to
their representative Functions. All DamageModifiers are
applicable to the entity based on the DamageSource and any
possible invulnerabilities due to the DamageSource.int getKnockbackModifier()
void setKnockbackModifier(int modifier)
modifier - The knock back modifier to set