rewrite 6xE4 logic
This commit is contained in:
@@ -13,100 +13,88 @@ write_address_of_code:
|
||||
|
||||
start:
|
||||
|
||||
# Change class_flags check to read only low 16 bits
|
||||
# This is annoying since the opcode we need is one byte longer than the
|
||||
# original, so we have to write a call to allocated code here, sigh
|
||||
push 6
|
||||
push 0x00773448
|
||||
push 1
|
||||
call +4
|
||||
.deltaof class_flags_check_start, class_flags_check_end
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call class_flags_check_end
|
||||
class_flags_check_start:
|
||||
movzx eax, word [esi + 0x2E8]
|
||||
ret
|
||||
class_flags_check_end:
|
||||
call write_call_to_code_multi
|
||||
|
||||
|
||||
|
||||
# Replace 6x09 with 6xE4 in subcommand handler table
|
||||
mov dword [0x00A0FC30], 0x000600E4 # subcommand=0xE4, flags=6
|
||||
push 0x00A0FC34
|
||||
call +4
|
||||
.deltaof on_6xE4_start, on_6xE4_end
|
||||
.deltaof handle_6xE4_start, handle_6xE4_end
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call on_6xE4_end
|
||||
on_6xE4_start: # (G_6xE4* cmd @ [esp + 4])
|
||||
mov edx, [esp + 4]
|
||||
movzx eax, word [edx + 2]
|
||||
.include GetEnemyEntity-59NL # eax = get_enemy_entity(cmd->header.entity_id)
|
||||
call handle_6xE4_end
|
||||
|
||||
handle_6xE4_start: # (G_6xE4* cmd @ [esp + 4]) -> void
|
||||
push ebx
|
||||
push esi
|
||||
push edi
|
||||
mov ebx, [esp + 0x10] # cmd
|
||||
movzx eax, word [ebx + 2]
|
||||
cmp eax, 0x1000
|
||||
jl handle_6xE4_return
|
||||
cmp eax, 0x1B50
|
||||
jge handle_6xE4_return
|
||||
|
||||
and eax, 0x0FFF
|
||||
imul eax, eax, 0x0C
|
||||
add eax, [0x00AB02B8] # eax = state_for_enemy(cmd->header.entity_id)
|
||||
|
||||
movzx edx, word [eax + 0x06] # st.total_damage
|
||||
movsx esi, word [ebx + 0x04] # cmd->hit_amount
|
||||
movzx edi, word [ebx + 0x0A] # cmd->max_hp
|
||||
add edx, esi # st.total_damage + cmd->hit_amount
|
||||
cmp edx, edi
|
||||
jl handle_6xE4_damage_less_than_max_hp
|
||||
mov [eax + 0x06], di # st.total_damage = cmd->max_hp;
|
||||
mov edx, [eax]
|
||||
test edx, 0x800
|
||||
jnz handle_6xE4_return
|
||||
or edx, 0x800
|
||||
mov [eax], edx
|
||||
push edx # out_cmd.flags
|
||||
sub esp, 8
|
||||
mov word [esp], 0x030A # out_cmd.header.{subcommand,size}
|
||||
mov si, [ebx + 2]
|
||||
mov [esp + 2], si # out_cmd.header.entity_id
|
||||
and si, 0x0FFF
|
||||
mov [esp + 4], si # out_cmd.entity_index
|
||||
mov [esp + 6], di # out_cmd.total_damage
|
||||
mov ecx, esp
|
||||
mov edx, 0x008003E0
|
||||
call edx # send_and_handle_60(&out_cmd);
|
||||
add esp, 0x0C
|
||||
jmp handle_6xE4_return
|
||||
|
||||
handle_6xE4_damage_less_than_max_hp:
|
||||
xor edi, edi
|
||||
cmp edx, edx
|
||||
cmovl edx, edi
|
||||
mov [eax + 0x06], dx # st.total_damage = std::max<int16_t>(st.total_damage + cmd->hit_amount, 0);
|
||||
|
||||
mov edx, eax # edx = ene_st
|
||||
movzx eax, word [ebx + 2]
|
||||
.include GetEnemyEntity-59NL # auto* ene = get_enemy_entity(cmd->header.entity_id);
|
||||
test eax, eax
|
||||
je on_6xE4_no_entity
|
||||
movzx ecx, word [eax + 0x2EA]
|
||||
movzx edx, word [edx + 4]
|
||||
add ecx, edx
|
||||
xor edx, edx
|
||||
cmp ecx, 0
|
||||
cmovl ecx, edx
|
||||
movzx edx, word [eax + 0x2BC]
|
||||
cmp ecx, edx
|
||||
cmovg ecx, edx
|
||||
mov [eax + 0x2EA], cx
|
||||
on_6xE4_no_entity:
|
||||
jz handle_6xE4_return
|
||||
mov ecx, eax
|
||||
push edx
|
||||
mov edx, [ecx]
|
||||
call [edx + 0x148] # ene->vtable[0x52](ene, &st);
|
||||
|
||||
handle_6xE4_return:
|
||||
pop edi
|
||||
pop esi
|
||||
pop ebx
|
||||
ret
|
||||
on_6xE4_end:
|
||||
|
||||
handle_6xE4_end:
|
||||
call write_address_of_code
|
||||
|
||||
|
||||
|
||||
# Write TObjectV00b441c0::add_hp_with_sync
|
||||
# Write TObjectV00b441c0::incr_hp_with_sync
|
||||
push 5
|
||||
push 0x00774448 # TObjectV00b441c0::v18_accept_hit (presumably Resta)
|
||||
push 1
|
||||
call +4
|
||||
.deltaof TObjectV00b441c0_add_hp_with_sync_start, TObjectV00b441c0_add_hp_with_sync_end
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call TObjectV00b441c0_add_hp_with_sync_end
|
||||
TObjectV00b441c0_add_hp_with_sync_start: # (TObjectV00b441c0* this @ ecx, int16_t amount @ [esp + 4]) -> bool @ eax
|
||||
mov ax, [ecx + 0x1C]
|
||||
cmp ax, 0x1000
|
||||
jl TObjectV00b441c0_add_hp_with_sync_skip_send
|
||||
cmp ax, 0x4000
|
||||
jge TObjectV00b441c0_add_hp_with_sync_skip_send
|
||||
sub esp, 0x0C
|
||||
mov word [esp], 0x03E4
|
||||
mov [esp + 0x02], ax # cmd.header.entity_id = this->entity_id
|
||||
mov ax, [esp + 0x10]
|
||||
neg ax
|
||||
mov [esp + 0x04], ax # cmd.hit_amount = -amount
|
||||
mov ax, [ecx + 0x2EA]
|
||||
mov [esp + 0x06], ax # cmd.total_damage_before_hit = this->total_damage
|
||||
mov ax, [ecx + 0x334]
|
||||
mov [esp + 0x08], ax # cmd.current_hp_before_hit = this->current_hp
|
||||
mov ax, [ecx + 0x2BC]
|
||||
mov [esp + 0x0A], ax # cmd.max_hp = this->max_hp
|
||||
push ecx
|
||||
lea ecx, [esp + 4]
|
||||
mov eax, 0x008003E0
|
||||
call eax # send_and_handle_60(void* data @ ecx)
|
||||
pop ecx
|
||||
add esp, 0x0C
|
||||
TObjectV00b441c0_add_hp_with_sync_skip_send:
|
||||
mov eax, 0x007773D4 # TObjectV00b441c0::add_hp
|
||||
jmp eax
|
||||
TObjectV00b441c0_add_hp_with_sync_end:
|
||||
call write_call_to_code_multi
|
||||
|
||||
|
||||
|
||||
# Write TObjectV00b441c0::subtract_hp_with_sync
|
||||
push 0x00774448 # TObjectV00b441c0::v18_accept_hit (presumably Resta) - this is add_hp, not subtract_hp!
|
||||
push 5
|
||||
push 0x00777287 # TObjectV00b441c0::subtract_hp_if_in_state_2
|
||||
push 0x00777287 # TObjectV00b441c0::subtract_hp_if_not_in_state_2
|
||||
push 5
|
||||
push 0x00776CD6 # TObjectV00b441c0::v19_handle_hit_special_effects
|
||||
push 5
|
||||
@@ -139,147 +127,66 @@ TObjectV00b441c0_add_hp_with_sync_end:
|
||||
push 0x00773EFA # TObjectV00b441c0::v18_accept_hit
|
||||
push 5
|
||||
push 0x00773937 # TObjectV00b441c0::v17
|
||||
push 17
|
||||
push 18
|
||||
call +4
|
||||
.deltaof TObjectV00b441c0_subtract_hp_with_sync_start, TObjectV00b441c0_subtract_hp_with_sync_end
|
||||
.deltaof on_add_or_subtract_hp_start, on_add_or_subtract_hp_end
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call TObjectV00b441c0_subtract_hp_with_sync_end
|
||||
TObjectV00b441c0_subtract_hp_with_sync_start: # (TObjectV00b441c0* this @ ecx, int16_t amount @ [esp + 4]) -> bool @ eax
|
||||
mov ax, [ecx + 0x1C]
|
||||
cmp ax, 0x1000
|
||||
jl TObjectV00b441c0_subtract_hp_with_sync_skip_send
|
||||
cmp ax, 0x4000
|
||||
jge TObjectV00b441c0_subtract_hp_with_sync_skip_send
|
||||
call on_add_or_subtract_hp_end
|
||||
|
||||
on_add_or_subtract_hp_start: # (TObjectV00b441c0* this @ ecx, int16_t amount @ [esp + 4]) -> bool @ eax
|
||||
movzx eax, word [ecx + 0x1C] # ene->entity_id
|
||||
cmp eax, 0x1000
|
||||
jl on_add_or_subtract_hp_skip_send
|
||||
cmp eax, 0x1B50
|
||||
jge on_add_or_subtract_hp_skip_send
|
||||
|
||||
and eax, 0x0FFF
|
||||
imul eax, eax, 0x0C
|
||||
add eax, [0x00AB02B8] # eax = state_for_enemy(cmd->header.entity_id)
|
||||
|
||||
sub esp, 0x0C
|
||||
mov word [esp], 0x03E4
|
||||
mov [esp + 0x02], ax # cmd.header.entity_id = this->entity_id
|
||||
mov ax, [esp + 0x10]
|
||||
mov [esp + 0x04], ax # cmd.hit_amount = amount
|
||||
mov ax, [ecx + 0x2EA]
|
||||
mov [esp + 0x06], ax # cmd.total_damage_before_hit = this->total_damage
|
||||
mov ax, [ecx + 0x334]
|
||||
mov [esp + 0x08], ax # cmd.current_hp_before_hit = this->current_hp
|
||||
mov ax, [ecx + 0x2BC]
|
||||
mov [esp + 0x0A], ax # cmd.max_hp = this->max_hp
|
||||
mov dx, [ecx + 0x1C]
|
||||
mov [esp + 0x02], dx # cmd.entity_id
|
||||
mov dx, [esp + 0x10]
|
||||
cmp dword [esp + 0x0C], 0x0077444D # Check if callsite is add_hp
|
||||
jne on_add_or_subtract_hp_skip_negate_amount
|
||||
neg dx
|
||||
on_add_or_subtract_hp_skip_negate_amount:
|
||||
mov [esp + 0x04], dx # cmd.hit_amount
|
||||
mov dx, [eax + 6]
|
||||
mov [esp + 0x06], dx # cmd.total_damage_before_hit
|
||||
mov dx, [ecx + 0x0334]
|
||||
mov [esp + 0x08], dx # cmd.current_hp
|
||||
mov dx, [ecx + 0x02BC]
|
||||
mov [esp + 0x0A], dx # cmd.max_hp
|
||||
mov edx, esp
|
||||
push ecx
|
||||
lea ecx, [esp + 4]
|
||||
mov eax, 0x008003E0
|
||||
call eax # send_and_handle_60(void* data @ ecx)
|
||||
pop ecx
|
||||
add esp, 0x0C
|
||||
TObjectV00b441c0_subtract_hp_with_sync_skip_send:
|
||||
mov eax, 0x00777414 # TObjectV00b441c0::subtract_hp
|
||||
jmp eax
|
||||
TObjectV00b441c0_subtract_hp_with_sync_end:
|
||||
call write_call_to_code_multi
|
||||
|
||||
|
||||
|
||||
# Write TObjectV00b441c0::subtract_hp_without_sync
|
||||
push 5
|
||||
push 0x00777CBD # TObjectV00b441c0::v25_give_poison_damage
|
||||
push 1
|
||||
call +4
|
||||
.deltaof TObjectV00b441c0_subtract_hp_without_sync_start, TObjectV00b441c0_subtract_hp_without_sync_end
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call TObjectV00b441c0_subtract_hp_without_sync_end
|
||||
TObjectV00b441c0_subtract_hp_without_sync_start: # (TObjectV00b441c0* this @ ecx, int16_t amount @ [esp + 4]) -> bool @ eax
|
||||
movzx edx, word [ecx + 0x2EA]
|
||||
movsx eax, word [esp + 2]
|
||||
add edx, eax
|
||||
movzx eax, word [ecx + 0x2BC]
|
||||
cmp edx, eax
|
||||
cmovg edx, eax
|
||||
mov [ecx + 0x2EA], dx
|
||||
mov eax, 0x00777414 # TObjectV00b441c0::subtract_hp
|
||||
jmp eax
|
||||
TObjectV00b441c0_subtract_hp_without_sync_end:
|
||||
call write_call_to_code_multi
|
||||
|
||||
|
||||
|
||||
# Write handle_6x0A_update_total_damage_hook
|
||||
push 5
|
||||
push 0x0078781F
|
||||
push 1
|
||||
call +4
|
||||
.deltaof handle_6x0A_update_total_damage_hook_start, handle_6x0A_update_total_damage_hook_end
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call handle_6x0A_update_total_damage_hook_end
|
||||
handle_6x0A_update_total_damage_hook_start: # (G_6x0A* cmd @ eax, int16_t cmd_total_damage @ cx) -> void
|
||||
# Nonstandard calling convention:
|
||||
# Caller-save: ecx, ebx
|
||||
# Callee-save: eax, edx, ebp, esi, edi
|
||||
push eax
|
||||
movzx eax, word [eax + 2]
|
||||
.include GetEnemyEntity-59NL # eax = get_enemy_entity(cmd->header.entity_id)
|
||||
test eax, eax
|
||||
jz handle_6x0A_update_total_damage_hook_no_entity
|
||||
mov ebx, [eax + 0x2EA]
|
||||
cmp ecx, ebx
|
||||
cmovl ecx, ebx
|
||||
mov ebx, [eax + 0x2BC]
|
||||
cmp ecx, ebx
|
||||
cmovg ecx, ebx
|
||||
handle_6x0A_update_total_damage_hook_no_entity:
|
||||
mov [esp + 0x0E], cx # ene_st.total_damage = cx
|
||||
pop eax
|
||||
ret
|
||||
handle_6x0A_update_total_damage_hook_end:
|
||||
call write_call_to_code_multi
|
||||
|
||||
|
||||
|
||||
# Write handle_6x0A_call_object_update_vfn
|
||||
push 6
|
||||
push 0x007878CC
|
||||
push 1
|
||||
call +4
|
||||
.deltaof handle_6x0A_call_object_update_vfn_start, handle_6x0A_call_object_update_vfn_end
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call handle_6x0A_call_object_update_vfn_end
|
||||
handle_6x0A_call_object_update_vfn_start: # (TObjectV00b441c0* this @ ecx, EnemyState* ene_st @ [esp + 4]) -> void
|
||||
# Standard calling conventions
|
||||
push dword [edx + 0x148] # vfn to call at end (which we do via ret)
|
||||
push ecx
|
||||
test dword [ecx + 0x30], 0x800 # this->game_flags & 0x800
|
||||
jnz handle_6x0A_call_object_update_vfn_tail_call
|
||||
mov edx, [esp + 0x0C]
|
||||
test dword [edx], 0x800 # ene_st->flags & 0x800
|
||||
jnz handle_6x0A_call_object_update_vfn_tail_call
|
||||
mov ax, [edx + 6]
|
||||
cmp ax, [ecx + 0x2BC] # ene_st->total_damage >= ene->max_hp
|
||||
jl handle_6x0A_call_object_update_vfn_tail_call
|
||||
or dword [edx], 0x800 # ene_st->game_flags |= 0x800 (set dead flag)
|
||||
mov eax, [0x00AAB284]
|
||||
test eax, eax
|
||||
jz handle_6x0A_call_object_update_vfn_tail_call
|
||||
push dword [edx] # cmd.game_flags = ene_st->game_flags
|
||||
sub esp, 8
|
||||
mov ax, [edx + 6]
|
||||
mov [esp + 0x06], ax # cmd.total_damage = ene_st->total_damage
|
||||
mov ax, [ecx + 0x2C]
|
||||
mov [esp + 0x04], ax # cmd.enemy_index = this->enemy_index
|
||||
mov ax, [ecx + 0x1C]
|
||||
mov [esp + 0x02], ax # cmd.header.entity_id = this->entity_id
|
||||
mov word [esp], 0x030A # cmd.header.subommand = 0x0A, cmd.header.size = 0x03
|
||||
push 0x0C
|
||||
lea ecx, [esp + 4]
|
||||
push ecx
|
||||
push edx
|
||||
mov ecx, [0x00AAB284]
|
||||
mov eax, 0x007D3F38
|
||||
call eax # send_60(TGameProtocol* this @ ecx, void* data @ [esp + 4], uint32_t size @ [esp + 8])
|
||||
add esp, 0x0C
|
||||
handle_6x0A_call_object_update_vfn_tail_call:
|
||||
mov edx, 0x007D3F38
|
||||
call edx # send_60(root_protocol, &cmd, sizeof(cmd));
|
||||
pop ecx
|
||||
ret
|
||||
handle_6x0A_call_object_update_vfn_end:
|
||||
add esp, 0x0C
|
||||
|
||||
on_add_or_subtract_hp_skip_send:
|
||||
mov eax, 0x00777414 # subtract_hp
|
||||
mov edx, 0x007773D4 # add_hp
|
||||
cmp dword [esp], 0x0077444D # Check if callsite is add_hp
|
||||
cmove eax, edx
|
||||
jmp eax
|
||||
|
||||
on_add_or_subtract_hp_end:
|
||||
call write_call_to_code_multi
|
||||
|
||||
|
||||
|
||||
# Don't let 6x0A handler overwrite total_damage
|
||||
mov byte [0x0078781F], 0x90
|
||||
mov dword [0x00787820], 0x90909090
|
||||
|
||||
|
||||
|
||||
ret
|
||||
|
||||
Reference in New Issue
Block a user