Files
sacred_k/docs/dwarf-arts.md
T
khallaandClaude Opus 5.5 471b8b13d5 Eingraben: 2 s move inside a barrier turning solid, 4 s duration
The barrier's model alpha goes to opaque over 1 s, the dwarf is moved,
and it clears over 1 s; orders to him are refused meanwhile (new
game::FilterCreatureOrders). The art's duration in its definition is a
fixed 4 s (was 7 + level), which the barrier, its bonus and the tooltip use.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 01:28:07 +01:00

8.1 KiB
Raw Blame History

Dwarf arts: Kanonenschuss, Mörsergranate, Eingraben

Requests (2026-10-25 / 2026-10-26)

  • Kanonenschuss (art 0x43f, gui_spells_kanone): "remove the knockback, instead it can be just a stun" (chosen: no push, only a stun); the range increased for the wider view; the stun particles not on targets that avoided the stun. The game's stun resistance stays (2026-10-26: "we dont ignore anything, the skill is fine for now").
  • Mörsergranate (art 0x43e, gui_spells_moerser): "the radius of the explosion should increase every 5 skill levels".

Measured

  • The cannon's code is the combat move function 0x5145d0, case 0x43f. Its ray: cmp edi,19h at 0x517389, 25 steps of 40 = 1000 range. Hostile targets get cEvent_creature 5 from 0x51768d.
  • Stun chance 0x4fc810(level, creature) = level × 5 / creature level × 100 (UI_STAT_STUNNCHANCE). On a successful roll: 0x5936e0(MOTION_HIT_A 0xaf, 3.0, 0.25) at 0x517709 (pushes from 0x5176f8), then the stun order cEvent_creature 3 with +0x14 = 100, sent by call [eax+18h] at 0x5177aa (returns to 0x5177ad).
  • The stun is the knockback. cCreature::ReceiveOrder 0x52e400 case 3: first the resistance vf24(0x50) (0x55d0a0: flag +0x4f0 & 0x1000 resists 2 in 3, effect 0x35d a percentage); otherwise push left +0x24d = 100, flag +0x200 |= 0x20000, attacker +0x259, ResetToIdle. cCreature::Update branch 0x594c82 moves a creature with that flag away from the attacker and lowers the push left by each step (0x594deb), measured about 100 units in 0.3 s; at 0 the flag is cleared.
  • The impact effect TYPE_FX_DWARF_SHOOT_IMPACT (0x47f) is created on every hit target by CreateAt at 0x517855 (target in ebx), resisted or not.
  • Mörsergranate: the grenade (type 0x3fa) lands and creates TYPE_FX_GRENADEIMPACT (0x3fc), which gathers its targets with cObjectManager 0x5ff820 (called from 0x5ab400 at 0x5ab63d): a creature is hit when its distance is below the impact's size (150, type table 0x428bb0) plus its own type's size.

