-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAugments.cpp
More file actions
215 lines (173 loc) · 7.64 KB
/
Copy pathAugments.cpp
File metadata and controls
215 lines (173 loc) · 7.64 KB
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#include "pch.h"
#include <cstdint>
#include <memory>
#include <array>
#include "Scanner.h"
#include "LuaCoreWrapper.h"
#include <format>
constexpr auto AUGMENT_DATA_SIZE = 86;
constexpr auto PathMap = std::array<const char*, 4>{
"A",
"B",
"C",
"D",
};
struct AugmentLookupItemData_t
{
uint32_t ExtDataBlock1;
uint32_t ExtDataBlock2;
uint32_t ExtDataBlock3;
uint16_t ItemId;
uint16_t Unk1;//used for weapon augments
uint16_t Unk2;//used for weapon augments
};
constexpr auto fnGetAugmentSystemFourDataPattern = "\x53\x55\x56\x57\x33\xc9\xe8\x00\x00\x00\x00\x8b\x74\x24\x18";
constexpr auto fnGetAugmentSystemFourDataMask = "xxxxxxx????xxxx";
using fnGetAugmentSystemFourData = int(__cdecl*)(int32_t*, AugmentLookupItemData_t*);
const auto oGetAugmentSystemFourData = reinterpret_cast<fnGetAugmentSystemFourData>(FindPattern::ScanModIn(
const_cast<char*>(fnGetAugmentSystemFourDataPattern),
const_cast<char*>(fnGetAugmentSystemFourDataMask),
"FFXiMain.dll"));
//Not needed currently, but here for reference
//all the augment data for this system is also stored in here some bytes after the RP map, via some *really* weird offsetting using ExtDataBlock3
//that offset gets you to an entry with the resource id and a table of stat values based on rank, with the stat index being: (dataStruct.extDataBlock2 >> 0x12 & 0x1f) * 2 + 0xc)
//the game loops over these 4 times with different offsetting each time to populate all the augment data, but it's a bit of a mess so that's why we're just calling the function that does all this instead of trying to replicate it
/*
super small, sig includes some of the preceding function. will hardcode the map instead if this is prone to breaking on updates
* **************************************************************
* FUNCTION *
**************************************************************
uint16_t * __stdcall GetAugmentRpLookupTable(void)
uint16_t * EAX:4 <RETURN>
GetAugmentRpLookupTable XREF[1]: RetrieveAugmentInfo_UnityDyna:10
100fe4b0 a1 08 5d MOV EAX,[g_AugmentRpLookupTable] = ??
56 10
100fe4b5 c3 RET
constexpr auto fnGetAugmentRpLookupTablePattern = "\x5f\x5e\x5d\x5b\x83\xc4\x08\xc3\x90\x90\xa1\x00\x00\x00\x00\xc3";
constexpr auto fnGetAugmentRpLookupTableMask = "xxxxxxxxxxx????x";
constexpr auto fnGetAugmentRpLookupTableOffset = 10;
using fnGetAugmentRpLookupTable = uint16_t * (__stdcall*)();
const auto oGetAugmentRpLookupTable = reinterpret_cast<fnGetAugmentRpLookupTable>(FindPattern::ScanModIn(
const_cast<char*>(fnGetAugmentRpLookupTablePattern),
const_cast<char*>(fnGetAugmentRpLookupTableMask),
"FFXiMain.dll") + fnGetAugmentRpLookupTableOffset);*/
void PopulateRawData(lua_State* L, const std::unique_ptr<int[]>& augmentData)
{
LuaCoreWrapper::oLua_NewTable(L);
for (auto i = 0; i < AUGMENT_DATA_SIZE; i++)
{
LuaCoreWrapper::oLua_PushNumber(L, augmentData[i]);
LuaCoreWrapper::oLua_RawSetI(L, -2, i + 1);
}
LuaCoreWrapper::oLua_PushNumber(L, AUGMENT_DATA_SIZE);
LuaCoreWrapper::oLua_SetField(L, -2, "count");
LuaCoreWrapper::oLua_SetField(L, -2, "_raw");
}
void PopulateAugmentData(lua_State* L, const std::unique_ptr<int[]>& augmentData)
{
auto augmentCount = 0;
for (auto i = 0; i < AUGMENT_DATA_SIZE; i++)
{
if (i % 2 == 0)
{
if (augmentData[i] == 0)
{
augmentCount = i / 2;
LuaCoreWrapper::oLua_PushNumber(L, augmentCount);
LuaCoreWrapper::oLua_SetField(L, -2, "Augment Count");
break;
}
LuaCoreWrapper::oLua_PushNumber(L, augmentData[i]);
LuaCoreWrapper::oLua_SetField(L, -2, std::format("Augment {} Id", i / 2 + 1).c_str());
}
else
{
LuaCoreWrapper::oLua_PushNumber(L, augmentData[i]);
LuaCoreWrapper::oLua_SetField(L, -2, std::format("Augment {} Potency", i / 2 + 1).c_str());
}
}
}
//ranks are hard capped at 30, there is a check for this in the game code that uses the current max rank if it's less than 31 or clamps it to 30 otherwise
//how the game unpacks these
/*const auto rank = augmentLookupItemData.ExtDataBlock2 >> 0x12 & 0x1f;
const auto maxRank = ((augmentLookupItemData.ExtDataBlock2 >> 0x17 & 3) + 3) * 5;
const auto path = augmentLookupItemData.ExtDataBlock2 & 3;
const auto tnl = maxRank == rank ? 0 : pRpMap[rank] - (augmentLookupItemData.ExtDataBlock2 >> 2 & 0xffff);*/
//no idea why there is so much empty space, maybe expansion room idk
void PopulatePathRankData(lua_State* L, const std::unique_ptr<int[]>& augmentData)
{
LuaCoreWrapper::oLua_PushString(L, PathMap[augmentData[77]]);
LuaCoreWrapper::oLua_SetField(L, -2, "Path");
LuaCoreWrapper::oLua_PushNumber(L, augmentData[78]);
LuaCoreWrapper::oLua_SetField(L, -2, "Rank");
LuaCoreWrapper::oLua_PushNumber(L, augmentData[79]);
LuaCoreWrapper::oLua_SetField(L, -2, "Tnl");
LuaCoreWrapper::oLua_PushNumber(L, augmentData[80]);
LuaCoreWrapper::oLua_SetField(L, -2, "Max Rank");
LuaCoreWrapper::oLua_PushBoolean(L, augmentData[85] % 2 != 0); //any odd displays the "Main Hand: " prefix, even displays nothing
LuaCoreWrapper::oLua_SetField(L, -2, "Main Hand");
}
void PopulateAugmentPerLineCounts(lua_State* L, const std::unique_ptr<int[]>& augmentData)
{
constexpr auto maxLines = 4;
auto lastAugmentsThisLine = 0;
for (auto i = 0; i < maxLines; i++)
{
const auto augmentsThisLine = augmentData[81 + i] - lastAugmentsThisLine;
if (augmentsThisLine < 0)
{
LuaCoreWrapper::oLua_PushNumber(L, i);
LuaCoreWrapper::oLua_SetField(L, -2, "Line Count");
break;
}
LuaCoreWrapper::oLua_PushNumber(L, augmentsThisLine);
LuaCoreWrapper::oLua_SetField(L, -2, std::format("Line {} Augment Count", i + 1).c_str());
lastAugmentsThisLine = augmentData[81 + i];
}
}
//TODO: decide on a better name maybe
static int GetAugmentSystemFourData(lua_State* L)
{
if(!oGetAugmentSystemFourData)
{
return LuaCoreWrapper::oLuaL_Error(L, "Failed to find oGetAugmentSystemFourData function, the signature may have changed");
}
if(LuaCoreWrapper::oLua_GetTop(L) != 2)
{
return LuaCoreWrapper::oLuaL_Error(L, "Invalid number of arguments passed to GetAugmentSystemFourData, expected 2 (item.extdata, item.id)");
}
size_t strSize = 0;
const auto extDataString = LuaCoreWrapper::oLuaL_CheckLString(L, 1, &strSize);
if(strSize < 12)
{
return LuaCoreWrapper::oLuaL_Error(L, "Invalid extdata string passed to GetAugmentSystemFourData, expected at least 12 characters");
}
const auto extData = std::make_unique<uint32_t[]>(3);
memcpy(extData.get(), extDataString, 12);
const auto itemId = static_cast<uint16_t>(LuaCoreWrapper::oLuaL_CheckInteger(L, 2));
auto augmentLookupItemData = AugmentLookupItemData_t{
extData[0], //exdatablock1
extData[1], //exdatablock2
extData[2], //exdatablock3
itemId, //itemId
0, //unk, only populated in memory for weapons that I saw but appears to work fine without it //TODO: figure out what this is
0, //unk, only populated in memory for weapons that I saw but appears to work fine without it
};
const auto augmentData = std::make_unique<int32_t[]>(AUGMENT_DATA_SIZE);
const auto result = oGetAugmentSystemFourData(augmentData.get(), &augmentLookupItemData);
LuaCoreWrapper::oLua_NewTable(L);
PopulateRawData(L, augmentData);
PopulateAugmentData(L, augmentData);
PopulatePathRankData(L, augmentData);
PopulateAugmentPerLineCounts(L, augmentData);
return 1;
}
extern "C" int __declspec(dllexport) luaopen_Augments(lua_State* L)
{
constexpr struct luaL_Reg funcs[] = {
{"GetAugmentSystemFourData", GetAugmentSystemFourData},
{nullptr, nullptr}
};
LuaCoreWrapper::oLuaL_Register(L, "Augments", funcs);
return 1;
}