Merge upstream newserv master
This commit is contained in:
@@ -1 +0,0 @@
|
||||
../item-tables/ItemPMT-bb-v4.prs
|
||||
+9
-7
@@ -1,6 +1,8 @@
|
||||
.meta name="Kill count fix"
|
||||
.meta description="Fixes client-side\nkill counts when\nmultiple enemies are\nkilled on the same\nframe"
|
||||
|
||||
.versions 59NJ 59NL
|
||||
|
||||
entry_ptr:
|
||||
reloc0:
|
||||
.offsetof start
|
||||
@@ -9,9 +11,9 @@ start:
|
||||
|
||||
|
||||
|
||||
.data 0x005E32C8
|
||||
.data <VERS 0x005E32A4 0x005E32C8>
|
||||
.deltaof TItemUnitUnsealable_count_kill, TItemUnitUnsealable_count_kill_end
|
||||
.address 0x005E32C8
|
||||
.address <VERS 0x005E32A4 0x005E32C8>
|
||||
TItemUnitUnsealable_count_kill: # [std] (TItemUnitUnsealable* this @ ecx) -> void
|
||||
mov eax, [ecx + 0xF8]
|
||||
movsx eax, word [eax + 0x11A] # eax = this->owner_player->num_kills_since_map_load
|
||||
@@ -29,14 +31,14 @@ TItemUnitUnsealable_count_kill_skip_update:
|
||||
setae dh
|
||||
shl edx, 1
|
||||
or dword [ecx + 0xDC], edx
|
||||
jmp 0x005E2C34
|
||||
jmp <VERS 0x005E2C10 0x005E2C34>
|
||||
TItemUnitUnsealable_count_kill_end:
|
||||
|
||||
|
||||
|
||||
.data 0x005F3EFC
|
||||
.data <VERS 0x005F3E94 0x005F3EFC>
|
||||
.deltaof TItemWeapon_LameDArgent_count_kill, TItemWeapon_LameDArgent_count_kill_end
|
||||
.address 0x005F3EFC
|
||||
.address <VERS 0x005F3E94 0x005F3EFC>
|
||||
TItemWeapon_LameDArgent_count_kill:
|
||||
mov eax, [ecx + 0xF8]
|
||||
movsx eax, word [eax + 0x11A]
|
||||
@@ -59,9 +61,9 @@ TItemWeapon_LameDArgent_count_kill_end:
|
||||
|
||||
|
||||
|
||||
.data 0x005FCA74
|
||||
.data <VERS 0x005FC95C 0x005FCA74>
|
||||
.deltaof TItemWeapon_SealedJSword_count_kill, TItemWeapon_SealedJSword_count_kill_end
|
||||
.address 0x005FCA74
|
||||
.address <VERS 0x005FC95C 0x005FCA74>
|
||||
TItemWeapon_SealedJSword_count_kill:
|
||||
mov eax, [ecx + 0xF8]
|
||||
movsx eax, word [eax + 0x11A]
|
||||
@@ -0,0 +1,624 @@
|
||||
# This patch changes the number of BB character save slots from 4 to any number
|
||||
# up to 127.
|
||||
|
||||
# This patch is for documentation purposes only; it works when used as a server
|
||||
# patch via newserv, but is decidedly inconvenient to use via this method. This
|
||||
# is because it affects logic that runs before any patches can be sent by the
|
||||
# server, so the player has to connect once to get the patch, then disconnect
|
||||
# and connect again to use the additional slots.
|
||||
|
||||
# As written, this patch changes the slot count from 4 to 12. To use a
|
||||
# different slot count, first compute the following values:
|
||||
# slot count = your desired number of player slots (must be >= 4, <= 127)
|
||||
# total file size = (slot count * 0x2EA4) + 0x14
|
||||
# bgm_test_songs_unlocked offset = total file size - 0x10
|
||||
# save_count offset = total file size - 8
|
||||
# round2_seed offset = total file size - 4
|
||||
# Then, for each of the above, search for the string to the left of the = sign
|
||||
# and change the values used in all of the matching lines.
|
||||
|
||||
.meta name="More save slots"
|
||||
.meta description=""
|
||||
.meta hide_from_patches_menu
|
||||
|
||||
entry_ptr:
|
||||
reloc0:
|
||||
.offsetof start
|
||||
|
||||
# Include a few functions first
|
||||
write_call_to_code:
|
||||
.include WriteCallToCode-59NJ
|
||||
memcpy:
|
||||
.include CopyData
|
||||
ret
|
||||
|
||||
|
||||
|
||||
start:
|
||||
# Apply all necessary patches
|
||||
call apply_enable_scroll_patch
|
||||
call apply_fix_scroll_patch1
|
||||
call apply_fix_scroll_patch2
|
||||
call apply_fix_file_index
|
||||
call apply_preview_window_fix
|
||||
call apply_static_patches
|
||||
# Rewrite the existing char file regions to have the appropriate size; this
|
||||
# must be done after the patches are applied because we call the checksum
|
||||
# function, which is patched by one of the above calls
|
||||
call update_existing_char_file_list
|
||||
jmp update_existing_char_file_list_memcard
|
||||
|
||||
|
||||
|
||||
apply_enable_scroll_patch:
|
||||
# This patch enables scrolling behavior within the character list
|
||||
push -5 # Jump size (negative = jmp instead of call)
|
||||
push 0x00413B77 # Jump address
|
||||
call get_code_size_for_enable_scroll
|
||||
.deltaof enable_scroll_start, enable_scroll_end
|
||||
get_code_size_for_enable_scroll:
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call enable_scroll_end
|
||||
enable_scroll_start:
|
||||
mov eax, dword ptr [edi + 0x28] # cursor = char_select_menu->cursor_obj (TAdSelectCurGC*)
|
||||
or dword [eax + 0x01F8], 3 # cursor->flags |= 3 # Enable scrolling
|
||||
mov eax, [0x00A38BD0] # scroll_bar = TAdScrollBarXb_objs[0]
|
||||
mov ecx, [eax + 0xEC] # ecx = scroll_bar->client_id
|
||||
imul ecx, ecx, 0x24
|
||||
# Set up scroll bar graphics (in struct at scroll_bar + 0x1C)
|
||||
mov dword [eax + ecx + 0x1C], 0x439D0000
|
||||
mov dword [eax + ecx + 0x20], 0x43360000
|
||||
mov dword [eax + ecx + 0x24], 0x439D0000
|
||||
mov dword [eax + ecx + 0x28], 0x4392AB85
|
||||
mov dword [eax + ecx + 0x2C], 0x40400000
|
||||
mov dword [eax + ecx + 0x30], 0x425EA3D7
|
||||
mov dword [eax + ecx + 0x34], 0x00000008
|
||||
mov dword [eax + ecx + 0x38], 0x00000000
|
||||
mov dword [eax + ecx + 0x3C], 0x00000000
|
||||
or dword [eax + 0xF0], 1 # scroll_bar->flags |= 1
|
||||
mov ecx, [eax + 0xEC]
|
||||
shl ecx, 4
|
||||
mov dword [eax + ecx + 0xAC], 0 # scroll_bar->selection_state[client_id].scroll_offset = 0
|
||||
mov dword [eax + ecx + 0xB0], 0 # scroll_bar->selection_state[client_id].selected_index = 0
|
||||
mov dword [eax + ecx + 0xB4], 4 # scroll_bar->selection_state[client_id].num_items_in_view = 4
|
||||
mov dword [eax + ecx + 0xB8], 0x0B # scroll_bar->selection_state[client_id].last_item_index = (slot count - 1)
|
||||
pop edi
|
||||
ret
|
||||
enable_scroll_end:
|
||||
call write_call_to_code
|
||||
ret
|
||||
|
||||
|
||||
|
||||
apply_fix_scroll_patch1:
|
||||
# This patch fixes character selection cursor object so it will take the
|
||||
# scroll offset into account
|
||||
push 6 # Call size
|
||||
push 0x00413C30 # Call address
|
||||
call get_code_size_for_fix_scroll_patch1
|
||||
.deltaof fix_scroll_patch1_start, fix_scroll_patch1_end
|
||||
get_code_size_for_fix_scroll_patch1:
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call fix_scroll_patch1_end
|
||||
fix_scroll_patch1_start:
|
||||
mov edx, [edi + 0x28] # cursor = this->ad_select_cur_obj (TAdSelectCurGC*)
|
||||
mov ebp, [edx + 0x44] # ebp = cursor->selected_index_within_view
|
||||
mov eax, [0x00A38BD0] # scroll_bar = TAdScrollBarXb_objs[0]
|
||||
add ebp, [eax + 0xAC] # ebp += scroll_bar->selection_state[0].scroll_offset
|
||||
ret
|
||||
fix_scroll_patch1_end:
|
||||
call write_call_to_code
|
||||
ret
|
||||
|
||||
|
||||
|
||||
apply_fix_scroll_patch2:
|
||||
# This patch changes the TAdSinglePlyChrSelectGC::selected_index_within_view
|
||||
# to be the selected character's absolute index (including scroll_offset),
|
||||
# not the index only within the displayed four characters
|
||||
push 6 # Call size
|
||||
push 0x00413CD0 # Call address
|
||||
call get_code_size_for_fix_scroll_patch2
|
||||
.deltaof fix_scroll_patch2_start, fix_scroll_patch2_end
|
||||
get_code_size_for_fix_scroll_patch2:
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call fix_scroll_patch2_end
|
||||
fix_scroll_patch2_start:
|
||||
mov eax, [0x00A38BD0] # scroll_bar = TAdScrollBarXb_objs[0]
|
||||
mov eax, [eax + 0xAC] # eax = scroll_bar->selection_state[0].scroll_offset
|
||||
mov edx, [edi + 0x28] # cursor = this->ad_select_cur_obj (TAdSelectCurGC*)
|
||||
add eax, [edx + 0x44] # eax += cursor->selected_index_within_view
|
||||
ret
|
||||
fix_scroll_patch2_end:
|
||||
call write_call_to_code
|
||||
ret
|
||||
|
||||
|
||||
|
||||
apply_fix_file_index:
|
||||
# This patch fixes the character file indexing so it will account for the
|
||||
# scroll position
|
||||
push 5 # Call size
|
||||
push 0x00413CE8 # Call address
|
||||
call get_code_size_for_selection_index_fix2
|
||||
.deltaof selection_index_fix2_start, selection_index_fix2_end
|
||||
get_code_size_for_selection_index_fix2:
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call selection_index_fix2_end
|
||||
selection_index_fix2_start:
|
||||
mov eax, [0x00A38BD0]
|
||||
mov eax, [eax + 0xAC] # eax = TAdScrollBarXb_objs[0]->selection_state[0].scroll_offset
|
||||
add ebp, eax # arg0 += eax
|
||||
mov [esp + 4], ebp
|
||||
mov eax, 0x006C1ABC
|
||||
jmp eax # set_current_char_slot
|
||||
selection_index_fix2_end:
|
||||
call write_call_to_code
|
||||
ret
|
||||
|
||||
|
||||
|
||||
apply_preview_window_fix:
|
||||
# This patch fixes the preview display so it will show the correct section
|
||||
# ID, level, etc.
|
||||
push 5 # Call size
|
||||
push 0x0040216C # Call address
|
||||
call get_code_size_for_preview_window_fix
|
||||
.deltaof preview_window_fix_start, preview_window_fix_end
|
||||
get_code_size_for_preview_window_fix:
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call preview_window_fix_end
|
||||
preview_window_fix_start:
|
||||
mov eax, [0x00A38BD0] # scroll_bar = TAdScrollBarXb_objs[0]
|
||||
mov eax, [eax + 0xAC] # eax = scroll_bar->selection_state[0].scroll_offset
|
||||
add [esp + 4], eax
|
||||
mov eax, 0x006C4514 # get_player_preview_info
|
||||
jmp eax
|
||||
preview_window_fix_end:
|
||||
# This patch applies in two places, so push the second set of args now, then
|
||||
# apply it twice
|
||||
push 5 # Call size
|
||||
push 0x00401842 # Call address
|
||||
push dword [esp + 0x10] # Code size
|
||||
push dword [esp + 0x10] # Code address
|
||||
call write_call_to_code
|
||||
call write_call_to_code
|
||||
ret
|
||||
|
||||
|
||||
|
||||
apply_static_patches:
|
||||
.include WriteCodeBlocksBB
|
||||
# These patches change various places where the character data size and slot
|
||||
# count are referenced
|
||||
.data 0x00475294
|
||||
.data 0x00000001
|
||||
.binary 0C # slot count; TDataProtocol::handle_E5
|
||||
.data 0x0047534B
|
||||
.data 0x00000001
|
||||
.binary 0C # slot count; import_player_preview
|
||||
.data 0x004786D1
|
||||
.data 0x00000001
|
||||
.binary 0C # slot count; TDataProtocol::handle_E4
|
||||
.data 0x00482559
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C17FB
|
||||
.data 0x00000001
|
||||
.binary 0C # slot count
|
||||
.data 0x006C1D07
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C1D3A
|
||||
.data 0x00000001
|
||||
.binary 0C # slot count
|
||||
.data 0x006C1D58
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C1E13
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C226A
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C22A9
|
||||
.data 0x00000001
|
||||
.binary 0C # slot count
|
||||
.data 0x006C22CA
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C22DA
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C2517
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C267F
|
||||
.data 0x00000004
|
||||
.data 0x00022FBC # save_count offset
|
||||
.data 0x006C2689
|
||||
.data 0x00000004
|
||||
.data 0x00022FBC # save_count offset
|
||||
.data 0x006C272B
|
||||
.data 0x00000004
|
||||
.data 0x00022FBC # save_count offset
|
||||
.data 0x006C2741
|
||||
.data 0x00000004
|
||||
.data 0x00022FC0 # round2_seed offset
|
||||
.data 0x006C27CF
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C28A8
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C314F
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C357B
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C35BA
|
||||
.data 0x00000001
|
||||
.binary 0C # slot count
|
||||
.data 0x006C35E6
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C35F3
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C360E
|
||||
.data 0x00000004
|
||||
.data 0x00022FBC # save_count offset
|
||||
.data 0x006C3617
|
||||
.data 0x00000004
|
||||
.data 0x00022FBC # save_count offset
|
||||
.data 0x006C371C
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C3B5A
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C424D
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C4833
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C486A
|
||||
.data 0x00000001
|
||||
.binary 0C # slot count
|
||||
.data 0x006C49A6
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C49DD
|
||||
.data 0x00000001
|
||||
.binary 0C # slot count
|
||||
.data 0x006C4AC5
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C4AFE
|
||||
.data 0x00000001
|
||||
.binary 0C # slot count
|
||||
.data 0x006C4CDE
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C4D15
|
||||
.data 0x00000001
|
||||
.binary 0C # slot count
|
||||
.data 0x006C4DFD
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C4E36
|
||||
.data 0x00000001
|
||||
.binary 0C # slot count
|
||||
.data 0x006C4F9C
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C4FD7
|
||||
.data 0x00000001
|
||||
.binary 0C # slot count
|
||||
.data 0x006C51C5
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C5201
|
||||
.data 0x00000001
|
||||
.binary 0C # slot count
|
||||
.data 0x006C5376
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C53B0
|
||||
.data 0x00000001
|
||||
.binary 0C # slot count
|
||||
.data 0x006C5545
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C5581
|
||||
.data 0x00000001
|
||||
.binary 0C # slot count
|
||||
.data 0x006C56F6
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C5730
|
||||
.data 0x00000001
|
||||
.binary 0C # slot count
|
||||
.data 0x006C58B6
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C58F0
|
||||
.data 0x00000001
|
||||
.binary 0C # slot count
|
||||
.data 0x006C5A85
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C5AC1
|
||||
.data 0x00000001
|
||||
.binary 0C # slot count
|
||||
.data 0x006C5BB2
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C5BEC
|
||||
.data 0x00000001
|
||||
.binary 0C # slot count
|
||||
.data 0x006C5D72
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C5DAC
|
||||
.data 0x00000001
|
||||
.binary 0C # slot count
|
||||
.data 0x006C5F32
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C5F6C
|
||||
.data 0x00000001
|
||||
.binary 0C # slot count
|
||||
.data 0x006C60F2
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C612C
|
||||
.data 0x00000001
|
||||
.binary 0C # slot count
|
||||
.data 0x006C6346
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C6381
|
||||
.data 0x00000001
|
||||
.binary 0C # slot count
|
||||
.data 0x006C6505
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C6541
|
||||
.data 0x00000001
|
||||
.binary 0C # slot count
|
||||
.data 0x006C6632
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C666C
|
||||
.data 0x00000001
|
||||
.binary 0C # slot count
|
||||
.data 0x006C67F2
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C682C
|
||||
.data 0x00000001
|
||||
.binary 0C # slot count
|
||||
.data 0x006C69B2
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C69EC
|
||||
.data 0x00000001
|
||||
.binary 0C # slot count
|
||||
.data 0x006C6B87
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C6BB8
|
||||
.data 0x00000004
|
||||
.data 0x0000005D # memcard block count
|
||||
.data 0x006C6C3A
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C6C74
|
||||
.data 0x00000001
|
||||
.binary 0C # slot count
|
||||
.data 0x006C6E82
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C6EBC
|
||||
.data 0x00000001
|
||||
.binary 0C # slot count
|
||||
.data 0x006C70B9
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C70F3
|
||||
.data 0x00000001
|
||||
.binary 0C # slot count
|
||||
.data 0x006C7A46
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C7D66
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x006C7D7C
|
||||
.data 0x00000001
|
||||
.binary 0C # slot count
|
||||
.data 0x006C7DC0
|
||||
.data 0x00000004
|
||||
.data 0x00022FC4 # total file size
|
||||
.data 0x0077CC72
|
||||
.data 0x00000004
|
||||
.data 0x00022FB4 # bgm_test_songs_unlocked offset
|
||||
|
||||
# Signature check on all save files (rewritten as loop)
|
||||
.data 0x006C1C69
|
||||
.deltaof sig_check_begin, sig_check_end
|
||||
sig_check_begin:
|
||||
mov edx, 0xC87ED5B1 # Expected signature value
|
||||
add eax, 0x04E8 # &char_file_list->chars[0].part2.signature
|
||||
mov ecx, 0x0C # slot count
|
||||
again:
|
||||
cmp dword [eax], 0 # signature == 0 (no char in slot)
|
||||
je sig_ok
|
||||
cmp dword [eax], edx # signature == expected value
|
||||
jne sig_bad
|
||||
sig_ok:
|
||||
add eax, 0x2EA4 # Advance to next slot
|
||||
dec ecx
|
||||
jnz again
|
||||
xor eax, eax # All signatures OK (eax = 0)
|
||||
jmp sig_check_end
|
||||
sig_bad:
|
||||
xor eax, eax # Bad signature (eax = 1)
|
||||
inc eax
|
||||
jmp sig_check_end
|
||||
.binary CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
|
||||
sig_check_end: # 006C1CB2
|
||||
|
||||
# Send slot count in E3 command
|
||||
.data 0x0046EC10 # TDataProtocol::send_E3_for_index
|
||||
.deltaof send_slot_count_in_E3_begin, send_slot_count_in_E3_end
|
||||
send_slot_count_in_E3_begin:
|
||||
# ecx = this (TDataProtocol*)
|
||||
# [esp + 4] = slot_index
|
||||
push 0
|
||||
push dword [esp + 8] # slot_index
|
||||
push 0x0C # slot count
|
||||
push 0x00E30010
|
||||
mov eax, esp
|
||||
push 0x10
|
||||
push eax
|
||||
mov eax, [ecx]
|
||||
call [eax + 0x20] # this->send_command(&cmd, 0x10) // ret 8
|
||||
add esp, 8
|
||||
mov eax, 0x006C1ABC
|
||||
call eax # set_current_char_slot(slot_index) // ret 0
|
||||
add esp, 8
|
||||
ret 4
|
||||
send_slot_count_in_E3_end:
|
||||
|
||||
# Show slot number in each menu item
|
||||
.data 0x00401D57
|
||||
.deltaof show_slot_number_begin, show_slot_number_end
|
||||
show_slot_number_begin:
|
||||
# Original call (sprintf(line_buf, "LV%d", preview_info->visual.disp.level + 1))
|
||||
lea edx, [esp + 0x02C4]
|
||||
mov ebx, [ebx + 8]
|
||||
inc ebx
|
||||
push ebx
|
||||
mov ecx, esi
|
||||
push edx
|
||||
mov eax, 0x00402604
|
||||
call eax
|
||||
# Find the end of the string
|
||||
lea eax, [esp + 0x02C4]
|
||||
show_slot_number_strend_again:
|
||||
cmp word [eax], 0
|
||||
je show_slot_number_strend_done
|
||||
add eax, 2
|
||||
jmp show_slot_number_strend_again
|
||||
show_slot_number_strend_done:
|
||||
# Format the slot number and append it to the string
|
||||
mov ecx, [0x00A38BD0] # scroll_bar = TAdScrollBarXb_objs[0]
|
||||
mov ecx, [ecx + 0xAC] # ecx = scroll_bar->selection_state[0].scroll_offset
|
||||
lea ecx, [ecx + ebp + 1]
|
||||
push ecx # Slot number (scroll_offset + z)
|
||||
call get_show_slot_number_suffix_fmt
|
||||
.binary 20002800230025006400290020000000 # L" (#%d) "
|
||||
get_show_slot_number_suffix_fmt:
|
||||
push eax # Destination buffer
|
||||
mov eax, 0x00835578 # _swprintf
|
||||
call eax
|
||||
add esp, 0x0C
|
||||
jmp show_slot_number_end
|
||||
.zero 0x96
|
||||
show_slot_number_end: # 00401E4D
|
||||
|
||||
# End static patches
|
||||
.data 0x00000000
|
||||
.data 0x00000000
|
||||
|
||||
|
||||
|
||||
update_existing_char_file_list:
|
||||
# Replace the existing character list with an appropriately-longer one. This
|
||||
# part does not need to be done if the patch is applied statically to the
|
||||
# executable; this is only necessary when used as a server patch because the
|
||||
# character list is already allocated at the time the patch is applied.
|
||||
push 0x00022FC4 # total file size
|
||||
mov eax, 0x00835915 # operator_new
|
||||
call eax
|
||||
add esp, 4
|
||||
mov edx, [0x00A939C4] # edx = old char_file_list
|
||||
mov [0x00A939C4], eax
|
||||
mov ecx, [edx + 0xBA94] # Copy bgm_test_songs_unlocked_high to new file
|
||||
mov [eax + 0x00022FB4], ecx
|
||||
mov ecx, [edx + 0xBA98] # Copy bgm_test_songs_unlocked_low to new file
|
||||
mov [eax + 0x00022FB8], ecx
|
||||
mov ecx, [edx + 0xBA9C] # Copy save_count to new file
|
||||
mov [eax + 0x00022FBC], ecx
|
||||
mov ecx, [edx + 0xBAA0] # Copy round2_seed to new file
|
||||
mov [eax + 0x00022FC0], ecx
|
||||
add eax, 4
|
||||
add edx, 4
|
||||
mov ecx, 0xBA90
|
||||
call memcpy # Copy the existing 4 characters over
|
||||
mov eax, [0x00A939C4]
|
||||
add eax, 0xBA94
|
||||
mov ecx, 4
|
||||
clear_next_char:
|
||||
cmp ecx, 0x0C # slot count
|
||||
jge clear_next_char_done
|
||||
lea edx, [eax + 0x2EA4] # edx = ptr to next char (or footer)
|
||||
clear_next_char_write_again:
|
||||
mov dword [eax], 0
|
||||
add eax, 4
|
||||
cmp eax, edx
|
||||
jl clear_next_char_write_again
|
||||
clear_next_char_done:
|
||||
|
||||
# Call eh_vector_constructor_iterator(
|
||||
# &char_file_list.chars[4],
|
||||
# sizeof(char_file_list.chars[0]),
|
||||
# countof(char_file_list.chars) - 4,
|
||||
# PSOCharacterFile::init,
|
||||
# PSOCharacterFile::destroy)
|
||||
push 0x006C197C # PSOCharacterFile::destroy
|
||||
push 0x006C182C # PSOCharacterFile::init
|
||||
push 0x08 # slot count - 4
|
||||
push 0x2EA4 # sizeof(PSOCharacterFile)
|
||||
mov eax, [0x00A939C4]
|
||||
add eax, 0xBA94
|
||||
push eax
|
||||
mov eax, 0x00835E86
|
||||
call eax
|
||||
|
||||
# Fix the file's checksum
|
||||
mov eax, [0x00A939C4]
|
||||
mov ecx, 0x006C2738
|
||||
jmp ecx # PSOBBCharacterFileList::checksum(char_file_list)
|
||||
|
||||
|
||||
|
||||
update_existing_char_file_list_memcard:
|
||||
# Allocate a new memory card file area and copy the data there too. It seems
|
||||
# Sega didn't fully strip out the local saving code from PSOBB; instead, they
|
||||
# just made it write to a heap-allocated buffer. Since the file is much
|
||||
# bigger now, we also have to make that heap-allocated buffer larger. We add
|
||||
# a few "blocks" on the end, since the original code in the game does that
|
||||
# too, but it's probably not strictly necessary.
|
||||
# Like the above, this part is not necessary if this patch is statically
|
||||
# applied to the executable.
|
||||
mov eax, 0x00022FC4 # total file size
|
||||
add eax, 0x0000FFFF
|
||||
and eax, 0xFFFFC000
|
||||
push eax
|
||||
mov eax, 0x0084F258
|
||||
call eax # malloc10(total file size)
|
||||
add esp, 4
|
||||
mov [0x00A939AC], eax
|
||||
mov edx, [0x00A939C4]
|
||||
mov ecx, 0x00022FC4 # total file size
|
||||
jmp memcpy
|
||||
@@ -0,0 +1,103 @@
|
||||
# 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 0x00A0DC54
|
||||
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, [0x00A9A074] # 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, 0x0068D618
|
||||
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 0x00976380 # prefix = L"EXP"
|
||||
push 0x14
|
||||
push 0x14
|
||||
push 0xFFFF00FF # color (ARGB)
|
||||
add eax, 0x300
|
||||
push eax # position
|
||||
mov eax, 0x0078B8E8
|
||||
call eax # TFontSmallTask___new__(...)
|
||||
add esp, 0x1C
|
||||
|
||||
skip_text:
|
||||
mov eax, 0x0069292C # Original handle_6xBF
|
||||
jmp eax # original_handle_6xBF(cmd)
|
||||
|
||||
get_enemy_entity:
|
||||
.include GetEnemyEntity-59NJ
|
||||
ret
|
||||
|
||||
handle_6xBF_end:
|
||||
push ecx
|
||||
.include WriteCallToCode-59NJ
|
||||
|
||||
|
||||
|
||||
apply_static_patches:
|
||||
.include WriteCodeBlocksBB
|
||||
|
||||
.data 0x0078827D
|
||||
.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 0x00777381
|
||||
.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
|
||||
+5
-3
@@ -10,6 +10,8 @@
|
||||
.meta description=""
|
||||
.meta hide_from_patches_menu
|
||||
|
||||
.versions 59NJ 59NL
|
||||
|
||||
entry_ptr:
|
||||
reloc0:
|
||||
.offsetof start
|
||||
@@ -17,7 +19,7 @@ start:
|
||||
.include WriteCodeBlocksBB
|
||||
|
||||
# Patch 1: rewrite item_is_stackable
|
||||
.data 0x005C502C
|
||||
.data <VERS 0x005C5020 0x005C502C>
|
||||
.deltaof item_is_stackable_start, item_is_stackable_end
|
||||
|
||||
item_is_stackable_start:
|
||||
@@ -32,7 +34,7 @@ item_is_stackable_start:
|
||||
push eax
|
||||
mov ecx, esp
|
||||
|
||||
.binary E8EC130100 # call max_stack_size_for_tool_start
|
||||
.binary <VERS E8D8130100 E8EC130100> # call max_stack_size_for_tool_start
|
||||
pop ecx
|
||||
cmp eax, 1
|
||||
jg return_1
|
||||
@@ -48,7 +50,7 @@ return_1:
|
||||
item_is_stackable_end:
|
||||
|
||||
# Patch 2: rewrite max_stack_size_for_tool
|
||||
.data 0x005D6430
|
||||
.data <VERS 0x005D6410 0x005D6430>
|
||||
.deltaof max_stack_size_for_tool_start, max_stack_size_for_tool_end
|
||||
|
||||
max_stack_size_for_tool_start:
|
||||
@@ -0,0 +1,146 @@
|
||||
# Currently beta quality, map objects that fade like boxes, and Pioneer's
|
||||
# background billboards and elevators still have regular draw distance.
|
||||
# TODO: 90% of stuff is included, bring home the last 10%.
|
||||
|
||||
.meta name="Draw Distance"
|
||||
.meta description="Extends the draw\ndistance of many\nobjects"
|
||||
|
||||
entry_ptr:
|
||||
reloc0:
|
||||
.offsetof start
|
||||
|
||||
write_call_func:
|
||||
.include WriteCallToCode-59NJ
|
||||
|
||||
start:
|
||||
mov eax, 0x41800000 # Environment clip distance mod 16.0f
|
||||
mov [0x0097D198], eax # This affects mostly static map objects
|
||||
mov [0x0097D19C], eax
|
||||
mov [0x00097D1A0], eax
|
||||
|
||||
mov ax, 0x9090
|
||||
mov [0x00689BC7], ax # Players draw distance 10000.0f always
|
||||
mov eax, 0x41000000 # Use newly acquired skipped branch room
|
||||
mov [0x00689BD1], eax # to store our float multiplier
|
||||
|
||||
call patch_func_1 # Floor items
|
||||
call patch_func_2 # Whole bunch of stuff, including NPCs
|
||||
call patch_func_3 # Duplicate function from above, reuse same hook
|
||||
call patch_func_4 # TODO: Which objects this affects?
|
||||
call patch_func_5 # TODO: This one too?
|
||||
call patch_func_6 # TODO: And this one?
|
||||
ret
|
||||
|
||||
# Floor items
|
||||
patch_func_1:
|
||||
pop ecx
|
||||
push 8
|
||||
push 0x005C525B
|
||||
call get_code_size1
|
||||
.deltaof patch_code1, patch_code_end1
|
||||
get_code_size1:
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call patch_code_end1
|
||||
patch_code1:
|
||||
mov edx, [esp + 0x18]
|
||||
fld st0, dword [0x00689BD1]
|
||||
fld st0, dword [esp + 0x14]
|
||||
fmulp st1, st0
|
||||
ret
|
||||
patch_code_end1:
|
||||
push ecx
|
||||
jmp write_call_func
|
||||
|
||||
# Whole bunch of stuff, including NPCs
|
||||
patch_func_2:
|
||||
pop ecx
|
||||
push 9
|
||||
push 0x007BB21E
|
||||
call get_code_size2
|
||||
.deltaof patch_code2, patch_code_end2
|
||||
get_code_size2:
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call patch_code_end2
|
||||
patch_code2:
|
||||
test eax, 0x400
|
||||
fld st0, dword [0x00689BD1]
|
||||
fld st0, dword [esp + 0x2C]
|
||||
fmulp st1, st0
|
||||
ret
|
||||
patch_code_end2:
|
||||
push ecx
|
||||
jmp write_call_func
|
||||
|
||||
# Duplicate function from above, reuse same hook
|
||||
patch_func_3:
|
||||
mov eax, dword [0x007BB21F]
|
||||
add eax, 0x002A1C74
|
||||
mov dword [0x00518843], eax
|
||||
mov byte [0x00518842], 0xE8
|
||||
mov dword [0x00518847], 0x90909090
|
||||
ret
|
||||
|
||||
# TOComputerMachine01
|
||||
patch_func_4:
|
||||
pop ecx
|
||||
push 7
|
||||
push 0x00616FF4
|
||||
call get_code_size4
|
||||
.deltaof patch_code4, patch_code_end4
|
||||
get_code_size4:
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call patch_code_end4
|
||||
patch_code4:
|
||||
lea edx, [edi + 0x38]
|
||||
fld st0, dword [0x00689BD1]
|
||||
fld st0, dword [esp + 0x14]
|
||||
fmulp st1, st0
|
||||
ret
|
||||
patch_code_end4:
|
||||
push ecx
|
||||
jmp write_call_func
|
||||
|
||||
# TObjCamera
|
||||
patch_func_5:
|
||||
pop ecx
|
||||
push 6
|
||||
push 0x006439A8
|
||||
call get_code_size5
|
||||
.deltaof patch_code5, patch_code_end5
|
||||
get_code_size5:
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call patch_code_end5
|
||||
patch_code5:
|
||||
fld st0, dword [0x00689BD1]
|
||||
fld st0, dword [esp + 0x28]
|
||||
fmulp st1, st0
|
||||
fchs st0
|
||||
ret
|
||||
patch_code_end5:
|
||||
push ecx
|
||||
jmp write_call_func
|
||||
|
||||
# TODO: And this one?
|
||||
patch_func_6:
|
||||
pop ecx
|
||||
push 6
|
||||
push 0x0065B959
|
||||
call get_code_size6
|
||||
.deltaof patch_code6, patch_code_end6
|
||||
get_code_size6:
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call patch_code_end6
|
||||
patch_code6:
|
||||
mov ebp, ecx
|
||||
fld st0, dword [0x00689BD1]
|
||||
fld st0, dword [esp + 0x30]
|
||||
fmulp st1, st0
|
||||
ret
|
||||
patch_code_end6:
|
||||
push ecx
|
||||
jmp write_call_func
|
||||
@@ -0,0 +1,258 @@
|
||||
.meta name="DMC"
|
||||
.meta description="Mitigates effects\nof enemy health\ndesync"
|
||||
.meta client_flag="0x0000001000000000"
|
||||
|
||||
entry_ptr:
|
||||
reloc0:
|
||||
.offsetof start
|
||||
|
||||
write_call_to_code_multi:
|
||||
.include WriteCallToCodeMulti-59NJ
|
||||
write_address_of_code:
|
||||
.include WriteAddressOfCode-59NJ
|
||||
|
||||
start:
|
||||
|
||||
# Replace 6x09 with 6xE4 in subcommand handler table
|
||||
mov dword [0x00A0DC30], 0x000600E4 # subcommand=0xE4, flags=6
|
||||
push 0x00A0DC34
|
||||
call +4
|
||||
.deltaof handle_6xE4_start, handle_6xE4_end
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call handle_6xE4_end
|
||||
|
||||
handle_6xE4_start: # (G_6xE4* cmd @ [esp + 4]) -> void
|
||||
push ebx
|
||||
push esi
|
||||
push edi
|
||||
|
||||
test byte [0x00AA8DFC], 0x80
|
||||
jz handle_6xE4_return
|
||||
mov ebx, [esp + 0x10] # cmd
|
||||
movzx eax, word [ebx + 2]
|
||||
cmp eax, 0x1000
|
||||
jl handle_6xE4_return
|
||||
cmp eax, 0x1B50
|
||||
jge handle_6xE4_return
|
||||
|
||||
movzx eax, word [ebx + 2]
|
||||
.include GetEnemyEntity-59NJ # auto* ene = get_enemy_entity(cmd->header.entity_id);
|
||||
push eax
|
||||
|
||||
movzx eax, word [ebx + 2]
|
||||
and eax, 0x0FFF
|
||||
imul eax, eax, 0x0C
|
||||
add eax, [0x00AADE38] # eax = state_for_enemy(cmd->header.entity_id)
|
||||
|
||||
cmp dword [ebx + 0x0C], 0
|
||||
jl handle_6xE4_not_proportional
|
||||
mov cx, [ebx + 0x0A] # cmd->max_hp
|
||||
sub cx, [eax + 0x06] # st.total_damage
|
||||
movzx ecx, cx
|
||||
xor edx, edx
|
||||
cmp ecx, edx
|
||||
cmovl ecx, edx
|
||||
push ecx
|
||||
fild st0, dword [esp] # current_hp = static_cast<float>(max<int32_t>(cmd->max_hp - st.total_damage, 0))
|
||||
fld st0, dword [ebx + 0x0C]
|
||||
fmulp st1, st0
|
||||
fistp dword [esp], st0
|
||||
mov ecx, dword [esp] # adjusted_hit_amount = static_cast<int16_t>(current_hp * cmd->factor)
|
||||
add esp, 4
|
||||
xor edx, edx
|
||||
inc edx
|
||||
cmp ecx, edx
|
||||
cmovl ecx, edx
|
||||
mov [ebx + 0x04], cx # cmd->hit_amount = min<int32_t>(1, adjusted_hit_amount)
|
||||
handle_6xE4_not_proportional:
|
||||
|
||||
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_pop_ene
|
||||
or edx, 0x800
|
||||
mov [eax], edx
|
||||
cmp dword [esp], 0
|
||||
je handle_6xE4_return_pop_ene
|
||||
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, 0x00801150
|
||||
call edx # send_and_handle_60(&out_cmd);
|
||||
add esp, 0x10
|
||||
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
|
||||
mov eax, [esp] # eax = ene
|
||||
test eax, eax
|
||||
jz handle_6xE4_return_pop_ene
|
||||
mov ecx, eax
|
||||
push edx
|
||||
mov edx, [ecx]
|
||||
call [edx + 0x148] # ene->vtable[0x52](ene, &st);
|
||||
|
||||
handle_6xE4_return_pop_ene:
|
||||
add esp, 4
|
||||
handle_6xE4_return:
|
||||
pop edi
|
||||
pop esi
|
||||
pop ebx
|
||||
ret
|
||||
|
||||
handle_6xE4_end:
|
||||
call write_address_of_code
|
||||
|
||||
|
||||
|
||||
# Write TObjectV00b421c0::incr_hp_with_sync
|
||||
push 5
|
||||
push 0x00775224 # TObjectV00b421c0::v18_accept_hit (presumably Resta) - this is add_hp, not subtract_hp!
|
||||
push 5
|
||||
push 0x00778063 # TObjectV00b421c0::subtract_hp_if_not_in_state_2
|
||||
push 5
|
||||
push 0x00777AB2 # TObjectV00b421c0::v19_handle_hit_special_effects
|
||||
push 5
|
||||
push 0x00777B2B # TObjectV00b421c0::v19_handle_hit_special_effects
|
||||
push 5
|
||||
push 0x00777BFC # TObjectV00b421c0::v19_handle_hit_special_effects
|
||||
push 5
|
||||
push 0x00777C75 # TObjectV00b421c0::v19_handle_hit_special_effects
|
||||
push 5
|
||||
push 0x00776D2D # TObjectV00b421c0::v19_handle_hit_special_effects
|
||||
push 5
|
||||
push 0x007769C2 # TObjectV00b421c0::v19_handle_hit_special_effects
|
||||
push 5
|
||||
push 0x0077683C # TObjectV00b421c0::v19_handle_hit_special_effects
|
||||
push 5
|
||||
push 0x00776502 # TObjectV00b421c0::v19_handle_hit_special_effects (Devil's/Demon's)
|
||||
push 5
|
||||
push 0x00775B57 # TObjectV00b421c0::v18_accept_hit
|
||||
push 5
|
||||
push 0x00775A23 # TObjectV00b421c0::v18_accept_hit
|
||||
push 5
|
||||
push 0x007757F0 # TObjectV00b421c0::v18_accept_hit
|
||||
push 5
|
||||
push 0x00775606 # TObjectV00b421c0::v18_accept_hit
|
||||
push 5
|
||||
push 0x007754BC # TObjectV00b421c0::v18_accept_hit
|
||||
push 5
|
||||
push 0x00774E3D # TObjectV00b421c0::v18_accept_hit
|
||||
push 5
|
||||
push 0x00774CD6 # TObjectV00b421c0::v18_accept_hit
|
||||
push 5
|
||||
push 0x00774713 # TObjectV00b421c0::v17
|
||||
push 18
|
||||
call +4
|
||||
.deltaof on_add_or_subtract_hp_start, on_add_or_subtract_hp_end
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call on_add_or_subtract_hp_end
|
||||
|
||||
on_add_or_subtract_hp_start: # (TObjectV00b421c0* this @ ecx, int16_t amount @ [esp + 4]) -> bool @ eax
|
||||
test byte [0x00AA8DFC], 0x80
|
||||
jz on_add_or_subtract_hp_skip_send
|
||||
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, [0x00AADE38] # eax = state_for_enemy(cmd->header.entity_id)
|
||||
|
||||
sub esp, 0x10
|
||||
mov word [esp], 0x04E4
|
||||
mov dx, [ecx + 0x1C]
|
||||
mov [esp + 0x02], dx # cmd.entity_id
|
||||
mov dx, [esp + 0x14]
|
||||
cmp dword [esp + 0x10], 0x00775229 # 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 dword [esp + 0x0C], 0xBF800000 # cmd.factor
|
||||
|
||||
cmp dword [esp + 0x10], 0x00776507 # Check if callsite is Devil's/Demon's
|
||||
jne on_add_or_subtract_hp_not_proportional
|
||||
# esp is 0x18 down from where it is in caller's context
|
||||
mov edx, 100
|
||||
sub edx, [esp + 0x24] # edx = (100 - special_amount)
|
||||
push edx
|
||||
fild st0, dword [esp] # current_hp_factor = static_cast<float>(100 - special_amount)
|
||||
fmul st0, dword [esp + 0x54] # *= weapon_reduction_factor
|
||||
mov dword [esp], 0x42C80000 # 100.0f
|
||||
fdiv st0, dword [esp]
|
||||
add esp, 4
|
||||
fstp dword [esp + 0x0C], st0 # cmd.factor = ((100 - special_amount) * weapon_reduction_factor) / 100
|
||||
on_add_or_subtract_hp_not_proportional:
|
||||
|
||||
mov edx, esp
|
||||
push ecx
|
||||
push 0x10
|
||||
push edx
|
||||
mov ecx, [0x00AA8E04]
|
||||
mov edx, 0x007D4CBC
|
||||
call edx # send_60(root_protocol, &cmd, sizeof(cmd));
|
||||
pop ecx
|
||||
add esp, 0x10
|
||||
|
||||
on_add_or_subtract_hp_skip_send:
|
||||
mov eax, 0x007781F0 # subtract_hp
|
||||
mov edx, 0x007781B0 # add_hp
|
||||
cmp dword [esp], 0x00775229 # Check if callsite is add_hp
|
||||
cmove eax, edx
|
||||
jmp eax
|
||||
|
||||
on_add_or_subtract_hp_end:
|
||||
call write_call_to_code_multi
|
||||
|
||||
|
||||
|
||||
push 5
|
||||
push 0x0078864B
|
||||
push 1
|
||||
call +4
|
||||
.deltaof on_6x0A_patch_start, on_6x0A_patch_end
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call on_6x0A_patch_end
|
||||
|
||||
on_6x0A_patch_start: # (TObjectV00b421c0* this @ ecx, int16_t amount @ [esp + 4]) -> bool @ eax
|
||||
test byte [0x00AA8DFC], 0x80
|
||||
jz on_6x0A_patch_skip_write
|
||||
mov [esp + 0x0A], cx
|
||||
on_6x0A_patch_skip_write:
|
||||
ret
|
||||
|
||||
on_6x0A_patch_end:
|
||||
call write_call_to_code_multi
|
||||
|
||||
|
||||
|
||||
ret
|
||||
+14
-12
@@ -1,45 +1,47 @@
|
||||
.meta name="Enemy HP bars"
|
||||
.meta description="Shows HP bars in\nenemy info windows"
|
||||
|
||||
.versions 59NJ 59NL
|
||||
|
||||
entry_ptr:
|
||||
reloc0:
|
||||
.offsetof start
|
||||
start:
|
||||
.include WriteCodeBlocksBB
|
||||
.data 0x007318DD
|
||||
.data <VERS 0x0073197D 0x007318DD>
|
||||
.data 6
|
||||
.binary 81E2FDFFFFFF
|
||||
.data 0x00731F2F
|
||||
.data <VERS 0x00731FCF 0x00731F2F>
|
||||
.data 1
|
||||
.binary FA
|
||||
.data 0x009F2DA4
|
||||
.data <VERS 0x009F0DA4 0x009F2DA4>
|
||||
.data 4
|
||||
.data 0x42480000
|
||||
.data 0x009F2DAC
|
||||
.data <VERS 0x009F0DAC 0x009F2DAC>
|
||||
.data 4
|
||||
.data 0x41C00000
|
||||
.data 0x009F2DD4
|
||||
.data <VERS 0x009F0DD4 0x009F2DD4>
|
||||
.data 4
|
||||
.data 0x42480000
|
||||
.data 0x009F2DDC
|
||||
.data <VERS 0x009F0DDC 0x009F2DDC>
|
||||
.data 4
|
||||
.data 0x41C00000
|
||||
.data 0x009F2E04
|
||||
.data <VERS 0x009F0E04 0x009F2E04>
|
||||
.data 4
|
||||
.data 0x42480000
|
||||
.data 0x009F2E0C
|
||||
.data <VERS 0x009F0E0C 0x009F2E0C>
|
||||
.data 4
|
||||
.data 0x41C00000
|
||||
.data 0x009F2E34
|
||||
.data <VERS 0x009F0E34 0x009F2E34>
|
||||
.data 4
|
||||
.data 0x42480000
|
||||
.data 0x009F2E3C
|
||||
.data <VERS 0x009F0E3C 0x009F2E3C>
|
||||
.data 4
|
||||
.data 0x41C00000
|
||||
.data 0x009F2E64
|
||||
.data <VERS 0x009F0E64 0x009F2E64>
|
||||
.data 4
|
||||
.data 0x42200000
|
||||
.data 0x009F2E80
|
||||
.data <VERS 0x009F0E80 0x009F2E80>
|
||||
.data 4
|
||||
.data 0xFF00FF15
|
||||
.data 0x00000000
|
||||
@@ -1,17 +0,0 @@
|
||||
# This function implements $exit in a game when no quest is loaded.
|
||||
|
||||
.meta name="Exit anywhere"
|
||||
.meta description=""
|
||||
.meta hide_from_patches_menu
|
||||
|
||||
entry_ptr:
|
||||
reloc0:
|
||||
.offsetof start
|
||||
|
||||
start:
|
||||
xor eax, eax
|
||||
mov [0x00A95624], eax # is_in_quest = false
|
||||
mov [0x00A955E0], eax # dat_source_type = NONE
|
||||
inc eax
|
||||
mov [0x00AAE6D4], ax # should_leave_game = true
|
||||
ret
|
||||
@@ -0,0 +1,19 @@
|
||||
# This function implements $exit in a game when no quest is loaded.
|
||||
|
||||
.meta name="Exit anywhere"
|
||||
.meta description=""
|
||||
.meta hide_from_patches_menu
|
||||
|
||||
.versions 59NJ 59NL
|
||||
|
||||
entry_ptr:
|
||||
reloc0:
|
||||
.offsetof start
|
||||
|
||||
start:
|
||||
xor eax, eax
|
||||
mov [<VERS 0x00A931A4 0x00A95624>], eax # is_in_quest = false
|
||||
mov [<VERS 0x00A93160 0x00A955E0>], eax # dat_source_type = NONE
|
||||
inc eax
|
||||
mov [<VERS 0x00AAC254 0x00AAE6D4>], ax # should_leave_game = true
|
||||
ret
|
||||
+4
-2
@@ -1,19 +1,21 @@
|
||||
.meta name="Fast tekker"
|
||||
.meta description="Skips wind-up sound\nat tekker window"
|
||||
|
||||
.versions 59NJ 59NL
|
||||
|
||||
entry_ptr:
|
||||
reloc0:
|
||||
.offsetof start
|
||||
start:
|
||||
.include WriteCodeBlocksBB
|
||||
|
||||
.data 0x006DA113
|
||||
.data <VERS 0x006DA14B 0x006DA113>
|
||||
.deltaof patch1_start, patch1_end
|
||||
patch1_start:
|
||||
mov dword [edi + 0x14C], 1
|
||||
patch1_end:
|
||||
|
||||
.data 0x006DA130
|
||||
.data <VERS 0x006DA168 0x006DA130>
|
||||
.deltaof patch2_start, patch2_end
|
||||
patch2_start:
|
||||
nop
|
||||
@@ -0,0 +1,34 @@
|
||||
.meta name="MAG alert"
|
||||
.meta description="Plays a sound when\nyour MAG is hungry"
|
||||
|
||||
entry_ptr:
|
||||
reloc0:
|
||||
.offsetof start
|
||||
start:
|
||||
pop ecx
|
||||
push 6
|
||||
push 0x005D91BE
|
||||
call get_code_size
|
||||
.deltaof patch_code, patch_code_end
|
||||
get_code_size:
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call patch_code_end
|
||||
patch_code: # [eax] (TItemMag* this @ ecx) -> void
|
||||
mov dword [ecx + 0x01B8], eax
|
||||
mov eax, [ecx + 0x00F8]
|
||||
movzx eax, word [eax + 0x001C] # eax = this->owner_player->entity_id
|
||||
cmp [0x00A9A074], eax
|
||||
jne patch_code_skip_sound
|
||||
push 0
|
||||
push 0
|
||||
push 0
|
||||
push 0xAC
|
||||
mov eax, 0x00815020
|
||||
call eax
|
||||
add esp, 0x10
|
||||
patch_code_skip_sound:
|
||||
ret
|
||||
patch_code_end:
|
||||
push ecx
|
||||
.include WriteCallToCode-59NJ
|
||||
@@ -0,0 +1,43 @@
|
||||
# Original patch by Soly, in Blue Burst Patch Project
|
||||
# https://github.com/Solybum/Blue-Burst-Patch-Project
|
||||
|
||||
.meta name="No rare selling"
|
||||
.meta description="Stops you from accidentally\nselling rares to vendors"
|
||||
|
||||
entry_ptr:
|
||||
reloc0:
|
||||
.offsetof start
|
||||
start:
|
||||
# This works by setting the item price to zero if it's rare, which causes
|
||||
# the game to prevent you from selling the item. For armors and weapons, this
|
||||
# is easy because there are easily-patchable opcodes within branches that
|
||||
# return a constant price for rare items.
|
||||
xor eax, eax
|
||||
mov [0x005D258F], eax # Rare armors
|
||||
mov [0x005D26D1], eax # Unidentified weapons
|
||||
mov [0x005D26E6], eax # Rare weapons
|
||||
|
||||
# For tools, it's harder to implement this, because the price comes from the
|
||||
# ItemPMT tools table and there is no branch for rares. Still, we can add a
|
||||
# branch to a stub to handle tools.
|
||||
pop ecx
|
||||
push 5
|
||||
push 0x005D2508
|
||||
call get_code_size
|
||||
.deltaof patch_code, patch_code_end
|
||||
get_code_size:
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call patch_code_end
|
||||
patch_code:
|
||||
# TODO: It'd be nice to have something like WriteJumpToAndFromCode, since
|
||||
# this hook is supposed to return to a different place than where it was
|
||||
# called, hence this mov [esp].
|
||||
mov dword [esp], 0x005D2556
|
||||
xor edi, edi
|
||||
test byte [eax + 0x14], 0x80 # flags & 0x80 = is rare
|
||||
cmovz edi, [eax + 0x10] # Use price from table if not rare
|
||||
ret
|
||||
patch_code_end:
|
||||
push ecx
|
||||
.include WriteCallToCode-59NJ
|
||||
@@ -0,0 +1,230 @@
|
||||
# Original patch by Soly, in Blue Burst Patch Project
|
||||
# https://github.com/Solybum/Blue-Burst-Patch-Project
|
||||
|
||||
.meta name="Palette"
|
||||
.meta description="Enables the alternate action\npalette for number keys"
|
||||
|
||||
entry_ptr:
|
||||
reloc0:
|
||||
.offsetof start
|
||||
|
||||
write_call_func:
|
||||
.include WriteCallToCode-59NJ
|
||||
|
||||
start:
|
||||
mov al, 0xEB
|
||||
mov [0x0068A7A5], al # SecondaryPaletteAttack1
|
||||
xor al, al
|
||||
mov [0x006A11B7], al # SecondaryPaletteAttack2
|
||||
mov [0x006A0CB7], al # SecondaryPaletteAttack3
|
||||
|
||||
call patch_func_1 # GetCurrentPalette
|
||||
call patch_func_2 # CheckHotkey1_1
|
||||
call patch_func_3 # CheckHotkey1_2
|
||||
call patch_func_4 # CheckHotkey2_1
|
||||
call patch_func_5 # CheckHotkey2_2
|
||||
call patch_func_6 # CheckHotkey3_1
|
||||
call patch_func_7 # CheckHotkey3_2
|
||||
jmp write_code_blocks # UnsetHotkey1, UnsetHotkey2, SetHotkey
|
||||
|
||||
# GetCurrentPalette
|
||||
patch_func_1:
|
||||
pop ecx
|
||||
push 8
|
||||
push 0x00748990
|
||||
call get_code_size1
|
||||
.deltaof patch_code1, patch_code_end1
|
||||
get_code_size1:
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call patch_code_end1
|
||||
patch_code1:
|
||||
mov edx, [ebp - 0x14]
|
||||
mov edx, [edx + 0x2C]
|
||||
movzx edx, byte [edx + 0x62]
|
||||
test edx, edx
|
||||
setnz byte [0x00748B1B]
|
||||
mov edx, edi
|
||||
and edx, 0xFF
|
||||
ret
|
||||
patch_code_end1:
|
||||
push ecx
|
||||
jmp write_call_func
|
||||
|
||||
# CheckHotkey1_1
|
||||
patch_func_2:
|
||||
pop ecx
|
||||
push 5
|
||||
push 0x007489DE
|
||||
call get_code_size2
|
||||
.deltaof patch_code2, patch_code_end2
|
||||
get_code_size2:
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call patch_code_end2
|
||||
patch_code2:
|
||||
cmp byte [0x00748B1B], 0
|
||||
jnz +0x06
|
||||
movzx edx, byte [eax + esi * 4 + 0x04] # main palette
|
||||
ret
|
||||
movzx edx, byte [eax + esi * 4 + 0x3C] # alt palette
|
||||
ret
|
||||
patch_code_end2:
|
||||
push ecx
|
||||
jmp write_call_func
|
||||
|
||||
# CheckHotkey1_2
|
||||
patch_func_3:
|
||||
pop ecx
|
||||
push 5
|
||||
push 0x007489ED
|
||||
call get_code_size3
|
||||
.deltaof patch_code3, patch_code_end3
|
||||
get_code_size3:
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call patch_code_end3
|
||||
patch_code3:
|
||||
cmp byte [0x00748B1B], 0
|
||||
jnz +0x06
|
||||
movzx ecx, byte [eax + ecx * 2 + 0x05] # main palette
|
||||
ret
|
||||
movzx ecx, byte [eax + ecx * 2 + 0x3D] # alt palette
|
||||
ret
|
||||
patch_code_end3:
|
||||
push ecx
|
||||
jmp write_call_func
|
||||
|
||||
# CheckHotkey2_1
|
||||
patch_func_4:
|
||||
pop ecx
|
||||
push 5
|
||||
push 0x00748A88
|
||||
call get_code_size4
|
||||
.deltaof patch_code4, patch_code_end4
|
||||
get_code_size4:
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call patch_code_end4
|
||||
patch_code4:
|
||||
cmp byte [0x00748B1B], 0
|
||||
jnz +0x06
|
||||
movzx edx, byte [edx + ebx * 4 + 0x04] # main palette
|
||||
ret
|
||||
movzx edx, byte [edx + ebx * 4 + 0x3C] # alt palette
|
||||
ret
|
||||
patch_code_end4:
|
||||
push ecx
|
||||
jmp write_call_func
|
||||
|
||||
# CheckHotkey2_2
|
||||
patch_func_5:
|
||||
pop ecx
|
||||
push 5
|
||||
push 0x00748A97
|
||||
call get_code_size5
|
||||
.deltaof patch_code5, patch_code_end5
|
||||
get_code_size5:
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call patch_code_end5
|
||||
patch_code5:
|
||||
cmp byte [0x00748B1B], 0
|
||||
jnz +0x06
|
||||
movzx ecx, byte [edx + eax * 2 + 0x05] # main palette
|
||||
ret
|
||||
movzx ecx, byte [edx + eax * 2 + 0x3D] # alt palette
|
||||
ret
|
||||
patch_code_end5:
|
||||
push ecx
|
||||
jmp write_call_func
|
||||
|
||||
# CheckHotkey3_1
|
||||
patch_func_6:
|
||||
pop ecx
|
||||
push 5
|
||||
push 0x007103D3
|
||||
call get_code_size6
|
||||
.deltaof patch_code6, patch_code_end6
|
||||
get_code_size6:
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call patch_code_end6
|
||||
patch_code6:
|
||||
cmp byte [0x00748B1B], 0
|
||||
jnz +0x06
|
||||
movzx ecx, byte [eax + edx * 4 + 0x04] # main palette
|
||||
ret
|
||||
movzx ecx, byte [eax + edx * 4 + 0x3C] # alt palette
|
||||
ret
|
||||
patch_code_end6:
|
||||
push ecx
|
||||
jmp write_call_func
|
||||
|
||||
# CheckHotkey3_2
|
||||
patch_func_7:
|
||||
pop ecx
|
||||
push 5
|
||||
push 0x007103DC
|
||||
call get_code_size7
|
||||
.deltaof patch_code7, patch_code_end7
|
||||
get_code_size7:
|
||||
pop eax
|
||||
push dword [eax]
|
||||
call patch_code_end7
|
||||
patch_code7:
|
||||
cmp byte [0x00748B1B], 0
|
||||
jnz +0x06
|
||||
movzx ecx, byte [eax + edx * 4 + 0x05] # main palette
|
||||
ret
|
||||
movzx ecx, byte [eax + edx * 4 + 0x3D] # alt palette
|
||||
ret
|
||||
patch_code_end7:
|
||||
push ecx
|
||||
jmp write_call_func
|
||||
|
||||
write_code_blocks:
|
||||
.include WriteCodeBlocksBB
|
||||
|
||||
.data 0x00748A05
|
||||
.deltaof code_block1_start, code_block1_end
|
||||
|
||||
# UnsetHotkey1
|
||||
code_block1_start:
|
||||
push dword [0x00748B1B]
|
||||
push eax
|
||||
mov eax, 0x0068CE4C # SetPaletteHotkey
|
||||
call eax
|
||||
.binary 909090909090909090
|
||||
code_block1_end:
|
||||
.data 0x00748AAB
|
||||
.deltaof code_block2_start, code_block2_end
|
||||
|
||||
# UnsetHotkey2
|
||||
code_block2_start:
|
||||
push dword [0x00748B1B]
|
||||
push eax
|
||||
mov eax, 0x0068CE4C # SetPaletteHotkey
|
||||
call eax
|
||||
.binary 909090909090909090
|
||||
code_block2_end:
|
||||
.data 0x00748B0A
|
||||
.deltaof code_block3_start, code_block3_end
|
||||
|
||||
# SetHotkey
|
||||
code_block3_start:
|
||||
mov eax, [ebp - 0x24]
|
||||
mov ecx, [ebp - 0x28]
|
||||
movzx ebx, word [eax]
|
||||
movzx edx, word [eax + 0x02]
|
||||
push edx
|
||||
push ebx
|
||||
push esi
|
||||
.binary 6800000000 # tmpCurrentPalette = 0x00748B1B
|
||||
push 0
|
||||
mov eax, 0x0068CE4C # SetPaletteHotkey
|
||||
call eax
|
||||
.binary 90909090909090909090909090909090
|
||||
code_block3_end:
|
||||
.data 0x00000000
|
||||
.data 0x00000000
|
||||
@@ -0,0 +1,44 @@
|
||||
# (uint16_t entity_id @ eax) -> TObjectV00b421c0* @ eax
|
||||
# Preserves all registers except eax
|
||||
get_enemy_entity:
|
||||
push esi
|
||||
push edi
|
||||
push edx
|
||||
push ecx
|
||||
xor edx, edx
|
||||
xchg edx, eax
|
||||
cmp edx, 0x1000
|
||||
jl done
|
||||
cmp edx, 0x4000
|
||||
jge done
|
||||
|
||||
mov esi, [0x00AABCE8] # bs_low = next_player_entity_index
|
||||
mov edi, [0x00AABCE4]
|
||||
lea edi, [edi + esi - 1] # bs_high = next_player_entity_index + next_enemy_entity_index - 1
|
||||
bs_again:
|
||||
cmp esi, edi
|
||||
jge bs_done
|
||||
lea ecx, [esi + edi]
|
||||
shr ecx, 1
|
||||
mov eax, [ecx * 4 + 0x00AAB2A0] # all_entities[ecx]
|
||||
cmp [eax + 0x1C], dx
|
||||
jge bs_not_less
|
||||
lea esi, [ecx + 1]
|
||||
jmp bs_again
|
||||
bs_not_less:
|
||||
mov edi, ecx
|
||||
jmp bs_again
|
||||
bs_done:
|
||||
|
||||
mov eax, [esi * 4 + 0x00AAB2A0] # all_entities[bs_low]
|
||||
test eax, eax
|
||||
je done
|
||||
xor ecx, ecx
|
||||
cmp [eax + 0x1C], dx
|
||||
cmovne eax, ecx
|
||||
|
||||
done:
|
||||
pop ecx
|
||||
pop edx
|
||||
pop edi
|
||||
pop esi
|
||||
@@ -0,0 +1,42 @@
|
||||
# This file defines the following function:
|
||||
# write_address_of_code(
|
||||
# const void* patch_code,
|
||||
# size_t patch_code_size,
|
||||
# void** ptr_addr);
|
||||
# This function allocates memory for patch_code, copies patch_code to that
|
||||
# memory, then writes the address of the allocated code at the specified
|
||||
# pointer. The allocated memory is never freed.
|
||||
# This function pops its arguments off the stack before returning.
|
||||
|
||||
write_call_to_code:
|
||||
# [esp + 0x04] = code ptr
|
||||
# [esp + 0x08] = code size
|
||||
# [esp + 0x0C] = ptr addr
|
||||
|
||||
# Allocate memory for the copied code
|
||||
mov ecx, [0x00AA8F84]
|
||||
push dword [esp + 0x08]
|
||||
mov eax, 0x007A984C
|
||||
call eax # malloc7
|
||||
test eax, eax
|
||||
je done
|
||||
|
||||
# Copy the code to the newly-allocated memory
|
||||
# eax = dest pointer (from malloc7 call above)
|
||||
mov edx, [esp + 0x04] # edx = source pointer
|
||||
mov ecx, [esp + 0x08] # ecx = source size
|
||||
push ebx
|
||||
memcpy_again:
|
||||
dec ecx
|
||||
mov bl, [edx + ecx] # Copy one byte from source to dest
|
||||
mov [eax + ecx], bl
|
||||
test ecx, ecx
|
||||
jne memcpy_again
|
||||
pop ebx
|
||||
|
||||
# Write the address
|
||||
mov ecx, [esp + 0x0C]
|
||||
mov [ecx], eax
|
||||
|
||||
done:
|
||||
ret 0x0C
|
||||
@@ -0,0 +1,76 @@
|
||||
# This file defines the following function:
|
||||
# write_call_to_code(
|
||||
# const void* patch_code,
|
||||
# size_t patch_code_size,
|
||||
# void* call_opcode_address,
|
||||
# ssize_t call_opcode_bytes);
|
||||
# This function allocates memory for patch_code, copies patch_code to that
|
||||
# memory, then writes a call or jmp opcode to call_opcode_address that calls
|
||||
# the code in the allocated memory region. The allocated memory is never freed.
|
||||
# call_opcode_bytes specifies how many bytes at the callsite should be
|
||||
# overwritten. This value must be at least 5; the first 5 bytes are overwritten
|
||||
# with the call/jmp opcode itself; the rest are overwritten with nop opcodes.
|
||||
# If call_opcode_bytes is positive, a call opcode is written; if it's negative,
|
||||
# a jmp opcode is written.
|
||||
# This function pops its arguments off the stack before returning.
|
||||
|
||||
write_call_to_code:
|
||||
# [esp + 0x04] = code ptr
|
||||
# [esp + 0x08] = code size
|
||||
# [esp + 0x0C] = jump callsite
|
||||
# [esp + 0x10] = callsite size (if zero, write the address instead of a call)
|
||||
|
||||
# Allocate memory for the copied code
|
||||
mov ecx, [0x00AA8F84]
|
||||
push dword [esp + 0x08]
|
||||
mov eax, 0x007A984C
|
||||
call eax # malloc7
|
||||
test eax, eax
|
||||
je done
|
||||
|
||||
# Copy the code to the newly-allocated memory
|
||||
# eax = dest pointer (from malloc7 call above)
|
||||
mov edx, [esp + 0x04] # edx = source pointer
|
||||
mov ecx, [esp + 0x08] # ecx = source size
|
||||
push ebx
|
||||
memcpy_again:
|
||||
dec ecx
|
||||
mov bl, [edx + ecx] # Copy one byte from source to dest
|
||||
mov [eax + ecx], bl
|
||||
test ecx, ecx
|
||||
jne memcpy_again
|
||||
pop ebx
|
||||
|
||||
mov edx, [esp + 0x0C] # edx = jump callsite
|
||||
|
||||
# If the callsite size is zero, just write the address directly
|
||||
cmp dword [esp + 0x10], 0
|
||||
jne write_call_or_jmp
|
||||
mov [edx], eax
|
||||
jmp done
|
||||
|
||||
# Write the call or jmp opcode
|
||||
write_call_or_jmp:
|
||||
lea ecx, [eax - 5]
|
||||
sub ecx, edx # ecx = (dest code addr) - (jump callsite) - 5
|
||||
cmp dword [esp + 0x10], 0
|
||||
setl al
|
||||
or al, 0xE8
|
||||
mov [edx], al # Write E8 (call), or E9 (jmp) if size was negative
|
||||
mov [edx + 1], ecx # Write delta
|
||||
|
||||
# Write as many nops after the call opcode as necessary
|
||||
mov ecx, 5
|
||||
mov eax, [esp + 0x10]
|
||||
cmp eax, 0
|
||||
jge write_nop_again
|
||||
neg eax
|
||||
write_nop_again:
|
||||
cmp ecx, eax
|
||||
jge done
|
||||
mov byte [edx + ecx], 0x90
|
||||
inc ecx
|
||||
jmp write_nop_again
|
||||
|
||||
done:
|
||||
ret 0x10
|
||||
@@ -0,0 +1,83 @@
|
||||
# This file defines the following function:
|
||||
# void [/std] write_call_to_code(
|
||||
# const void* patch_code @ [esp + 0x04],
|
||||
# size_t patch_code_size @ [esp + 0x08],
|
||||
# size_t call_count @ [esp + 0x0C],
|
||||
# void* call_opcode_address @ [esp + 0x10],
|
||||
# ssize_t call_opcode_bytes @ [esp + 0x14],
|
||||
# ...);
|
||||
# This function allocates memory for patch_code, copies patch_code to that
|
||||
# memory, then writes a call or jmp opcode to call_opcode_address that calls
|
||||
# the code in the allocated memory region. The allocated memory is never freed.
|
||||
# call_opcode_bytes specifies how many bytes at the callsite should be
|
||||
# overwritten. This value must be at least 5; the first 5 bytes are overwritten
|
||||
# with the call/jmp opcode itself; the rest are overwritten with nop opcodes.
|
||||
# This function pops its arguments off the stack before returning (including
|
||||
# all the varargs).
|
||||
|
||||
write_call_to_code:
|
||||
# [esp + 0x04] = code ptr
|
||||
# [esp + 0x08] = code size
|
||||
# [esp + 0x0C] = callsite count
|
||||
# [esp + 0x10] = callsite address
|
||||
# [esp + 0x14] = callsite size
|
||||
# ... (further callsite address/size pairs)
|
||||
|
||||
# Allocate memory for the copied code
|
||||
mov ecx, [0x00AA8F84]
|
||||
push dword [esp + 0x08]
|
||||
mov eax, 0x007A984C
|
||||
call eax # malloc7
|
||||
test eax, eax
|
||||
je done
|
||||
|
||||
# Copy the code to the newly-allocated memory
|
||||
# eax = dest pointer (from malloc7 call above)
|
||||
mov edx, [esp + 0x04] # edx = source pointer
|
||||
mov ecx, [esp + 0x08] # ecx = source size
|
||||
push ebx
|
||||
memcpy_again:
|
||||
dec ecx
|
||||
mov bl, [edx + ecx] # Copy one byte from source to dest
|
||||
mov [eax + ecx], bl
|
||||
test ecx, ecx
|
||||
jne memcpy_again
|
||||
pop ebx
|
||||
|
||||
# Write the call opcodes
|
||||
xchg ebx, [esp + 0x0C] # Save ebx; get callsite count
|
||||
mov [esp - 0x08], esi
|
||||
mov [esp - 0x0C], eax
|
||||
mov esi, 0x10 # Stack offset of first callsite pair
|
||||
|
||||
next_callsite:
|
||||
mov edx, [esp + esi] # edx = jump callsite
|
||||
lea ecx, [eax - 5]
|
||||
sub ecx, edx # ecx = (dest code addr) - (jump callsite) - 5
|
||||
mov byte [edx], 0xE8
|
||||
mov [edx + 1], ecx # Write E8 (call) followed by delta
|
||||
|
||||
# Write as many nops after the call opcode as necessary
|
||||
mov ecx, 5
|
||||
mov eax, [esp + esi + 4]
|
||||
write_nop_again:
|
||||
cmp ecx, eax
|
||||
jge this_callsite_done
|
||||
mov byte [edx + ecx], 0x90
|
||||
inc ecx
|
||||
jmp write_nop_again
|
||||
|
||||
this_callsite_done:
|
||||
mov eax, [esp - 0x0C]
|
||||
add esi, 8
|
||||
dec ebx
|
||||
jnz next_callsite
|
||||
|
||||
mov ecx, esi
|
||||
mov ebx, [esp + 0x0C]
|
||||
mov esi, [esp - 0x08]
|
||||
|
||||
done:
|
||||
mov eax, [esp]
|
||||
add esp, ecx
|
||||
jmp eax
|
||||
@@ -576,14 +576,14 @@
|
||||
],
|
||||
|
||||
// BB bank size. If you change either of these values, you must also add "BankSize" to BBRequiredPatches, and change
|
||||
// the patch contents in system/client-functions/BlueBurstExclusive/BankSize.59NL.patch.s to reflect the counts here.
|
||||
// the patch contents in system/client-functions/BlueBurstExclusive/BankSize.5___.patch.s to reflect the counts here.
|
||||
"BBMaxBankItems": 200,
|
||||
"BBMaxBankMeseta": 999999,
|
||||
|
||||
// Item stack limits. Note that changing these does not affect the client's behavior automatically - this only exists
|
||||
// to allow the server to understand the behavior of clients that are already patched with different stack limits.
|
||||
// If you want to use an unpatched BB client but still have custom stack limits, you can use the StackLimits runtime
|
||||
// patch by editing system/client-functions/BlueBurstExclusive/StackLimits.59NL.patch.s to match the BB stack limits
|
||||
// patch by editing system/client-functions/BlueBurstExclusive/StackLimits.5___.patch.s to match the BB stack limits
|
||||
// and adding "StackLimits" to the BBRequiredPatches list.
|
||||
// It's important that all players in the same game have the same stack limits, both on the client and server! So, if
|
||||
// you change the BB stack limits, you must either prevent BB from playing with other versions (see
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +0,0 @@
|
||||
ItemPMT-pc-v2.prs
|
||||
@@ -1 +0,0 @@
|
||||
ItemPMT-gc-v3.prs
|
||||
@@ -1 +0,0 @@
|
||||
ItemPMT-gc-v3.prs
|
||||
Binary file not shown.
Binary file not shown.
@@ -1 +0,0 @@
|
||||
ItemPMT-pc-v2.prs
|
||||
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
item-parameter-table-pc-v2.json
|
||||
@@ -0,0 +1 @@
|
||||
item-parameter-table-gc-v3.json
|
||||
@@ -0,0 +1 @@
|
||||
item-parameter-table-gc-v3.json
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
||||
item-parameter-table-pc-v2.json
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,19 +1,15 @@
|
||||
[
|
||||
// This table maps in-game primary identifiers across client versions. The
|
||||
// high bit of the entries in this table specifies the entry type; if this
|
||||
// bit is set, the entry is not "canonical"; that is, it's a one-way mapping
|
||||
// and the client does not actually have that item defined. Each primary
|
||||
// identifier must have at most one "canonical" listing for each version
|
||||
// (but may have none). To convert an item from client A to client B:
|
||||
// 1. Scan the column for A's version in the table to find the cell that
|
||||
// contains the primary identifier sent by A. (We optimize this with an
|
||||
// index.)
|
||||
// This table maps in-game primary identifiers across client versions. The high bit of the entries in this table
|
||||
// specifies the entry type; if this bit is set, the entry is not "canonical"; that is, it's a one-way mapping and
|
||||
// the client does not actually have that item defined. Each primary identifier must have at most one "canonical"
|
||||
// listing for each version (but may have none). To convert an item from client A to client B:
|
||||
// 1. Scan the column for A's version in the table to find the cell that contains the primary identifier sent by A.
|
||||
// (We optimize this with an index.)
|
||||
// 2. Move left or right to the column for B's version.
|
||||
// 3. Take the value from that cell, clear the high bit if needed, and use
|
||||
// that as the primary identifier to show to B.
|
||||
// 3. Take the value from that cell, clear the high bit if needed, and use that as the primary identifier for B.
|
||||
// This logic is implemented in ItemTranslationTable.cc.
|
||||
|
||||
// DC_NTE-- 11/2000--- DC_V1----- DC_V2----- PC_NTE---- PC_V2----- GC_NTE---- GC_V3----- GC_EP3_NTE GC_EP3---- XB_V3----- BB_V4----- NAME
|
||||
// DC_NTE-- 11/2000--- DC_V1----- DC_V2----- PC_NTE---- PC_V2----- GC_NTE---- GC_V3----- GC_EP3_NTE GC_EP3---- XB_V3----- BB_V4----- NAME
|
||||
[0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, "UNUSED"],
|
||||
[0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000, "Saber"],
|
||||
[0x00010100, 0x00010100, 0x00010100, 0x00010100, 0x00010100, 0x00010100, 0x00010100, 0x00010100, 0x00010100, 0x00010100, 0x00010100, 0x00010100, "Brand"],
|
||||
@@ -134,7 +130,6 @@
|
||||
[0x000F0100, 0x000F0100, 0x000F0100, 0x000F0100, 0x000F0100, 0x000F0100, 0x800F0000, 0x000F0100, 0x000F0100, 0x000F0100, 0x000F0100, 0x000F0100, "ANGRY FIST"],
|
||||
[0x000F0200, 0x000F0200, 0x000F0200, 0x000F0200, 0x000F0200, 0x000F0200, 0x800F0000, 0x000F0200, 0x000F0200, 0x000F0200, 0x000F0200, 0x000F0200, "GOD HAND"],
|
||||
[0x000F0300, 0x000F0300, 0x000F0300, 0x000F0300, 0x000F0300, 0x000F0300, 0x800F0000, 0x000F0300, 0x000F0300, 0x000F0300, 0x000F0300, 0x000F0300, "SONIC KNUCKLE"],
|
||||
[0x000F0400, 0x000F0400, 0x000F0400, 0x000F0400, 0x000F0400, 0x000F0400, 0x80020500, 0x80100000, 0x80100000, 0x80100000, 0x80100000, 0x80100000, "OROTIAGITO (v0-v2)"],
|
||||
[0x800F0300, 0x800F0300, 0x800F0300, 0x800F0300, 0x800F0300, 0x800F0300, 0x800F0000, 0x800F0300, 0x800F0300, 0x800F0300, 0x800F0300, 0x000F0400, "LOGiN"],
|
||||
[0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000, "OROTIAGITO"],
|
||||
[0x00100100, 0x00100100, 0x00100100, 0x00100100, 0x00100100, 0x00100100, 0x80100000, 0x00100100, 0x00100100, 0x00100100, 0x00100100, 0x00100100, "AGITO (1975)"],
|
||||
@@ -439,7 +434,9 @@
|
||||
[0x80080500, 0x80080500, 0x80080500, 0x80770000, 0x80770000, 0x80770000, 0x80080500, 0x80770000, 0x80770000, 0x80770000, 0x80770000, 0x00EA0000, "TypeME/MECHGUN"],
|
||||
[0x80090500, 0x80090500, 0x80090500, 0x80780000, 0x80780000, 0x80780000, 0x80090500, 0x80780000, 0x80780000, 0x80780000, 0x80780000, 0x00EB0000, "TypeSH/SHOT"],
|
||||
[0x800C0400, 0x800C0400, 0x800C0400, 0x807B0000, 0x807B0000, 0x807B0000, 0x800C0400, 0x807B0000, 0x807B0000, 0x807B0000, 0x807B0000, 0x00EC0000, "TypeWA/WAND"],
|
||||
[0x80010000, 0x80010000, 0x80010000, 0x00890000, 0x00890000, 0x00890000, 0x008D0000, 0x00AA0000, 0x00AA0000, 0x00AA0000, 0x00AA0000, 0x00ED0000, "???? (WEAPON)"],
|
||||
|
||||
// DC_NTE-- 11/2000--- DC_V1----- DC_V2----- PC_NTE---- PC_V2----- GC_NTE---- GC_V3----- GC_EP3_NTE GC_EP3---- XB_V3----- BB_V4----- NAME
|
||||
[0x01010000, 0x01010000, 0x01010000, 0x01010000, 0x01010000, 0x01010000, 0x01010000, 0x01010000, 0x01010000, 0x01010000, 0x01010000, 0x01010000, "Frame"],
|
||||
[0x01010100, 0x01010100, 0x01010100, 0x01010100, 0x01010100, 0x01010100, 0x01010100, 0x01010100, 0x01010100, 0x01010100, 0x01010100, 0x01010100, "Armor"],
|
||||
[0x01010200, 0x01010200, 0x01010200, 0x01010200, 0x01010200, 0x01010200, 0x01010200, 0x01010200, 0x01010200, 0x01010200, 0x01010200, 0x01010200, "Psy Armor"],
|
||||
@@ -528,8 +525,9 @@
|
||||
[0x81012800, 0x81012800, 0x81012800, 0x81013400, 0x81013400, 0x81013400, 0x81010C00, 0x81013400, 0x81013400, 0x81013400, 0x81013400, 0x01015500, "UNION FIELD"],
|
||||
[0x81012800, 0x81012800, 0x81012800, 0x81013400, 0x81013400, 0x81013400, 0x81010C00, 0x81013400, 0x81013400, 0x81013400, 0x81013400, 0x01015600, "SAMURAI ARMOR"],
|
||||
[0x81012800, 0x81012800, 0x81012800, 0x81013400, 0x81013400, 0x81013400, 0x81010C00, 0x81013400, 0x81013400, 0x81013400, 0x81013400, 0x01015700, "STEALTH SUIT"],
|
||||
[0x81012800, 0x81012800, 0x81012800, 0x81013400, 0x81013400, 0x81013400, 0x01013500, 0x01013500, 0x01013500, 0x01013500, 0x01013500, 0x01015800, "???? (ARMOR)"],
|
||||
[0x81012800, 0x81012800, 0x81012800, 0x01013500, 0x01013500, 0x01013500, 0x01013500, 0x01013500, 0x01013500, 0x01013500, 0x01013500, 0x01015800, "???? (ARMOR)"],
|
||||
|
||||
// DC_NTE-- 11/2000--- DC_V1----- DC_V2----- PC_NTE---- PC_V2----- GC_NTE---- GC_V3----- GC_EP3_NTE GC_EP3---- XB_V3----- BB_V4----- NAME
|
||||
[0x01020000, 0x01020000, 0x01020000, 0x01020000, 0x01020000, 0x01020000, 0x01020000, 0x01020000, 0x01020000, 0x01020000, 0x01020000, 0x01020000, "Barrier"],
|
||||
[0x01020100, 0x01020100, 0x01020100, 0x01020100, 0x01020100, 0x01020100, 0x01020100, 0x01020100, 0x01020100, 0x01020100, 0x01020100, 0x01020100, "Shield"],
|
||||
[0x01020200, 0x01020200, 0x01020200, 0x01020200, 0x01020200, 0x01020200, 0x01020200, 0x01020200, 0x01020200, 0x01020200, 0x01020200, 0x01020200, "Core Shield"],
|
||||
@@ -695,8 +693,9 @@
|
||||
[0x81022600, 0x81022600, 0x81022600, 0x81023500, 0x81023500, 0x81023500, 0x81020C00, 0x81028400, 0x81028400, 0x81028400, 0x81028400, 0x0102A200, "GENPEI (unused)"],
|
||||
[0x81022600, 0x81022600, 0x81022600, 0x81023500, 0x81023500, 0x81023500, 0x81020C00, 0x81028400, 0x81028400, 0x81028400, 0x81028400, 0x0102A300, "GENPEI (unused)"],
|
||||
[0x81022600, 0x81022600, 0x81022600, 0x81023500, 0x81023500, 0x81023500, 0x81020C00, 0x81028400, 0x81028400, 0x81028400, 0x81028400, 0x0102A400, "GENPEI (unused)"],
|
||||
[0x81022600, 0x81022600, 0x81022600, 0x81023500, 0x81023500, 0x81023500, 0x81020C00, 0x01028500, 0x01028500, 0x01028500, 0x01028500, 0x0102A500, "???? (SHIELD)"],
|
||||
[0x81022600, 0x81022600, 0x81022600, 0x01023A00, 0x01023A00, 0x01023A00, 0x81020C00, 0x01028500, 0x01028500, 0x01028500, 0x01028500, 0x0102A500, "???? (SHIELD)"],
|
||||
|
||||
// DC_NTE-- 11/2000--- DC_V1----- DC_V2----- PC_NTE---- PC_V2----- GC_NTE---- GC_V3----- GC_EP3_NTE GC_EP3---- XB_V3----- BB_V4----- NAME
|
||||
[0x01030000, 0x01030000, 0x01030000, 0x01030000, 0x01030000, 0x01030000, 0x01030000, 0x01030000, 0x01030000, 0x01030000, 0x01030000, 0x01030000, "Knight/Power"],
|
||||
[0x01030100, 0x01030100, 0x01030100, 0x01030100, 0x01030100, 0x01030100, 0x01030100, 0x01030100, 0x01030100, 0x01030100, 0x01030100, 0x01030100, "General/Power"],
|
||||
[0x01030200, 0x01030200, 0x01030200, 0x01030200, 0x01030200, 0x01030200, 0x01030200, 0x01030200, 0x01030200, 0x01030200, 0x01030200, 0x01030200, "Ogre/Power"],
|
||||
@@ -799,8 +798,9 @@
|
||||
[0x81033500, 0x81033500, 0x81033500, 0x81033500, 0x81033500, 0x81033500, 0x81033400, 0x81033500, 0x81033500, 0x81033500, 0x81033500, 0x01036100, "HP/Resurrection"],
|
||||
[0x81033800, 0x81033800, 0x81033800, 0x81033800, 0x81033800, 0x81033800, 0x81033700, 0x81033800, 0x81033800, 0x81033800, 0x81033800, 0x01036200, "TP/Resurrection"],
|
||||
[0x81033B00, 0x81033B00, 0x81033B00, 0x81033B00, 0x81033B00, 0x81033B00, 0x81033A00, 0x81033B00, 0x81033B00, 0x81033B00, 0x81033B00, 0x01036300, "PB/Increase"],
|
||||
[0x81033B00, 0x81033B00, 0x81033B00, 0x81033B00, 0x81033B00, 0x81033B00, 0x01034700, 0x01034800, 0x01034800, 0x01034800, 0x01034800, 0x01036400, "???? (UNIT)"],
|
||||
[0x81033B00, 0x81033B00, 0x81033B00, 0x01034400, 0x01034400, 0x01034400, 0x01034700, 0x01034800, 0x01034800, 0x01034800, 0x01034800, 0x01036400, "???? (UNIT)"],
|
||||
|
||||
// DC_NTE-- 11/2000--- DC_V1----- DC_V2----- PC_NTE---- PC_V2----- GC_NTE---- GC_V3----- GC_EP3_NTE GC_EP3---- XB_V3----- BB_V4----- NAME
|
||||
[0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000, "Mag"],
|
||||
[0x02010000, 0x02010000, 0x02010000, 0x02010000, 0x02010000, 0x02010000, 0x02010000, 0x02010000, 0x02010000, 0x02010000, 0x02010000, 0x02010000, "Varuna"],
|
||||
[0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, "Mitra"],
|
||||
@@ -841,10 +841,10 @@
|
||||
[0x02250000, 0x02250000, 0x02250000, 0x02250000, 0x02250000, 0x02250000, 0x02250000, 0x02250000, 0x02250000, 0x02250000, 0x02250000, 0x02250000, "Naraka"],
|
||||
[0x02260000, 0x02260000, 0x02260000, 0x02260000, 0x02260000, 0x02260000, 0x02260000, 0x02260000, 0x02260000, 0x02260000, 0x02260000, 0x02260000, "Madhu"],
|
||||
[0x02270000, 0x02270000, 0x02270000, 0x02270000, 0x02270000, 0x02270000, 0x02270000, 0x02270000, 0x02270000, 0x02270000, 0x02270000, 0x02270000, "Churel"],
|
||||
[0x82000000, 0x82000000, 0x82000000, 0x02280000, 0x02280000, 0x02280000, 0x82000000, 0x02280000, 0x02280000, 0x02280000, 0x02280000, 0x02280000, "ROBOCHAO"],
|
||||
[0x82000000, 0x82000000, 0x82000000, 0x02290000, 0x02290000, 0x02290000, 0x82000000, 0x02290000, 0x02290000, 0x02290000, 0x02290000, 0x02290000, "OPA-OPA"],
|
||||
[0x82000000, 0x82000000, 0x82000000, 0x022A0000, 0x022A0000, 0x022A0000, 0x82000000, 0x022A0000, 0x022A0000, 0x022A0000, 0x022A0000, 0x022A0000, "PIAN"],
|
||||
[0x82000000, 0x82000000, 0x82000000, 0x022B0000, 0x022B0000, 0x022B0000, 0x82000000, 0x022B0000, 0x022B0000, 0x022B0000, 0x022B0000, 0x022B0000, "CHAO"],
|
||||
[0x02280000, 0x02280000, 0x02280000, 0x02280000, 0x02280000, 0x02280000, 0x82000000, 0x02280000, 0x02280000, 0x02280000, 0x02280000, 0x02280000, "ROBOCHAO"],
|
||||
[0x02290000, 0x02290000, 0x02290000, 0x02290000, 0x02290000, 0x02290000, 0x82000000, 0x02290000, 0x02290000, 0x02290000, 0x02290000, 0x02290000, "OPA-OPA"],
|
||||
[0x022A0000, 0x022A0000, 0x022A0000, 0x022A0000, 0x022A0000, 0x022A0000, 0x82000000, 0x022A0000, 0x022A0000, 0x022A0000, 0x022A0000, 0x022A0000, "PIAN"],
|
||||
[0x022B0000, 0x022B0000, 0x022B0000, 0x022B0000, 0x022B0000, 0x022B0000, 0x82000000, 0x022B0000, 0x022B0000, 0x022B0000, 0x022B0000, 0x022B0000, "CHAO"],
|
||||
[0x82000000, 0x82000000, 0x82000000, 0x022C0000, 0x022C0000, 0x022C0000, 0x82000000, 0x022C0000, 0x022C0000, 0x022C0000, 0x022C0000, 0x022C0000, "CHU CHU"],
|
||||
[0x82000000, 0x82000000, 0x82000000, 0x022D0000, 0x022D0000, 0x022D0000, 0x82000000, 0x022D0000, 0x022D0000, 0x022D0000, 0x022D0000, 0x022D0000, "KAPU KAPU"],
|
||||
[0x82000000, 0x82000000, 0x82000000, 0x022E0000, 0x022E0000, 0x022E0000, 0x82000000, 0x022E0000, 0x022E0000, 0x022E0000, 0x022E0000, 0x022E0000, "ANGEL'S WING"],
|
||||
@@ -883,8 +883,9 @@
|
||||
[0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x024F0000, "Cell of MAG 0505 (mag)"],
|
||||
[0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x02500000, "Cell of MAG 0506 (mag)"],
|
||||
[0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x02510000, "Cell of MAG 0507 (mag)"],
|
||||
[0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x02280000, 0x02420000, 0x02420000, 0x02420000, 0x02420000, 0x02520000, "???? (MAG)"],
|
||||
[0x82000000, 0x82000000, 0x82000000, 0x02390000, 0x02390000, 0x02390000, 0x02280000, 0x02420000, 0x02420000, 0x02420000, 0x02420000, 0x02520000, "???? (MAG)"],
|
||||
|
||||
// DC_NTE-- 11/2000--- DC_V1----- DC_V2----- PC_NTE---- PC_V2----- GC_NTE---- GC_V3----- GC_EP3_NTE GC_EP3---- XB_V3----- BB_V4----- NAME
|
||||
[0x03000000, 0x03000000, 0x03000000, 0x03000000, 0x03000000, 0x03000000, 0x03000000, 0x03000000, 0x03000000, 0x03000000, 0x03000000, 0x03000000, "Monomate"],
|
||||
[0x03000100, 0x03000100, 0x03000100, 0x03000100, 0x03000100, 0x03000100, 0x03000100, 0x03000100, 0x03000100, 0x03000100, 0x03000100, 0x03000100, "Dimate"],
|
||||
[0x03000200, 0x03000200, 0x03000200, 0x03000200, 0x03000200, 0x03000200, 0x03000200, 0x03000200, 0x03000200, 0x03000200, 0x03000200, 0x03000200, "Trimate"],
|
||||
@@ -1027,7 +1028,7 @@
|
||||
[0x830C0100, 0x830D0500, 0x830D0500, 0x830D0500, 0x830D0500, 0x830D0500, 0x830E0000, 0x03100200, 0x03100200, 0x03100200, 0x03100200, 0x03100200, "Photon Crystal"],
|
||||
[0x830C0100, 0x830D0500, 0x830D0500, 0x830D0500, 0x830D0500, 0x830D0500, 0x830E0000, 0x83100000, 0x83100000, 0x83100000, 0x83100000, 0x03100300, "Secret Ticket"],
|
||||
[0x830C0100, 0x830D0500, 0x830D0500, 0x830D0500, 0x830D0500, 0x830D0500, 0x830E0000, 0x83100000, 0x83100000, 0x83100000, 0x83100000, 0x03100400, "Photon Ticket"],
|
||||
[0x830C0100, 0x830D0500, 0x830D0500, 0x030E0700, 0x030E0700, 0x030E0700, 0x830E0000, 0x03120000, 0x03120000, 0x03120000, 0x03120000, 0x03120000, "Weapons Bronze Badge"],
|
||||
[0x830C0100, 0x830D0500, 0x830D0500, 0x030E0700, 0x030E0700, 0x030E0700, 0x03120000, 0x03120000, 0x03120000, 0x03120000, 0x03120000, 0x03120000, "Weapons Bronze Badge"],
|
||||
[0x830C0100, 0x830D0500, 0x830D0500, 0x030E0800, 0x030E0800, 0x030E0800, 0x830E0000, 0x03120100, 0x03120100, 0x03120100, 0x03120100, 0x03120100, "Weapons Silver Badge"],
|
||||
[0x830C0100, 0x830D0500, 0x830D0500, 0x030E0900, 0x030E0900, 0x030E0900, 0x830E0000, 0x03120200, 0x03120200, 0x03120200, 0x03120200, 0x03120200, "Weapons Gold Badge"],
|
||||
[0x830C0100, 0x830D0500, 0x830D0500, 0x030E0A00, 0x030E0A00, 0x030E0A00, 0x830E0000, 0x03120300, 0x03120300, 0x03120300, 0x03120300, 0x03120300, "Weapons Crystal Badge"],
|
||||
@@ -1090,5 +1091,6 @@
|
||||
[0x830C0100, 0x830D0500, 0x830D0500, 0x830D0500, 0x830D0500, 0x830D0500, 0x830E0000, 0x830D0500, 0x830D0500, 0x830D0500, 0x830D0500, 0x03190100, "Team Points 1000"],
|
||||
[0x830C0100, 0x830D0500, 0x830D0500, 0x830D0500, 0x830D0500, 0x830D0500, 0x830E0000, 0x830D0500, 0x830D0500, 0x830D0500, 0x830D0500, 0x03190200, "Team Points 5000"],
|
||||
[0x830C0100, 0x830D0500, 0x830D0500, 0x830D0500, 0x830D0500, 0x830D0500, 0x830E0000, 0x830D0500, 0x830D0500, 0x830D0500, 0x830D0500, 0x03190300, "Team Points 10000"],
|
||||
[0x830C0100, 0x830D0500, 0x830D0500, 0x030F0000, 0x030F0000, 0x030F0000, 0x03120000, 0x83170400, 0x83170400, 0x83170400, 0x83170400, 0x031A0000, "???? (TOOL)"],
|
||||
[0x830C0100, 0x830D0500, 0x830D0500, 0x030F0000, 0x030F0000, 0x030F0000, 0x03130000, 0x03180000, 0x03180000, 0x03180000, 0x03180000, 0x031A0000, "???? (TOOL)"],
|
||||
// DC_NTE-- 11/2000--- DC_V1----- DC_V2----- PC_NTE---- PC_V2----- GC_NTE---- GC_V3----- GC_EP3_NTE GC_EP3---- XB_V3----- BB_V4----- NAME
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user