2017-05-23 22:28:42 +08:00
|
|
|
/*
|
2017-04-01 21:11:19 +07:00
|
|
|
|
|
|
|
|
NPC Combat Control
|
2017-05-23 22:28:42 +08:00
|
|
|
|
2017-04-01 21:11:19 +07:00
|
|
|
Allows to take control of your party member or other NPCs during combat
|
2017-05-23 22:28:42 +08:00
|
|
|
|
2017-04-01 21:11:19 +07:00
|
|
|
NOTE: this script requires compiler from sfall modderspack with -s option
|
|
|
|
|
(short circuit evaluation)
|
2017-05-23 22:28:42 +08:00
|
|
|
|
2019-02-20 21:26:23 +08:00
|
|
|
version 1.1
|
2017-04-01 21:11:19 +07:00
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
2017-10-02 09:54:47 +08:00
|
|
|
#include "..\headers\define.h"
|
2018-07-10 12:05:15 +08:00
|
|
|
#include "..\headers\command.h"
|
2017-04-01 21:11:19 +07:00
|
|
|
#include "main.h"
|
|
|
|
|
|
2019-03-03 11:00:30 +08:00
|
|
|
#define OBJ_DATA_LIGHT_DISTANCE (0x6C)
|
|
|
|
|
#define OBJ_DATA_LIGHT_INTENSITY (0x70)
|
|
|
|
|
|
2017-04-01 21:11:19 +07:00
|
|
|
variable
|
|
|
|
|
controlMode,
|
2019-02-20 21:26:23 +08:00
|
|
|
noCheckArray,
|
2017-10-02 09:54:47 +08:00
|
|
|
pidList,
|
2019-03-03 11:00:30 +08:00
|
|
|
lightInt, lightDist, npcControl,
|
|
|
|
|
displayName, displayNameColor,
|
2018-07-13 11:25:42 +08:00
|
|
|
inControl := false,
|
2017-10-02 09:54:47 +08:00
|
|
|
hasGeckoSkinning := false;
|
2017-05-23 22:28:42 +08:00
|
|
|
|
2017-04-01 21:11:19 +07:00
|
|
|
|
2019-02-20 21:26:23 +08:00
|
|
|
procedure AllowControl(variable pid) begin
|
|
|
|
|
if (noCheckArray or scan_array(pidList, pid bwand 0xFFFFFF) != -1) and (party_member_obj(pid)) then return true;
|
|
|
|
|
return false;
|
|
|
|
|
end
|
|
|
|
|
|
2017-04-01 21:11:19 +07:00
|
|
|
procedure combatturn_handler begin
|
|
|
|
|
variable
|
|
|
|
|
status := get_sfall_arg,
|
2017-05-23 22:28:42 +08:00
|
|
|
critter := get_sfall_arg,
|
2019-02-20 21:26:23 +08:00
|
|
|
//arg3 := get_sfall_arg,
|
2017-04-01 21:11:19 +07:00
|
|
|
pid;
|
2017-05-23 22:28:42 +08:00
|
|
|
|
2019-02-20 21:26:23 +08:00
|
|
|
//display_msg("Combat Turn: " + status + ", by " + obj_name(critter) + ", arg3: " + arg3);
|
2019-03-03 11:00:30 +08:00
|
|
|
if npcControl then begin
|
|
|
|
|
if lightInt then lightInt := round((lightInt / 65536.0) * 100); // calc percent of intensity
|
|
|
|
|
obj_set_light_level(npcControl, lightInt, lightDist); // restore/off light for NPC
|
|
|
|
|
end
|
|
|
|
|
|
2017-04-01 21:11:19 +07:00
|
|
|
pid := obj_pid(critter);
|
2019-02-20 21:26:23 +08:00
|
|
|
if (status == 1 and (AllowControl(pid) or controlMode == 1)) then begin
|
|
|
|
|
set_dude_obj(critter);
|
|
|
|
|
if (critter != real_dude_obj) then begin
|
2019-03-03 11:00:30 +08:00
|
|
|
if not(npcControl) then obj_set_light_level(real_dude_obj, 0, 0); // dude off light
|
|
|
|
|
npcControl := critter;
|
|
|
|
|
lightDist := get_object_data(critter, OBJ_DATA_LIGHT_DISTANCE);
|
|
|
|
|
lightInt := get_object_data(critter, OBJ_DATA_LIGHT_INTENSITY);
|
|
|
|
|
obj_set_light_level(critter, 100, 4);
|
|
|
|
|
|
2018-07-11 10:03:03 +08:00
|
|
|
if hasGeckoSkinning then critter_add_trait(critter, TRAIT_PERK, PERK_gecko_skinning_perk, 1);
|
2018-07-13 11:25:42 +08:00
|
|
|
inControl := true;
|
2019-03-03 11:00:30 +08:00
|
|
|
end else if npcControl then begin
|
|
|
|
|
obj_set_light_level(dude_obj, 100, 4); // set default light
|
|
|
|
|
npcControl := 0;
|
2018-07-11 10:03:03 +08:00
|
|
|
end
|
2018-07-13 11:25:42 +08:00
|
|
|
if inControl then begin
|
|
|
|
|
// center the screen on the controlled critter and remove roof tiles
|
|
|
|
|
move_to(dude_obj, dude_tile, dude_elevation);
|
2018-11-01 17:25:29 +08:00
|
|
|
if (displayName and critter != real_dude_obj) then begin
|
2018-07-13 11:25:42 +08:00
|
|
|
set_iface_tag_text(displayName, obj_name(critter), displayNameColor);
|
|
|
|
|
show_iface_tag(displayName);
|
|
|
|
|
end
|
2018-07-10 12:05:15 +08:00
|
|
|
end
|
2018-07-13 11:25:42 +08:00
|
|
|
end else if inControl then begin
|
|
|
|
|
if displayName then hide_iface_tag(displayName);
|
2019-02-20 21:26:23 +08:00
|
|
|
if (status == -1 or AllowControl(pid) == false) then begin
|
|
|
|
|
set_dude_obj(real_dude_obj);
|
2019-03-03 11:00:30 +08:00
|
|
|
obj_set_light_level(dude_obj, 100, 4);
|
|
|
|
|
npcControl := 0;
|
2019-02-20 21:26:23 +08:00
|
|
|
end
|
2017-04-01 21:11:19 +07:00
|
|
|
end
|
2018-07-13 11:25:42 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
procedure gamemodechange_handler begin
|
2019-02-20 21:26:23 +08:00
|
|
|
if not(hasGeckoSkinning) then hasGeckoSkinning := has_trait(TRAIT_PERK, real_dude_obj, PERK_gecko_skinning_perk);
|
|
|
|
|
if (inControl and not(get_game_mode BWAND COMBAT)) then begin
|
|
|
|
|
inControl := false;
|
|
|
|
|
if (dude_obj != real_dude_obj) then begin
|
|
|
|
|
set_dude_obj(real_dude_obj);
|
2019-03-03 11:00:30 +08:00
|
|
|
obj_set_light_level(dude_obj, 100, 4);
|
|
|
|
|
npcControl := 0;
|
2019-02-20 21:26:23 +08:00
|
|
|
end
|
|
|
|
|
move_to(dude_obj, dude_tile, dude_elevation);
|
|
|
|
|
end
|
2017-04-01 21:11:19 +07:00
|
|
|
end
|
|
|
|
|
|
2018-11-01 17:25:29 +08:00
|
|
|
procedure inventorymove_handler begin
|
|
|
|
|
if (inControl 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
|
|
|
|
|
|
2017-04-01 21:11:19 +07:00
|
|
|
procedure start begin
|
2018-11-01 17:25:29 +08:00
|
|
|
if (game_loaded and sfall_ver_major >= 4) then begin
|
2019-02-20 21:26:23 +08:00
|
|
|
variable configSection := "CombatControl";
|
|
|
|
|
|
2018-01-02 09:58:30 +08:00
|
|
|
set_perk_ranks(PERK_gecko_skinning_perk, 1);
|
2018-03-28 21:29:22 +08:00
|
|
|
set_perk_level(PERK_gecko_skinning_perk, 999); // prevent it from appearing in the perk selection window
|
2019-02-20 21:26:23 +08:00
|
|
|
|
2017-04-01 21:11:19 +07:00
|
|
|
controlMode := GetConfig("CombatControl", "Mode", 0);
|
|
|
|
|
if (controlMode > 2) then controlMode := 0;
|
|
|
|
|
if (controlMode > 0) then begin
|
2019-02-20 21:26:23 +08:00
|
|
|
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
|
|
|
|
|
|
2017-04-01 21:11:19 +07:00
|
|
|
pidList := GetConfigListInt("CombatControl", "PIDList");
|
|
|
|
|
fix_array(pidList);
|
2019-02-20 21:26:23 +08:00
|
|
|
noCheckArray := (len_array(pidList) == 0);
|
2017-05-23 22:28:42 +08:00
|
|
|
|
2017-04-01 21:11:19 +07:00
|
|
|
register_hook_proc(HOOK_COMBATTURN, combatturn_handler);
|
2018-07-13 11:25:42 +08:00
|
|
|
register_hook_proc(HOOK_GAMEMODECHANGE, gamemodechange_handler);
|
2018-11-01 17:25:29 +08:00
|
|
|
register_hook_proc(HOOK_INVENTORYMOVE, inventorymove_handler);
|
2017-04-01 21:11:19 +07:00
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|