/** Item Highlighting mod Previously was part of sfall itself, now a separate mod. Features: - 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 - 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) - motion scanner is required to enable highlight (optional) - motion scanner charges are decreased on each use (optional) NOTE: this script requires compiler from sfall modderspack with -s option (short circuit evaluation) version 1.3 **/ #pragma sce #include "main.h" //#include "..\..\..\!SRC\headers\define.h" #define CRITTER_IS_DEAD (1) #define PID_MOTION_SENSOR (59) #define REPEAT_FRAMES (10) #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 IS_EMPTY(obj) (inven_ptr(obj, 0) == 0) variable begin configSection := "Highlighting"; highlightKey; isHighlight; alsoContainer; alsoCorpse; alsoCritter; checkLOS; outlineColor; outlineColorContainers; outlineColorContainersEmpty; outlineColorCorpses; outlineColorCorpsesEmpty; motionScanner; highlightFailMsg1; highlightFailMsg2; end procedure DudeCanSee(variable obj) begin variable block := obj_blocking_line(dude_obj, tile_num(obj), BLOCKING_TYPE_SHOOT); return not block or block == obj or tile_num(block) == tile_num(obj); end 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 return OUTLINE_RED_GLOW; end if checkLOS and not DudeCanSee(obj) then return 0; if obj_type(obj) == OBJ_TYPE_CRITTER then return outlineColorCorpsesEmpty if IS_EMPTY(obj) else outlineColorCorpses; if obj_item_subtype(obj) == item_type_container then return outlineColorContainersEmpty if IS_EMPTY(obj) else outlineColorContainers; 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 procedure ToggleHighlight(variable enable) begin variable obj, isCorpse; foreach obj in list_as_array(LIST_GROUNDITEMS) begin if obj and obj != outlined_object then begin call ToggleHighlightObject(obj, enable, false); end end if (alsoCorpse or alsoCritter) then begin foreach obj in list_as_array(LIST_CRITTERS) begin if obj and obj != dude_obj then begin 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 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 procedure KeyPressHandler begin variable pressed := get_sfall_arg, scanCode := get_sfall_arg, scanner, charges; if scanCode == highlightKey and not(get_game_mode bwand bwnot(COMBAT bwor PCOMBAT)) then begin if pressed then begin set_global_script_repeat(REPEAT_FRAMES); if motionScanner then begin scanner := obj_carrying_pid_obj(dude_obj, PID_MOTION_SENSOR); if scanner then begin if motionScanner >= 2 then begin charges := get_weapon_ammo_count(scanner); if charges > 0 then begin set_weapon_ammo_count(scanner, charges - 1); intface_redraw; call ToggleHighlight(true); end else begin display_msg(highlightFailMsg2); end end else begin call ToggleHighlight(true); end end else begin display_msg(highlightFailMsg1); end end else begin call ToggleHighlight(true); end end else begin call ToggleHighlight(false); end end end // visual glitch fix, turn off highlight when entering combat procedure CombatTurnHandler begin if isHighlight then begin call ToggleHighlight(false); end end // visual glitch fix, turn off highlight when opening other interfaces procedure GameModeChangeHandler begin if isHighlight and (get_game_mode bwand bwnot(COMBAT bwor PCOMBAT)) then begin call ToggleHighlight(false); end end procedure InventoryMoveHandler begin // remove item outline when player picks up the item if (isHighlight and get_sfall_arg == 7) then set_outline(get_sfall_arg, 0); end procedure start begin if game_loaded then begin if (sfall_ver_major < 4) then return; call InitConfigs; highlightKey := GetConfig(configSection, "Key", 0); alsoContainer := GetConfig(configSection, "Containers", 0); alsoCorpse := GetConfig(configSection, "Corpses", 0); alsoCritter := GetConfig(configSection, "Critters", 0); checkLOS := GetConfig(configSection, "CheckLOS", 0); outlineColor := GetConfig(configSection, "OutlineColor", 16); if (outlineColor < 1) then outlineColor := 64; outlineColorContainers := GetConfig(configSection, "OutlineColorContainers", 32); if (outlineColorContainers < 1) then outlineColorContainers := 64; outlineColorContainersEmpty := GetConfig(configSection, "OutlineColorContainersEmpty", 4); if (outlineColorContainersEmpty < 0) then outlineColorContainersEmpty := 64; // allow 0 outlineColorCorpses := GetConfig(configSection, "OutlineColorCorpses", 32); if (outlineColorCorpses < 1) then outlineColorCorpses := 64; outlineColorCorpsesEmpty := GetConfig(configSection, "OutlineColorCorpsesEmpty", 4); if (outlineColorCorpsesEmpty < 0) then outlineColorCorpsesEmpty := 64; // allow 0 motionScanner := GetConfig(configSection, "MotionScanner", 0); highlightFailMsg1 := Translate("HighlightFail1", "You aren't carrying a motion sensor."); highlightFailMsg2 := Translate("HighlightFail2", "Your motion sensor is out of charge."); register_hook_proc(HOOK_KEYPRESS, KeyPressHandler); register_hook_proc(HOOK_COMBATTURN, CombatTurnHandler); register_hook_proc(HOOK_GAMEMODECHANGE, GameModeChangeHandler); register_hook_proc(HOOK_INVENTORYMOVE, InventoryMoveHandler); set_global_script_type(1); end else begin if isHighlight and not(get_game_mode bwand bwnot(COMBAT bwor PCOMBAT)) then begin call ToggleHighlight(true); end end end