Old School Ops

RF455-098 RF 4.55: monster special attacks deal no damage, and specials with a cast condition never fire

Game server RF Online: Dragonborn v0.3.1 low · filed by cybercyber
New

Game: RF 4.55 (Dragonborn), server v0.3.1, Windows build (stock gameserver.exe, 22,061,568 bytes). Client: the supported Taiwan build, RF_Online.bin SHA-256 46528aac…2bbc558 (2025-07-16), Language=Taiwan. Data: the shipped db\gamedata_rf455.db.

Summary

Two gaps in monster specials (monstercharacterai):

  1. A special with a cast condition never fires. rollMonsterSpecial skips every AI row whose m_nMotiveCondition isn't 0, instead of checking the condition (e.g. "HP below 60 %"). That is 241 of the 482 AI rows, and 255 monster rows have no special that can ever fire.
  2. A special that fires deals no damage. On the player side GoMMO only installs the special's continuous effect. 82 AI rows that can fire are attack skills/forces with no continuous effect (Frost Nova, Poison Stinking, Aqua Blade…), so they do nothing. 143 monster rows have one.

Also, the 8 AI rows that can fire with m_nDstType 2 return without doing anything. rfdatabase.net lists the same specials for these monsters (e.g. Sandworm → Poison Stinking), and its force pages give them damage. Read from the code and data (static); not live-tested.

The server (read, v0.3.1)

  • Loading. gamedata.(*Data).loadMonsterSkills 0x14050c320 reads 13 monstercharacterai columns (SELECT at VA 0x140bed28b) into a 0x78-byte row: m_nMotiveCondition +0x38 (scanned into a temporary, stored at 0x14050c6b0), m_nMotiveValue +0x40, m_nMotiveTime +0x58, m_nDstType +0x60, m_nLimitCount +0x68, m_nProbability +0x70. A monster's rows are the m_strSPCode values in monstercharacter__m_strspcode.
  • Which rows can fire. (*Server).rollMonsterSpecial 0x1408b90c0 (its only caller is monsterMelee, after the melee damage is applied) gets the rows from MonsterSkillsFor and copies each one to rsp+0xd0. For each row:
    • m_nMotiveCondition ≠ 0 → skipped (0x1408b9393 cmp [rsp+0x108],0; jne). m_nMotiveValue and the exception fields are never read.
    • m_nLimitCount > 0 and the use count has reached it → skipped.
    • The m_nMotiveTime cooldown hasn't run out → skipped.
    • m_nProbability ≤ 0, or rand.Intn(100) ≥ m_nProbability → skipped, and the cooldown restarts (m_nMotiveTime seconds, 10 s when ≤ 0).
    • Otherwise the use count goes up, the cooldown starts, and fireMonsterSpecial runs on that row.
  • What it does. (*Server).fireMonsterSpecial 0x1408b9880 resolves the code (ResolveSFCode, resolveSFEffectOK; it returns if either fails), then branches on m_nDstType ([rsp+0x2d0]):
    • 1: fireMonsterSelfSpecial 0x1408b8ce0 (on the monster itself, applyMonsterAffect);
    • 2: returns at once (0x1408b992e → 0x1408b9eb9);
    • otherwise: a range check on m_fSpecialRange, then applyContEffectTo 0x1408968e0 at level m_nAttLv clamped to 1..7, then sendMonsterAssist (the broadcast).
  • applyContEffectTo is the affect system only (haveEffect, addAffectFrom, refreshEffectState, scheduleAffectExpiry, notifyPartyEffect, checkAlterMaxPoint…). No HP change on any path.
  • (*client).applyDamage 0x1407d8700 is called by monsterMelee, animusStrikePlayer, pvpStrike, towerHitPlayer, trapHitPlayer, nuclearHit and actTransDestHP. No special path reaches it, and the server has no damage-over-time code.

The data (read, gamedata_rf455.db)

  • 482 AI rows: m_nMotiveCondition 0 on 241 rows, 1 on 223 (a value 5–90, inferred to be an HP %), 2 on 11, 3 on
    1. Of the 241 that can fire, 8 have m_nDstType 2. No row has a probability ≤ 0.
  • Attack specials (a skill/force with m_nAttackable / m_bAttackable = 1 and m_nContEffectType −1): 184 rows; 82 can fire (no damage), 102 have a condition (never fire). Monster rows: 347 have one, 143 have one that can fire.
  • The firing attack specials most used (monster rows): Frost Nova 9309 25, Poison Stinking 9401 21, Aqua Blade 9305 10, Frost Arrow 9304 9, Gust Of Blast 9508 8, Rock Blade 9404 8, Poison Breath 9405 7.
  • Examples:
    • Sandworm and Anabola (02B00, 02A00, level 31): Poison Stinking, condition 0, probability 100, every 10 s. It fires and does nothing.
    • DagnuYoungFlam (0BE03, 12): Electric Bolt 9504, condition 0. It fires and does nothing.
    • Robust Lava (03A00, 36): Electric Ball 9500 with condition 1, value 60. It never fires.
    • Chuty 0590B: Healing 7104 on itself (condition 1, value 50; and condition 2, value 90, m_nDstType 2). Neither ever fires.

Expected

  • A special with a motive condition fires when the condition holds (inferred: condition 1 = the monster's HP below m_nMotiveValue %; 2 and 3 not known here).
  • An attackable special deals its force/skill damage to the player (as the same code does when a player casts it), plus its continuous effect if it has one.
  • What m_nDstType 2 means isn't known here (inferred: an area or party target); it should do something.

How to see it

Let a Sandworm (level 31) fight you for a minute. Its Poison Stinking should land every 10 s, and your HP drops only by its melee hits. (fireMonsterSpecial writes a debug-level log line, "monster special landed…", each time.) A Robust Lava should never cast Electric Ball, even below 60 % HP.

Related

  • RF455-094New (zero-value effects): Spin A Web / Entangle 9407 (Wheel, Chuty…) has no state reader.
  • RF455-093New (instant effects) would also stop Healing 7104 as a self special, but Chuty's Healing rows never fire in the first place (condition ≠ 0).
Reported on version 0.3.1

Replies

Nobody has replied yet.

Sign in to comment.

Top xp sources

How xp works
Loading…

Open the full search page