forked from phenom/healer-man
Update Healer Man server
This commit is contained in:
1 parent
39458d5de6
commit
6cc1b9217f
203 files changed
+133929
-31271
No files matched your search
@@ -0,0 +1,111 @@
|
||||
# RoM native Priest healing source adapter
|
||||
|
||||
This is a local RuneWaker source implementation for native RoM healing. It is
|
||||
not a Chronicles of Arcadia formula, and it does not infer a spell rank from a
|
||||
source catalog value. `MagicProc.MagicLv` is a required runtime input. The
|
||||
simulator may explicitly map its trained skill level to
|
||||
`clamp(characterLevel, 1, 80)`; that is simulator policy, not a claim about the
|
||||
source database's configured `MagicLV` field.
|
||||
|
||||
## Direct HolyHeal
|
||||
|
||||
`romNativeHealing.ts` resolves the `MagicProcess.cpp` `AtkCalType::HolyHeal`
|
||||
branch. The source equation is:
|
||||
|
||||
```text
|
||||
OrgPower = DmgPower + DmgPower * DmgPower_SkillLVArg * MagicLv / 100
|
||||
SpellTime = MagicCol.SpellTime; use 1 when below 1 or IsFixDmgEffect is true
|
||||
MNDPart = MND * 0.3 * SpellTime
|
||||
Power = OrgPower * 6 when OrgPower * 5 < MNDPart; otherwise OrgPower + MNDPart
|
||||
unless IsIgnoreDmgEffect:
|
||||
add MDMG * FIX.Dmg_HealArg, once when fixed or multiplied by SpellTime otherwise
|
||||
Power = Power * MPow * HealPowerRate + HealPoint * SpellTime
|
||||
per target, apply Atk.Rand variation
|
||||
unless MagicBase.SettingEx.IgnoreMagicAbsorb:
|
||||
Power = Power * (1 + HealAbsorbRate / 100) + HealAbsorb
|
||||
clamp Power below zero; reverse sign for undead; suppress negative undead output out of combat
|
||||
```
|
||||
|
||||
The generated source map binds ability and rank identity to raw `MagicCollect`
|
||||
rows and direct HP `MagicObject` components. It preserves source component IDs,
|
||||
`AtkCalType`, signed `DmgPower`, its skill-level argument, fixed fields,
|
||||
random range, critical rate, `SpellTime`, range/sharing data, and the distinct
|
||||
`MagicCollect` timing flags and mode flags. `holyHealBindings` is the 18-row
|
||||
subset with `AtkCalType == 5`; `attackBindings` retains all 225 direct HP
|
||||
ability rows for shared combat integrations.
|
||||
|
||||
The Priest bindings include Heal (`490261`, `DmgPower 90`, argument `30`,
|
||||
`SpellTime 2`), Group Heal (`490281`, `DmgPower 65`, argument `20`,
|
||||
`SpellTime 3`), and Urgent Heal (`491147`, `DmgPower 35`, argument `20`,
|
||||
`SpellTime 1`). Their exact component and rank records are in the generated
|
||||
metadata. The helper expects already-effective native caster and recipient
|
||||
channels; callers must not run generic healing modifiers a second time when
|
||||
those modifiers were included in the effective inputs.
|
||||
|
||||
## Periodic HP healing
|
||||
|
||||
Runewaker has a separate native HoT path. It is not a HolyHeal cast repeated
|
||||
each tick. `MagicProcess.cpp` computes the applied buff duration and invokes
|
||||
`CalAddDotMagicLv`; `RD_Normal.cxx` calculates the buff's source rank
|
||||
correction; `RD_ValueCal.cxx::BuffProc` uses the frozen `Buff.Power` at each
|
||||
tick. The helper supports active positive magical `DotMagic` with HP type 0,
|
||||
including Priest's Regenerate (`490269`). It deliberately returns no result
|
||||
for unsupported `DotMagic` types, including percentage HP type 5.
|
||||
|
||||
At application, the source first derives actual buff duration from
|
||||
`EffectTime`, `EffectTime_SkillLVArg`, `DLV_EffectTime`, and owner/target
|
||||
levels, then uses `DotTimes = max(1, int(EffectTime / Dot.Time))`. For a
|
||||
positive magic HP dot, the source calculates:
|
||||
|
||||
```text
|
||||
DotBase = Dot.Base * (1 + MagicLv * DotSkillLVArg / 100)
|
||||
ExRate = 0.6 + abs(DotBase) / 600 for an IsPlayer owner; otherwise 1
|
||||
Power = DotBase + ExRate * MDMG * int(SpellTime) * FIX.Dmg_HealDotArg / DotTimes
|
||||
MNDPart = MND * 0.3 * int(SpellTime) / DotTimes
|
||||
Power = Power * 6 when Power * 5 < MNDPart; otherwise Power + MNDPart
|
||||
Power = Power * HealPowerRate + HealPoint * int(SpellTime) / DotTimes
|
||||
unless IgnoreMagicAbsorb:
|
||||
Power = Power * (1 + HealAbsorbRate / 100) + HealAbsorb / DotTimes
|
||||
clamp Power below zero; Power *= MagicPow(MagicType)
|
||||
MagicLvAdjustment = int((Power - Dot.Base) / (Dot.Base * DotSkillLVArg / 100) - MagicLv)
|
||||
Buff.Power = MagicLvAdjustment + MagicLv
|
||||
```
|
||||
|
||||
`FixDotPower` or a zero `DotSkillLVArg` bypasses the rank correction, leaving
|
||||
`Buff.Power = MagicLv`. The source tick then computes
|
||||
`Damage = int(-Dot.Base * (100 + DotSkillLVArg * Buff.Power) / 100)` and applies
|
||||
`AddHP(-Damage)`. C++ integer conversion truncates toward zero. Recipient
|
||||
absorb and caster channels are captured through the buff-rank correction at
|
||||
application; the source does not reapply them on each tick. The helper returns
|
||||
the resulting integer tick amount and the `DotTimes` interval count so the
|
||||
runtime can preserve that application snapshot.
|
||||
|
||||
The live helper requires an explicit effective
|
||||
`MagicPow(MagicType)` value. The existing native stat sidecar has an all-magic
|
||||
neutral MPow channel but does not expose all six element-specific MPow
|
||||
`BodyRate` channels. The caller must supply an effective source value when
|
||||
element-specific modifiers are modeled. For this simulator's active
|
||||
player-build identities, `sourceIsPlayer=true` is an explicit policy applied
|
||||
to both the active player and party companions; the original `IsPlayer()` test
|
||||
itself distinguishes actual server player roles.
|
||||
|
||||
The current Priest Regenerate source row contains positive HP DotMagic
|
||||
components `500469` (argument 18), `621318` (argument 18), and `621548`
|
||||
(argument 25). They share `Dot.Time 2`, `Dot.Base 20`, and duration 20 seconds.
|
||||
The generated map retains each component ID so the runtime can use the
|
||||
component selected by its own source semantics instead of guessing which raw
|
||||
component is active.
|
||||
|
||||
## Source snapshot and limits
|
||||
|
||||
The generated artifact is
|
||||
`src/game/generated/romNativeHolyHealBindings.generated.json`; regenerate it
|
||||
with `scripts/runewaker-pipeline/export-rom-native-healing.mjs`. It is tied to
|
||||
the current hashes of `magiccollectobject.db`, `magicobject.db`, the local
|
||||
server formula files, the player catalog, and generated native stat rules.
|
||||
The output includes 225 direct-attack ability rows, 18 HolyHeal ability rows,
|
||||
and 8 positive magical HP DotMagic ability rows across the catalog.
|
||||
|
||||
The data and formula boundary is the local RuneWaker source version hashed in
|
||||
that artifact. This work does not add CoA rank data, model percentage HP
|
||||
periodics, or infer unavailable source skill levels from `configuredCollectMagicLevel`.
|
||||
Reference in new issue
Block a user