forked from jewalky/srvmgr
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathscroll_burn.cpp
61 lines (53 loc) · 2.3 KB
/
scroll_burn.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include "utils.h"
#include "lib/utils.hpp"
bool IsScroll(T_INVENTORY_ITEM* item) {
return 3590 <= item->id && item->id <= 3647; // Reference: https://igroglaz.com/allods2/razrabotka/opisanie-predmetov
}
void a2insert(T_INVENTORY_LIST* list, int pos, T_INVENTORY_ITEM* item);
void RefreshPlayerInventory(T_UNIT* unit);
int __fastcall CheckItemWhenCasting(T_INVENTORY_ITEM* item, T_UNIT* unit, int position) {
Printf("[scroll_burn] CheckItemWhenCasting: item=0x%x (id=%d), unit=0x%x (%s), position=%d", item, item ? item->id : 0, unit, unit ? unit->name : "?", position);
if (!item || !unit) { // Impossible, but let's check anyway.
return 1;
}
// If the item is not a scroll, or it's not a scroll with spell (for some
// reason), or if current unit is a mage --- don't cast anything and put
// the item back.
// Note: vanilla logic is `item->effects.size == 0 || item->effects.first_node->value->effect_id != 0x29`.
if (!IsScroll(item) || item->effects.size == 0 || item->effects.first_node->value->effect_id != 0x29 || !IsWarrior(unit)) {
Printf(
"[scroll_burn] prevent burning item: id=%d, effects=%d, first=%d, warrior=%d",
item->id,
item->effects.size,
item->effects.size && item->effects.first_node && item->effects.first_node->value ? item->effects.first_node->value->effect_id : 0,
IsWarrior(unit)
);
if (unit->inventory) {
Printf("[scroll_burn] item id=%d should be put into inventory of unit '%s' at position %d", item->id, unit->name, position);
a2insert(unit->inventory, position, item);
RefreshPlayerInventory(unit);
}
return 1;
}
return 0;
}
// Address: 005056e1
extern "C" __declspec(naked) void fix_scroll_burn() {
__asm {
mov edx, DWORD PTR [ebp-0x10] // Packet.
mov eax, 0
mov ax, WORD PTR [edx+0x10] // 2-byte position in the inventory.
push eax
mov ecx, DWORD PTR [ebp-0x40] // Item.
mov edx, DWORD PTR [ebp-0x18] // Unit.
call CheckItemWhenCasting
cmp eax, 0
jz item_allowed // If casting is not allowed, bail.
mov eax, 0x005056f4
jmp eax
item_allowed:
// Proceed with original logic.
mov eax, 0x005056f9
jmp eax
}
}