Backported "car_gas_amount" and "set_car_intface_art" functions from 4.0

Added prefixes to some functions (fake classes)
This commit is contained in:
NovaRain
2020-10-08 22:14:32 +08:00
parent cc5561d3d6
commit 0c547da134
22 changed files with 99 additions and 67 deletions
+2
View File
@@ -264,6 +264,7 @@
#define add_trait(traitID) sfall_func1("add_trait", traitID)
#define art_cache_clear sfall_func0("art_cache_clear")
#define attack_is_aimed sfall_func0("attack_is_aimed")
#define car_gas_amount sfall_func0("car_gas_amount")
#define combat_data sfall_func0("combat_data")
#define create_win(winName, x, y, w, h) sfall_func5("create_win", winName, x, y, w, h)
#define create_win_flag(winName, x, y, w, h, flag) sfall_func6("create_win", winName, x, y, w, h, flag)
@@ -315,6 +316,7 @@
#define real_dude_obj sfall_func0("real_dude_obj")
#define remove_all_timer_events sfall_func0("remove_timer_event")
#define remove_timer_event(fixedParam) sfall_func1("remove_timer_event", fixedParam)
#define set_car_intface_art(artIndex) sfall_func1("set_car_intface_art", artIndex)
#define set_cursor_mode(mode) sfall_func1("set_cursor_mode", mode)
#define set_flags(obj, flags) sfall_func2("set_flags", obj, flags)
#define set_iface_tag_text(tag, text, color) sfall_func3("set_iface_tag_text", tag, text, color)
+10 -1
View File
@@ -439,7 +439,16 @@ Some utility/math functions are available:
- returns an object that is currently highlighted by hovering the mouse above it
> void sfall_func0("real_dude_obj")
- returns the initial dude_obj after taking control of other critters
- returns the initial dude_obj after taking control of other critters in combat
> int sfall_func0("car_gas_amount")
- returns the current amount of fuel in player's car (between 0 and 80000)
- to change fuel amount, use vanilla function: metarule(METARULE_GIVE_CAR_GAS, amount) - amount can be positive or negative
> void sfall_func1("set_car_intface_art", int artIndex)
- changes the interface art (index in intrface.lst) for the car image on the world map interface
- should be called before going to the world map
- vanilla art index is 433
> int sfall_func0("get_cursor_mode")
- returns the current cursor mode (0 - movement cursor, 1 - command cursor, 2 - targeting cursor)
+6 -6
View File
@@ -222,7 +222,7 @@ static void SetEngine(int count) {
}
}
long SetBoxMaxSlots() {
long BarBoxes_SetMaxSlots() {
long scrWidth = Gfx_GetGameWidthRes();
int slots = scrWidth / 127;
@@ -242,7 +242,7 @@ long SetBoxMaxSlots() {
static long __fastcall GetOffsetX(int width) {
int x_offset = 0;
if (SetBoxMaxSlots() > 640 && width > ifaceWidth) {
if (BarBoxes_SetMaxSlots() > 640 && width > ifaceWidth) {
x_offset -= (width - ifaceWidth) / 2;
}
return x_offset;
@@ -305,7 +305,7 @@ void BarBoxesInit() {
if (ifaceWidth < 640) ifaceWidth = 640;
}
long __stdcall AddExtraBox() {
long __stdcall BarBoxes_AddExtraBox() {
if (boxCount < totalBoxCount) {
actualBoxCount++;
boxCount++;
@@ -344,18 +344,18 @@ long __stdcall AddExtraBox() {
return BarBoxes_MaxBox(); // current number of added box
}
bool __stdcall GetBox(int i) {
bool __stdcall BarBoxes_GetBox(int i) {
if (i < 5 || i > BarBoxes_MaxBox()) return false;
return boxText[i - 5].isActive;
}
void __stdcall AddBox(int i) {
void __stdcall BarBoxes_AddBox(int i) {
if (i < 5 || i > BarBoxes_MaxBox()) return;
boxText[i - 5].isActive = true;
__asm call refresh_box_bar_win_;
}
void __stdcall RemoveBox(int i) {
void __stdcall BarBoxes_RemoveBox(int i) {
if (i < 5 || i > BarBoxes_MaxBox()) return;
boxText[i - 5].isActive = false;
__asm call refresh_box_bar_win_;
+5 -5
View File
@@ -3,12 +3,12 @@
void BarBoxesInit();
void BarBoxesExit();
void BarBoxes_OnGameLoad();
long SetBoxMaxSlots();
long BarBoxes_SetMaxSlots();
int __stdcall BarBoxes_MaxBox();
void __stdcall BarBoxes_SetText(int box, const char* text, DWORD color);
bool __stdcall GetBox(int i);
void __stdcall AddBox(int i);
void __stdcall RemoveBox(int i);
long __stdcall AddExtraBox();
bool __stdcall BarBoxes_GetBox(int i);
void __stdcall BarBoxes_AddBox(int i);
void __stdcall BarBoxes_RemoveBox(int i);
long __stdcall BarBoxes_AddExtraBox();
+5 -5
View File
@@ -339,8 +339,8 @@ void __stdcall KnockbackSetMod(TGameObj* object, DWORD type, float val, DWORD mo
}
long id = (mode == 0)
? SetSpecialID(object)
: SetObjectUniqueID(object);
? Objects_SetSpecialID(object)
: Objects_SetObjectUniqueID(object);
KnockbackModifier mod = { id, type, (double)val };
for (size_t i = 0; i < mods->size(); i++) {
@@ -370,7 +370,7 @@ void __stdcall KnockbackRemoveMod(TGameObj* object, DWORD mode) {
for (size_t i = 0; i < mods->size(); i++) {
if ((*mods)[i].id == object->id) {
mods->erase(mods->begin() + i);
if (mode == 0) SetNewEngineID(object); // revert to engine range id
if (mode == 0) Objects_SetNewEngineID(object); // revert to engine range id
return;
}
}
@@ -383,7 +383,7 @@ void __stdcall SetHitChanceMax(TGameObj* critter, DWORD maximum, DWORD mod) {
return;
}
if (critter->Type() != OBJ_TYPE_CRITTER) return;
long id = SetObjectUniqueID(critter);
long id = Objects_SetObjectUniqueID(critter);
for (size_t i = 0; i < hitChanceMods.size(); i++) {
if (id == hitChanceMods[i].id) {
hitChanceMods[i].maximum = maximum;
@@ -401,7 +401,7 @@ void __stdcall SetHitChanceMax(TGameObj* critter, DWORD maximum, DWORD mod) {
void __stdcall SetNoBurstMode(TGameObj* critter, bool on) {
if (critter == *ptr_obj_dude || critter->Type() != OBJ_TYPE_CRITTER) return;
long id = SetObjectUniqueID(critter);
long id = Objects_SetObjectUniqueID(critter);
for (size_t i = 0; i < noBursts.size(); i++) {
if (noBursts[i] == id) {
if (!on) noBursts.erase(noBursts.begin() + i); // off
+2 -1
View File
@@ -37,7 +37,8 @@ BYTE* ptr_BlueColor = reinterpret_cast<BYTE*>(_BlueColor);
DWORD* ptr_bottom_line = reinterpret_cast<DWORD*>(_bottom_line);
DWORD* ptr_btable = reinterpret_cast<DWORD*>(_btable);
DWORD* ptr_btncnt = reinterpret_cast<DWORD*>(_btncnt);
DWORD* ptr_CarCurrArea = reinterpret_cast<DWORD*>(_CarCurrArea);
DWORD* ptr_carCurrentArea = reinterpret_cast<DWORD*>(_carCurrentArea);
long* ptr_carGasAmount = reinterpret_cast<long*>(_carGasAmount); // from 0 to 80000
DWORD* ptr_cmap = reinterpret_cast<DWORD*>(_cmap);
DWORD* ptr_colorTable = reinterpret_cast<DWORD*>(_colorTable);
DWORD* ptr_combat_free_move = reinterpret_cast<DWORD*>(_combat_free_move);
+4 -2
View File
@@ -49,7 +49,8 @@
#define _bottom_line 0x664524
#define _btable 0x59E944
#define _btncnt 0x43EA1C
#define _CarCurrArea 0x672E68
#define _carCurrentArea 0x672E68
#define _carGasAmount 0x672E6C
#define _card_old_fid1 0x5709EC
#define _character_points 0x518538
#define _cmap 0x51DF34
@@ -339,7 +340,8 @@ extern BYTE* ptr_BlueColor;
extern DWORD* ptr_bottom_line;
extern DWORD* ptr_btable;
extern DWORD* ptr_btncnt;
extern DWORD* ptr_CarCurrArea;
extern DWORD* ptr_carCurrentArea;
extern long* ptr_carGasAmount; // from 0 to 80000
extern DWORD* ptr_cmap;
extern DWORD* ptr_colorTable;
extern DWORD* ptr_combat_free_move;
+4 -4
View File
@@ -18,10 +18,10 @@
#pragma once
long __stdcall GetInvenApCost();
void __fastcall SetInvenApCost(int cost);
DWORD __stdcall sf_item_total_size(TGameObj* critter);
void InventoryInit();
void InventoryReset();
void InventoryKeyPressedHook(DWORD dxKey, bool pressed);
long __stdcall GetInvenApCost();
void __fastcall SetInvenApCost(int cost);
DWORD __stdcall sf_item_total_size(TGameObj* critter);
+3 -3
View File
@@ -131,7 +131,7 @@ static void __stdcall SaveGame2() {
HANDLE h = CreateFileA(buf, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
if (h != INVALID_HANDLE_VALUE) {
SaveGlobals(h);
WriteFile(h, &objUniqueID, 4, &size, 0); // save unique id counter
WriteFile(h, &Objects_uniqueID, 4, &size, 0); // save unique id counter
data = Worldmap_GetAddedYears(false) << 16; // save to high bytes (short)
WriteFile(h, &data, 4, &size, 0);
PerksSave(h);
@@ -218,7 +218,7 @@ static bool __stdcall LoadGame_Before() {
if (LoadGlobals(h)) goto errorLoad;
long uID = 0;
ReadFile(h, &uID, 4, &size, 0);
if (uID > UID_START) objUniqueID = uID;
if (uID > UID_START) Objects_uniqueID = uID;
ReadFile(h, &data, 4, &size, 0);
Worldmap_SetAddedYears(data >> 16);
if (size != 4 || !PerksLoad(h)) goto errorLoad;
@@ -305,7 +305,7 @@ static void __stdcall GameInitialized(int initResult) { // OnAfterGameInit
}
#endif
RemoveSavFiles();
SetBoxMaxSlots();
BarBoxes_SetMaxSlots();
if (Use32BitTalkingHeads) TalkingHeadsSetup();
}
+14 -14
View File
@@ -24,32 +24,32 @@
static int unjamTimeState;
static int maxCountLoadProto = 512;
long objUniqueID = UID_START; // current counter id, saving to sfallgv.sav
long Objects_uniqueID = UID_START; // current counter id, saving to sfallgv.sav
// 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
// player ID = 18000, all party members have ID = 18000 + its pid (file number of prototype)
long __fastcall SetObjectUniqueID(TGameObj* obj) {
long __fastcall Objects_SetObjectUniqueID(TGameObj* obj) {
long id = obj->id;
if (id > UID_START || (id >= PLAYER_ID && id < 83536)) return id; // 65535 maximum possible number of prototypes
if ((DWORD)objUniqueID >= (DWORD)UID_END) objUniqueID = UID_START;
obj->id = ++objUniqueID;
return objUniqueID;
if ((DWORD)Objects_uniqueID >= (DWORD)UID_END) Objects_uniqueID = UID_START;
obj->id = ++Objects_uniqueID;
return Objects_uniqueID;
}
// Assigns a unique ID in the negative range (0xFFFFFFF6 - 0x8FFFFFF7)
long __fastcall SetSpecialID(TGameObj* obj) {
long __fastcall Objects_SetSpecialID(TGameObj* obj) {
long id = obj->id;
if (id <= -10 || id > UID_START) return id;
if ((DWORD)objUniqueID >= (DWORD)UID_END) objUniqueID = UID_START;
id = -9 - (++objUniqueID - UID_START);
if ((DWORD)Objects_uniqueID >= (DWORD)UID_END) Objects_uniqueID = UID_START;
id = -9 - (++Objects_uniqueID - UID_START);
obj->id = id;
return id;
}
void SetNewEngineID(TGameObj* obj) {
void Objects_SetNewEngineID(TGameObj* obj) {
if (obj->id > UID_START) return;
obj->id = NewObjId();
}
@@ -80,7 +80,7 @@ pickNewID: // skip PM range (18000 - 83535)
}
// Reassigns object IDs to all critters upon first loading a map
static void __stdcall map_fix_critter_id() {
static void map_fix_critter_id() {
long npcStartID = 4096;
TGameObj* obj = ObjFindFirst();
while (obj) {
@@ -130,7 +130,7 @@ fix:
push ecx;
push edx;
mov ecx, edi;
call SetSpecialID;
call Objects_SetSpecialID;
pop edx;
pop ecx;
retn;
@@ -142,7 +142,7 @@ notItem:
push ecx;
push edx;
mov ecx, edi;
call SetObjectUniqueID;
call Objects_SetObjectUniqueID;
pop edx;
pop ecx;
end:
@@ -151,7 +151,7 @@ end:
}
}
void SetAutoUnjamLockTime(DWORD time) {
void Objects_SetAutoUnjamLockTime(DWORD time) {
if (!unjamTimeState) BlockCall(0x4A364A); // disable auto unjam at midnight
if (time > 0) {
@@ -192,7 +192,7 @@ end:
}
}
void LoadProtoAutoMaxLimit() {
void Objects_LoadProtoAutoMaxLimit() {
MakeCall(0x4A21B2, proto_ptr_hack);
}
+8 -8
View File
@@ -5,14 +5,14 @@ enum UniqueID : long {
UID_END = 0x7FFFFFFF
};
extern long objUniqueID;
extern long Objects_uniqueID;
void ObjectsInit();
long __fastcall SetObjectUniqueID(TGameObj* obj);
long __fastcall SetSpecialID(TGameObj* obj);
void SetNewEngineID(TGameObj* obj);
void SetAutoUnjamLockTime(DWORD time);
void RestoreObjUnjamAllLocks();
void LoadProtoAutoMaxLimit();
long __fastcall Objects_SetObjectUniqueID(TGameObj* obj);
long __fastcall Objects_SetSpecialID(TGameObj* obj);
void Objects_SetNewEngineID(TGameObj* obj);
void Objects_SetAutoUnjamLockTime(DWORD time);
void Objects_LoadProtoAutoMaxLimit();
+1
View File
@@ -862,6 +862,7 @@ static const SfallOpcodeMetadata opcodeMetaArray[] = {
{mf_inventory_redraw, "inventory_redraw", {DATATYPE_MASK_INT}},
{mf_message_box, "message_box", {DATATYPE_MASK_STR, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT}},
{mf_remove_timer_event, "remove_timer_event", {DATATYPE_MASK_INT}},
{mf_set_car_intface_art, "set_car_intface_art", {DATATYPE_MASK_INT}},
{mf_set_cursor_mode, "set_cursor_mode", {DATATYPE_MASK_INT}},
{mf_set_flags, "set_flags", {DATATYPE_MASK_VALID_OBJ, DATATYPE_MASK_INT}},
{mf_set_iface_tag_text, "set_iface_tag_text", {DATATYPE_MASK_INT, DATATYPE_MASK_STR, DATATYPE_MASK_INT}},
+4 -4
View File
@@ -260,7 +260,7 @@ end:
}
static void mf_add_iface_tag() {
int result = AddExtraBox();
int result = BarBoxes_AddExtraBox();
if (result == -1) opHandler.printOpcodeError("add_iface_tag() - cannot add new tag as the maximum limit of 126 tags has been reached.");
opHandler.setReturn(result);
}
@@ -273,7 +273,7 @@ static void __stdcall op_show_iface_tag2() {
__asm mov eax, tag;
__asm call pc_flag_on_;
} else {
AddBox(tag);
BarBoxes_AddBox(tag);
}
} else {
OpcodeInvalidArgs("show_iface_tag");
@@ -292,7 +292,7 @@ static void __stdcall op_hide_iface_tag2() {
__asm mov eax, tag;
__asm call pc_flag_off_;
} else {
RemoveBox(tag);
BarBoxes_RemoveBox(tag);
}
} else {
OpcodeInvalidArgs("hide_iface_tag");
@@ -326,7 +326,7 @@ static void __stdcall op_is_iface_tag_active2() {
result = ((*(int*)(proto + 0x20) & flagBit) != 0);
}
} else {
result = GetBox(tag);
result = BarBoxes_GetBox(tag);
}
opHandler.setReturn(result);
} else {
+2
View File
@@ -120,6 +120,7 @@ static const SfallMetarule metaruleArray[] = {
{"add_trait", mf_add_trait, 1, 1},
{"art_cache_clear", mf_art_cache_flush, 0, 0},
{"attack_is_aimed", mf_attack_is_aimed, 0, 0},
{"car_gas_amount", mf_car_gas_amount, 0, 0},
{"combat_data", mf_combat_data, 0, 0},
{"create_win", mf_create_win, 5, 6},
{"critter_inven_obj2", mf_critter_inven_obj2, 2, 2},
@@ -161,6 +162,7 @@ static const SfallMetarule metaruleArray[] = {
{"outlined_object", mf_outlined_object, 0, 0},
{"real_dude_obj", mf_real_dude_obj, 0, 0},
{"remove_timer_event", mf_remove_timer_event, 0, 1},
{"set_car_intface_art", mf_set_car_intface_art, 1, 1},
{"set_cursor_mode", mf_set_cursor_mode, 1, 1},
{"set_flags", mf_set_flags, 2, 2},
{"set_iface_tag_text", mf_set_iface_tag_text, 3, 3},
+1 -1
View File
@@ -599,7 +599,7 @@ static void __declspec(naked) op_get_uptime() {
static void __declspec(naked) op_set_car_current_town() {
__asm {
_GET_ARG_INT(end);
mov ds:[_CarCurrArea], eax;
mov ds:[_carCurrentArea], eax;
end:
retn;
}
+7 -3
View File
@@ -494,6 +494,10 @@ static void mf_real_dude_obj() {
opHandler.setReturn(RealDudeObject());
}
static void mf_car_gas_amount() {
opHandler.setReturn(*ptr_carGasAmount);
}
static void mf_lock_is_jammed() {
TGameObj* obj = opHandler.arg(0).asObject();
if (obj) {
@@ -514,7 +518,7 @@ static void mf_set_unjam_locks_time() {
opHandler.printOpcodeError("set_unjam_locks_time() - time argument must be in the range of 0 to 127.");
opHandler.setReturn(-1);
} else {
SetAutoUnjamLockTime(time);
Objects_SetAutoUnjamLockTime(time);
}
}
@@ -599,7 +603,7 @@ static void __stdcall op_set_proto_data2() {
if (result != -1) {
*(long*)((BYTE*)protoPtr + offsetArg.rawValue()) = valueArg.rawValue();
if (!protoMaxLimitPatch) {
LoadProtoAutoMaxLimit();
Objects_LoadProtoAutoMaxLimit();
protoMaxLimitPatch = true;
}
} else {
@@ -639,7 +643,7 @@ static void mf_set_unique_id() {
id = NewObjId();
obj->id = id;
} else {
id = SetObjectUniqueID(obj);
id = Objects_SetObjectUniqueID(obj);
}
opHandler.setReturn(id);
}
+4 -4
View File
@@ -84,7 +84,7 @@ static void __stdcall op_get_pc_base_stat2() {
} else {
OpcodeInvalidArgs("get_pc_base_stat");
}
opHandler.setReturn(value, DATATYPE_INT);
opHandler.setReturn(value);
}
@@ -106,7 +106,7 @@ static void __stdcall op_get_pc_extra_stat2() {
} else {
OpcodeInvalidArgs("get_pc_extra_stat");
}
opHandler.setReturn(value, DATATYPE_INT);
opHandler.setReturn(value);
}
static void __declspec(naked) op_get_pc_extra_stat() {
@@ -185,7 +185,7 @@ static void __stdcall op_get_critter_base_stat2() {
} else {
OpcodeInvalidArgs("get_critter_base_stat");
}
opHandler.setReturn(result, DATATYPE_INT);
opHandler.setReturn(result);
}
static void __declspec(naked) op_get_critter_base_stat() {
@@ -212,7 +212,7 @@ static void __stdcall op_get_critter_extra_stat2() {
} else {
OpcodeInvalidArgs("get_critter_extra_stat");
}
opHandler.setReturn(result, DATATYPE_INT);
opHandler.setReturn(result);
}
static void __declspec(naked) op_get_critter_extra_stat() {
+5 -1
View File
@@ -65,7 +65,7 @@ static void __declspec(naked) wmRndEncounterOccurred_hack() {
jnz noCar;
cmp ds:[_Move_on_Car], 0;
jz noCar;
mov edx, _CarCurrArea;
mov edx, _carCurrentArea;
mov eax, ForceEncounterMapID;
call wmMatchAreaContainingMapIdx_;
noCar:
@@ -202,6 +202,10 @@ fail:
}
}
static void mf_set_car_intface_art() {
Worldmap_SetCarInterfaceArt(opHandler.arg(0).rawValue());
}
static void mf_set_map_enter_position() {
int tile = opHandler.arg(0).rawValue();
int elev = opHandler.arg(1).rawValue();
+2 -2
View File
@@ -267,7 +267,7 @@ void __stdcall SetSkillMax(TGameObj* critter, int maximum) {
return;
}
long id = SetObjectUniqueID(critter);
long id = Objects_SetObjectUniqueID(critter);
for (DWORD i = 0; i < skillMaxMods.size(); i++) {
if (id == skillMaxMods[i].id) {
skillMaxMods[i].maximum = maximum;
@@ -288,7 +288,7 @@ void __stdcall SetPickpocketMax(TGameObj* critter, DWORD maximum, DWORD mod) {
return;
}
long id = SetObjectUniqueID(critter);
long id = Objects_SetObjectUniqueID(critter);
for (DWORD i = 0; i < pickpocketMods.size(); i++) {
if (id == pickpocketMods[i].id) {
pickpocketMods[i].maximum = maximum;
+3 -3
View File
@@ -18,9 +18,9 @@
#pragma once
void __stdcall SetPickpocketMax(TGameObj* critter, DWORD maximum, DWORD mod);
void __stdcall SetSkillMax(TGameObj* critter, int maximum);
void SkillsInit();
void SkillsExit();
void Skills_OnGameLoad();
void __stdcall SetSkillMax(TGameObj* critter, int maximum);
void __stdcall SetPickpocketMax(TGameObj* critter, DWORD maximum, DWORD mod);

Some files were not shown because too many files have changed in this diff Show More