mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added assignment of unique IDs to items/critters for event queue
* to prevent event queue being added to the incorrect object on the map.
This commit is contained in:
@@ -740,4 +740,22 @@ namespace WinFlags {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum QueueType : long
|
||||||
|
{
|
||||||
|
drug_effect_event = 0, // critter use drug
|
||||||
|
knockout_event = 1, // critter
|
||||||
|
addict_event = 2, // critter
|
||||||
|
script_timer_event = 3, // any object
|
||||||
|
game_time_event = 4, // no object
|
||||||
|
poison_event = 5, // dude
|
||||||
|
radiation_event = 6, // dude
|
||||||
|
flare_time_event = 7, // item
|
||||||
|
explode_event = 8, // item
|
||||||
|
item_trickle_event = 9,
|
||||||
|
sneak_event = 10, // dude
|
||||||
|
explode_fail_event = 11, // item
|
||||||
|
map_update_event = 12,
|
||||||
|
gsound_sfx_event = 13 // no object
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,22 +33,22 @@ long Objects::uniqueID = UniqueID::Start; // current counter id, saving to sfall
|
|||||||
// Assigns a new unique identifier to an object if it has not been previously assigned
|
// Assigns a new unique identifier to an object if it has not been previously assigned
|
||||||
// the identifier is saved with the object in the saved game and this can used in various script
|
// the identifier is saved with the object in the saved game and this can used in various script
|
||||||
// player ID = 18000, all party members have ID = 18000 + its pid (file number of prototype)
|
// player ID = 18000, all party members have ID = 18000 + its pid (file number of prototype)
|
||||||
long Objects::SetObjectUniqueID(fo::GameObject* obj) {
|
long __fastcall Objects::SetObjectUniqueID(fo::GameObject* obj) {
|
||||||
long id = obj->id;
|
long id = obj->id;
|
||||||
if (id > UniqueID::Start || obj == fo::var::obj_dude || (id >= PLAYER_ID && id < 83536)) return id; // 65535 maximum possible number of prototypes
|
if (id > UniqueID::Start || (id >= PLAYER_ID && id < 83536)) return id; // 65535 maximum possible number of prototypes
|
||||||
|
|
||||||
if ((DWORD)uniqueID >= UniqueID::End) uniqueID = UniqueID::Start;
|
if ((DWORD)uniqueID >= (DWORD)UniqueID::End) uniqueID = UniqueID::Start;
|
||||||
obj->id = ++uniqueID;
|
obj->id = ++uniqueID;
|
||||||
return uniqueID;
|
return uniqueID;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assigns a unique ID in the negative range (0x8FFFFFFF - 0xFFFFFFFE)
|
// Assigns a unique ID in the negative range (0xFFFFFFF6 - 0x8FFFFFF7)
|
||||||
long Objects::SetSpecialID(fo::GameObject* obj) {
|
long __fastcall Objects::SetSpecialID(fo::GameObject* obj) {
|
||||||
long id = obj->id;
|
long id = obj->id;
|
||||||
if (id < -1 || id > UniqueID::Start) return id;
|
if (id <= -10 || id > UniqueID::Start) return id;
|
||||||
|
|
||||||
if ((DWORD)uniqueID >= UniqueID::End) uniqueID = UniqueID::Start;
|
if ((DWORD)uniqueID >= (DWORD)UniqueID::End) uniqueID = UniqueID::Start;
|
||||||
id = ++uniqueID + UniqueID::End;
|
id = -9 - (++uniqueID - UniqueID::Start);
|
||||||
obj->id = id;
|
obj->id = id;
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
@@ -111,6 +111,43 @@ saveable:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __declspec(naked) queue_add_hack() {
|
||||||
|
using namespace fo;
|
||||||
|
using namespace Fields;
|
||||||
|
__asm {
|
||||||
|
mov [edx + 8], edi; // queue.object
|
||||||
|
mov [edx], esi; // queue.time
|
||||||
|
test edi, edi;
|
||||||
|
jnz fix;
|
||||||
|
retn;
|
||||||
|
fix:
|
||||||
|
mov eax, [edi + protoId];
|
||||||
|
and eax, 0x0F000000;
|
||||||
|
jnz notItem; // object is not an item?
|
||||||
|
push ecx;
|
||||||
|
push edx;
|
||||||
|
mov ecx, edi;
|
||||||
|
call Objects::SetSpecialID;
|
||||||
|
pop edx;
|
||||||
|
pop ecx;
|
||||||
|
retn;
|
||||||
|
notItem:
|
||||||
|
cmp ecx, script_timer_event; // QueueType
|
||||||
|
je end;
|
||||||
|
cmp eax, OBJ_TYPE_CRITTER << 24;
|
||||||
|
jne end;
|
||||||
|
push ecx;
|
||||||
|
push edx;
|
||||||
|
mov ecx, edi;
|
||||||
|
call Objects::SetObjectUniqueID;
|
||||||
|
pop edx;
|
||||||
|
pop ecx;
|
||||||
|
end:
|
||||||
|
xor edi, edi; // fix: don't set "Used" flag for critter objects
|
||||||
|
retn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Objects::SetAutoUnjamLockTime(DWORD time) {
|
void Objects::SetAutoUnjamLockTime(DWORD time) {
|
||||||
if (!unjamTimeState) {
|
if (!unjamTimeState) {
|
||||||
BlockCall(0x4A364A); // disable auto unjam at midnight
|
BlockCall(0x4A364A); // disable auto unjam at midnight
|
||||||
@@ -171,6 +208,8 @@ void Objects::init() {
|
|||||||
// Fix mapper bug by reassigning object IDs to critters (for unvisited maps)
|
// Fix mapper bug by reassigning object IDs to critters (for unvisited maps)
|
||||||
MakeCall(0x482E6B, map_load_file_hack);
|
MakeCall(0x482E6B, map_load_file_hack);
|
||||||
SafeWrite8(0x482E71, 0x85); // jz > jnz
|
SafeWrite8(0x482E71, 0x85); // jz > jnz
|
||||||
|
// Additionally fix object IDs for queue events
|
||||||
|
MakeCall(0x4A25BA, queue_add_hack);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
namespace sfall
|
namespace sfall
|
||||||
{
|
{
|
||||||
|
|
||||||
enum UniqueID {
|
enum UniqueID : long {
|
||||||
Start = 0x0FFFFFFF, // start at 0x10000000
|
Start = 0x0FFFFFFF, // start at 0x10000000
|
||||||
End = 0x7FFFFFFF
|
End = 0x7FFFFFFF
|
||||||
};
|
};
|
||||||
@@ -17,8 +17,8 @@ public:
|
|||||||
|
|
||||||
static long uniqueID;
|
static long uniqueID;
|
||||||
|
|
||||||
static long SetObjectUniqueID(fo::GameObject* obj);
|
static long __fastcall SetObjectUniqueID(fo::GameObject* obj);
|
||||||
static long SetSpecialID(fo::GameObject* obj);
|
static long __fastcall SetSpecialID(fo::GameObject* obj);
|
||||||
static void SetNewEngineID(fo::GameObject* obj);
|
static void SetNewEngineID(fo::GameObject* obj);
|
||||||
|
|
||||||
static void SetAutoUnjamLockTime(DWORD time);
|
static void SetAutoUnjamLockTime(DWORD time);
|
||||||
|
|||||||
Reference in New Issue
Block a user