mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Fixed set_unique_id script function
* it unassigned unique ID even when the object doesn't have one. * it didn't sync the attached script's owner id after unassignment. Added a safeguard to prevent item_identical function returning false when comparing a unique_id item to itself. (ref. fallout2-ce/fallout2-ce#466)
This commit is contained in:
@@ -35,7 +35,7 @@ bool Objects::IsUniqueID(long id) {
|
|||||||
return (id > UniqueID::Start || (id >= fo::PLAYER_ID && id < 83536)); // 65535 maximum possible number of prototypes
|
return (id > UniqueID::Start || (id >= fo::PLAYER_ID && id < 83536)); // 65535 maximum possible number of prototypes
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetScriptObjectID(fo::GameObject* obj) {
|
void Objects::SetScriptObjectID(fo::GameObject* obj) {
|
||||||
fo::ScriptInstance* script;
|
fo::ScriptInstance* script;
|
||||||
if (fo::func::scr_ptr(obj->scriptId, &script) != -1) {
|
if (fo::func::scr_ptr(obj->scriptId, &script) != -1) {
|
||||||
script->ownerObjectId = obj->id;
|
script->ownerObjectId = obj->id;
|
||||||
@@ -74,8 +74,11 @@ void Objects::SetNewEngineID(fo::GameObject* obj) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static __declspec(naked) void item_identical_hack() {
|
static __declspec(naked) void item_identical_hack() {
|
||||||
|
static const DWORD item_identical_End = 0x477AD5;
|
||||||
using namespace fo::Fields;
|
using namespace fo::Fields;
|
||||||
__asm {
|
__asm {
|
||||||
|
cmp esi, edi; // inv_item == place_item? (safeguard)
|
||||||
|
je identical;
|
||||||
mov ecx, [edi]; // place_item id
|
mov ecx, [edi]; // place_item id
|
||||||
cmp ecx, Start; // start unique ID
|
cmp ecx, Start; // start unique ID
|
||||||
jg notIdentical;
|
jg notIdentical;
|
||||||
@@ -87,6 +90,9 @@ static __declspec(naked) void item_identical_hack() {
|
|||||||
cmp eax, ebx;
|
cmp eax, ebx;
|
||||||
notIdentical:
|
notIdentical:
|
||||||
retn; // if ZF == 0 then item is not identical
|
retn; // if ZF == 0 then item is not identical
|
||||||
|
identical:
|
||||||
|
add esp, 4;
|
||||||
|
jmp item_identical_End;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,7 +117,7 @@ static void map_fix_critter_id() {
|
|||||||
if (obj->IsCritter()) {
|
if (obj->IsCritter()) {
|
||||||
if (obj->id < fo::PLAYER_ID) {
|
if (obj->id < fo::PLAYER_ID) {
|
||||||
obj->id = npcStartID++;
|
obj->id = npcStartID++;
|
||||||
SetScriptObjectID(obj);
|
Objects::SetScriptObjectID(obj);
|
||||||
}
|
}
|
||||||
Stats::UpdateHPStat(obj);
|
Stats::UpdateHPStat(obj);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ public:
|
|||||||
static long uniqueID;
|
static long uniqueID;
|
||||||
|
|
||||||
static bool IsUniqueID(long id);
|
static bool IsUniqueID(long id);
|
||||||
|
static void SetScriptObjectID(fo::GameObject* obj);
|
||||||
|
|
||||||
static long __fastcall SetObjectUniqueID(fo::GameObject* obj);
|
static long __fastcall SetObjectUniqueID(fo::GameObject* obj);
|
||||||
static long __fastcall SetSpecialID(fo::GameObject* obj);
|
static long __fastcall SetSpecialID(fo::GameObject* obj);
|
||||||
|
|||||||
@@ -584,14 +584,16 @@ void mf_set_drugs_data(OpcodeContext& ctx) {
|
|||||||
|
|
||||||
void mf_set_unique_id(OpcodeContext& ctx) {
|
void mf_set_unique_id(OpcodeContext& ctx) {
|
||||||
fo::GameObject* obj = ctx.arg(0).object();
|
fo::GameObject* obj = ctx.arg(0).object();
|
||||||
long id;
|
if (ctx.numArgs() > 1 && ctx.arg(1).rawValue() == -1) {
|
||||||
if (ctx.arg(1).rawValue() == -1) {
|
// unassign unique ID only if the object currently has one
|
||||||
id = fo::func::new_obj_id();
|
if (obj->id > UniqueID::Start) {
|
||||||
obj->id = id;
|
obj->id = fo::func::new_obj_id();
|
||||||
} else {
|
Objects::SetScriptObjectID(obj);
|
||||||
id = Objects::SetObjectUniqueID(obj);
|
}
|
||||||
|
ctx.setReturn(obj->id);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
ctx.setReturn(id);
|
ctx.setReturn(Objects::SetObjectUniqueID(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
void mf_objects_in_radius(OpcodeContext& ctx) {
|
void mf_objects_in_radius(OpcodeContext& ctx) {
|
||||||
|
|||||||
Reference in New Issue
Block a user