mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added NPC combat control mod to example mods
Updated item highlighting mod and NPC armor mod.
This commit is contained in:
Binary file not shown.
@@ -1,11 +1,13 @@
|
|||||||
/**
|
/**
|
||||||
|
|
||||||
Item Highlight mod (Lite version)
|
Item Highlighting mod (Lite version)
|
||||||
|
|
||||||
A cut-down version of the mod included in sfall 4.x, offers a bit more features than the built-in function.
|
A cut-down version of the mod included in sfall 4.x, offering more features than the built-in function.
|
||||||
Features:
|
Features:
|
||||||
- highlighting items, containers (optional) and lootable corpses (optional) on the ground
|
- highlights items, containers (optional) and lootable corpses (optional) on the ground
|
||||||
|
- highlights critters using the same rules as combat mode highlighting (optional)
|
||||||
- configurable hotkey is used to trigger highlight
|
- configurable hotkey is used to trigger highlight
|
||||||
|
- hotkey can be pressed and held to continuously update highlighted objects based on current position
|
||||||
- only objects in direct line-of-sight of player are highlighted (optional)
|
- only objects in direct line-of-sight of player are highlighted (optional)
|
||||||
- motion scanner is required to enable highlight (optional)
|
- motion scanner is required to enable highlight (optional)
|
||||||
- motion scanner charges are decreased on each use (optional)
|
- motion scanner charges are decreased on each use (optional)
|
||||||
@@ -15,7 +17,7 @@
|
|||||||
NOTE: this script requires compiler from sfall modderspack with -s option
|
NOTE: this script requires compiler from sfall modderspack with -s option
|
||||||
(short circuit evaluation)
|
(short circuit evaluation)
|
||||||
|
|
||||||
version 1.1
|
version 1.2
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
@@ -24,6 +26,7 @@
|
|||||||
|
|
||||||
#define CRITTER_IS_DEAD (1)
|
#define CRITTER_IS_DEAD (1)
|
||||||
#define PID_MOTION_SENSOR (59)
|
#define PID_MOTION_SENSOR (59)
|
||||||
|
#define REPEAT_FRAMES (10)
|
||||||
#define NO_HIGHLIGHT(obj) (get_flags(obj) bwand FLAG_NOHIGHLIGHT)
|
#define NO_HIGHLIGHT(obj) (get_flags(obj) bwand FLAG_NOHIGHLIGHT)
|
||||||
#define NO_STEAL(obj) (get_proto_data(obj_pid(obj), PROTO_CR_FLAGS) bwand CFLG_NOSTEAL)
|
#define NO_STEAL(obj) (get_proto_data(obj_pid(obj), PROTO_CR_FLAGS) bwand CFLG_NOSTEAL)
|
||||||
|
|
||||||
@@ -32,36 +35,70 @@ variable highlightKey;
|
|||||||
variable isHighlight;
|
variable isHighlight;
|
||||||
variable alsoContainer;
|
variable alsoContainer;
|
||||||
variable alsoCorpse;
|
variable alsoCorpse;
|
||||||
|
variable alsoCritter;
|
||||||
variable checkLOS;
|
variable checkLOS;
|
||||||
variable outlineColor;
|
variable outlineColor;
|
||||||
variable motionScanner;
|
variable motionScanner;
|
||||||
variable highlightFailMsg1;
|
variable highlightFailMsg1;
|
||||||
variable highlightFailMsg2;
|
variable highlightFailMsg2;
|
||||||
|
|
||||||
procedure ToggleHighlightObject(variable obj, variable enable) begin
|
procedure DudeCanSee(variable obj) begin
|
||||||
if obj and (not enable or not checkLOS or not obj_blocking_line(dude_obj, tile_num(obj), BLOCKING_TYPE_SHOOT)) then begin
|
variable block := obj_blocking_line(dude_obj, tile_num(obj), BLOCKING_TYPE_SHOOT);
|
||||||
if (alsoContainer and obj_item_subtype(obj) == item_type_container) or (not NO_HIGHLIGHT(obj)) then begin
|
return not block or block == obj;
|
||||||
if (enable) then set_outline(obj, outlineColor);
|
end
|
||||||
else set_outline(obj, 0);
|
|
||||||
|
procedure DudeCanHear(variable obj) begin
|
||||||
|
variable hearDist := dude_perception * 5;
|
||||||
|
if (get_flags(obj) bwand FLAG_TRANSGLASS) then
|
||||||
|
hearDist /= 2;
|
||||||
|
|
||||||
|
return tile_distance_objs(dude_obj, obj) <= hearDist;
|
||||||
|
end
|
||||||
|
|
||||||
|
procedure GetOutlineColor(variable obj, variable isCritter) begin
|
||||||
|
if isCritter then begin
|
||||||
|
if get_team(obj) == get_team(dude_obj) then return OUTLINE_GREEN_GLOW;
|
||||||
|
if not DudeCanSee(obj) then begin
|
||||||
|
if (DudeCanHear(obj)) then return OUTLINE_DARK_YELLOW;
|
||||||
|
return 0;
|
||||||
end
|
end
|
||||||
|
return OUTLINE_RED_GLOW;
|
||||||
end
|
end
|
||||||
|
if checkLOS and not DudeCanSee(obj) then
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return outlineColor;
|
||||||
|
end
|
||||||
|
|
||||||
|
procedure ToggleHighlightObject(variable obj, variable enable, variable isCritter) begin
|
||||||
|
if (not alsoContainer or obj_item_subtype(obj) != item_type_container) and NO_HIGHLIGHT(obj) then return;
|
||||||
|
|
||||||
|
set_outline(obj, GetOutlineColor(obj, isCritter) if enable else 0);
|
||||||
end
|
end
|
||||||
|
|
||||||
procedure ToggleHighlight(variable enable) begin
|
procedure ToggleHighlight(variable enable) begin
|
||||||
variable obj;
|
variable obj, isCorpse;
|
||||||
foreach obj in list_as_array(LIST_GROUNDITEMS) begin
|
foreach obj in list_as_array(LIST_GROUNDITEMS) begin
|
||||||
if obj != outlined_object then begin
|
if obj and obj != outlined_object then begin
|
||||||
call ToggleHighlightObject(obj, enable);
|
call ToggleHighlightObject(obj, enable, false);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if (alsoCorpse) then begin
|
if (alsoCorpse or alsoCritter) then begin
|
||||||
foreach obj in list_as_array(LIST_CRITTERS) begin
|
foreach obj in list_as_array(LIST_CRITTERS) begin
|
||||||
if critter_state(obj) == CRITTER_IS_DEAD and not NO_STEAL(obj) then begin
|
if obj and obj != dude_obj then begin
|
||||||
call ToggleHighlightObject(obj, enable);
|
isCorpse := critter_state(obj) == CRITTER_IS_DEAD;
|
||||||
|
if (alsoCritter and not isCorpse) or (isCorpse and not NO_STEAL(obj)) then begin
|
||||||
|
call ToggleHighlightObject(obj, enable, not isCorpse);
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
tile_refresh_display;
|
tile_refresh_display;
|
||||||
|
if (checkLOS or alsoCritter) and enable != isHighlight then begin
|
||||||
|
set_global_script_repeat(REPEAT_FRAMES if enable else 0);
|
||||||
|
end
|
||||||
|
|
||||||
|
isHighlight := enable;
|
||||||
end
|
end
|
||||||
|
|
||||||
procedure KeyPressHandler begin
|
procedure KeyPressHandler begin
|
||||||
@@ -71,7 +108,7 @@ procedure KeyPressHandler begin
|
|||||||
|
|
||||||
if scanCode == highlightKey and not(get_game_mode bwand (INTFACELOOT bwor BARTER)) then begin
|
if scanCode == highlightKey and not(get_game_mode bwand (INTFACELOOT bwor BARTER)) then begin
|
||||||
if pressed then begin
|
if pressed then begin
|
||||||
isHighlight := true;
|
set_global_script_repeat(REPEAT_FRAMES);
|
||||||
if motionScanner then begin
|
if motionScanner then begin
|
||||||
scanner := obj_carrying_pid_obj(dude_obj, PID_MOTION_SENSOR);
|
scanner := obj_carrying_pid_obj(dude_obj, PID_MOTION_SENSOR);
|
||||||
if scanner then begin
|
if scanner then begin
|
||||||
@@ -94,16 +131,21 @@ procedure KeyPressHandler begin
|
|||||||
call ToggleHighlight(true);
|
call ToggleHighlight(true);
|
||||||
end
|
end
|
||||||
end else begin
|
end else begin
|
||||||
isHighlight := false;
|
|
||||||
call ToggleHighlight(false);
|
call ToggleHighlight(false);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
// visual glitch fix - for 3.8.29+
|
// visual glitch fix, turn off highlight when entering combat - for 3.8.40+
|
||||||
|
procedure CombatTurnHandler begin
|
||||||
|
if isHighlight then begin
|
||||||
|
call ToggleHighlight(false);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// visual glitch fix, turn off highlight when opening loot/barter screens - for 3.8.29+
|
||||||
procedure GameModeChangeHandler begin
|
procedure GameModeChangeHandler begin
|
||||||
if isHighlight and (get_game_mode bwand (INTFACELOOT bwor BARTER)) then begin
|
if isHighlight and (get_game_mode bwand (INTFACELOOT bwor BARTER)) then begin
|
||||||
isHighlight := false;
|
|
||||||
call ToggleHighlight(false);
|
call ToggleHighlight(false);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -114,12 +156,15 @@ procedure InventoryMoveHandler begin
|
|||||||
end
|
end
|
||||||
|
|
||||||
procedure start begin
|
procedure start begin
|
||||||
if game_loaded and (sfall_ver_major < 4 and sfall_ver_build >= 12) then begin
|
if game_loaded then begin
|
||||||
|
if (sfall_ver_major >= 4 or sfall_ver_build < 12) then return;
|
||||||
|
|
||||||
call InitConfigs;
|
call InitConfigs;
|
||||||
|
|
||||||
highlightKey := GetConfig(configSection, "Key", 0);
|
highlightKey := GetConfig(configSection, "Key", 0);
|
||||||
alsoContainer := GetConfig(configSection, "Containers", 0);
|
alsoContainer := GetConfig(configSection, "Containers", 0);
|
||||||
alsoCorpse := GetConfig(configSection, "Corpses", 0);
|
alsoCorpse := GetConfig(configSection, "Corpses", 0);
|
||||||
|
alsoCritter := GetConfig(configSection, "Critters", 0);
|
||||||
checkLOS := GetConfig(configSection, "CheckLOS", 0);
|
checkLOS := GetConfig(configSection, "CheckLOS", 0);
|
||||||
outlineColor := GetConfig(configSection, "OutlineColor", 16);
|
outlineColor := GetConfig(configSection, "OutlineColor", 16);
|
||||||
if (outlineColor < 1) then outlineColor := 64;
|
if (outlineColor < 1) then outlineColor := 64;
|
||||||
@@ -129,7 +174,13 @@ procedure start begin
|
|||||||
highlightFailMsg2 := Translate("HighlightFail2", "Your motion sensor is out of charge.");
|
highlightFailMsg2 := Translate("HighlightFail2", "Your motion sensor is out of charge.");
|
||||||
|
|
||||||
register_hook_proc(HOOK_KEYPRESS, KeyPressHandler);
|
register_hook_proc(HOOK_KEYPRESS, KeyPressHandler);
|
||||||
|
register_hook_proc(HOOK_COMBATTURN, CombatTurnHandler);
|
||||||
register_hook_proc(HOOK_GAMEMODECHANGE, GameModeChangeHandler);
|
register_hook_proc(HOOK_GAMEMODECHANGE, GameModeChangeHandler);
|
||||||
register_hook_proc(HOOK_INVENTORYMOVE, InventoryMoveHandler);
|
register_hook_proc(HOOK_INVENTORYMOVE, InventoryMoveHandler);
|
||||||
|
set_global_script_type(1);
|
||||||
|
end else begin
|
||||||
|
if isHighlight and not(get_game_mode bwand (INTFACELOOT bwor BARTER)) then begin
|
||||||
|
call ToggleHighlight(true);
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
#include "..\scripting\headers\lib.inven.h"
|
#include "..\scripting\headers\lib.inven.h"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
variable ini := "sfall-mods.ini";
|
variable ini := "mods\\sfall-mods.ini";
|
||||||
variable translationIni;
|
variable translationIni;
|
||||||
|
|
||||||
// Gets the integer value from the specified ini
|
// Gets the integer value from the specified ini
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
Item Highlight mod (Lite version) for sfall 3.8.x
|
Item Highlighting mod (Lite version) for sfall 3.8.x
|
||||||
-------------------------------------------------
|
----------------------------------------------------
|
||||||
|
|
||||||
A cut-down version of the mod included in sfall 4.x, offers a bit more features than the built-in function.
|
A cut-down version of the mod included in sfall 4.x, offers more features than the built-in function.
|
||||||
Features:
|
Features:
|
||||||
- highlighting items, containers (optional) and lootable corpses (optional) on the ground
|
- highlights items, containers (optional) and lootable corpses (optional) on the ground
|
||||||
- configurable hotkey is used to trigger highlight
|
- configurable hotkey is used to trigger highlight
|
||||||
- only objects in direct line-of-sight of player are highlighted (optional)
|
- only objects in direct line-of-sight of player are highlighted (optional)
|
||||||
- motion scanner is required to enable highlight (optional)
|
- motion scanner is required to enable highlight (optional)
|
||||||
@@ -12,10 +12,10 @@ Features:
|
|||||||
|
|
||||||
Requires sfall 3.8.12 or higher.
|
Requires sfall 3.8.12 or higher.
|
||||||
|
|
||||||
To use, copy gl_highlighting_lite.int to your scripts folder, and copy sfall-mods.ini to the same directory as sfall.
|
To use, copy gl_highlighting_lite.int to your scripts folder and sfall-mods.ini to the mods folder in the same directory as sfall.
|
||||||
Also, you should disable the built-in function in ddraw.ini (ToggleItemHighlightsKey=0).
|
Create the mods folder if it does not exist. Also, you should disable the built-in function in ddraw.ini (ToggleItemHighlightsKey=0).
|
||||||
|
|
||||||
Note that due to the lack of newer game hooks in sfall 3.8.x, there are some minor visual glitches in the lite version:
|
Note that due to the lack of newer game hooks in sfall 3.8.x, there are some minor visual glitches in the lite version:
|
||||||
- items will be kept highlighted when entering combat while holding the highlight key.
|
- items will be kept highlighted when entering combat while holding the highlight key (fixed in 3.8.40+).
|
||||||
- when you pick up items while holding the highlight key, they will be kept highlighted if you drop them on the ground (fixed for 3.8.18+).
|
- when you pick up items while holding the highlight key, they will be kept highlighted if you drop them on the ground (fixed in 3.8.18+).
|
||||||
Both glitches can bo solved by pressing and releasing the highlight key again.
|
Both glitches can bo solved by pressing and releasing the highlight key again.
|
||||||
|
|||||||
@@ -9,10 +9,13 @@ Containers=0
|
|||||||
; Set to 1 to also highlight lootable corpses
|
; Set to 1 to also highlight lootable corpses
|
||||||
Corpses=0
|
Corpses=0
|
||||||
|
|
||||||
; Set to 1 to only highlight objects in the player's line-of-sight
|
; Set to 1 to also highlight critters, with the same rules as in combat
|
||||||
CheckLOS=0
|
Critters=0
|
||||||
|
|
||||||
; Set the color of outlines, available colors:
|
; Set to 1 to only highlight objects in the player's line-of-sight
|
||||||
|
CheckLOS=1
|
||||||
|
|
||||||
|
; Set the color of outlines for items, corpses, and containers; available colors:
|
||||||
; 1 - glowing red
|
; 1 - glowing red
|
||||||
; 2 - red
|
; 2 - red
|
||||||
; 4 - grey
|
; 4 - grey
|
||||||
@@ -20,7 +23,7 @@ CheckLOS=0
|
|||||||
; 16 - bright yellow
|
; 16 - bright yellow
|
||||||
; 32 - dark yellow
|
; 32 - dark yellow
|
||||||
; 64 - purple
|
; 64 - purple
|
||||||
; You can set a custom color from the game palette by multiplying the color index value by 256 (available since sfall 4.2.7)
|
; You can set a custom color from the game palette by multiplying the color index value by 256 (in 3.8.27 or later)
|
||||||
OutlineColor=16
|
OutlineColor=16
|
||||||
|
|
||||||
; Motion Scanner mode:
|
; Motion Scanner mode:
|
||||||
@@ -28,3 +31,37 @@ OutlineColor=16
|
|||||||
; 1 - requires Motion Scanner present in player inventory to activate highlighting
|
; 1 - requires Motion Scanner present in player inventory to activate highlighting
|
||||||
; 2 - requires Motion Scanner and also requires 1 charge on every use (depleted scanner will not work anymore)
|
; 2 - requires Motion Scanner and also requires 1 charge on every use (depleted scanner will not work anymore)
|
||||||
MotionScanner=0
|
MotionScanner=0
|
||||||
|
|
||||||
|
|
||||||
|
[CombatControl]
|
||||||
|
;Allows you to control other critters directly in combat
|
||||||
|
;Set to 0 to disable
|
||||||
|
;Set to 1 to control all critters in combat (allowed only in sfall debugging mode)
|
||||||
|
;Set to 2 to control all party members
|
||||||
|
;Set to 3 to let you use the command cursor to specify targets for party members to attack in combat
|
||||||
|
Mode=0
|
||||||
|
;If you want to control only specific critters, uncomment the PIDList line and set a comma delimited list of PIDs
|
||||||
|
;PIDList=62,89,97,107,160,161
|
||||||
|
|
||||||
|
;Set a comma delimited list of perk IDs for perks to be inherited from the player during the combat control
|
||||||
|
PerksList=0,73
|
||||||
|
|
||||||
|
;Set to 1 to allow the player to gain a positive reputation when killing NPCs while controlling other critters
|
||||||
|
GainReputation=0
|
||||||
|
|
||||||
|
;Choose a notification box to display the name of the controlled critter above the interface bar
|
||||||
|
;Must be between 5 and (4 + the value of BoxBarCount in ddraw.ini)
|
||||||
|
;For sfall 4.1.6+ the number for the notification box is set automatically, so just use any value
|
||||||
|
;Set to 0 to disable
|
||||||
|
DisplayName=0
|
||||||
|
|
||||||
|
;Set the color of display name, available colors:
|
||||||
|
;0 - green
|
||||||
|
;1 - red
|
||||||
|
;2 - white
|
||||||
|
;3 - yellow
|
||||||
|
;4 - dark yellow
|
||||||
|
;5 - blue
|
||||||
|
;6 - purple
|
||||||
|
;7 - dull pink
|
||||||
|
DisplayNameColor=0
|
||||||
|
|||||||
Binary file not shown.
@@ -23,6 +23,7 @@
|
|||||||
#define FID_OBJ_CRITTER (0x01000000)
|
#define FID_OBJ_CRITTER (0x01000000)
|
||||||
|
|
||||||
procedure update_armor_apperance;
|
procedure update_armor_apperance;
|
||||||
|
procedure canuseweapon_handler;
|
||||||
|
|
||||||
variable
|
variable
|
||||||
modIni := "npcarmor.ini",
|
modIni := "npcarmor.ini",
|
||||||
@@ -165,7 +166,9 @@ end
|
|||||||
|
|
||||||
procedure start begin
|
procedure start begin
|
||||||
variable sect, sects, armorTypes, armorType, npc, pid, pids, i;
|
variable sect, sects, armorTypes, armorType, npc, pid, pids, i;
|
||||||
if game_loaded and (sfall_ver_major < 4 and sfall_ver_build >= 29) then begin
|
if game_loaded then begin
|
||||||
|
if (sfall_ver_major >= 4 or sfall_ver_build < 29) then return;
|
||||||
|
|
||||||
armorTypes := get_ini_section(modIni, "ArmorTypes");
|
armorTypes := get_ini_section(modIni, "ArmorTypes");
|
||||||
armorPidMap := create_array_map;
|
armorPidMap := create_array_map;
|
||||||
foreach (armorType: pids in armorTypes) begin
|
foreach (armorType: pids in armorTypes) begin
|
||||||
@@ -205,6 +208,7 @@ procedure start begin
|
|||||||
register_hook_proc(HOOK_INVENWIELD, invenwield_handler);
|
register_hook_proc(HOOK_INVENWIELD, invenwield_handler);
|
||||||
register_hook_proc(HOOK_ADJUSTFID, adjustfid_handler);
|
register_hook_proc(HOOK_ADJUSTFID, adjustfid_handler);
|
||||||
register_hook_proc(HOOK_INVENTORYMOVE, inventorymove_handler);
|
register_hook_proc(HOOK_INVENTORYMOVE, inventorymove_handler);
|
||||||
|
register_hook_proc_spec(HOOK_CANUSEWEAPON, canuseweapon_handler);
|
||||||
|
|
||||||
debug_msg("NPC armor appearance mod: Done.");
|
debug_msg("NPC armor appearance mod: Done.");
|
||||||
end
|
end
|
||||||
@@ -222,3 +226,16 @@ procedure update_armor_apperance begin
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
// prevent NPCs from equipping "unusable" weapons - for 3.8.40+
|
||||||
|
procedure canuseweapon_handler begin
|
||||||
|
variable critter, canUse;
|
||||||
|
critter := get_sfall_arg;
|
||||||
|
if (critter != dude_obj and get_sfall_arg_at(3)) then begin
|
||||||
|
canUse := check_weapon_change(critter, get_sfall_arg, true);
|
||||||
|
if (canUse == false) then begin
|
||||||
|
set_sfall_arg(3, 0);
|
||||||
|
set_sfall_return(0); // overrides the result of engine function. Any non-zero value allows using the weapon
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ Can be adopted to any mod by adjusting armor PIDs, allowed weapon anim codes, NP
|
|||||||
|
|
||||||
Requires sfall 3.8.29 or higher.
|
Requires sfall 3.8.29 or higher.
|
||||||
|
|
||||||
To use, copy gl_npcarmor_lite.int to your scripts folder, and copy npcarmor.ini to the same directory as sfall.
|
To use, copy gl_npcarmor_lite.int to your scripts folder and copy npcarmor.ini to the same directory as sfall.
|
||||||
|
|
||||||
The default npcarmor.ini is set up for Restoration Project 2.3.3.
|
The default npcarmor.ini is set up for Restoration Project 2.3.3.
|
||||||
Check the included "npcarmor - vanilla.ini" for an example that does not require any new graphics.
|
Check the included "npcarmor - vanilla.ini" for an example that does not require any new graphics.
|
||||||
|
|
||||||
Note that due to the lack of newer game hooks in sfall 3.8.x, there is a minor glitch in the lite version:
|
Note that due to the lack of newer game hooks in sfall 3.8.x, there is a minor glitch in the lite version:
|
||||||
- in combat, NPCs can pick up and try to equip weapons with anim codes that are not allowed in INI file but supported by their appearance.
|
- in combat, NPCs can pick up and try to equip weapons with anim codes that are not allowed in INI file but supported by their appearance (fixed in 3.8.40+).
|
||||||
|
|||||||
Binary file not shown.
@@ -0,0 +1,246 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
NPC Combat Control (Lite version)
|
||||||
|
|
||||||
|
A script-based mod of the removed built-in ControlCombat option, offering more features and improvements.
|
||||||
|
Features:
|
||||||
|
- allows you to take control of your party members or other NPCs during combat
|
||||||
|
(unlike in newer 4.x versions, controlled critters cannot use Sneak skill in combat)
|
||||||
|
- configurable list of perk IDs for perks being inherited from the player (optional, not all perks can work)
|
||||||
|
- allows the player to gain a positive reputation when killing NPCs while controlling other critters (optional)
|
||||||
|
- a notification box to display the name of the controlled critter above the interface bar (optional)
|
||||||
|
|
||||||
|
NOTE: this script requires compiler from sfall modderspack with -s option
|
||||||
|
(short circuit evaluation)
|
||||||
|
|
||||||
|
Requires sfall 3.8.40 or higher
|
||||||
|
|
||||||
|
version 1.3
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "..\headers\global.h"
|
||||||
|
#include "..\headers\critrpid.h"
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
#ifndef DEBUG
|
||||||
|
#define DEBUGMSG(x)
|
||||||
|
#else
|
||||||
|
#define DEBUGMSG(x) debug_msg(x);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
procedure start;
|
||||||
|
procedure AllowControl(variable pid);
|
||||||
|
procedure SetLight(variable critter, variable int, variable dist);
|
||||||
|
procedure CombatTurn_Handler;
|
||||||
|
procedure GameModeChange_Handler;
|
||||||
|
procedure InventoryMove_Handler;
|
||||||
|
procedure InvenWield_Handler;
|
||||||
|
procedure SetGlobalVar_Handler;
|
||||||
|
|
||||||
|
variable
|
||||||
|
controlMode,
|
||||||
|
pidList, perksList,
|
||||||
|
lightInt, lightDist, npcControl,
|
||||||
|
displayName, displayNameColor, isShowTag,
|
||||||
|
inControl := false,
|
||||||
|
dudeLightInt, dudeLightDist;
|
||||||
|
|
||||||
|
|
||||||
|
procedure AllowControl(variable pid) begin
|
||||||
|
return ((pidList == 0 or scan_array(pidList, pid bwand 0xFFFFFF) != -1) and (party_member_obj(pid)));
|
||||||
|
end
|
||||||
|
|
||||||
|
procedure SetLight(variable critter, variable lInt, variable lDist) begin
|
||||||
|
if (lInt) then lInt := round((lInt / 65536.0) * 100); // calc percent of intensity
|
||||||
|
obj_set_light_level(critter, lInt, lDist); // TODO: make sfall obj_set_light_level function
|
||||||
|
end
|
||||||
|
|
||||||
|
procedure CombatTurn_Handler begin
|
||||||
|
variable
|
||||||
|
status := get_sfall_arg,
|
||||||
|
critter := get_sfall_arg,
|
||||||
|
pid, perkID, level;
|
||||||
|
|
||||||
|
DEBUGMSG("Combat Turn: " + status + ", by " + obj_name(critter) + "/" + critter + ", arg3: " + get_sfall_arg)
|
||||||
|
|
||||||
|
pid := obj_pid(critter);
|
||||||
|
if (pid == PID_PLAYER and inControl == false) then return;
|
||||||
|
|
||||||
|
if (pid != PID_PLAYER and controlMode != 1 and AllowControl(pid) == false) then begin
|
||||||
|
DEBUGMSG("Skip control.")
|
||||||
|
|
||||||
|
if (npcControl) then begin
|
||||||
|
npcControl := 0;
|
||||||
|
set_dude_obj(real_dude_obj);
|
||||||
|
call SetLight(dude_obj, dudeLightInt, dudeLightDist); // restore dude light
|
||||||
|
move_to(dude_obj, dude_tile, dude_elevation);
|
||||||
|
|
||||||
|
DEBUGMSG("Set dude after NPC control.")
|
||||||
|
end
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (status == 1) then begin
|
||||||
|
set_dude_obj(critter);
|
||||||
|
|
||||||
|
DEBUGMSG("Take control of: " + obj_name(critter))
|
||||||
|
|
||||||
|
if (critter != real_dude_obj) then begin
|
||||||
|
if (npcControl == 0) then begin
|
||||||
|
dudeLightDist := get_object_data(real_dude_obj, OBJ_DATA_LIGHT_DISTANCE);
|
||||||
|
dudeLightInt := get_object_data(real_dude_obj, OBJ_DATA_LIGHT_INTENSITY);
|
||||||
|
obj_set_light_level(real_dude_obj, 0, 0); // dude off light
|
||||||
|
end
|
||||||
|
npcControl := critter;
|
||||||
|
|
||||||
|
lightDist := get_object_data(critter, OBJ_DATA_LIGHT_DISTANCE);
|
||||||
|
lightInt := get_object_data(critter, OBJ_DATA_LIGHT_INTENSITY);
|
||||||
|
|
||||||
|
// set perks (only work with 4.1.8+)
|
||||||
|
foreach (perkID in perksList) begin
|
||||||
|
level := has_trait(TRAIT_PERK, real_dude_obj, perkID);
|
||||||
|
if (level) then critter_add_trait(critter, TRAIT_PERK, perkID, level);
|
||||||
|
end
|
||||||
|
intface_redraw;
|
||||||
|
|
||||||
|
obj_set_light_level(critter, 100, 4);
|
||||||
|
inControl := true;
|
||||||
|
end else if (npcControl) then begin
|
||||||
|
call SetLight(dude_obj, dudeLightInt, dudeLightDist); // restore dude light
|
||||||
|
npcControl := 0; // for dude control
|
||||||
|
intface_redraw;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (inControl) then begin
|
||||||
|
// check preference setting _combat_highlight
|
||||||
|
if (read_byte(0x56D38C)) then set_outline(critter, OUTLINE_GREY); // TODO: replace read_byte with normal function
|
||||||
|
|
||||||
|
// center the screen on the controlled critter/dude and remove roof tiles
|
||||||
|
move_to(dude_obj, dude_tile, dude_elevation);
|
||||||
|
|
||||||
|
if (displayName and critter != real_dude_obj) then begin
|
||||||
|
set_iface_tag_text(displayName, obj_name(critter), displayNameColor);
|
||||||
|
show_iface_tag(displayName);
|
||||||
|
isShowTag := true;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end else begin
|
||||||
|
if (npcControl) then begin
|
||||||
|
call SetLight(critter, lightInt, lightDist); // restore light for controlled NPC
|
||||||
|
end
|
||||||
|
if (isShowTag) then begin
|
||||||
|
hide_iface_tag(displayName);
|
||||||
|
isShowTag := false;
|
||||||
|
end
|
||||||
|
|
||||||
|
// remove perks before switching control (only work with 4.1.8+)
|
||||||
|
if (dude_obj != real_dude_obj) then begin
|
||||||
|
DEBUGMSG("Remove perks after NPC control.")
|
||||||
|
foreach (perkID in perksList) begin
|
||||||
|
level := has_trait(TRAIT_PERK, real_dude_obj, perkID);
|
||||||
|
if (level) then critter_rm_trait(critter, TRAIT_PERK, perkID, level);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if (status < 0) then begin
|
||||||
|
set_dude_obj(real_dude_obj);
|
||||||
|
call SetLight(dude_obj, dudeLightInt, dudeLightDist);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
procedure GameModeChange_Handler begin
|
||||||
|
if (inControl and (get_game_mode bwand COMBAT) == 0) then begin
|
||||||
|
inControl := false;
|
||||||
|
npcControl := 0;
|
||||||
|
move_to(dude_obj, dude_tile, dude_elevation);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
procedure InventoryMove_Handler begin
|
||||||
|
if (npcControl and get_sfall_arg == 3) then begin // armor slot
|
||||||
|
if (obj_pid(dude_obj) == PID_MARCUS or proto_data(obj_pid(dude_obj), cr_body_type) != CR_BODY_BIPED) then begin
|
||||||
|
display_msg(message_str_game(GAME_MSG_PROTO, 675));
|
||||||
|
set_sfall_return(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
procedure InvenWield_Handler begin
|
||||||
|
variable
|
||||||
|
critter := get_sfall_arg,
|
||||||
|
item := get_sfall_arg,
|
||||||
|
slot := get_sfall_arg,
|
||||||
|
event := get_sfall_arg;
|
||||||
|
|
||||||
|
// Fix weapon duplication when equipping in combat
|
||||||
|
if (event and slot == INVEN_TYPE_RIGHT_HAND and AllowControl(obj_pid(critter))) then begin
|
||||||
|
set_flags(item, get_flags(item) bwand bwnot(FLAG_LEFT_HAND));
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
procedure SetGlobalVar_Handler begin
|
||||||
|
if (npcControl and get_sfall_arg == GVAR_PLAYER_REPUTATION and obj_pid(dude_obj) != PID_PLAYER) then begin
|
||||||
|
variable value := global_var(GVAR_PLAYER_REPUTATION);
|
||||||
|
if (get_sfall_arg > value) then begin
|
||||||
|
set_sfall_arg(1, value);
|
||||||
|
set_sfall_return(value);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
procedure start begin
|
||||||
|
if game_loaded then begin
|
||||||
|
if (sfall_ver_major >= 4 or sfall_ver_build < 40) then return;
|
||||||
|
|
||||||
|
controlMode := GetConfig("CombatControl", "Mode", 0);
|
||||||
|
if (controlMode >= 3) then begin
|
||||||
|
if (controlMode == 3) then metarule3(999, 0, 0, 0); // enable feature: order party members to attack a specified target
|
||||||
|
controlMode := 0;
|
||||||
|
end else if (controlMode == 1 and GetIniConfig("Debugging", "Enable", 0, "ddraw.ini") == 0) then begin
|
||||||
|
controlMode := 2;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (controlMode > 0) then begin
|
||||||
|
displayName := GetConfig("CombatControl", "DisplayName", 0);
|
||||||
|
|
||||||
|
if (displayName) then begin
|
||||||
|
variable nameTag := add_iface_tag;
|
||||||
|
debug_msg("NPC control - added new box: " + nameTag);
|
||||||
|
if (nameTag <= 0) then begin // box added?
|
||||||
|
variable maxBoxCount := get_ini_setting("ddraw.ini|Misc|BoxBarCount");
|
||||||
|
if (maxBoxCount < 0) then maxBoxCount := 9;
|
||||||
|
else maxBoxCount += 4;
|
||||||
|
if (displayName < 5 or displayName > maxBoxCount) then displayName := 0;
|
||||||
|
end else begin
|
||||||
|
displayName := nameTag;
|
||||||
|
end
|
||||||
|
displayNameColor := GetConfig("CombatControl", "DisplayNameColor", 0);
|
||||||
|
end
|
||||||
|
|
||||||
|
set_perk_ranks(PERK_gecko_skinning_perk, 1);
|
||||||
|
set_perk_level(PERK_gecko_skinning_perk, 999); // prevent it from appearing in the perk selection window
|
||||||
|
|
||||||
|
pidList := GetConfigListInt("CombatControl", "PIDList");
|
||||||
|
if (len_array(pidList) > 0) then
|
||||||
|
fix_array(pidList);
|
||||||
|
else
|
||||||
|
pidList := 0;
|
||||||
|
|
||||||
|
perksList := GetConfigListInt("CombatControl", "PerksList");
|
||||||
|
fix_array(perksList);
|
||||||
|
|
||||||
|
register_hook_proc(HOOK_COMBATTURN, CombatTurn_Handler);
|
||||||
|
register_hook_proc(HOOK_GAMEMODECHANGE, GameModeChange_Handler);
|
||||||
|
register_hook_proc(HOOK_INVENTORYMOVE, InventoryMove_Handler);
|
||||||
|
register_hook_proc(HOOK_INVENWIELD, InvenWield_Handler);
|
||||||
|
|
||||||
|
if (GetConfig("CombatControl", "GainReputation", 0) == 0) then begin
|
||||||
|
register_hook_proc(HOOK_SETGLOBALVAR, SetGlobalVar_Handler);
|
||||||
|
end
|
||||||
|
end else begin
|
||||||
|
exit;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
NPC Combat Control mod (Lite version) for sfall 3.8.x
|
||||||
|
-----------------------------------------------------
|
||||||
|
|
||||||
|
A script-based mod of the removed built-in ControlCombat option, offering more features and improvements.
|
||||||
|
Features:
|
||||||
|
- allows you to take control of your party members or other NPCs during combat
|
||||||
|
(unlike in newer 4.x versions, controlled critters cannot use Sneak skill in combat)
|
||||||
|
- configurable list of perk IDs for perks being inherited from the player (optional, not all perks can work)
|
||||||
|
- allows the player to gain a positive reputation when killing NPCs while controlling other critters (optional)
|
||||||
|
- a notification box to display the name of the controlled critter above the interface bar (optional)
|
||||||
|
|
||||||
|
|
||||||
|
Requires sfall 3.8.40 or higher.
|
||||||
|
|
||||||
|
To use, copy gl_partycontrol_lite.int to your scripts folder and sfall-mods.ini (in ItemHighlight_Lite) to the mods folder in the same directory as sfall.
|
||||||
|
Create the mods folder if it does not exist.
|
||||||
@@ -356,6 +356,7 @@ There are several changes in this version of sslc which may result in problems f
|
|||||||
- fixed optimizer not treating `call string_variable` as variable use
|
- fixed optimizer not treating `call string_variable` as variable use
|
||||||
- fixed unused arguments in a procedure being removed incorrectly by the optimizer
|
- fixed unused arguments in a procedure being removed incorrectly by the optimizer
|
||||||
- fixed unused string literals in an optimized-out procedure not being removed by the optimizer
|
- fixed unused string literals in an optimized-out procedure not being removed by the optimizer
|
||||||
|
- fixed `get_array` syntax not working for exported variables
|
||||||
|
|
||||||
**sfall 4.2.9:**
|
**sfall 4.2.9:**
|
||||||
- added support for additional universal opcodes `sfall_func7` and `sfall_func8`
|
- added support for additional universal opcodes `sfall_func7` and `sfall_func8`
|
||||||
|
|||||||
@@ -907,7 +907,7 @@ sfall_funcX metarule functions
|
|||||||
|
|
||||||
----
|
----
|
||||||
#### string_format
|
#### string_format
|
||||||
`string sfall_func2("string_format", string format, any val1)`
|
`string sfall_func2("string_format", string format, any val1)`\
|
||||||
`string sfall_funcX("string_format", string format, any val1, any val2, ...)`
|
`string sfall_funcX("string_format", string format, any val1, any val2, ...)`
|
||||||
- Formats given values using standard syntax of C `printf` function (google "printf" for format details). However, it is limited to formatting up to 7 values
|
- Formats given values using standard syntax of C `printf` function (google "printf" for format details). However, it is limited to formatting up to 7 values
|
||||||
- The format string is limited to 1024 characters
|
- The format string is limited to 1024 characters
|
||||||
|
|||||||
Reference in New Issue
Block a user