Interface AttackEntityEvent

  • All Superinterfaces:
    Cancellable, Event
    All Known Implementing Classes:
    AbstractAttackEntityEvent

    public interface AttackEntityEvent
    extends Event, Cancellable
    Represents the base event for when an 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 ArrowEntity, 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.cause().

    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 ArrowEntity 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 finalOutputDamage() can be exemplified like so:

    
     double damage = this.baseDamage;<br />
     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 entity(). The AttackEntityEvent is used to process the various DamageModifiers of which originate or are associated with the targeted Entity.