Old School Ops

RF455-157 RF 4.55 v0.5.1: a base tower's own hit clears the monster's target, and no tower holds the target it is firing at

Game server RF Online: Dragonborn v0.5.1 low · filed by cybercyber
Released

Expected: a tower should fire on a monster its owner is attacking and stay on it until the owner attacks something else, the monster dies, or it leaves range. Only the owner-driven half has a source: the GamesCampus beginner guide, archived 2012-09-26 at https://web.archive.org/web/20120926004401/http://rfonline.gamescampus.com/guide/beginner%20guide/guard%20tower, says under "03 ASSEMBLING COMPLETE": "The Guard Tower has a given firing range and it will only attack incoming enemies or enemies that the user is attacking." Staying on the target is in no source we found, so that half is our request. We are not asking for the sentry behaviour the same page's characteristic (1) describes ("They will automatically open fire at any monsters or other race (acknowledged as enemies) that are within their fire range"). The page never says which of its two statements wins, and neither finding needs that settled.

Which monster a tower may shoot is decided by one test, (*Server).towerDefendsAgainst 0x140a2d040, which asks whose aggro the monster is on: for a player's tower, true when monster+0x238 holds the owner's serial, and false for any tower when it is 0. Two things fall out of that.

1. A base tower's own hit clears the monster's target

A base tower's owner is 0: (*Server).standSystemTower 0x140a1a320 writes mov dword ptr [rax+8], 0 at 0x140a1a3ed, and placement_system_towers holds 134 such rows. (*Server).towerHitMonster 0x140a2d5e0 loads that owner from +8 and passes it to (*Server).engageMonsterFrom at 0x140a2d914, which has no zero guard, so (*monster).setAggro 0x140977ee0 writes 0 into monster+0x238 at 0x140978003.

So the monster forgets what it was fighting, (*Server).stepMonsterAIIn re-acquires through searchNearPlayerIn, and the gate refuses that monster to every tower until something engages it again. This one is a plain bug in our reading: a tower's shot should not erase what its victim was fighting.

Fix: skip the engageMonsterFrom call at 0x140a2d914 when the owner serial is 0, or have setAggro refuse serial 0.

2. No tower holds the target it is firing at

(*Server).towerFire 0x140a2cb60 chooses a target afresh on every shot, calling towerNearestMonster and towerNearestEnemyPlayer once each and keeping the nearer. It records nothing: every store in it, in (*Server).stepTower and in (*Server).towerHitMonster is to that function's own stack frame, as is every struct copy and clear the three of them make. And towerNearestMonster re-runs the gate for every candidate before every shot (0x140a2cee6), so even a remembered target would be re-tested.

What a tower must win each time is the monster's single aggro slot, and that slot belongs to whoever hit last: setAggro overwrites it for any non-zero serial, and (*Server).handleAttack 0x140877600 passes the attacker's own serial to engageMonsterFrom at 0x140877aa0. So two characters on one monster is enough. While the other one's hit is the more recent, the tower is refused the monster it was firing at, and is let back in only when the owner hits it again. It costs shots rather than the fight: a refused tower arms nothing (stepTower arms only on a true return from towerFire) and is looked at again on the 200 ms towerLoop tick.

Fix: give liveTower a current target, set on the shot that first passes the gate, kept while that monster is alive and in range without re-running the gate, and dropped when it dies, leaves range, or the owner attacks something else. Nothing in the firing path keeps one today, so this is new state rather than a changed condition.

How to see it

  1. Attack a monster inside your own tower's range and let the tower fire, then have a second character hit the same monster, both of you keeping at it. The tower should go quiet whenever the other character's hit is the more recent one, and fire again after each of your own.
  2. For finding 1, let a monster engage you inside a base ring and count the shots that base tower lands on it.
Reported on version 0.5.1

Replies 2

OSO AI Staff
13h ago

Reported: A base tower's shot cleared the monster's target, and no tower held the target it was firing at.

Fix: Both are fixed in the next RF 4.55 update.

  • A base tower's shot no longer erases whom the monster is fighting, so the monster stays on its player and the base tower keeps firing on it.
  • A tower now keeps its current target while that monster is alive and in range, and takes the monster its owner attacks as its priority. Its owner attacking something else, the monster dying or leaving range drops it. A second player hitting the same monster no longer pulls the owner's tower off it.

Also affected: A monster the tower picked up on its own, not its owner's, is still checked each shot against whom that monster is fighting, as in the original game.

OSO AI Staff
9h ago

Fix: Released in 0.6.0. A base tower's hit no longer makes a monster forget who it is fighting.

This report is Released, so only staff can reply. If the problem is back, file a new report.

Top xp sources

How xp works
Loading…

Open the full search page