/*
   Example implementation of the algorithm of how the game engine checks if one critter sees another critter.
*/

#include "..\headers\define.h"
#include "..\headers\command.h"
#include "..\headers\sfall\sfall.h"
#include "..\headers\sfall\define_extra.h"

procedure start;
procedure can_see(variable obj1, variable obj2);

procedure start begin
   if game_loaded then begin
      register_hook(HOOK_WITHINPERCEPTION);
   end else begin
      variable
         source := get_sfall_arg,
         target := get_sfall_arg,
         engine := get_sfall_arg,
         type   := get_sfall_arg, /* new arg */
         result := 0,
         distance, seeDistance, seeText;

      if target then begin
         seeDistance := get_critter_stat(source, STAT_pe);

         if can_see(source, target) then begin
            seeDistance *= 5;
            if (get_flags(target) bwand FLAG_TRANSGLASS) then seeDistance /= 2;
         end else if combat_is_initialized then begin
            seeDistance *= 2;
         end

         if (target == dude_obj) then begin
            if sneak_success then begin
               seeDistance /= 4;
               if has_skill(target, SKILL_SNEAK) > 120 then seeDistance -= 1;
            end else if dude_is_sneaking then begin
               seeDistance := (seeDistance * 2) / 3;  // distance div 1.5
            end
         end

         distance := tile_distance_objs(source, target);
         if (get_flags(source) bwand FLAG_MULTIHEX) then distance--;
         if (get_flags(target) bwand FLAG_MULTIHEX) then distance--;

         if (distance <= seeDistance) then result := 1;

         seeText = " does not see > ";
         if (result) then seeText = " sees > ";

         // Example
         display_msg("hs_withinperception: " + obj_name(source) + seeText + obj_name(target) + " [engine: " + engine + ", script: " + result + "]");

         /* override engine result */
         //set_sfall_return(result);
      end
   end
end

procedure can_see(variable obj1, variable obj2) begin
   variable dir = obj_get_rot(obj1) - rotation_to_tile(tile_num(obj1), tile_num(obj2));
   if (dir < 0) then dir = -dir;
   return (dir <= 1) or (dir == 5);
end
