mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added "unwield_slot" script function
Re-fixed obj_art_fid for player's FID (commit 36523d8)
This commit is contained in:
@@ -265,3 +265,4 @@
|
||||
#define spatial_radius(obj) sfall_func1("spatial_radius", obj)
|
||||
#define tile_refresh_display sfall_func0("tile_refresh_display")
|
||||
#define unjam_lock(obj) sfall_func1("unjam_lock", obj)
|
||||
#define unwield_slot(critter, slot) sfall_func2("unwield_slot", critter, slot)
|
||||
|
||||
@@ -507,6 +507,11 @@ Some utility/math functions are available:
|
||||
- there is also a unique ID number range for the player and party members from 18000 to 83535
|
||||
- to assign a new ID number generated by the engine to the object (i.e. unassign a unique ID), call the function with two arguments and pass -1 for the flag argument
|
||||
|
||||
> void sfall_func2("unwield_slot", object critter, int slot)
|
||||
- unequips an item from the specified slot for a critter or the player
|
||||
- can take off player's equipped item when the inventory is opened, or the player is in the barter screen
|
||||
- slot: 0 - armor slot, 1 - right slot, 2 - left slot (see INVEN_TYPE_* in define.h)
|
||||
|
||||
------------------------
|
||||
------ MORE INFO -------
|
||||
------------------------
|
||||
|
||||
+13
-14
@@ -51,7 +51,7 @@ struct sPath {
|
||||
sPath* next;
|
||||
};
|
||||
|
||||
sPath **tempPathPtr = (sPath**)_paths;
|
||||
sPath **heroAppPaths = (sPath**)_paths;
|
||||
// index: 0 - only folder (w/o extension .dat), 1 - file or folder .dat
|
||||
sPath *heroPathPtr[2] = {nullptr, nullptr};
|
||||
sPath *racePathPtr[2] = {nullptr, nullptr};
|
||||
@@ -826,7 +826,7 @@ static __declspec(noinline) int _stdcall LoadHeroDat(unsigned int race, unsigned
|
||||
}
|
||||
|
||||
//heroPathPtr[1]->next = nullptr;
|
||||
tempPathPtr = &heroPathPtr[1 - folderIsExist]; // set path for selected appearance
|
||||
heroAppPaths = &heroPathPtr[1 - folderIsExist]; // set path for selected appearance
|
||||
heroPathPtr[0 + heroDatIsExist]->next = *(sPath**)_paths; // heroPathPtr[] >> foPaths
|
||||
|
||||
if (style != 0) {
|
||||
@@ -860,12 +860,12 @@ static __declspec(noinline) int _stdcall LoadHeroDat(unsigned int race, unsigned
|
||||
static void __declspec(naked) LoadNewHeroArt() {
|
||||
__asm {
|
||||
cmp byte ptr ds:[esi], 'r';
|
||||
je isReading;
|
||||
jne isNotReading;
|
||||
mov ecx, heroAppPaths;
|
||||
mov ecx, dword ptr ds:[ecx]; // set app path
|
||||
retn;
|
||||
isNotReading:
|
||||
mov ecx, _paths;
|
||||
jmp setPath;
|
||||
isReading:
|
||||
mov ecx, tempPathPtr;
|
||||
setPath:
|
||||
mov ecx, dword ptr ds:[ecx];
|
||||
retn;
|
||||
}
|
||||
@@ -1945,10 +1945,10 @@ static void __declspec(naked) CharScrnEnd() {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////FIX FUNCTIONS//////////////////////////////////////////////////////////////////
|
||||
|
||||
// Adjust PC SFX acm name. Skip Underscore char at the start of PC App Name
|
||||
// Adjust PC SFX acm name. Skip Underscore char at the start of PC frm file name
|
||||
static void __declspec(naked) FixPcSFX() {
|
||||
__asm {
|
||||
cmp byte ptr ds:[ebx], 0x5F; // check if Name begins with an '_' character
|
||||
cmp byte ptr ds:[ebx], '_'; // check if Name begins with an 0x5F character
|
||||
jne endFunc;
|
||||
inc ebx; // shift address to next char
|
||||
endFunc:
|
||||
@@ -1991,11 +1991,10 @@ static const DWORD op_obj_art_fid_Ret = 0x45C5D9;
|
||||
static void __declspec(naked) op_obj_art_fid_hack() {
|
||||
__asm {
|
||||
mov esi, [edi + 0x20]; // artFid
|
||||
push ecx;
|
||||
call RealDudeObject;
|
||||
pop ecx;
|
||||
cmp eax, edi; // object is dude?
|
||||
jnz skip;
|
||||
mov eax, esi;
|
||||
and eax, 0xFFF; // LST index
|
||||
cmp eax, critterListSize;
|
||||
jle skip;
|
||||
sub esi, critterListSize; // fix hero FrmID
|
||||
skip:
|
||||
jmp op_obj_art_fid_Ret;
|
||||
|
||||
@@ -410,6 +410,7 @@ static const SfallOpcodeMetadata opcodeMetaArray[] = {
|
||||
{sf_set_unjam_locks_time, "set_unjam_locks_time", {DATATYPE_MASK_INT}},
|
||||
{sf_spatial_radius, "spatial_radius", {DATATYPE_MASK_VALID_OBJ}},
|
||||
{sf_unjam_lock, "unjam_lock", {DATATYPE_MASK_VALID_OBJ}},
|
||||
{sf_unwield_slot, "unwield_slot", {DATATYPE_MASK_VALID_OBJ, DATATYPE_MASK_INT}},
|
||||
#ifndef NDEBUG
|
||||
{sf_test, "validate_test", {DATATYPE_MASK_INT, DATATYPE_MASK_INT | DATATYPE_MASK_FLOAT, DATATYPE_MASK_STR, DATATYPE_NONE}},
|
||||
#endif
|
||||
|
||||
@@ -429,3 +429,63 @@ static void sf_create_win() {
|
||||
opHandler.printOpcodeError("create_win() - couldn't create window.");
|
||||
}
|
||||
}
|
||||
|
||||
static void sf_unwield_slot() {
|
||||
long slot = static_cast<long>(opHandler.arg(1).rawValue());
|
||||
if (slot < INVEN_TYPE_WORN || slot > INVEN_TYPE_LEFT_HAND) {
|
||||
opHandler.printOpcodeError("unwield_slot() - incorrect slot number.");
|
||||
return;
|
||||
}
|
||||
TGameObj* critter = opHandler.arg(0).asObject();
|
||||
if (critter->pid >> 24 != OBJ_TYPE_CRITTER) {
|
||||
opHandler.printOpcodeError("unwield_slot() - the object is not a critter.");
|
||||
return;
|
||||
}
|
||||
bool isDude = (critter == *ptr_obj_dude);
|
||||
bool update = false;
|
||||
if (slot && (GetLoopFlags() && (INVENTORY | INTFACEUSE | INTFACELOOT | BARTER)) == false) {
|
||||
if (InvenUnwield(critter, (slot == INVEN_TYPE_LEFT_HAND) ? 0 : 1) == 0) {
|
||||
update = isDude;
|
||||
}
|
||||
} else {
|
||||
// force unwield for opened inventory
|
||||
bool forceAdd = false;
|
||||
TGameObj* item = nullptr;
|
||||
if (slot != INVEN_TYPE_WORN) {
|
||||
if (!isDude) return;
|
||||
long* itemRef = nullptr;
|
||||
if (slot == INVEN_TYPE_LEFT_HAND) {
|
||||
item = *ptr_i_lhand;
|
||||
itemRef = (long*)_i_lhand;
|
||||
} else {
|
||||
item = *ptr_i_rhand;
|
||||
itemRef = (long*)_i_rhand;
|
||||
}
|
||||
if (item) {
|
||||
if (!CorrectFidForRemovedItem_wHook(critter, item, (slot == INVEN_TYPE_LEFT_HAND) ? 0x1000000 : 0x2000000)) {
|
||||
return;
|
||||
}
|
||||
*itemRef = 0;
|
||||
forceAdd = true;
|
||||
update = true;
|
||||
}
|
||||
} else {
|
||||
if (isDude) item = *ptr_i_worn;
|
||||
if (!item) {
|
||||
item = InvenWorn(critter);
|
||||
} else {
|
||||
*ptr_i_worn = nullptr;
|
||||
forceAdd = true;
|
||||
}
|
||||
if (item) {
|
||||
if (!CorrectFidForRemovedItem_wHook(critter, item, 0x4000000)) {
|
||||
if (forceAdd) *ptr_i_worn = item;
|
||||
return;
|
||||
}
|
||||
if (isDude) IntfaceUpdateAc(0);
|
||||
}
|
||||
}
|
||||
if (forceAdd) ItemAddForce(critter, item, 1);
|
||||
}
|
||||
if (update) IntfaceUpdateItems(0, -1, -1);
|
||||
}
|
||||
|
||||
@@ -157,6 +157,7 @@ static const SfallMetarule metaruleArray[] = {
|
||||
{"spatial_radius", sf_spatial_radius, 1, 1},
|
||||
{"tile_refresh_display", sf_tile_refresh_display, 0, 0},
|
||||
{"unjam_lock", sf_unjam_lock, 1, 1},
|
||||
{"unwield_slot", sf_unwield_slot, 2, 2},
|
||||
#ifndef NDEBUG
|
||||
{"validate_test", sf_test, 2, 5},
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user