mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Some code/document edits
This commit is contained in:
@@ -132,7 +132,7 @@ int arg1 - The pid of the weapon performing the attack. (May be -1 if the at
|
||||
critter arg2 - The attacker
|
||||
critter arg3 - The target
|
||||
int arg4 - The amount of damage
|
||||
int arg5 - Unused, always -1 (since sfall 4.1)
|
||||
int arg5 - Unused, always -1. Use this if you are using the same procedure for HOOK_DEATHANIM1 and HOOK_DEATHANIM2 (since sfall 4.1/3.8.24)
|
||||
|
||||
int ret1 - The pid of an object to override the attacking weapon with
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ has_fake_trait and has_fake_perk return the number of levels the player has of t
|
||||
|
||||
perk_add_mode, set_selectable_perk, set_perkbox_title, hide_real_perks, show_real_perks and clear_selectable_perks control the behaviour of the select a perk box. set_selectable_perk can be used to add additional items by setting the 'active' parameter to 1, and to remove them again by setting it to 0. set_perkbox_title can be used to change the title of the box, or by using "" it will be set back to the default. hide and show_real_perks can be used to prevent the dialog from displaying any of the original 119 perks. perk_add_mode modifies what happens when a fake perk is selected from the perks dialog. It is treated as a set of flags - if bit 1 is set then it is added to the player's traits, if bit 2 is set it is added to the player's perks, and if bit 3 is set it is removed from the list of selectable perks. The default is 0x2. clear_selectable_perks restores the dialog to its default state.
|
||||
|
||||
show_iface_tag, hide_iface_tag and is_iface_tag_active relate to the boxes that appear above the interface such as SNEAK and LEVEL. You can use 3 for LEVEL and 4 for ADDICT, or the range from 5 to (4 + the value of BoxBarCount in ddraw.ini) for custom boxes. Remember to add your messages to intrface.msg and set up the font colours in ddraw.ini if you're going to use custom boxes. Starting from sfall 4.1, is_iface_tag_active can also be used to check 0 for SNEAK, 1 for POISONED, and 2 for RADIATED.
|
||||
show_iface_tag, hide_iface_tag and is_iface_tag_active relate to the boxes that appear above the interface such as SNEAK and LEVEL. You can use 3 for LEVEL and 4 for ADDICT, or the range from 5 to (4 + the value of BoxBarCount in ddraw.ini) for custom boxes. Remember to add your messages to intrface.msg and set up the font colours in ddraw.ini if you're going to use custom boxes. Starting from sfall 4.1/3.8.12, is_iface_tag_active can also be used to check 0 for SNEAK, 1 for POISONED, and 2 for RADIATED.
|
||||
|
||||
get/set_bodypart_hit_modifier alter the hit percentage modifiers for aiming at specific bodyparts. Valid bodypart id's are from 0 to 8. Changes are not saved, and will reset to the defaults (or to the values specified in ddraw.ini if they exist) at each reload.
|
||||
|
||||
|
||||
@@ -411,7 +411,7 @@ void DebugEditor::init() {
|
||||
debugEditorKey = GetConfigInt("Input", "DebugEditorKey", 0);
|
||||
if (debugEditorKey != 0) {
|
||||
OnKeyPressed() += [](DWORD scanCode, bool pressed) {
|
||||
if (scanCode == debugEditorKey && pressed && IsMapLoaded()) {
|
||||
if (scanCode == debugEditorKey && pressed && IsGameLoaded()) {
|
||||
RunDebugEditor();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -41,9 +41,9 @@ void SavePageOffsets() {
|
||||
sprintf_s(SavePath, MAX_PATH, filename, fo::var::patches);
|
||||
|
||||
_itoa_s(fo::var::slot_cursor, buffer, 10);
|
||||
WritePrivateProfileString("POSITION", "ListNum", buffer, SavePath);
|
||||
WritePrivateProfileStringA("POSITION", "ListNum", buffer, SavePath);
|
||||
_itoa_s(LSPageOffset, buffer, 10);
|
||||
WritePrivateProfileString("POSITION", "PageOffset", buffer, SavePath);
|
||||
WritePrivateProfileStringA("POSITION", "PageOffset", buffer, SavePath);
|
||||
}
|
||||
|
||||
//------------------------------------------
|
||||
|
||||
@@ -101,7 +101,7 @@ DWORD initingHookScripts;
|
||||
|
||||
// BEGIN HOOKS
|
||||
void HookScripts::KeyPressHook(DWORD* dxKey, bool pressed, DWORD vKey) {
|
||||
if (!IsMapLoaded() || !HookHasScript(HOOK_KEYPRESS)) {
|
||||
if (!IsGameLoaded() || !HookHasScript(HOOK_KEYPRESS)) {
|
||||
return;
|
||||
}
|
||||
BeginHook();
|
||||
@@ -115,7 +115,7 @@ void HookScripts::KeyPressHook(DWORD* dxKey, bool pressed, DWORD vKey) {
|
||||
}
|
||||
|
||||
void _stdcall MouseClickHook(DWORD button, bool pressed) {
|
||||
if (!IsMapLoaded() || !HookScripts::HookHasScript(HOOK_MOUSECLICK)) {
|
||||
if (!IsGameLoaded() || !HookScripts::HookHasScript(HOOK_MOUSECLICK)) {
|
||||
return;
|
||||
}
|
||||
BeginHook();
|
||||
|
||||
@@ -371,7 +371,7 @@ static void __declspec(naked) CarTravelHack() {
|
||||
static long __fastcall GlobalVarHook_Script(register DWORD number, register int value) {
|
||||
int old = fo::var::game_global_vars[number];
|
||||
|
||||
if (IsMapLoaded() && HookScripts::HookHasScript(HOOK_SETGLOBALVAR)) { // IsMapLoaded - don't execute hook until loading sfall scripts
|
||||
if (IsGameLoaded() && HookScripts::HookHasScript(HOOK_SETGLOBALVAR)) { // IsGameLoaded - don't execute hook until loading sfall scripts
|
||||
BeginHook();
|
||||
argCount = 2;
|
||||
args[0] = number;
|
||||
|
||||
@@ -39,7 +39,7 @@ static DWORD itemFastMoveKey = 0;
|
||||
static DWORD skipFromContainer = 0;
|
||||
|
||||
void InventoryKeyPressedHook(DWORD dxKey, bool pressed) {
|
||||
if (pressed && reloadWeaponKey && dxKey == reloadWeaponKey && IsMapLoaded() && (GetLoopFlags() & ~(COMBAT | PCOMBAT)) == 0) {
|
||||
if (pressed && reloadWeaponKey && dxKey == reloadWeaponKey && IsGameLoaded() && (GetLoopFlags() & ~(COMBAT | PCOMBAT)) == 0) {
|
||||
DWORD maxAmmo, curAmmo;
|
||||
fo::GameObject* item = fo::GetActiveItem();
|
||||
maxAmmo = fo::func::item_w_max_ammo(item);
|
||||
|
||||
@@ -70,10 +70,11 @@ static DWORD inLoop = 0;
|
||||
static DWORD saveInCombatFix;
|
||||
static bool disableHorrigan = false;
|
||||
static bool pipBoyAvailableAtGameStart = false;
|
||||
static bool mapLoaded = false;
|
||||
static bool gameLoaded = false;
|
||||
|
||||
bool IsMapLoaded() {
|
||||
return mapLoaded;
|
||||
// True if game was started, false when on the main menu
|
||||
bool IsGameLoaded() {
|
||||
return gameLoaded;
|
||||
}
|
||||
|
||||
DWORD InWorldMap() {
|
||||
@@ -260,7 +261,7 @@ errorLoad:
|
||||
|
||||
// called whenever game is being reset (prior to loading a save or when returning to main menu)
|
||||
static bool _stdcall GameReset(DWORD isGameLoad) {
|
||||
if (mapLoaded) { // prevent resetting when a new game has not been started (loading saved game from main menu)
|
||||
if (gameLoaded) { // prevent resetting when a new game has not been started (loading saved game from main menu)
|
||||
onGameReset.invoke();
|
||||
if (isDebug) {
|
||||
char* str = (isGameLoad) ? "on Load" : "on Exit";
|
||||
@@ -268,7 +269,7 @@ static bool _stdcall GameReset(DWORD isGameLoad) {
|
||||
}
|
||||
}
|
||||
inLoop = 0;
|
||||
mapLoaded = false;
|
||||
gameLoaded = false;
|
||||
|
||||
return (isGameLoad) ? LoadGame_Before() : false;
|
||||
}
|
||||
@@ -276,7 +277,7 @@ static bool _stdcall GameReset(DWORD isGameLoad) {
|
||||
// Called after game was loaded from a save
|
||||
static void _stdcall LoadGame_After() {
|
||||
onAfterGameStarted.invoke();
|
||||
mapLoaded = true;
|
||||
gameLoaded = true;
|
||||
}
|
||||
|
||||
static void __declspec(naked) LoadGame_hook() {
|
||||
@@ -318,7 +319,7 @@ static void __stdcall NewGame_After() {
|
||||
|
||||
dlogr("New Game started.", DL_MAIN);
|
||||
|
||||
mapLoaded = true;
|
||||
gameLoaded = true;
|
||||
}
|
||||
|
||||
static void __declspec(naked) main_load_new_hook() {
|
||||
@@ -718,8 +719,8 @@ void LoadGameHook::init() {
|
||||
SafeWrite32(0x5194C0, (DWORD)&EndLoadHook);
|
||||
HookCalls(SaveGame_hook, {0x443AAC, 0x443B1C, 0x48FCFF});
|
||||
HookCalls(game_reset_hook, {
|
||||
0x47DD6B, // LoadSlot_ (on error)
|
||||
0x47DDF3, // LoadSlot_ (on error)
|
||||
0x47DD6B, // LoadSlot_ (on load error)
|
||||
0x47DDF3, // LoadSlot_ (on load error)
|
||||
//0x480708, // RestoreLoad_ (never called)
|
||||
0x480AD3, // gnw_main_ (game ended after playing via New Game)
|
||||
0x480BCC, // gnw_main_ (game ended after playing via Load Game)
|
||||
|
||||
@@ -62,8 +62,8 @@ public:
|
||||
static DWORD LootTarget;
|
||||
};
|
||||
|
||||
// True if some map was loaded, false when on the main menu
|
||||
bool IsMapLoaded();
|
||||
// True if game was started, false when on the main menu
|
||||
bool IsGameLoaded();
|
||||
|
||||
DWORD InWorldMap();
|
||||
|
||||
|
||||
@@ -622,7 +622,7 @@ static void RunGlobalScriptsOnMainLoop() {
|
||||
}
|
||||
|
||||
static void RunGlobalScriptsOnInput() {
|
||||
if (IsMapLoaded()) {
|
||||
if (IsGameLoaded()) {
|
||||
RunGlobalScripts(1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +80,8 @@ void __declspec(naked) op_get_mouse_y() {
|
||||
}
|
||||
}
|
||||
|
||||
#define MOUSE_MIDDLE_BTN (4)
|
||||
enum { MOUSE_MIDDLE_BTN = 4 };
|
||||
|
||||
void sf_get_mouse_buttons(OpcodeContext& ctx) {
|
||||
DWORD button = fo::var::last_buttons;
|
||||
if (button == 0 && middleMouseDown) {
|
||||
|
||||
@@ -99,11 +99,7 @@ error:
|
||||
void __declspec(naked) op_write_byte() {
|
||||
__asm {
|
||||
push ecx;
|
||||
call fo::funcoffs::interpretPopShort_;
|
||||
mov ecx, eax; // type
|
||||
mov eax, ebx;
|
||||
call fo::funcoffs::interpretPopLong_;
|
||||
mov esi, eax; // write value
|
||||
_GET_ARG(esi, ecx); // write value
|
||||
mov eax, ebx;
|
||||
_GET_ARG_INT(end);
|
||||
cmp cx, VAR_TYPE_INT;
|
||||
@@ -129,11 +125,7 @@ end:
|
||||
void __declspec(naked) op_write_short() {
|
||||
__asm {
|
||||
push ecx;
|
||||
call fo::funcoffs::interpretPopShort_;
|
||||
mov ecx, eax; // type
|
||||
mov eax, ebx;
|
||||
call fo::funcoffs::interpretPopLong_;
|
||||
mov esi, eax; // write value
|
||||
_GET_ARG(esi, ecx); // write value
|
||||
mov eax, ebx;
|
||||
_GET_ARG_INT(end);
|
||||
cmp cx, VAR_TYPE_INT;
|
||||
@@ -159,11 +151,7 @@ end:
|
||||
void __declspec(naked) op_write_int() {
|
||||
__asm {
|
||||
push ecx;
|
||||
call fo::funcoffs::interpretPopShort_;
|
||||
mov ecx, eax; // type
|
||||
mov eax, ebx;
|
||||
call fo::funcoffs::interpretPopLong_;
|
||||
mov esi, eax; // write value
|
||||
_GET_ARG(esi, ecx); // write value
|
||||
mov eax, ebx;
|
||||
_GET_ARG_INT(end);
|
||||
cmp cx, VAR_TYPE_INT;
|
||||
@@ -197,11 +185,7 @@ static void __fastcall WriteStringInternal(char* addr, long type, long strID, fo
|
||||
void __declspec(naked) op_write_string() {
|
||||
__asm {
|
||||
push ecx;
|
||||
call fo::funcoffs::interpretPopShort_;
|
||||
mov ecx, eax; // type
|
||||
mov eax, ebx;
|
||||
call fo::funcoffs::interpretPopLong_;
|
||||
mov esi, eax; // str value
|
||||
_GET_ARG(esi, ecx); // str value
|
||||
mov eax, ebx;
|
||||
_GET_ARG_INT(end);
|
||||
cmp cx, VAR_TYPE_STR2;
|
||||
|
||||
@@ -819,7 +819,7 @@ void sf_set_ini_setting(OpcodeContext& ctx) {
|
||||
char section[33], file[128];
|
||||
int result = ParseIniSetting(ctx.arg(0).strValue(), key, section, file);
|
||||
if (result > 0) {
|
||||
result = WritePrivateProfileString(section, key, saveValue, file);
|
||||
result = WritePrivateProfileStringA(section, key, saveValue, file);
|
||||
}
|
||||
|
||||
switch (result) {
|
||||
|
||||
@@ -141,11 +141,13 @@ void sf_set_weapon_ammo_count(OpcodeContext& ctx) {
|
||||
obj->item.charges = ctx.arg(1).rawValue();
|
||||
}
|
||||
|
||||
#define BLOCKING_TYPE_BLOCK (0)
|
||||
#define BLOCKING_TYPE_SHOOT (1)
|
||||
#define BLOCKING_TYPE_AI (2)
|
||||
#define BLOCKING_TYPE_SIGHT (3)
|
||||
#define BLOCKING_TYPE_SCROLL (4)
|
||||
enum {
|
||||
BLOCKING_TYPE_BLOCK = 0,
|
||||
BLOCKING_TYPE_SHOOT = 1,
|
||||
BLOCKING_TYPE_AI = 2,
|
||||
BLOCKING_TYPE_SIGHT = 3,
|
||||
BLOCKING_TYPE_SCROLL = 4
|
||||
};
|
||||
|
||||
static DWORD getBlockingFunc(DWORD type) {
|
||||
switch (type) {
|
||||
@@ -159,7 +161,6 @@ static DWORD getBlockingFunc(DWORD type) {
|
||||
return fo::funcoffs::obj_sight_blocking_at_;
|
||||
//case 4:
|
||||
// return obj_scroll_blocking_at_;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -202,17 +202,20 @@ void sf_string_compare(OpcodeContext& ctx) {
|
||||
static char* sprintf_lite(const char* format, ScriptValue value) {
|
||||
int fmtlen = strlen(format);
|
||||
int buflen = fmtlen + 1;
|
||||
|
||||
for (int i = 0; i < fmtlen; i++) {
|
||||
if (format[i] == '%') buflen++; // will possibly be escaped, need space for that
|
||||
}
|
||||
|
||||
// parse format to make it safe
|
||||
char* newfmt = new char[buflen];
|
||||
byte mode = 0;
|
||||
int j = 0;
|
||||
char c, specifier;
|
||||
unsigned char mode = 0;
|
||||
char specifier = 0;
|
||||
bool hasDigits = false;
|
||||
int j = 0;
|
||||
|
||||
for (int i = 0; i < fmtlen; i++) {
|
||||
c = format[i];
|
||||
char c = format[i];
|
||||
switch (mode) {
|
||||
case 0: // prefix
|
||||
if (c == '%') {
|
||||
@@ -221,12 +224,11 @@ static char* sprintf_lite(const char* format, ScriptValue value) {
|
||||
break;
|
||||
case 1: // definition
|
||||
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
|
||||
if (c == 'h' || c == 'l' || c == 'j' || c == 'z' || c == 't' || c == 'L') { // ignore sub-specifiers
|
||||
continue;
|
||||
}
|
||||
if (c == 's' && !value.isString()) { // don't allow to treat non-string values as string pointers
|
||||
c = 'd';
|
||||
} else if (c == 'n') { // don't allow "n" specifier
|
||||
if (c == 'h' || c == 'l' || c == 'j' || c == 'z' || c == 't' || c == 'L') continue; // ignore sub-specifiers
|
||||
|
||||
if (c == 's' && !value.isString() || // don't allow to treat non-string values as string pointers
|
||||
c == 'n') // don't allow "n" specifier
|
||||
{
|
||||
c = 'd';
|
||||
}
|
||||
specifier = c;
|
||||
@@ -239,12 +241,9 @@ static char* sprintf_lite(const char* format, ScriptValue value) {
|
||||
}
|
||||
break;
|
||||
case 2: // postfix
|
||||
default:
|
||||
if (c == '%') { // don't allow more than one specifier
|
||||
newfmt[j++] = '%'; // escape it
|
||||
if (format[i + 1] == '%') {
|
||||
i++; // skip already escaped
|
||||
}
|
||||
if (format[i + 1] == '%') i++; // skip already escaped
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ static __declspec(naked) void set_game_time_hack() {
|
||||
__asm {
|
||||
mov dword ptr ds:[FO_VAR_fallout_game_time], eax;
|
||||
mov edx, eax;
|
||||
call IsMapLoaded;
|
||||
call IsGameLoaded;
|
||||
test al, al;
|
||||
jz end;
|
||||
cmp edx, ONE_GAME_YEAR * 13;
|
||||
|
||||
Reference in New Issue
Block a user