# Target level in the Target window (staged 2026-10-04, TEST only, not published)

Trevor: show the target's level in the Target window, e.g. "Lvl 52".

Files:
- dinput8.dll: md5 3ab2f066, client_dll 9eea550 (build of 25320c9) on top of 58b48a3 (Invite All, staged_botinvite,
  97664513), which is on top of the published ae01b7c (= patch_files/dinput8.dll 6b094b7a). So this DLL carries
  Invite All too, and nothing else unpublished.
- EQUI_TargetWindow.xml (md5 2a47ac19): the stock RoF2 uifiles/default file (e8ed6c16, same as Trevor's desktop
  client) + one label, Target_LevelLabel (EQType 900), added to the TargetWindow pieces. Nothing else changed.
  patch_files has no EQUI_TargetWindow.xml today, so this is a new patcher file (uifiles/default/).
verify_sites.py vs patch_files/eqgame.exe: 39 hook sites, 40 byte patches + signatures, 5 call sites, 0 problems
(one new call site, no new function hook).

What it does:
- Under the target's name, on the HP bar row at the left (the HP number "100 %" stays in the middle): "Lvl 52" in
  small white text (font 1, like the HP number). Label box x 7..52 from the window's left, y 17..29.
- NPCs (pets included) and players: shown. Corpses and no target: empty. Self-target shows your own level.
- Refreshes every frame the window is drawn: a new target or the target levelling shows at once.
- How: the label's text comes from GetLabelFromEQ, which CLabel::UpdateText calls for labels with an EQType; that one
  call (0x6B4D88) is retargeted to the DLL, which answers EQType 900 from pinstTarget's level byte and passes every
  other type to the stock function (and so to the server exe's 9000-9004 cave as before).
- Old DLL + new XML: the label shows the stock "Unknown Label900" text, so ship both together (the patcher does).
  New DLL + old XML: nothing shows, nothing else changes. A different UI skin with its own EQUI_TargetWindow.xml:
  no label (stock behaviour). DLL on an exe whose call site differs: logged "SKIP call LabelTextFromEQ", label shows
  "Unknown Label900".
- Not done: the floating name plate. Its text is built inside PlayerClient::SetNameSpriteState 0x58E2D0 and handed
  to the actor through an indirect vtable call (+0x18C), so there is no checked call to retarget; it would need a
  mid-function hook plus forced name-plate refreshes of the old and new target. Not cheap or safe enough for now.
  The HJ Extended Target window is unchanged.

## Test on the desktop (close the game first)
    scp -r openclawvm:heroes_journey_workspace/patcher/staged_targetlevel /tmp/ && bash /tmp/staged_targetlevel/install_desktop.sh
Launch with "EverQuest RoF2 Tanks (Direct)" (the Patcher launcher would put the live DLL back), log in (TEST
world for the Invite All server half; the level label works on either world). hjclient.log: line 1 ends
"+botinvite+targetlevel) loaded", and "call LabelTextFromEQ @006b4d88 ok", "5/5 call sites retargeted".
1. No target: the Target window shows no level text.
2. Target an NPC (F8 or click): "Lvl N" under its name, left of the HP number; check N against /con or /target
   + the map overlay's lvl. Tab/F8 through several mobs: the number follows at once.
3. Target your pet and a bot: their levels show. Target yourself (F1) and another player: shown too.
4. Kill a mob and target its corpse: the level text disappears.
5. Level up (or have a bot level) while targeted: the number updates.
6. Resize the Target window: the label stays at the bottom-left of the name box. /loadskin default 1 (UI reload):
   still works.
7. Invite All is in this DLL too: if staged_botinvite's HJ_BotWnd.xml is installed (or published), /bots still shows
   the button and it works on TEST.
Undo: `bash /tmp/staged_targetlevel/install_desktop.sh --revert`. That is the only complete undo until this kit is
published: the Patcher launcher puts back the live DLL but leaves EQUI_TargetWindow.xml (not a patcher file yet), and
the live DLL + this XML shows "Unknown Label900" in the Target window.

## Publish (after Trevor confirms on test). Patcher only, no server change
Back up patch_files/dinput8.dll to ~/.local/share/eq-backups/<date>/targetlevel; copy this folder's dinput8.dll to
patch_files/ and EQUI_TargetWindow.xml to patch_files/uifiles/default/ (new file); add a news.txt line at the top
(e.g. "Oct 5: The Target window shows your target's level under its name."); `python3 generate_manifest.py`; check the
manifest lists both with md5 3ab2f066 / 2a47ac19.
Ordering with staged_botinvite: this DLL includes Invite All, so it can replace that kit's DLL. If the botinvite
publish has already happened, patch_files/dinput8.dll is 97664513 and this one is a straight superset. If
patch_files/dinput8.dll is anything other than 6b094b7a or 97664513 by then (another DLL feature published), rebuild
from client_dll HEAD instead: this one would drop that feature.
The Invite All button only appears with staged_botinvite's HJ_BotWnd.xml, so publishing this DLL alone (before
that kit) shows no new button and needs no server change.
