mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added displaying the NPC's addictions in the character screen when controlled by the player (from Mr.Stalin)
Added "npc_engine_level_up" script function. Moved the code of set_map_time_multi to Worldmap handler, and NPCAutoLevel to PartyControl module. Removed validate_test example function from release builds.
This commit is contained in:
@@ -270,6 +270,7 @@
|
||||
#define item_weight(obj) sfall_func1("item_weight", obj)
|
||||
#define lock_is_jammed(obj) sfall_func1("lock_is_jammed", obj)
|
||||
#define loot_obj sfall_func0("loot_obj")
|
||||
#define npc_engine_level_up(toggle) sfall_func1("npc_engine_level_up", toggle)
|
||||
#define obj_under_cursor(crSwitch, inclDude) sfall_func2("obj_under_cursor", crSwitch, inclDude)
|
||||
#define outlined_object sfall_func0("outlined_object")
|
||||
#define real_dude_obj sfall_func0("real_dude_obj")
|
||||
|
||||
@@ -569,6 +569,10 @@ Some utility/math functions are available:
|
||||
> void sfall_func0("art_cache_clear")
|
||||
- clears the cache of FRM image files loaded into memory
|
||||
|
||||
> void sfall_func1("npc_engine_level_up", bool toggle)
|
||||
- enables/disables the engine function that increases the level of party members in the player leveling process
|
||||
- if the engine function is disabled, the process of leveling up party members should be performed by script functions
|
||||
|
||||
------------------------
|
||||
------ MORE INFO -------
|
||||
------------------------
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <cassert>
|
||||
|
||||
#include "Functions.h"
|
||||
#include "FunctionOffsets.h"
|
||||
#include "Structs.h"
|
||||
#include "Variables.h"
|
||||
#include "VariableOffsets.h"
|
||||
@@ -107,20 +108,29 @@ bool HeroIsFemale() {
|
||||
return (fo::func::stat_level(fo::var::obj_dude, fo::Stat::STAT_gender) == fo::Gender::GENDER_FEMALE);
|
||||
}
|
||||
|
||||
long CheckAddictByPid(fo::GameObject* critter, long pid) {
|
||||
__asm {
|
||||
mov eax, pid;
|
||||
mov esi, critter;
|
||||
call fo::funcoffs::item_d_check_addict_;
|
||||
}
|
||||
/* keyword 'return' is not needed, the compiler will do everything correctly */
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
//print text to surface
|
||||
void PrintText(char *DisplayText, BYTE ColourIndex, DWORD Xpos, DWORD Ypos, DWORD TxtWidth, DWORD ToWidth, BYTE *ToSurface) {
|
||||
DWORD posOffset = Ypos * ToWidth + Xpos;
|
||||
__asm {
|
||||
xor eax, eax
|
||||
mov al, ColourIndex
|
||||
push eax
|
||||
mov edx, DisplayText
|
||||
mov ebx, TxtWidth
|
||||
mov ecx, ToWidth
|
||||
mov eax, ToSurface
|
||||
add eax, posOffset
|
||||
call dword ptr ds:[FO_VAR_text_to_buf]
|
||||
xor eax, eax;
|
||||
mov al, ColourIndex;
|
||||
push eax;
|
||||
mov edx, DisplayText;
|
||||
mov ebx, TxtWidth;
|
||||
mov ecx, ToWidth;
|
||||
mov eax, ToSurface;
|
||||
add eax, posOffset;
|
||||
call dword ptr ds:[FO_VAR_text_to_buf];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,8 +139,8 @@ void PrintText(char *DisplayText, BYTE ColourIndex, DWORD Xpos, DWORD Ypos, DWOR
|
||||
DWORD GetTextHeight() {
|
||||
DWORD TxtHeight;
|
||||
__asm {
|
||||
call dword ptr ds:[FO_VAR_text_height] //get text height
|
||||
mov TxtHeight, eax
|
||||
call dword ptr ds:[FO_VAR_text_height]; //get text height
|
||||
mov TxtHeight, eax;
|
||||
}
|
||||
return TxtHeight;
|
||||
}
|
||||
@@ -140,9 +150,9 @@ DWORD GetTextHeight() {
|
||||
DWORD GetTextWidth(char *TextMsg) {
|
||||
DWORD TxtWidth;
|
||||
__asm {
|
||||
mov eax, TextMsg
|
||||
call dword ptr ds:[FO_VAR_text_width] //get text width
|
||||
mov TxtWidth, eax
|
||||
mov eax, TextMsg;
|
||||
call dword ptr ds:[FO_VAR_text_width]; //get text width
|
||||
mov TxtWidth, eax;
|
||||
}
|
||||
return TxtWidth;
|
||||
}
|
||||
@@ -152,9 +162,9 @@ DWORD GetTextWidth(char *TextMsg) {
|
||||
DWORD GetCharWidth(char CharVal) {
|
||||
DWORD charWidth;
|
||||
__asm {
|
||||
mov al, CharVal
|
||||
call dword ptr ds:[FO_VAR_text_char_width]
|
||||
mov charWidth, eax
|
||||
mov al, CharVal;
|
||||
call dword ptr ds:[FO_VAR_text_char_width];
|
||||
mov charWidth, eax;
|
||||
}
|
||||
return charWidth;
|
||||
}
|
||||
@@ -164,9 +174,9 @@ DWORD GetCharWidth(char CharVal) {
|
||||
DWORD GetMaxTextWidth(char *TextMsg) {
|
||||
DWORD msgWidth;
|
||||
__asm {
|
||||
mov eax, TextMsg
|
||||
call dword ptr ds:[FO_VAR_text_mono_width]
|
||||
mov msgWidth, eax
|
||||
mov eax, TextMsg;
|
||||
call dword ptr ds:[FO_VAR_text_mono_width];
|
||||
mov msgWidth, eax;
|
||||
}
|
||||
return msgWidth;
|
||||
}
|
||||
@@ -176,8 +186,8 @@ DWORD GetMaxTextWidth(char *TextMsg) {
|
||||
DWORD GetCharGapWidth() {
|
||||
DWORD gapWidth;
|
||||
__asm {
|
||||
call dword ptr ds:[FO_VAR_text_spacing]
|
||||
mov gapWidth, eax
|
||||
call dword ptr ds:[FO_VAR_text_spacing];
|
||||
mov gapWidth, eax;
|
||||
}
|
||||
return gapWidth;
|
||||
}
|
||||
@@ -187,8 +197,8 @@ DWORD GetCharGapWidth() {
|
||||
DWORD GetMaxCharWidth() {
|
||||
DWORD charWidth = 0;
|
||||
__asm {
|
||||
call dword ptr ds:[FO_VAR_text_max]
|
||||
mov charWidth, eax
|
||||
call dword ptr ds:[FO_VAR_text_max];
|
||||
mov charWidth, eax;
|
||||
}
|
||||
return charWidth;
|
||||
}
|
||||
|
||||
@@ -60,6 +60,8 @@ GameObject* GetActiveItem();
|
||||
|
||||
bool HeroIsFemale();
|
||||
|
||||
long CheckAddictByPid(fo::GameObject* critter, long pid);
|
||||
|
||||
// Print text to surface
|
||||
void PrintText(char *displayText, BYTE colorIndex, DWORD x, DWORD y, DWORD textWidth, DWORD destWidth, BYTE *surface);
|
||||
// gets the height of the currently selected font
|
||||
|
||||
@@ -709,4 +709,11 @@ struct Queue {
|
||||
Queue* next;
|
||||
};
|
||||
|
||||
#pragma pack(1)
|
||||
struct DrugInfoList {
|
||||
DWORD itemPid;
|
||||
long addictGvar;
|
||||
long numEffects;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ VAR_(dialogue_switch_mode, DWORD)
|
||||
VAR_(dialog_target, DWORD)
|
||||
VAR_(dialog_target_is_party, DWORD)
|
||||
VAR_(dropped_explosive, DWORD)
|
||||
VAR_(drugInfoList, DWORD)
|
||||
VARA(drugInfoList, DrugInfoList, 9)
|
||||
VAR_(edit_win, DWORD)
|
||||
VAR_(Educated, DWORD)
|
||||
VAR_(elevation, DWORD)
|
||||
|
||||
@@ -39,8 +39,6 @@ static char versionString[65];
|
||||
|
||||
static int* scriptDialog = nullptr;
|
||||
|
||||
bool npcAutoLevelEnabled;
|
||||
|
||||
static const DWORD PutAwayWeapon[] = {
|
||||
0x411EA2, // action_climb_ladder_
|
||||
0x412046, // action_use_an_item_on_object_
|
||||
@@ -467,15 +465,6 @@ static const DWORD EncounterTableSize[] = {
|
||||
0x4C0815, 0x4C0D4A, 0x4C0FD4,
|
||||
};
|
||||
|
||||
void NpcAutoLevelPatch() {
|
||||
npcAutoLevelEnabled = GetConfigInt("Misc", "NPCAutoLevel", 0) != 0;
|
||||
if (npcAutoLevelEnabled) {
|
||||
dlog("Applying NPC autolevel patch.", DL_INIT);
|
||||
SafeWrite8(0x495CFB, 0xEB); // jmps 0x495D28 (skip random check)
|
||||
dlogr(" Done", DL_INIT);
|
||||
}
|
||||
}
|
||||
|
||||
void AdditionalWeaponAnimsPatch() {
|
||||
if (GetConfigInt("Misc", "AdditionalWeaponAnims", 0)) {
|
||||
dlog("Applying additional weapon animations patch.", DL_INIT);
|
||||
@@ -924,7 +913,6 @@ void MiscPatches::init() {
|
||||
LoadGameHook::OnBeforeGameStart() += BodypartHitChances; // set on start & load
|
||||
|
||||
CombatProcFix();
|
||||
NpcAutoLevelPatch();
|
||||
DialogueFix();
|
||||
AdditionalWeaponAnimsPatch();
|
||||
MultiPatchesPatch();
|
||||
|
||||
@@ -35,9 +35,5 @@ struct CodeData {
|
||||
BYTE db = 0x90;
|
||||
};
|
||||
|
||||
extern bool npcAutoLevelEnabled;
|
||||
|
||||
void _stdcall SetMapMulti(float d);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,9 @@
|
||||
namespace sfall
|
||||
{
|
||||
|
||||
bool npcAutoLevelEnabled;
|
||||
bool npcEngineLevelUp = true;
|
||||
|
||||
bool isControllingNPC = false;
|
||||
bool skipCounterAnim = false;
|
||||
|
||||
@@ -54,8 +57,7 @@ static struct DudeState {
|
||||
DWORD itemCurrentItem;
|
||||
fo::ItemButtonItem itemButtonItems[2];
|
||||
long perkLevelDataList[fo::PERK_count];
|
||||
//DWORD drug_gvar[6];
|
||||
//DWORD jet_gvar;
|
||||
long addictGvar[8];
|
||||
long tag_skill[4];
|
||||
//DWORD bbox_sneak;
|
||||
} realDude;
|
||||
@@ -78,6 +80,10 @@ static void SaveRealDudeState() {
|
||||
realDude.sneak_working = fo::var::sneak_working;
|
||||
fo::SkillGetTags(realDude.tag_skill, 4);
|
||||
|
||||
for (int i = 0; i < 6; i++) realDude.addictGvar[i] = fo::var::game_global_vars[fo::var::drugInfoList[i].addictGvar];
|
||||
realDude.addictGvar[6] = fo::var::game_global_vars[fo::var::drugInfoList[7].addictGvar];
|
||||
realDude.addictGvar[7] = fo::var::game_global_vars[fo::var::drugInfoList[8].addictGvar];
|
||||
|
||||
if (skipCounterAnim) SafeWriteBatch<BYTE>(0, {0x422BDE, 0x4229EC}); // no animate
|
||||
}
|
||||
|
||||
@@ -121,6 +127,17 @@ static void SetCurrentDude(fo::GameObject* npc) {
|
||||
fo::var::itemCurrentItem = 1;
|
||||
}
|
||||
|
||||
long alcoholAddict = 0;
|
||||
for (int i = 0; i < 9; i++) {
|
||||
long result = fo::CheckAddictByPid(npc, fo::var::drugInfoList[i].itemPid);
|
||||
if (i == 6) {
|
||||
alcoholAddict = result;
|
||||
} else if (i == 7) {
|
||||
result |= alcoholAddict;
|
||||
}
|
||||
fo::var::game_global_vars[fo::var::drugInfoList[i].addictGvar] = result;
|
||||
}
|
||||
|
||||
// switch main dude_obj pointers - this should be done last!
|
||||
fo::var::obj_dude = npc;
|
||||
fo::var::inven_dude = npc;
|
||||
@@ -160,6 +177,10 @@ static void RestoreRealDudeState() {
|
||||
fo::func::stat_pc_add_experience(delayedExperience);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 6; i++) fo::var::game_global_vars[fo::var::drugInfoList[i].addictGvar] = realDude.addictGvar[i];
|
||||
fo::var::game_global_vars[fo::var::drugInfoList[7].addictGvar] = realDude.addictGvar[6];
|
||||
fo::var::game_global_vars[fo::var::drugInfoList[8].addictGvar] = realDude.addictGvar[7];
|
||||
|
||||
if (skipCounterAnim) SafeWriteBatch<BYTE>(1, {0x422BDE, 0x4229EC}); // restore
|
||||
fo::func::intface_redraw();
|
||||
|
||||
@@ -279,12 +300,28 @@ static void __declspec(naked) gdControlUpdateInfo_hook() {
|
||||
}
|
||||
}
|
||||
|
||||
void PartyControl::init() {
|
||||
LoadGameHook::OnGameReset() += PartyControlReset;
|
||||
static void NpcAutoLevelPatch() {
|
||||
npcAutoLevelEnabled = GetConfigInt("Misc", "NPCAutoLevel", 0) != 0;
|
||||
if (npcAutoLevelEnabled) {
|
||||
dlog("Applying NPC autolevel patch.", DL_INIT);
|
||||
SafeWrite8(0x495CFB, 0xEB); // jmps 0x495D28 (skip random check)
|
||||
dlogr(" Done", DL_INIT);
|
||||
}
|
||||
}
|
||||
|
||||
void PartyControl::init() {
|
||||
LoadGameHook::OnGameReset() += []() {
|
||||
PartyControlReset();
|
||||
if (!npcEngineLevelUp) {
|
||||
npcEngineLevelUp = true;
|
||||
SafeWrite16(0x4AFC1C, 0x840F);
|
||||
}
|
||||
};
|
||||
HookCall(0x454218, stat_pc_add_experience_hook); // call inside op_give_exp_points_hook
|
||||
HookCalls(pc_flag_toggle_hook, { 0x4124F1, 0x41279A });
|
||||
|
||||
NpcAutoLevelPatch();
|
||||
|
||||
skipCounterAnim = (GetConfigInt("Misc", "SpeedInterfaceCounterAnims", 0) == 3);
|
||||
|
||||
// display party member's current level & AC & addict flag
|
||||
|
||||
@@ -39,5 +39,7 @@ public:
|
||||
};
|
||||
|
||||
extern bool isControllingNPC;
|
||||
extern bool npcAutoLevelEnabled;
|
||||
extern bool npcEngineLevelUp;
|
||||
|
||||
}
|
||||
|
||||
@@ -110,6 +110,7 @@ static const SfallMetarule metarules[] = {
|
||||
{"item_weight", sf_item_weight, 1, 1, {ARG_OBJECT}},
|
||||
{"lock_is_jammed", sf_lock_is_jammed, 1, 1, {ARG_OBJECT}},
|
||||
{"loot_obj", sf_get_loot_object, 0, 0},
|
||||
{"npc_engine_level_up", sf_npc_engine_level_up, 1, 1, {ARG_ANY}},
|
||||
{"obj_under_cursor", sf_get_obj_under_cursor, 2, 2, {ARG_INT, ARG_INT}},
|
||||
{"outlined_object", sf_outlined_object, 0, 0},
|
||||
{"real_dude_obj", sf_real_dude_obj, 0, 0},
|
||||
@@ -129,38 +130,11 @@ static const SfallMetarule metarules[] = {
|
||||
{"spatial_radius", sf_spatial_radius, 1, 1, {ARG_OBJECT}},
|
||||
{"tile_refresh_display", sf_tile_refresh_display, 0, 0},
|
||||
{"unjam_lock", sf_unjam_lock, 1, 1, {ARG_OBJECT}},
|
||||
#ifndef NDEBUG
|
||||
{"validate_test", sf_test, 2, 5, {ARG_INT, ARG_NUMBER, ARG_STRING, ARG_OBJECT, ARG_ANY}},
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
static std::string sf_test_stringBuf;
|
||||
void sf_test(OpcodeContext& ctx) {
|
||||
std::ostringstream sstream;
|
||||
sstream << "sfall_funcX(\"test\"";
|
||||
for (int i = 0; i < ctx.numArgs(); i++) {
|
||||
const ScriptValue &arg = ctx.arg(i);
|
||||
sstream << ", ";
|
||||
switch (arg.type()) {
|
||||
case DataType::INT:
|
||||
sstream << arg.asInt();
|
||||
break;
|
||||
case DataType::FLOAT:
|
||||
sstream << arg.asFloat();
|
||||
break;
|
||||
case DataType::STR:
|
||||
sstream << '"' << arg.asString() << '"';
|
||||
break;
|
||||
default:
|
||||
sstream << "???";
|
||||
break;
|
||||
}
|
||||
}
|
||||
sstream << ")";
|
||||
|
||||
sf_test_stringBuf = sstream.str();
|
||||
ctx.setReturn(sf_test_stringBuf.c_str());
|
||||
}
|
||||
|
||||
// returns current contents of metarule table
|
||||
static void sf_get_metarule_table(OpcodeContext& ctx) {
|
||||
DWORD arrId = TempArray(metaruleTable.size(), 0);
|
||||
@@ -219,5 +193,35 @@ void HandleMetarule(OpcodeContext& ctx) {
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
static std::string sf_test_stringBuf;
|
||||
void sf_test(OpcodeContext& ctx) {
|
||||
std::ostringstream sstream;
|
||||
sstream << "sfall_funcX(\"test\"";
|
||||
for (int i = 0; i < ctx.numArgs(); i++) {
|
||||
const ScriptValue &arg = ctx.arg(i);
|
||||
sstream << ", ";
|
||||
switch (arg.type()) {
|
||||
case DataType::INT:
|
||||
sstream << arg.asInt();
|
||||
break;
|
||||
case DataType::FLOAT:
|
||||
sstream << arg.asFloat();
|
||||
break;
|
||||
case DataType::STR:
|
||||
sstream << '"' << arg.asString() << '"';
|
||||
break;
|
||||
default:
|
||||
sstream << "???";
|
||||
break;
|
||||
}
|
||||
}
|
||||
sstream << ")";
|
||||
|
||||
sf_test_stringBuf = sstream.str();
|
||||
ctx.setReturn(sf_test_stringBuf.c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,9 @@ namespace script
|
||||
{
|
||||
|
||||
// Example handler. Feel free to add handlers in other files.
|
||||
#ifndef NDEBUG
|
||||
void sf_test(OpcodeContext&);
|
||||
#endif
|
||||
|
||||
// returns current contents of metarule table
|
||||
void sf_get_metarule_table(OpcodeContext&);
|
||||
|
||||
@@ -25,9 +25,10 @@
|
||||
#include "..\..\HeroAppearance.h"
|
||||
#include "..\..\Inventory.h"
|
||||
#include "..\..\KillCounter.h"
|
||||
#include "..\..\MiscPatches.h"
|
||||
//#include "..\..\MiscPatches.h"
|
||||
#include "..\..\Movies.h"
|
||||
#include "..\..\Objects.h"
|
||||
#include "..\..\PartyControl.h"
|
||||
#include "..\..\PlayerModel.h"
|
||||
#include "..\..\ScriptExtender.h"
|
||||
#include "..\..\Stats.h"
|
||||
@@ -201,36 +202,6 @@ void __declspec(naked) op_game_loaded() {
|
||||
}
|
||||
}
|
||||
|
||||
void __declspec(naked) op_set_map_time_multi() {
|
||||
__asm {
|
||||
push ebx;
|
||||
push ecx;
|
||||
push edx;
|
||||
mov ecx, eax;
|
||||
call fo::funcoffs::interpretPopShort_;
|
||||
mov edx, eax;
|
||||
mov eax, ecx;
|
||||
call fo::funcoffs::interpretPopLong_;
|
||||
cmp dx, VAR_TYPE_FLOAT;
|
||||
jz paramWasFloat;
|
||||
cmp dx, VAR_TYPE_INT;
|
||||
jnz fail;
|
||||
push eax;
|
||||
fild dword ptr [esp];
|
||||
fstp dword ptr [esp];
|
||||
jmp end;
|
||||
paramWasFloat:
|
||||
push eax;
|
||||
end:
|
||||
call SetMapMulti;
|
||||
fail:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
pop ebx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
void __declspec(naked) op_set_pipboy_available() {
|
||||
__asm {
|
||||
push ebx;
|
||||
@@ -1646,5 +1617,15 @@ void sf_get_ini_section(OpcodeContext& ctx) {
|
||||
ctx.setReturn(arrayId);
|
||||
}
|
||||
|
||||
void sf_npc_engine_level_up(OpcodeContext& ctx) {
|
||||
if (ctx.arg(0).asBool()) {
|
||||
if (!npcEngineLevelUp) SafeWrite16(0x4AFC1C, 0x840F); // enable
|
||||
npcEngineLevelUp = true;
|
||||
} else {
|
||||
if (npcEngineLevelUp) SafeWrite16(0x4AFC1C, 0xE990);
|
||||
npcEngineLevelUp = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,8 +41,6 @@ void sf_get_year(OpcodeContext&);
|
||||
|
||||
void __declspec() op_game_loaded();
|
||||
|
||||
void __declspec() op_set_map_time_multi();
|
||||
|
||||
void __declspec() op_set_pipboy_available();
|
||||
|
||||
// Kill counters
|
||||
@@ -165,5 +163,7 @@ void sf_get_ini_sections(OpcodeContext&);
|
||||
|
||||
void sf_get_ini_section(OpcodeContext&);
|
||||
|
||||
void sf_npc_engine_level_up(OpcodeContext&);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,6 +227,36 @@ end:
|
||||
}
|
||||
}
|
||||
|
||||
void __declspec(naked) op_set_map_time_multi() {
|
||||
__asm {
|
||||
push ebx;
|
||||
push ecx;
|
||||
push edx;
|
||||
mov ecx, eax;
|
||||
call fo::funcoffs::interpretPopShort_;
|
||||
mov edx, eax;
|
||||
mov eax, ecx;
|
||||
call fo::funcoffs::interpretPopLong_;
|
||||
cmp dx, VAR_TYPE_FLOAT;
|
||||
jz paramWasFloat;
|
||||
cmp dx, VAR_TYPE_INT;
|
||||
jnz fail;
|
||||
push eax;
|
||||
fild dword ptr [esp];
|
||||
fstp dword ptr [esp];
|
||||
jmp end;
|
||||
paramWasFloat:
|
||||
push eax;
|
||||
end:
|
||||
call SetMapMulti;
|
||||
fail:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
pop ebx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
void sf_set_car_intface_art(OpcodeContext& ctx) {
|
||||
Worldmap::SetCarInterfaceArt(ctx.arg(0).asInt());
|
||||
}
|
||||
|
||||
@@ -40,6 +40,8 @@ void __declspec() op_get_world_map_y_pos();
|
||||
|
||||
void __declspec() op_set_world_map_pos();
|
||||
|
||||
void __declspec() op_set_map_time_multi();
|
||||
|
||||
void sf_set_car_intface_art(OpcodeContext&);
|
||||
|
||||
void sf_set_map_enter_position(OpcodeContext&);
|
||||
|
||||
@@ -44,4 +44,6 @@ public:
|
||||
static void SetAddedYears(DWORD years);
|
||||
};
|
||||
|
||||
void _stdcall SetMapMulti(float d);
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user