# This patch causes the client not to generate its own EXP text and instead use
# the EXP values generated by the server when showing the purple text for enemy
# deaths. This makes EXP gained via EXP share visible, as well as makes
# fractional EXP multiplers (in config.json) display properly.

.meta name="Server EXP display"
.meta description=""
.meta hide_from_patches_menu

entry_ptr:
reloc0:
  .offsetof start
start:
  call      install_hook
  call      apply_static_patches
  ret



install_hook:
  pop       ecx
  push      0  # Write address instead of a call/jmp opcode
  push      0x00A0FC54
  call      get_code_size
  .deltaof  handle_6xBF_start, handle_6xBF_end
get_code_size:
  pop       eax
  push      dword [eax]
  call      handle_6xBF_end
handle_6xBF_start:  # [std](G_6xBF* cmd @ [esp + 4]) -> void
  mov       edx, [esp + 4]

  mov       ecx, [0x00A9C4F4]  # local_client_id
  cmp       [edx + 2], cx
  jne       skip_text

  cmp       byte [edx + 1], 3
  jl        skip_text
  movzx     eax, word [edx + 8]  # cmd.from_enemy_id
  cmp       eax, 0x1000
  jl        skip_text
  cmp       eax, 0x1B50
  jge       skip_text
  call      get_enemy_entity

  test      eax, eax
  jnz       enemy_entity_ok

  # Use player entity if enemy entity is already gone
  mov       eax, 0x0068D5AC
  xchg      eax, ecx
  call      ecx  # eax = TObjPlayer::for_client_id(local_client_id); conveniently, this function preserves all regs except eax

enemy_entity_ok:
  push      0x0000FFFF  # entity_id; ignored by TFontSmallTask if not a player
  push      dword [edx + 4]  # amount = cmd.amount
  push      0x009783A0  # prefix = L"EXP"
  push      0x14
  push      0x14
  push      0xFFFF00FF  # color (ARGB)
  add       eax, 0x300
  push      eax  # position
  mov       eax, 0x0078AABC
  call      eax  # TFontSmallTask___new__(...)
  add       esp, 0x1C

skip_text:
  mov       eax, 0x006928C0  # Original handle_6xBF
  jmp       eax  # original_handle_6xBF(cmd)

get_enemy_entity:
  .include  GetEnemyEntity-59NL
  ret

handle_6xBF_end:
  push      ecx
  .include  WriteCallToCode-59NL



apply_static_patches:
  .include  WriteCodeBlocksBB

  .data     0x0078749D
  .deltaof  disable_kill_enemy_callsite_start, disable_kill_enemy_callsite_end
disable_kill_enemy_callsite_start:
  nop
  nop
  nop
  nop
  nop
disable_kill_enemy_callsite_end:

  .data     0x007765A5
  .deltaof  disable_exp_steal_callsite_start, disable_exp_steal_callsite_end
disable_exp_steal_callsite_start:
  add       esp, 0x0C  # Original function has `ret 0x0C`
  nop
  nop
disable_exp_steal_callsite_end:

  .data     0x00000000
  .data     0x00000000
