mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Fixed move_obj_inven_to_obj script function
* it didn't remove the equipped armor properly for the player and party members, resulting in broken armor stats. Added a check for valid objects to get/set_object_data functions. Some code edits to HeroAppearance.cpp.
This commit is contained in:
+82
-39
@@ -10,6 +10,7 @@ namespace sfall
|
|||||||
{
|
{
|
||||||
using namespace fo;
|
using namespace fo;
|
||||||
using namespace Fields;
|
using namespace Fields;
|
||||||
|
using namespace ObjectFlag;
|
||||||
|
|
||||||
static DWORD critterBody = 0;
|
static DWORD critterBody = 0;
|
||||||
static DWORD sizeOnBody = 0;
|
static DWORD sizeOnBody = 0;
|
||||||
@@ -388,30 +389,66 @@ static void __declspec(naked) queue_clear_type_mem_free_hook() {
|
|||||||
static void __declspec(naked) partyMemberCopyLevelInfo_hook_stat_level() {
|
static void __declspec(naked) partyMemberCopyLevelInfo_hook_stat_level() {
|
||||||
__asm {
|
__asm {
|
||||||
nextArmor:
|
nextArmor:
|
||||||
mov eax, esi
|
mov eax, esi;
|
||||||
call fo::funcoffs::inven_worn_
|
call fo::funcoffs::inven_worn_;
|
||||||
test eax, eax
|
test eax, eax;
|
||||||
jz noArmor
|
jz noArmor;
|
||||||
and byte ptr [eax+0x27], 0xFB // Unset the flag of equipped armor
|
and byte ptr [eax + flags+3], ~Worn >> 24; // Unset the flag of equipped armor
|
||||||
jmp nextArmor
|
jmp nextArmor;
|
||||||
noArmor:
|
noArmor:
|
||||||
mov eax, esi
|
mov eax, esi;
|
||||||
jmp fo::funcoffs::stat_level_
|
jmp fo::funcoffs::stat_level_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __declspec(naked) correctFidForRemovedItem_hook_adjust_ac() {
|
static void __declspec(naked) correctFidForRemovedItem_hook_adjust_ac() {
|
||||||
__asm {
|
__asm {
|
||||||
call fo::funcoffs::adjust_ac_
|
call fo::funcoffs::adjust_ac_;
|
||||||
nextArmor:
|
nextArmor:
|
||||||
mov eax, esi
|
mov eax, esi;
|
||||||
call fo::funcoffs::inven_worn_
|
call fo::funcoffs::inven_worn_;
|
||||||
test eax, eax
|
test eax, eax;
|
||||||
jz end
|
jz end;
|
||||||
and byte ptr [eax+0x27], 0xFB // Unset flag of equipped armor
|
and byte ptr [eax + flags+3], ~Worn >> 24; // Unset flag of equipped armor
|
||||||
jmp nextArmor
|
jmp nextArmor;
|
||||||
end:
|
end:
|
||||||
retn
|
retn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __declspec(naked) op_move_obj_inven_to_obj_hook() {
|
||||||
|
__asm {
|
||||||
|
jz skip; // source == dude
|
||||||
|
mov eax, edx;
|
||||||
|
call fo::funcoffs::isPartyMember_;
|
||||||
|
test eax, eax; // is source a party member?
|
||||||
|
jnz skip;
|
||||||
|
retn; // must be eax = 0
|
||||||
|
skip:
|
||||||
|
mov eax, edx;
|
||||||
|
call fo::funcoffs::inven_worn_;
|
||||||
|
cmp edx, ecx; // source(edx) == dude(ecx)
|
||||||
|
jz dudeFix;
|
||||||
|
test eax, eax;
|
||||||
|
jz end;
|
||||||
|
mov ecx, edx;
|
||||||
|
xor ebx, ebx; // new armor
|
||||||
|
xchg eax, edx; // set: eax - source, edx - removed armor
|
||||||
|
call fo::funcoffs::adjust_ac_; // fix for party member
|
||||||
|
mov edx, ecx;
|
||||||
|
xor eax, eax;
|
||||||
|
end:
|
||||||
|
retn; // must be eax = 0
|
||||||
|
dudeFix:
|
||||||
|
test eax, eax;
|
||||||
|
jz equipped; // no armor
|
||||||
|
// additionally check flag of equipped armor for dude
|
||||||
|
test byte ptr [eax + flags+3], Worn >> 24;
|
||||||
|
jnz equipped;
|
||||||
|
xor eax, eax;
|
||||||
|
equipped:
|
||||||
|
or cl, 1; // reset ZF
|
||||||
|
retn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -825,7 +862,7 @@ static void __declspec(naked) op_wield_obj_critter_adjust_ac_hook() {
|
|||||||
static const DWORD partyMember_init_End = 0x493D16;
|
static const DWORD partyMember_init_End = 0x493D16;
|
||||||
static void __declspec(naked) NPCStage6Fix1() {
|
static void __declspec(naked) NPCStage6Fix1() {
|
||||||
__asm {
|
__asm {
|
||||||
imul eax, edx, 204; // necessary memory = number of NPC records in party.txt * record size
|
imul eax, edx, 204; // multiply record size 204 bytes by number of NPC records in party.txt
|
||||||
mov ebx, eax; // copy total record size for later memset
|
mov ebx, eax; // copy total record size for later memset
|
||||||
call fo::funcoffs::mem_malloc_; // malloc the necessary memory
|
call fo::funcoffs::mem_malloc_; // malloc the necessary memory
|
||||||
jmp partyMember_init_End; // call memset to set all malloc'ed memory to 0
|
jmp partyMember_init_End; // call memset to set all malloc'ed memory to 0
|
||||||
@@ -1646,16 +1683,16 @@ end:
|
|||||||
|
|
||||||
static void __declspec(naked) op_obj_can_hear_obj_hack() {
|
static void __declspec(naked) op_obj_can_hear_obj_hack() {
|
||||||
__asm {
|
__asm {
|
||||||
mov eax, [esp + 0x28 - 0x28 + 4]; // target
|
mov eax, [esp + 0x28 - 0x28 + 4]; // target
|
||||||
mov edx, [esp + 0x28 - 0x24 + 4]; // source
|
mov edx, [esp + 0x28 - 0x24 + 4]; // source
|
||||||
retn;
|
retn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __declspec(naked) ai_best_weapon_hook() {
|
static void __declspec(naked) ai_best_weapon_hook() {
|
||||||
__asm {
|
__asm {
|
||||||
mov eax, [esp + 0xF4 - 0x10 + 4]; // prev.item
|
mov eax, [esp + 0xF4 - 0x10 + 4]; // prev.item
|
||||||
jmp fo::funcoffs::item_w_perk_;
|
jmp fo::funcoffs::item_w_perk_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1676,11 +1713,11 @@ static void __declspec(naked) wmSetupRandomEncounter_hook() {
|
|||||||
static void __declspec(naked) inven_obj_examine_func_hack() {
|
static void __declspec(naked) inven_obj_examine_func_hack() {
|
||||||
__asm {
|
__asm {
|
||||||
mov edx, dword ptr ds:[0x519064]; // inven_display_msg_line
|
mov edx, dword ptr ds:[0x519064]; // inven_display_msg_line
|
||||||
cmp edx, 2; // 2 or more lines
|
cmp edx, 2; // >2
|
||||||
ja fix;
|
ja fix;
|
||||||
retn;
|
retn;
|
||||||
fix:
|
fix:
|
||||||
cmp edx, 9; // 8 lines (half of the display window)
|
cmp edx, 5; // 4 lines
|
||||||
ja limit;
|
ja limit;
|
||||||
dec edx;
|
dec edx;
|
||||||
sub eax, 3;
|
sub eax, 3;
|
||||||
@@ -1688,7 +1725,7 @@ fix:
|
|||||||
add eax, 3;
|
add eax, 3;
|
||||||
retn;
|
retn;
|
||||||
limit:
|
limit:
|
||||||
mov eax, 57;
|
mov eax, 30;
|
||||||
retn;
|
retn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1894,9 +1931,9 @@ skip:
|
|||||||
|
|
||||||
static void __declspec(naked) op_attack_hook() {
|
static void __declspec(naked) op_attack_hook() {
|
||||||
__asm {
|
__asm {
|
||||||
mov esi, dword ptr [esp + 0x3C + 4]; // free_move
|
mov esi, dword ptr [esp + 0x3C + 4]; // free_move
|
||||||
mov ebx, dword ptr [esp + 0x40 + 4]; // add amount damage to target
|
mov ebx, dword ptr [esp + 0x40 + 4]; // add amount damage to target
|
||||||
jmp fo::funcoffs::gdialogActive_;
|
jmp fo::funcoffs::gdialogActive_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1964,8 +2001,8 @@ isLoad:
|
|||||||
|
|
||||||
static void __declspec(naked) JesseContainerFid() {
|
static void __declspec(naked) JesseContainerFid() {
|
||||||
__asm {
|
__asm {
|
||||||
dec edx; // set fid to -1
|
dec edx; // set fid to -1
|
||||||
jmp fo::funcoffs::obj_new_;
|
jmp fo::funcoffs::obj_new_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2053,11 +2090,11 @@ static void __declspec(naked) obj_load_dude_hook1() {
|
|||||||
|
|
||||||
static void __declspec(naked) PrintAMList_hook() {
|
static void __declspec(naked) PrintAMList_hook() {
|
||||||
__asm {
|
__asm {
|
||||||
cmp ebp, 20; // max line count
|
cmp ebp, 20; // max line count
|
||||||
jle skip;
|
jle skip;
|
||||||
mov ebp, 20;
|
mov ebp, 20;
|
||||||
skip:
|
skip:
|
||||||
jmp fo::funcoffs::qsort_;
|
jmp fo::funcoffs::qsort_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2323,9 +2360,9 @@ void BugFixes::init()
|
|||||||
// Missing game initialization
|
// Missing game initialization
|
||||||
LoadGameHook::OnGameInit() += MusicVolInitialization;
|
LoadGameHook::OnGameInit() += MusicVolInitialization;
|
||||||
|
|
||||||
// fix vanilla negate operator on float values
|
// Fix vanilla negate operator on float values
|
||||||
MakeCall(0x46AB68, NegateFixHack);
|
MakeCall(0x46AB68, NegateFixHack);
|
||||||
// fix incorrect int-to-float conversion
|
// Fix incorrect int-to-float conversion
|
||||||
// op_mult:
|
// op_mult:
|
||||||
SafeWrite16(0x46A3F4, 0x04DB); // replace operator to "fild 32bit"
|
SafeWrite16(0x46A3F4, 0x04DB); // replace operator to "fild 32bit"
|
||||||
SafeWrite16(0x46A3A8, 0x04DB);
|
SafeWrite16(0x46A3A8, 0x04DB);
|
||||||
@@ -2397,6 +2434,10 @@ void BugFixes::init()
|
|||||||
dlog("Applying fix for armor reducing NPC original stats when removed.", DL_INIT);
|
dlog("Applying fix for armor reducing NPC original stats when removed.", DL_INIT);
|
||||||
HookCall(0x495F3B, partyMemberCopyLevelInfo_hook_stat_level);
|
HookCall(0x495F3B, partyMemberCopyLevelInfo_hook_stat_level);
|
||||||
HookCall(0x45419B, correctFidForRemovedItem_hook_adjust_ac);
|
HookCall(0x45419B, correctFidForRemovedItem_hook_adjust_ac);
|
||||||
|
// Fix for move_obj_inven_to_obj function
|
||||||
|
HookCall(0x45C49A, op_move_obj_inven_to_obj_hook);
|
||||||
|
SafeWrite16(0x45C496, 0x9090);
|
||||||
|
SafeWrite8(0x45C4A3, 0x75); // jmp > jnz
|
||||||
dlogr(" Done", DL_INIT);
|
dlogr(" Done", DL_INIT);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
@@ -2512,19 +2553,21 @@ void BugFixes::init()
|
|||||||
// Fix for op_lookup_string_proc_ engine function not searching the last procedure in a script
|
// Fix for op_lookup_string_proc_ engine function not searching the last procedure in a script
|
||||||
SafeWrite8(0x46C7AC, 0x76); // jb > jbe
|
SafeWrite8(0x46C7AC, 0x76); // jb > jbe
|
||||||
|
|
||||||
|
// Update the AC counter
|
||||||
//if (GetConfigInt("Misc", "WieldObjCritterFix", 1)) {
|
//if (GetConfigInt("Misc", "WieldObjCritterFix", 1)) {
|
||||||
dlog("Applying wield_obj_critter fix.", DL_INIT);
|
dlog("Applying wield_obj_critter fix.", DL_INIT);
|
||||||
SafeWrite8(0x456912, 0x1E);
|
SafeWrite8(0x456912, 0x1E); // jnz 0x456931
|
||||||
HookCall(0x45697F, op_wield_obj_critter_adjust_ac_hook);
|
HookCall(0x45697F, op_wield_obj_critter_adjust_ac_hook);
|
||||||
dlogr(" Done", DL_INIT);
|
dlogr(" Done", DL_INIT);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
// Enable party members with level 6 protos to reach level 6
|
||||||
//if (GetConfigInt("Misc", "NPCStage6Fix", 1)) {
|
//if (GetConfigInt("Misc", "NPCStage6Fix", 1)) {
|
||||||
dlog("Applying NPC Stage 6 Fix.", DL_INIT);
|
dlog("Applying NPC Stage 6 Fix.", DL_INIT);
|
||||||
MakeJump(0x493CE9, NPCStage6Fix1);
|
MakeJump(0x493CE9, NPCStage6Fix1); // partyMember_init_
|
||||||
SafeWrite8(0x494063, 6); // loop should look for a potential 6th stage
|
MakeJump(0x494224, NPCStage6Fix2); // partyMemberGetAIOptions_
|
||||||
|
SafeWrite8(0x494063, 6); // loop should look for a potential 6th stage (partyMember_init_)
|
||||||
SafeWrite8(0x4940BB, 204); // move pointer by 204 bytes instead of 200
|
SafeWrite8(0x4940BB, 204); // move pointer by 204 bytes instead of 200
|
||||||
MakeJump(0x494224, NPCStage6Fix2);
|
|
||||||
dlogr(" Done", DL_INIT);
|
dlogr(" Done", DL_INIT);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ BYTE *charScrnBackSurface = nullptr;
|
|||||||
DWORD charRotTick = 0;
|
DWORD charRotTick = 0;
|
||||||
DWORD charRotOri = 0;
|
DWORD charRotOri = 0;
|
||||||
|
|
||||||
bool raceButtions = false, styleButtions = false;
|
bool raceButtons = false, styleButtons = false;
|
||||||
int currentRaceVal = 0, currentStyleVal = 0; // holds Appearance values to restore after global reset in NewGame2 function in LoadGameHooks.cpp
|
int currentRaceVal = 0, currentStyleVal = 0; // holds Appearance values to restore after global reset in NewGame2 function in LoadGameHooks.cpp
|
||||||
DWORD critterListSize = 0, critterArraySize = 0; // Critter art list size
|
DWORD critterListSize = 0, critterArraySize = 0; // Critter art list size
|
||||||
|
|
||||||
@@ -198,7 +198,7 @@ static __declspec(noinline) int _stdcall LoadHeroDat(unsigned int race, unsigned
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char sex = GetSex();
|
const char sex = GetSex();
|
||||||
bool folderIsExist = false, datIsExist = false;
|
bool folderIsExist = false, heroDatIsExist = false;
|
||||||
// check if folder exists for selected appearance
|
// check if folder exists for selected appearance
|
||||||
sprintf_s(heroPathPtr[0]->path, 64, appearancePathFmt, sex, race, style, "");
|
sprintf_s(heroPathPtr[0]->path, 64, appearancePathFmt, sex, race, style, "");
|
||||||
if (GetFileAttributes(heroPathPtr[0]->path) != INVALID_FILE_ATTRIBUTES) {
|
if (GetFileAttributes(heroPathPtr[0]->path) != INVALID_FILE_ATTRIBUTES) {
|
||||||
@@ -213,17 +213,17 @@ static __declspec(noinline) int _stdcall LoadHeroDat(unsigned int race, unsigned
|
|||||||
heroPathPtr[1]->isDat = 1;
|
heroPathPtr[1]->isDat = 1;
|
||||||
}
|
}
|
||||||
if (folderIsExist) heroPathPtr[0]->next = heroPathPtr[1];
|
if (folderIsExist) heroPathPtr[0]->next = heroPathPtr[1];
|
||||||
datIsExist = true;
|
heroDatIsExist = true;
|
||||||
} else if (!folderIsExist) {
|
} else if (!folderIsExist) {
|
||||||
return -1; // no .dat files and folder
|
return -1; // no .dat files and folder
|
||||||
}
|
}
|
||||||
|
|
||||||
heroPathPtr[1]->next = nullptr;
|
//heroPathPtr[1]->next = nullptr;
|
||||||
tempPathPtr = &heroPathPtr[1 - folderIsExist]; // set path for selected appearance
|
tempPathPtr = &heroPathPtr[1 - folderIsExist]; // set path for selected appearance
|
||||||
heroPathPtr[0 + datIsExist]->next = &fo::var::paths[0]; // heroPathPtr[] >> foPaths
|
heroPathPtr[0 + heroDatIsExist]->next = &fo::var::paths[0]; // heroPathPtr[] >> foPaths
|
||||||
|
|
||||||
if (style != 0) {
|
if (style != 0) {
|
||||||
datIsExist = false, folderIsExist = false;
|
bool raceDatIsExist = false, folderIsExist = false;
|
||||||
// check if folder exists for selected race base appearance
|
// check if folder exists for selected race base appearance
|
||||||
sprintf_s(racePathPtr[0]->path, 64, appearancePathFmt, sex, race, 0, "");
|
sprintf_s(racePathPtr[0]->path, 64, appearancePathFmt, sex, race, 0, "");
|
||||||
if (GetFileAttributes(racePathPtr[0]->path) != INVALID_FILE_ATTRIBUTES) {
|
if (GetFileAttributes(racePathPtr[0]->path) != INVALID_FILE_ATTRIBUTES) {
|
||||||
@@ -238,14 +238,13 @@ static __declspec(noinline) int _stdcall LoadHeroDat(unsigned int race, unsigned
|
|||||||
racePathPtr[1]->isDat = 1;
|
racePathPtr[1]->isDat = 1;
|
||||||
}
|
}
|
||||||
if (folderIsExist) racePathPtr[0]->next = racePathPtr[1];
|
if (folderIsExist) racePathPtr[0]->next = racePathPtr[1];
|
||||||
datIsExist = true;
|
raceDatIsExist = true;
|
||||||
} else if (!folderIsExist) {
|
} else if (!folderIsExist) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
long i = 0 + (heroPathPtr[1]->next != nullptr);
|
heroPathPtr[0 + heroDatIsExist]->next = racePathPtr[1 - folderIsExist]; // set path for selected race base appearance
|
||||||
heroPathPtr[i]->next = racePathPtr[1 - folderIsExist]; // set path for selected race base appearance
|
racePathPtr[0 + raceDatIsExist]->next = &fo::var::paths[0]; // insert racePathPtr in chain path: heroPathPtr[] >> racePathPtr[] >> foPaths
|
||||||
racePathPtr[0 + datIsExist]->next = &fo::var::paths[0]; // insert racePathPtr in chain path: heroPathPtr[] >> racePathPtr[] >> foPaths
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -356,13 +355,13 @@ static long _stdcall AddHeroCritNames() { // art_init_
|
|||||||
critterListSize = critterArt.total / 2;
|
critterListSize = critterArt.total / 2;
|
||||||
critterArraySize = critterListSize * 13;
|
critterArraySize = critterListSize * 13;
|
||||||
|
|
||||||
char *CritList = critterArt.names; // critter list offset
|
char *CritList = critterArt.names; // critter list offset
|
||||||
char *HeroList = CritList + critterArraySize; // set start of hero critter list after regular critter list
|
char *HeroList = CritList + critterArraySize; // set start of hero critter list after regular critter list
|
||||||
|
|
||||||
memset(HeroList, 0, critterArraySize);
|
memset(HeroList, 0, critterArraySize);
|
||||||
|
|
||||||
for (DWORD i = 0; i < critterListSize; i++) { // copy critter name list to hero name list
|
for (DWORD i = 0; i < critterListSize; i++) { // copy critter name list to hero name list
|
||||||
*HeroList = '_'; // insert a '_' char at the front of new hero critt names. fallout wont load the same name twice
|
*HeroList = '_'; // insert a '_' char at the front of new hero critt names. fallout wont load the same name twice
|
||||||
memcpy(HeroList + 1, CritList, 11);
|
memcpy(HeroList + 1, CritList, 11);
|
||||||
HeroList += 13;
|
HeroList += 13;
|
||||||
CritList += 13;
|
CritList += 13;
|
||||||
@@ -442,11 +441,11 @@ void _stdcall SetNewCharAppearanceGlobals() {
|
|||||||
void _stdcall SetHeroStyle(int newStyleVal) {
|
void _stdcall SetHeroStyle(int newStyleVal) {
|
||||||
if (!HeroAppearance::appModEnabled || newStyleVal == currentStyleVal) return;
|
if (!HeroAppearance::appModEnabled || newStyleVal == currentStyleVal) return;
|
||||||
|
|
||||||
if (LoadHeroDat(currentRaceVal, newStyleVal, true) != 0) { // if new style cannot be set
|
if (LoadHeroDat(currentRaceVal, newStyleVal, true) != 0) { // if new style cannot be set
|
||||||
if (currentRaceVal == 0 && newStyleVal == 0) {
|
if (currentRaceVal == 0 && newStyleVal == 0) {
|
||||||
currentStyleVal = 0; // ignore error if appearance = default
|
currentStyleVal = 0; // ignore error if appearance = default
|
||||||
} else {
|
} else {
|
||||||
LoadHeroDat(currentRaceVal, currentStyleVal); // reload original style
|
LoadHeroDat(currentRaceVal, currentStyleVal); // reload original style
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
currentStyleVal = newStyleVal;
|
currentStyleVal = newStyleVal;
|
||||||
@@ -459,10 +458,10 @@ void _stdcall SetHeroStyle(int newStyleVal) {
|
|||||||
void _stdcall SetHeroRace(int newRaceVal) {
|
void _stdcall SetHeroRace(int newRaceVal) {
|
||||||
if (!HeroAppearance::appModEnabled || newRaceVal == currentRaceVal) return;
|
if (!HeroAppearance::appModEnabled || newRaceVal == currentRaceVal) return;
|
||||||
|
|
||||||
if (LoadHeroDat(newRaceVal, 0, true) != 0) { // if new race fails with style at 0
|
if (LoadHeroDat(newRaceVal, 0, true) != 0) { // if new race fails with style at 0
|
||||||
if (newRaceVal == 0) {
|
if (newRaceVal == 0) {
|
||||||
currentRaceVal = 0;
|
currentRaceVal = 0;
|
||||||
currentStyleVal = 0; // ignore if appearance = default
|
currentStyleVal = 0; // ignore if appearance = default
|
||||||
} else {
|
} else {
|
||||||
LoadHeroDat(currentRaceVal, currentStyleVal); // reload original race & style
|
LoadHeroDat(currentRaceVal, currentStyleVal); // reload original race & style
|
||||||
}
|
}
|
||||||
@@ -1104,7 +1103,7 @@ static void __declspec(naked) AddCharScrnButtons() {
|
|||||||
fo::func::win_register_button(WinRef, 332, 0, 82, 32, -1, -1, 0x501, -1, 0, 0, 0, 0);
|
fo::func::win_register_button(WinRef, 332, 0, 82, 32, -1, -1, 0x501, -1, 0, 0, 0, 0);
|
||||||
fo::func::win_register_button(WinRef, 332, 226, 82, 32, -1, -1, 0x502, -1, 0, 0, 0, 0);
|
fo::func::win_register_button(WinRef, 332, 226, 82, 32, -1, -1, 0x502, -1, 0, 0, 0, 0);
|
||||||
|
|
||||||
if (fo::var::glblmode == 1 && (styleButtions || raceButtions)) { // equals 1 if new char screen - equals 0 if ingame char screen
|
if (fo::var::glblmode == 1 && (styleButtons || raceButtons)) { // equals 1 if new char screen - equals 0 if ingame char screen
|
||||||
if (newButtonSurface == nullptr) {
|
if (newButtonSurface == nullptr) {
|
||||||
newButtonSurface = new BYTE [20 * 18 * 4];
|
newButtonSurface = new BYTE [20 * 18 * 4];
|
||||||
|
|
||||||
@@ -1129,11 +1128,11 @@ static void __declspec(naked) AddCharScrnButtons() {
|
|||||||
|
|
||||||
frmSurface = nullptr;
|
frmSurface = nullptr;
|
||||||
}
|
}
|
||||||
if (raceButtions) { // race selection buttons
|
if (raceButtons) { // race selection buttons
|
||||||
fo::func::win_register_button(WinRef, 348, 37, 20, 18, -1, -1, -1, 0x511, newButtonSurface, newButtonSurface + (20 * 18), 0, 0x20);
|
fo::func::win_register_button(WinRef, 348, 37, 20, 18, -1, -1, -1, 0x511, newButtonSurface, newButtonSurface + (20 * 18), 0, 0x20);
|
||||||
fo::func::win_register_button(WinRef, 374, 37, 20, 18, -1, -1, -1, 0x513, newButtonSurface + (20 * 18 * 2), newButtonSurface + (20 * 18 * 3), 0, 0x20);
|
fo::func::win_register_button(WinRef, 374, 37, 20, 18, -1, -1, -1, 0x513, newButtonSurface + (20 * 18 * 2), newButtonSurface + (20 * 18 * 3), 0, 0x20);
|
||||||
}
|
}
|
||||||
if (styleButtions) { // style selection buttons
|
if (styleButtons) { // style selection buttons
|
||||||
fo::func::win_register_button(WinRef, 348, 199, 20, 18, -1, -1, -1, 0x512, newButtonSurface, newButtonSurface + (20 * 18), 0, 0x20);
|
fo::func::win_register_button(WinRef, 348, 199, 20, 18, -1, -1, -1, 0x512, newButtonSurface, newButtonSurface + (20 * 18), 0, 0x20);
|
||||||
fo::func::win_register_button(WinRef, 374, 199, 20, 18, -1, -1, -1, 0x514, newButtonSurface + (20 * 18 * 2), newButtonSurface + (20 * 18 * 3), 0, 0x20);
|
fo::func::win_register_button(WinRef, 374, 199, 20, 18, -1, -1, -1, 0x514, newButtonSurface + (20 * 18 * 2), newButtonSurface + (20 * 18 * 3), 0, 0x20);
|
||||||
}
|
}
|
||||||
@@ -1222,10 +1221,10 @@ static void __declspec(naked) FixCharScrnBack() {
|
|||||||
fo::func::art_ptr_unlock(FrmObj);
|
fo::func::art_ptr_unlock(FrmObj);
|
||||||
|
|
||||||
// frm background for char screen Appearance button
|
// frm background for char screen Appearance button
|
||||||
if (fo::var::glblmode == 1 && (styleButtions || raceButtions)) {
|
if (fo::var::glblmode && (styleButtons || raceButtons)) {
|
||||||
FrmSurface = fo::func::art_ptr_lock_data(BuildFrmId(fo::OBJ_TYPE_INTRFACE, 174), 0, 0, &FrmObj); // Pickchar frm
|
FrmSurface = fo::func::art_ptr_lock_data(BuildFrmId(fo::OBJ_TYPE_INTRFACE, 174), 0, 0, &FrmObj); // Pickchar frm
|
||||||
if (raceButtions) sub_draw(69, 20, 640, 480, 281, 319, FrmSurface, 640, 480, 337, 36, charScrnBackSurface, 0); // button backround top
|
if (raceButtons) sub_draw(69, 20, 640, 480, 281, 319, FrmSurface, 640, 480, 337, 36, charScrnBackSurface, 0); // button backround top
|
||||||
if (styleButtions) sub_draw(69, 20, 640, 480, 281, 319, FrmSurface, 640, 480, 337, 198, charScrnBackSurface, 0); // button backround bottom
|
if (styleButtons) sub_draw(69, 20, 640, 480, 281, 319, FrmSurface, 640, 480, 337, 198, charScrnBackSurface, 0); // button backround bottom
|
||||||
fo::func::art_ptr_unlock(FrmObj);
|
fo::func::art_ptr_unlock(FrmObj);
|
||||||
}
|
}
|
||||||
FrmSurface = nullptr;
|
FrmSurface = nullptr;
|
||||||
@@ -1388,12 +1387,12 @@ static void EnableHeroAppearanceMod() {
|
|||||||
// check if Data exists for other races male or female, and if so enable race selection buttons
|
// check if Data exists for other races male or female, and if so enable race selection buttons
|
||||||
if (GetFileAttributes("Appearance\\hmR01S00") != INVALID_FILE_ATTRIBUTES || GetFileAttributes("Appearance\\hfR01S00") != INVALID_FILE_ATTRIBUTES ||
|
if (GetFileAttributes("Appearance\\hmR01S00") != INVALID_FILE_ATTRIBUTES || GetFileAttributes("Appearance\\hfR01S00") != INVALID_FILE_ATTRIBUTES ||
|
||||||
GetFileAttributes("Appearance\\hmR01S00.dat") != INVALID_FILE_ATTRIBUTES || GetFileAttributes("Appearance\\hfR01S00.dat") != INVALID_FILE_ATTRIBUTES) {
|
GetFileAttributes("Appearance\\hmR01S00.dat") != INVALID_FILE_ATTRIBUTES || GetFileAttributes("Appearance\\hfR01S00.dat") != INVALID_FILE_ATTRIBUTES) {
|
||||||
raceButtions = true;
|
raceButtons = true;
|
||||||
}
|
}
|
||||||
// check if Data exists for other styles male or female, and if so enable style selection buttons
|
// check if Data exists for other styles male or female, and if so enable style selection buttons
|
||||||
if (GetFileAttributes("Appearance\\hmR00S01") != INVALID_FILE_ATTRIBUTES || GetFileAttributes("Appearance\\hfR00S01") != INVALID_FILE_ATTRIBUTES ||
|
if (GetFileAttributes("Appearance\\hmR00S01") != INVALID_FILE_ATTRIBUTES || GetFileAttributes("Appearance\\hfR00S01") != INVALID_FILE_ATTRIBUTES ||
|
||||||
GetFileAttributes("Appearance\\hmR00S01.dat") != INVALID_FILE_ATTRIBUTES || GetFileAttributes("Appearance\\hfR00S01.dat") != INVALID_FILE_ATTRIBUTES) {
|
GetFileAttributes("Appearance\\hmR00S01.dat") != INVALID_FILE_ATTRIBUTES || GetFileAttributes("Appearance\\hfR00S01.dat") != INVALID_FILE_ATTRIBUTES) {
|
||||||
styleButtions = true;
|
styleButtons = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if new Appearance char scrn button pushed (editor_design_)
|
// Check if new Appearance char scrn button pushed (editor_design_)
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ void sArrayVar::clearRange( int from, int to /*= -1*/ )
|
|||||||
|
|
||||||
void sArrayVar::clearAll()
|
void sArrayVar::clearAll()
|
||||||
{
|
{
|
||||||
for (auto it = val.begin(); it != val.end(); ++it) {
|
for (std::vector<sArrayElement>::iterator it = val.begin(); it != val.end(); ++it) {
|
||||||
it->clearData();
|
it->clearData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -586,7 +586,7 @@ static void MapSort(sArrayVar& arr, int type) {
|
|||||||
arr.val.clear();
|
arr.val.clear();
|
||||||
arr.keyHash.clear();
|
arr.keyHash.clear();
|
||||||
for (size_t i = 0; i < vmap.size(); ++i) {
|
for (size_t i = 0; i < vmap.size(); ++i) {
|
||||||
auto el = arr.val.size();
|
size_t el = arr.val.size();
|
||||||
if (sortByValue) {
|
if (sortByValue) {
|
||||||
arr.val.emplace_back(vmap[i].second); // map value > key
|
arr.val.emplace_back(vmap[i].second); // map value > key
|
||||||
arr.val.emplace_back(vmap[i].first); // map key > value
|
arr.val.emplace_back(vmap[i].first); // map key > value
|
||||||
|
|||||||
@@ -435,13 +435,23 @@ void sf_get_loot_object(OpcodeContext& ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void sf_get_object_data(OpcodeContext& ctx) {
|
void sf_get_object_data(OpcodeContext& ctx) {
|
||||||
BYTE* object_ptr = (BYTE*)ctx.arg(0).asObject();
|
DWORD result = 0;
|
||||||
ctx.setReturn(*(long*)(object_ptr + ctx.arg(1).asInt()), DataType::INT);
|
DWORD* object_ptr = (DWORD*)ctx.arg(0).rawValue();
|
||||||
|
if (*(object_ptr - 1) != 0xFEEDFACE) {
|
||||||
|
ctx.printOpcodeError("%s() - invalid object pointer.", ctx.getMetaruleName());
|
||||||
|
} else {
|
||||||
|
result = *(long*)((BYTE*)object_ptr + ctx.arg(1).rawValue());
|
||||||
|
}
|
||||||
|
ctx.setReturn(result, DataType::INT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sf_set_object_data(OpcodeContext& ctx) {
|
void sf_set_object_data(OpcodeContext& ctx) {
|
||||||
BYTE* object_ptr = (BYTE*)ctx.arg(0).asObject();
|
DWORD* object_ptr = (DWORD*)ctx.arg(0).rawValue();
|
||||||
*(long*)(object_ptr + ctx.arg(1).asInt()) = ctx.arg(2).asInt();
|
if (*(object_ptr - 1) != 0xFEEDFACE) {
|
||||||
|
ctx.printOpcodeError("%s() - invalid object pointer.", ctx.getMetaruleName());
|
||||||
|
} else {
|
||||||
|
*(long*)((BYTE*)object_ptr + ctx.arg(1).rawValue()) = ctx.arg(2).rawValue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sf_get_object_ai_data(OpcodeContext& ctx) {
|
void sf_get_object_ai_data(OpcodeContext& ctx) {
|
||||||
|
|||||||
Reference in New Issue
Block a user