The mod (src/mods/dwarfarts.cpp)

  • The HIT_A motion is jumped over (0x5176f8: jmp past the call).
  • The push step at 0x594deb calls PushStepThunk: creatures the cannon stunned (order 3 from 0x5177ad, kept with an end time) move by 0 and keep their push left above 0 for 1.5 s, so they stand still, then carry on.
  • The impact effect is created only on targets in the stun state.
  • The ray gets 45 steps (1800); confirmed to reach across the widened view.
  • The impact's gather call gets a radius of size × (1 + 0.1 × (level / 5)), with the owner's Mörsergranate level (game::ArtLevel). The growth 0.1 per step is our choice; not yet seen in the game (Borf's level is 2).

Mörsergranate impact marker (asked 2026-10-25, done 2026-10-26)

"Show exactly where the grenade will land and its explosion radius, a red circle with low alpha on the ground."

Measured:

  • The landing point is decided at launch (0x5145d0 case 0x43e): the target's position, or, closer than 200, a point 200 from the dwarf with a +-15 jitter. It goes to the new grenade (type 0x3fa) in cEventFX 0x96, constructed at 0x5169fa (cEventFX::Construct 0x41e0a0, thiscall, ret 0x44: code, owner id, target id, position area / x / y / level, ...).
  • The impact gathers its targets at exactly that point, on several frames. The grenade object stays about 30 s after the explosion.
  • Ground -> screen: 0x622700 (world units -> world pixels, the isometric plane), then (pixel - camera +0x14/+0x18) / zoom +0xb60 + screen centre (floating texts 0x41e546). Checked with the hero: the screen centre.
  • The world view draws the ground (0x62d530, ground quad list), then the objects.

Mod: the construct call notes grenade, owner, landing point and radius (ImpactRadius, shared with the hit check); after 0x62d530 a disc (alpha 0x40) with a 2 px rim (alpha 0xa0) is drawn there, without depth test, until the impact of that owner's grenade at that point gathers its targets.

Tooltip (2026-10-26, "the skills tooltip does not show the current radius"): a game::Art tooltip filter adds "Explosionsradius: N" after the last value line of each level section (current level, and the next level's in the skill book), in that line's colour, from the same ImpactRadiusAt(level) as the hit check and the marker.

Grenade impact crash (2026-10-26)

Crashes at sacred.exe+0x361b54 (2026-10-26 00:12 and 22:39) in the particle drawer 0x7613e0, called by cParticleSystem_grenadeimpact::Render (vf04 0x7b66b0): colour = table +0x20d0 at row (+0x3d) * 256 + life (+0x2c), and a particle had a life of over 500000. Guard (mods/guards.cpp): live particles with life >= 256 or row >= 3 are switched off before drawing. Logged in the next session: 5 particles, all row 3, life 255, garbage sizes (e.g. 190555, 4.6e-40): the explosion emits into a fourth row whose emitter parameters it never sets (vf10 0x7b6980 fills three rows at +0x30d0). No crash since.

Eingraben: the dwarf's escape (request 2026-10-28)

"I want it to be the Dwarfs option to Teleport/Escape. The Skill will cast a protective barrier around the Dwarf (current visual effect), clear him of all movement impending effects and then teleport to the position marked by the cursor (if possible). The Teleport is visually shown by the dwarf going underground and coming out again at target position." Range: the visible area; the barrier is the skill's current defensive bonus for 3 s; digging in and out 1 s each; "he should be able to see the target location", compared to the battlemage's Phasenverschiebung; the original lock in place goes.

Found in the code:

  • Spells run in cCreature::CastSpell (0x5222c0, thiscall (cast), ret 4; cast +0x08 / +0x0c the ground point, +0x20 the spell id). Eingraben is spell 0x39 (gui_moves_eingraben, launch type 5 around the caster).
  • Case 0x39 creates object type 0x480 at the caster with cEventFX 0x9d (owner and target the caster) and plays sound 0x840: the barrier, which follows the dwarf.
  • Case 1 (Phasenverschiebung, launch type 3) walks from the caster towards the target in steps of 10 while the cell is passable (cWorld::IsPassable 0x636b60) and keeps the last point a creature can stand on (cWorld::CanStand 0x636eb0); a wall or cliff in the way ends the walk.

Logged (2026-10-28): the barrier adds, all with art 0x39, kind 0x3a value 0 from its particles (0x7b9602), the lock in place (the dwarf was stuck 2-3 s), and kind 2 value 0.5 plus kinds 7..0xa value 30 from its update (0x5b5862..), the defensive bonus (resistances up while it lasts).

Mod (mods/dwarfarts.cpp): Eingraben's definition +0x3c becomes 3 (a point); after the original case the dwarf is teleported to the end of Phasenverschiebung's walk towards the point (the cursor keeps it within the visible area). The effect hook (aurarecast.cpp, KeepEffect) drops kind 0x3a for art 0x39. Confirmed 2026-10-28: aimed, stops before walls and cliffs, casts at once at the screen edge, the barrier moves with him, no lock.

Duration ("more like 8 seconds as described in the tooltip, i want that to go down to 4 seconds"): an art's duration is 0x4d24f0 on its definition, +0x76 + level x +0x78, at most +0x82 when set (Eingraben: 7 + level, at most 15). The barrier's lifetime (shield +0x20a8), its bonus (the effect applier, 0x5b56ab) and the tooltip all use it; the mod sets 4 / 0 / 0.

Digging in and out: lowering the dwarf's height (creature +0xf0) moved only his marker; lowering the terrain height the game asks for him (0x449b20) moved the camera with him, so he never looked sunk. Instead ("change the barrier animation to turn from transparent to solid and back"): the barrier is cParticleSystem_dwarf_shield (constructor 0x7b8fc0, update vf08 0x7b91a0, draw vf04 0x7b92b0; models fx_shield_phase1..4.grn). Its draw passes the model with alpha pulse x 128 (pulse 0.4..1 at +0x20b8; __ftol at 0x7b9483), then again additively. The mod redirects that __ftol: during a dig the alpha goes to 255 over 1 s, the dwarf is moved (engine tick), and it goes back over 1 s. Orders to the dwarf are refused meanwhile (game::FilterCreatureOrders). Confirmed 2026-10-28, barrier and bonus 4 s. Open: clearing slows, roots and stuns.