Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expansion of Living Damage Event Sequence #548

Closed
wants to merge 5 commits into from
Closed

Expansion of Living Damage Event Sequence #548

wants to merge 5 commits into from

Conversation

Caltinor
Copy link
Contributor

Damage Events Overhaul

This expands upon the event sequence tied to damaging living entities. The goal of these changes are:

  1. Fill gaps in the damage sequence, which are currently unexposed to modders
  2. Implement a solution that does not affect existing implementations

Background/Context

currently the sequence of damage events and calculations is as follows:

  1. play behavior results in LivingEntity#hurt being called
    1. NeoForge posts LivingAttackEvent, an immutable reference to damage intended to be applied by the attacker for the entity provided, cancellation prevents all subsequent behavior
    2. Cancel the damage if:
      1. entity is invulnerable
      2. entity is already dead/dying
      3. source is in the fire tag and entity has fire resistance
    3. else
      1. Check if damage is blocked
        1. NeoForge posts ShieldBlockEvent, which allows modification of the damage and whether the shield takes durability loss
        2. multiplies the damage by 5 if the damage source IS_FREEZING and entity is in the FREEZE_HURTS_EXTRA_TYPES tag
      2. if entity has invulnerability remaining and damage source does not bypass cooldowns
        1. call actuallyHurt for damage less than last damage received
      3. else
        1. call actuallyHurt for whole damage

LivingEntity#actuallyHurt sequence

  1. skip all logic if entity is invulnerable to this specific damage source
  2. NeoForge posts LivingHurtEvent, which allows mutation of the damage.
    • if damage after the event <= 0 all subsequent behavior ignored
  3. armor reduction applied to damage and durability lost
  4. damage reduced if resistance effect is active
  5. enchantment effects are applied to reduce damage
  6. damage is reduced by the absorption amount
  7. absorption is reduced by the amount consumed from above
  8. Absorbed damage stat increased by absorption consumed
  9. NeoForge posts LivingDamageEvent, which allows mutation of the damage. subsequent behavior ignored if damage output is zero
  10. Damage added to combat tracker
  11. Health is then reduced by the final damage value
  12. Absorption is reconsumed based on event-output damage
  13. vanilla gameEvent triggered for ENTITY_DAMAGE

back to LivingEntity#hurt sequence

Once actuallyHurt logic completes, the hurt behavior continues with the following

  1. damage sources that harm helmets apply the post-actuallyhurt damage to the helmet
  2. set lastHurtBy properties
  3. if not hurt while invulnerability remained
    • broadcast entity event based on shield block outcome from above
    • mark hurt if damage actually dealt
    • apply knockback
  4. if damage would cause death, check for totem of undying, else die
    • NeoForge posts LivingUseTotemEvent during this check
  5. else, play hurt sound
  6. update internal damage source field
  7. trigger advancement criteria based on whether this and/or the source entity was a player

Upstream behavior significant to the above sequence

Player#hurt, ServerPlayer#hurt, RemotePlayer#hurt, and LocalPlayer#hurt overrides

  • Invokes LivingAttackEvent before later calling super.hurt which starts with another LivingAttackEvent
  • prevents super.hurt from being called for peaceful mode and invulnerability checks

ArmorStand#hurt override

  • ignores all damage events

WitherBoss#hurt override

  • ignores all damage and damage events if damage source entity is the same mob type as the wither

Identified Gaps

Based on the above sequence and event distribution, this PR attempts to address the following gaps

  1. Armor reduction and damage to the armor
  2. Magic reduction
  3. Absorption consumed
  4. References to the original damage

Areas for potential implementation

  1. invulnerability checks
  2. fireproof checks

Lastly

I started this as a draft in case there was any feedback regarding additional content to implement, or changes in how the current implementation was done. Once any input, if any, has been incorporated, I will create the tests and submit for review.

@neoforged-pr-publishing
Copy link

  • Publish PR to GitHub Packages

@sciwhiz12 sciwhiz12 added enhancement New (or improvement to existing) feature or request 1.20 Targeted at Minecraft 1.20 labels Jan 22, 2024
@Caltinor Caltinor closed this Jan 27, 2024
@Caltinor Caltinor deleted the living_damage_rework branch January 27, 2024 21:50
@Caltinor
Copy link
Contributor Author

The scope of this PR was expanded. A fresh PR will be created with a cleaner git history.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
1.20 Targeted at Minecraft 1.20 enhancement New (or improvement to existing) feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants