Skip to content

What the attacker does to the defender's resistances - #2308

Open
denislauri1999 wants to merge 1 commit into
NosCoreIO:masterfrom
denislauri1999:pr/enemy-element-resistance
Open

What the attacker does to the defender's resistances#2308
denislauri1999 wants to merge 1 commit into
NosCoreIO:masterfrom
denislauri1999:pr/enemy-element-resistance

Conversation

@denislauri1999

@denislauri1999 denislauri1999 commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

BCard type 14, "Changes enemy's resistances"210 declarations, and the mirror of type 13 in #2307. That one is the resistance of whoever is being hit; this is what the one hitting does to it, so it rides on the attacker and is read against the defender's own number.

11: Increases the enemy's elemental resistances by %s.
12: Reduces the enemy's elemental resistances by %s.
21..52: the same, one element at a time.

A "reduces by 20" folds to -20, so the damage step simply adds the two. The sign is the whole point: read backwards, resistance-piercing effects would protect the target instead, and nothing would report it — the fight goes on and the numbers are just wrong.

Written on the fold rather than beside the equipment, so the 194 declarations on items arrive with no further work once the worn pieces' BCards reach the same place.

The tests needed a second layer

Four of the seven go through the damage step with the field set by hand. A mutation that folded the water value into the fire field left all four green — so three more go through BattleStatsProvider itself. Testing the new code and not the step that fills it is a hole I had pointed out to me on #2304 earlier today.

Flipping the sign fails two; folding the wrong element fails one.

One known conflict, and it is trivial

This conflicts with #2305 on CombatStats.cs, and only there. Both PRs add optional parameters to the same positional record, and C# requires those to come last — so both insertions land at the same point and git cannot merge them. The resolution is keep both blocks; nothing has to be decided.

I checked every other pair among my open PRs with git merge-tree (36 combinations) and this is the only one left.

Summary by CodeRabbit

  • New Features

    • Elemental resistance increases and reductions from active buffs now affect combat damage calculations.
    • Added support for fire, water, light, dark, and all-element resistance modifiers.
    • Resistance modifiers are applied only to matching attack elements.
  • Bug Fixes

    • Improved handling of resistance-piercing and resistance-increasing effects, including zero-value and sign behavior.

BCard type 14, "Changes enemy's resistances": 210 declarations, and the mirror
of the type 13 just added. That one is the resistance of whoever is being hit;
this is what the one hitting does to it, so it rides on the attacker and is read
against the defender's own number.

    11: Increases the enemy's elemental resistances by %s.
    12: Reduces the enemy's elemental resistances by %s.
    21..52: the same, one element at a time.

A "reduces by 20" folds to -20, so the damage step simply adds the two. The sign
is the whole point: read backwards, resistance-piercing effects would protect
the target instead, and nothing would report it.

Written on the fold rather than beside the equipment, so the 194 declarations on
items arrive with no further work once the worn pieces' BCards reach the same
place.

Three of the seven tests go through BattleStatsProvider and not only through the
damage step. The first four set the field by hand, and a mutation that folded
the water value into the fire field left all four green - the fold needed tests
of its own, which is the same hole one level up that a review found earlier
today.

Flipping the sign fails two; folding the wrong element fails one.
@coderabbitai

coderabbitai Bot commented Aug 24, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: cafbb3ba-fd85-4c73-852c-475056b56fa9

📥 Commits

Reviewing files that changed from the base of the PR and between 55dc38c and 600d95b.

📒 Files selected for processing (4)
  • src/NosCore.GameObject/Services/BattleService/BattleStatsProvider.cs
  • src/NosCore.GameObject/Services/BattleService/DamageCalculator.cs
  • src/NosCore.GameObject/Services/BattleService/Model/CombatStats.cs
  • test/NosCore.GameObject.Tests/Services/BattleService/EnemyElementResistanceTests.cs

Included review availability: Your plan provides up to 2 included reviews per hour; 1 remains after this review.


Walkthrough

The battle system now collects enemy elemental resistance modifiers from buffs, stores them in CombatStats, and applies them to matching elemental damage calculations. Tests cover element-specific and all-element modifiers, signed values, zero values, and non-attacking elements.

Changes

Enemy elemental resistance modifiers

Layer / File(s) Summary
Resistance stat aggregation
src/NosCore.GameObject/Services/BattleService/Model/CombatStats.cs, src/NosCore.GameObject/Services/BattleService/BattleStatsProvider.cs
CombatStats stores four attacker-side enemy resistance values. BattleStatsProvider sums all-element and element-specific resistance buffs and applies the results.
Elemental damage application and validation
src/NosCore.GameObject/Services/BattleService/DamageCalculator.cs, test/NosCore.GameObject.Tests/Services/BattleService/EnemyElementResistanceTests.cs
DamageCalculator combines defender resistance with the attacker’s matching modifier. Tests verify resistance arithmetic, element selection, sign preservation, and all-element folding.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: ⚪ Minimal · up to 600d9

The change is localized to attacker-side resistance handling and damage calculation, with targeted coverage included. No actionable merge-blocking risk remains after normal checks and review.

Sequence Diagram(s)

sequenceDiagram
  participant ActiveBuffs
  participant BattleStatsProvider
  participant CombatStats
  participant DamageCalculator
  participant Defender
  ActiveBuffs->>BattleStatsProvider: provide enemy resistance buffs
  BattleStatsProvider->>CombatStats: store accumulated elemental modifiers
  Defender->>DamageCalculator: provide elemental resistance
  CombatStats->>DamageCalculator: provide matching enemy resistance modifier
  DamageCalculator->>DamageCalculator: calculate elemental damage
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: attacker effects modify defender elemental resistances.
Docstring Coverage ✅ Passed Docstring check was indeterminate for this PR — some files could not be analyzed in time. Not blocking.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@denislauri1999

Copy link
Copy Markdown
Contributor Author

Heads-up for whoever merges: this compiles on its own but not alongside another of my open PRs, and git will not warn you — the merge is clean and the break shows up at build time.

BattleStatsProvider gains an IEquipmentStatsService parameter in #2293. The tests this PR adds construct it with one argument, so after both land they need new Mock<IEquipmentStatsService>().Object as a second.

I found it by merging all nine of today's branches onto a scratch branch: with those two lines fixed the lot builds at zero warnings and passes 983 tests. Pairwise git merge-tree says every combination is clean, which is true and not enough.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant