/*

Auto Doors mod v1.2 for Fallout 2 by Mr.Stalin
----------------------------------------------

- allows the player to automatically open/walk through unlocked doors when not in combat

Requires sfall 3.7b or higher

NOTE: this script requires compiler from sfall modderspack with -s option (short circuit evaluation)

*/

/* Include Files */
#include "..\headers\define.h"
//#include "..\headers\command.h"
#include "..\..\scripting_docs\headers\sfall.h"
#include "..\..\scripting_docs\headers\define_extra.h"

/* Standard Script Procedures */
procedure start;
procedure map_enter_p_proc;

procedure set_door_flag(variable state);
procedure set_door_flag_array(variable state);
procedure combatturn_handler;

/* Defines */
#define PORTAL      (0)
#define DOOR_FLAGS  (0x24)

variable onlyOnce := 0;
variable pidDoors;

procedure start begin
   if game_loaded then begin
      if (sfall_ver_major >= 4) then
         register_hook_proc(HOOK_COMBATTURN, combatturn_handler);
      else
         set_global_script_repeat(40); // for sfall 3.x
      call map_enter_p_proc;
   end else begin
      if (onlyOnce == 1 and combat_is_initialized) then begin
         onlyOnce := 2;
         call set_door_flag(0); // reset flag when entering combat mode
      end else if (onlyOnce == 2 and not(combat_is_initialized)) then begin
         onlyOnce := 1;
         if (sfall_ver_major >= 4) then set_global_script_repeat(0);
         call set_door_flag(FLAG_WALKTHRU); // set flag after combat mode ends
      end
   end
end

procedure map_enter_p_proc begin
   if (pidDoors) then begin
      // when changing the map, delete the current array to create a new one
      free_array(pidDoors);
      pidDoors := 0;
   end
   onlyOnce := 1;
   call set_door_flag(FLAG_WALKTHRU); // set flag when entering the map
end

procedure set_door_flag(variable state) begin
   variable objectMap, obj, objPid, i;

   if (pidDoors) then begin
      call set_door_flag_array(state);
      return;
   end

   objectMap := list_as_array(LIST_SCENERY);
   pidDoors  := create_array(0, 0);

   foreach (obj in objectMap) begin
      objPid := obj_pid(obj);

      if (proto_data(objPid, sc_type) != PORTAL or get_proto_data(objPid, DOOR_FLAGS) or is_in_array(objPid, pidDoors)) then begin
         continue; // next object
      end

      resize_array(pidDoors, i + 1);
      pidDoors[i] := objPid; // add pid to array
      i++;
      set_proto_data(objPid, DOOR_FLAGS, state);
   end
end

procedure set_door_flag_array(variable state) begin
   variable objPid;
   foreach (objPid in pidDoors) begin
      set_proto_data(objPid, DOOR_FLAGS, state);
   end
end

procedure combatturn_handler begin
   if (onlyOnce == 1) then begin
      onlyOnce := 2;
      call set_door_flag_array(0);
      set_global_script_repeat(60);
   end
end
