--function printf() --end --' Смотрим ли мы сейчас туда, куда нужно или нет? class "eva_state_mgr_direction" (property_evaluator) function eva_state_mgr_direction:__init(name, st) super (nil, name) self.st = st end function eva_state_mgr_direction:evaluate() -- Если мы идем в смарткавер if self.st.target_state == "smartcover" then return true end local sight_type = self.object:sight_params() -- Если задан объект на который смотреть if self.st.look_object ~= nil then if sight_type.m_object == nil or sight_type.m_object:id() ~= self.st.look_object or self.st.point_obj_dir ~= look_object_type(self.object, self.st) then return false end self:callback() return true end -- Если задана позиция в которую смотреть if self.st.look_position ~= nil then if sight_type.m_sight_type ~= look_position_type(self.object, self.st) then --printf("false type") return false elseif sight_type.m_sight_type == CSightParams.eSightTypeAnimationDirection then return true end local dir = vector():sub(self.st.look_position, self.object:position()) if look_object_type(self.object, self.st) == true then dir.y = 0 end dir:normalize() if utils.vector_cmp_prec(sight_type.m_vector, dir, 0.01) ~= true then --printf("%s false vector", self.object:name()) --printf("%s %s %s", sight_type.m_vector.x, sight_type.m_vector.y, sight_type.m_vector.z) --printf("%s %s %s", dir.x, dir.y, dir.z) return false end self:callback() return true end -- Если не задано куда смотреть. -- И если мы до этого куда то смотрели if sight_type.m_object ~= nil then return false end --' Или если мы смотрели не так как надо if sight_type.m_sight_type ~= look_position_type(self.object, self.st) then return false end self:callback() return true end function eva_state_mgr_direction:callback() if self.st.callback ~= nil and self.st.callback.turn_end_func ~= nil then self.st.callback.turn_end_func(self.st.callback.obj) if self.st.callback ~= nil then self.st.callback.turn_end_func = nil end end end class "eva_state_mgr_direction_search" (property_evaluator) function eva_state_mgr_direction_search:__init(name, st) super (nil, name) self.st = st end function eva_state_mgr_direction_search:evaluate() if self.st.look_position ~= nil or self.st.look_object ~= nil then return false end return true end --' Включаем поворот class "act_state_mgr_direction_turn" (action_base) function act_state_mgr_direction_turn:__init(name, st) super (nil, name) self.st = st end function act_state_mgr_direction_turn:initialize() --printf("turning object %s ",self.object:name()) action_base.initialize(self) self:turn() end function act_state_mgr_direction_turn:execute() action_base.execute(self) --' Нельзя дергать дирекшн сталкера когда он в смарткавере... self:turn() end function act_state_mgr_direction_turn:finalize() action_base.finalize(self) end function act_state_mgr_direction_turn:turn() self.st.point_obj_dir = look_object_type(self.object, self.st) if self.st.look_object ~= nil and level.object_by_id(self.st.look_object) ~= nil then look_at_object(self.object, self.st) elseif self.st.look_position ~= nil then --' Если принудительно задано тип смотрения if state_lib.states[self.st.target_state].direction then --printf("SET STATE SIGHT! %s", tostring(self.st.target_state)) self.object:set_sight(CSightParams.eSightTypeAnimationDirection, false,false) return end local dir = vector():sub(self.st.look_position, self.object:position()) if self.st.point_obj_dir == true then dir.y = 0 end dir:normalize() if utils.vector_cmp(dir, vector():set(0,0,0)) then callstack() printf("Before normalize direction [%s]", vec_to_str(vector():sub(self.st.look_position, self.object:position()))) printf("You are trying to set wrong direction %s (look_pos = [%s] npc_pos = [%s])!!!", vec_to_str(dir), vec_to_str(self.st.look_position), vec_to_str(self.object:position())) -- Затычка, если дирекшн плохой, то ставим текущий и меняем позицию куда смотреть(для эвалуатора) self.st.look_position = vector():set(self.object:position().x + self.object:direction().x,self.object:position().y + self.object:direction().y,self.object:position().z + self.object:direction().z) dir = self.object:direction() end --printf("SET_SIGHT!!!act_state_mgr_direction_turn:turn() %s", vec_to_str(dir)) self.object:set_sight(look.direction, dir, true) end end function look_at_object(npc, st) st.point_obj_dir = look_object_type(npc, st) if st.point_obj_dir == true then npc:set_sight(level.object_by_id(st.look_object),true, false, false) else npc:set_sight(level.object_by_id(st.look_object),true, true) end end --' Включаем поворот в никуда class "act_state_mgr_direction_search" (action_base) function act_state_mgr_direction_search:__init(name, st) super (nil, name) self.st = st end function act_state_mgr_direction_search:initialize() action_base.initialize(self) --' Если принудительно задано тип смотрения if state_lib.states[self.st.target_state].direction and state_lib.states[self.st.target_state].direction == CSightParams.eSightTypeAnimationDirection then self.object:set_sight(CSightParams.eSightTypeAnimationDirection, false,false) else self.object:set_sight(look_position_type(self.object, self.st), nil, 0) end end function act_state_mgr_direction_search:execute() action_base.execute(self) end function act_state_mgr_direction_search:finalize() action_base.finalize(self) end local look_direction_states = { -- threat = true, threat_na = true, wait_na = true, guard_na = true } function look_object_type(npc, st) --' Возвращает true если нужно смотреть по направлению --' false - нужно смотреть на объект if look_direction_states[st.target_state] == true then return true end return state_lib.states[st.target_state].animation ~= nil end function look_position_type(npc, st) if st == nil then return look.path_dir end --' Если принудительно задано тип смотрения if state_lib.states[st.target_state].direction then return state_lib.states[st.target_state].direction end --' Для движения if not st.planner:evaluator(st.properties["movement_stand"]):evaluate() then if st.look_position ~= nil then return look.direction end return look.path_dir end --' Смотрим в позицию if st.look_position ~= nil then return look.direction end return look.danger end --' поворот function turn(npc, st) st.point_obj_dir = look_object_type(npc, st) if st.look_object ~= nil and level.object_by_id(st.look_object) ~= nil then look_at_object(npc, st) elseif st.look_position ~= nil then local dir = vector():sub(st.look_position, npc:position()) if st.point_obj_dir == true then dir.y = 0 end dir:normalize() if utils.vector_cmp(dir, vector():set(0,0,0)) then callstack() printf("Before normalize direction [%s]", vec_to_str(vector():sub(st.look_position, npc:position()))) printf("You are trying to set wrong direction %s (look_pos = [%s] npc_pos = [%s])!!!", vec_to_str(dir), vec_to_str(st.look_position), vec_to_str(npc:position())) -- Затычка, если дирекшн плохой, то ставим текущий и меняем позицию куда смотреть(для эвалуатора) st.look_position = vector():set(npc:position().x + npc:direction().x,npc:position().y + npc:direction().y,npc:position().z + npc:direction().z) dir = npc:direction() end npc:set_sight(look.direction, dir, true) end end