290 lines
9.5 KiB
Text
290 lines
9.5 KiB
Text
|
|
----------------------------------------------------------------------------------------------------
|
|
-- Mob remarks
|
|
----------------------------------------------------------------------------------------------------
|
|
-- Ðàçðàáîò÷èê: Andrey Fidrya (Zmey) af@svitonline.com
|
|
-- Èñõîäíûé ñêðèïò (trader): Evgeniy Negrobov (Jon) jon@gsc-game.kiev.ua
|
|
----------------------------------------------------------------------------------------------------
|
|
|
|
local default_wait_time = 5000 -- âðåìÿ â ms, èëè nil äëÿ anim_end condition
|
|
local default_anim_standing = anim.stand_idle
|
|
|
|
local state_moving = 0
|
|
local state_standing = 1
|
|
|
|
class "mob_walker"
|
|
|
|
function mob_walker:__init(obj, storage)
|
|
self.object = obj
|
|
self.st = storage
|
|
end
|
|
|
|
function mob_walker:reset_scheme()
|
|
printf("_bp: mob_walker:reset_scheme: %s", self.object:name())
|
|
|
|
mob_state_mgr.set_state(self.object, db.actor, self.st.state)
|
|
|
|
self.st.signals = {}
|
|
|
|
xr_logic.mob_capture(self.object, true)
|
|
|
|
self.patrol_walk = patrol(self.st.path_walk)
|
|
if not self.patrol_walk then
|
|
abort("object '%s': unable to find path_walk '%s' on the map",
|
|
self.object:name(), self.st.path_walk)
|
|
end
|
|
|
|
if self.st.path_look then
|
|
self.patrol_look = patrol(self.st.path_look)
|
|
if not self.patrol_look then
|
|
abort("object '%s': unable to find path_look '%s' on the map",
|
|
self.object:name(), self.st.path_look)
|
|
end
|
|
else
|
|
self.patrol_look = nil
|
|
end
|
|
|
|
if self.st.path_walk_info == nil then
|
|
self.st.path_walk_info = utils.path_parse_waypoints(self.st.path_walk)
|
|
self.path_walk_info = self.st.path_walk_info
|
|
end
|
|
if self.st.path_look_info == nil then
|
|
self.st.path_look_info = utils.path_parse_waypoints(self.st.path_look)
|
|
self.path_look_info = self.st.path_look_info
|
|
end
|
|
|
|
self.state = state_moving
|
|
|
|
self.crouch = false
|
|
self.running = false
|
|
self.cur_anim_set = default_anim_standing
|
|
self.pt_wait_time = default_wait_time -- ñêîëüêî æäàòü â òî÷êå, ãäå èãðàåì àíèìàöèþ
|
|
|
|
self.scheduled_snd = nil
|
|
|
|
self.last_index = nil
|
|
self.last_look_index = nil
|
|
|
|
action(self.object, move(move.walk_fwd, patrol(self.st.path_walk, patrol.next, patrol.continue)),
|
|
cond(cond.move_end))
|
|
end
|
|
|
|
function mob_walker:update(delta)
|
|
-- printf("__bp: mob_walker update: %d", time_global())
|
|
--if not xr_logic.is_active(self.object, self.st) then
|
|
-- return
|
|
--end
|
|
local actor = db.actor
|
|
-- Ìîíñòð ïîñëå âûõîäà èç alife ìîæåò óæå áûòü íå ïîä ñêðèïòîì, ïîýòîìó âçÿòü îïÿòü ïîä ñêðèïò
|
|
if not xr_logic.mob_captured(self.object) then
|
|
self:reset_scheme()
|
|
return
|
|
end
|
|
--[[
|
|
if self:arrived_to_first_waypoint() then
|
|
if xr_logic.try_switch_to_another_section(self.object, self.st, actor) then
|
|
return
|
|
end
|
|
end
|
|
]]
|
|
if self.state == state_standing then
|
|
if not self.object:action() then
|
|
local patrol_walk_count = self.patrol_walk:count()
|
|
if patrol_walk_count == 1 and utils.stalker_at_waypoint(self.object, self.patrol_walk, 0) then
|
|
self.state = state_moving
|
|
self:waypoint_callback(self.object, nil, self.last_index)
|
|
else
|
|
self.last_look_index = nil
|
|
self.state = state_moving
|
|
self:update_movement_state() -- èäòè äàëüøå
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function mob_walker:arrived_to_first_waypoint()
|
|
return self.last_index ~= nil
|
|
end
|
|
|
|
function mob_walker:waypoint_callback(obj, action_type, index)
|
|
printf("mob_walker:waypoint_callback(): name=%s, index=%d", self.object:name(), index)
|
|
if index == -1 or index == nil then
|
|
printf("ERROR: mob_walker: waypoint_callback: index is %s", if_then_else(index == -1, "-1", "nil"))
|
|
return
|
|
end
|
|
|
|
self.last_index = index
|
|
|
|
local suggested_snd = self.path_walk_info[index]["s"]
|
|
if suggested_snd then
|
|
self.scheduled_snd = suggested_snd
|
|
end
|
|
|
|
local suggested_crouch = self.path_walk_info[index]["c"]
|
|
if suggested_crouch == "true" then
|
|
self.crouch = true
|
|
else
|
|
self.crouch = false
|
|
end
|
|
|
|
local suggested_running = self.path_walk_info[index]["r"]
|
|
if suggested_running == "true" then
|
|
self.running = true
|
|
else
|
|
self.running = false
|
|
end
|
|
|
|
local sig = self.path_walk_info[index]["sig"]
|
|
if sig then
|
|
-- HACK, fixme:
|
|
local npc_id = self.object:id()
|
|
local scheme = db.storage[npc_id]["active_scheme"]
|
|
local signals = db.storage[npc_id][scheme].signals
|
|
signals[sig] = true
|
|
printf("_bp: mob_walker [%s]: SIGNALLING: %s", self.object:name(), sig)
|
|
end
|
|
|
|
local beh = self.path_walk_info[index]["b"]
|
|
if beh then
|
|
mob_state_mgr.set_state(self.object, db.actor, beh)
|
|
else
|
|
mob_state_mgr.set_state(self.object, db.actor, self.st.state)
|
|
end
|
|
|
|
local search_for = self.path_walk_info[index].flags
|
|
if search_for:get() == 0 then
|
|
-- TODO: çàïðåòèòü îäíîòî÷å÷íûå ïóòè áåç ñîîòâåòñòâóþùåãî path_look ïî àíàëîãèè ñ move_mgr
|
|
printf("_bp: no flags")
|
|
self:update_movement_state() -- èäòè äàëüøå
|
|
return
|
|
end
|
|
|
|
local pt_chosen_idx = move_mgr.choose_look_point(self.patrol_look, self.path_look_info, search_for)
|
|
if pt_chosen_idx then
|
|
local suggested_wait_time = self.path_look_info[pt_chosen_idx]["t"]
|
|
if suggested_wait_time then
|
|
self.pt_wait_time = tonumber(suggested_wait_time)
|
|
else
|
|
local patrol_walk_count = self.patrol_walk:count()
|
|
if patrol_walk_count == 1 and utils.stalker_at_waypoint(self.object, self.patrol_walk, 0) then
|
|
self.pt_wait_time = time_infinite
|
|
else
|
|
self.pt_wait_time = default_wait_time
|
|
end
|
|
end
|
|
|
|
local suggested_anim_set = self.path_look_info[pt_chosen_idx]["a"]
|
|
if suggested_anim_set then
|
|
if suggested_anim_set == "nil" then
|
|
suggested_anim_set = nil
|
|
end
|
|
self.cur_anim_set = anim[xr_logic.pick_section_from_condlist(db.actor, self.object, suggested_anim_set)]
|
|
else
|
|
self.cur_anim_set = default_anim_standing
|
|
end
|
|
|
|
local beh = self.path_walk_info[index]["b"]
|
|
if beh then
|
|
mob_state_mgr.set_state(self.object, db.actor, beh)
|
|
else
|
|
mob_state_mgr.set_state(self.object, db.actor, self.st.state)
|
|
end
|
|
|
|
if pt_chosen_idx ~= self.last_look_index then -- åñëè óæå ñìîòðåëè òóäà - íå ïîâîðà÷èâàòüñÿ
|
|
self:look_at_waypoint(pt_chosen_idx) -- ïîâîðà÷èâàåìñÿ
|
|
end
|
|
self.state = state_standing
|
|
self:update_standing_state()
|
|
|
|
-- Ñðàçó æå ñòàðòîâàòü update, íå æäàòü execute. Òîãäà, åñëè ìû óæå ñìîòðèì
|
|
-- â íóæíóþ ñòîðîíó - íå áóäåò ïàóçû â íåñêîëüêî ìèëëèñåêóíä íà ïîâîðîò.
|
|
self:update(true)
|
|
else
|
|
abort("object '%s': path_walk '%s', index %d: cannot find corresponding point(s) on path_look '%s'",
|
|
self.object:name(), self.path_walk, index, self.path_look)
|
|
end
|
|
end
|
|
|
|
function mob_walker:update_movement_state()
|
|
printf("_bp [%s]: update_movement_state", self.object:name())
|
|
xr_logic.mob_capture(self.object, true)
|
|
|
|
local m
|
|
if self.running then
|
|
m = move.run_fwd
|
|
elseif self.crouch then
|
|
m = move.steal
|
|
else
|
|
m = move.walk_fwd
|
|
end
|
|
|
|
if self.scheduled_snd then
|
|
printf("_bp [%s]: playing scheduled sound", self.object:name())
|
|
action(self.object, move(m, patrol(self.st.path_walk, patrol.next, patrol.continue)),
|
|
sound(sound[self.scheduled_snd]), cond(cond.move_end))
|
|
self.scheduled_snd = nil
|
|
else
|
|
action(self.object, move(m, patrol(self.st.path_walk, patrol.next, patrol.continue)), cond(cond.move_end))
|
|
end
|
|
end
|
|
|
|
function mob_walker:update_standing_state()
|
|
printf("_bp [%s]: update_standing_state", self.object:name())
|
|
xr_logic.mob_capture(self.object, true)
|
|
if self.scheduled_snd then
|
|
printf("_bp [%s]: playing scheduled sound", self.object:name())
|
|
action(self.object, anim(self.cur_anim_set, 0),
|
|
sound(sound[self.scheduled_snd]), cond(cond.time_end, self.pt_wait_time))
|
|
self.scheduled_snd = nil
|
|
else
|
|
action(self.object, anim(self.cur_anim_set, 0), cond(cond.time_end, self.pt_wait_time))
|
|
end
|
|
end
|
|
|
|
function mob_walker:deactivate()
|
|
xr_logic.mob_capture(self.object, true)
|
|
action(self.object, move(move.steal, self.patrol_walk:point(0)), cond(cond.move_end))
|
|
end
|
|
|
|
function mob_walker:look_at_waypoint(pt)
|
|
if not self.patrol_look then
|
|
return
|
|
end
|
|
|
|
local look_pt = utils.vector_copy_by_val(self.patrol_look:point(pt)):sub(self.object:position())
|
|
look_pt:normalize()
|
|
--self.object:set_sight(look.direction, look_pt, 0)
|
|
|
|
xr_logic.mob_capture(self.object, true)
|
|
action(self.object, look(look.direction, look_pt), cond(cond.look_end))
|
|
|
|
self.last_look_index = pt
|
|
end
|
|
|
|
---------------------------------------------------------------------------------------------------------------------
|
|
function add_to_binder(npc, ini, scheme, section, storage)
|
|
printf("DEBUG: add_to_binder: npc:name()='%s', scheme='%s', section='%s'", npc:name(), scheme, section)
|
|
|
|
local new_action = mob_walker(npc, storage)
|
|
|
|
-- Çàðåãèñòðèðîâàòü âñå actions, â êîòîðûõ äîëæåí áûòü âûçâàí ìåòîä reset_scheme ïðè èçìåíåíèè íàñòðîåê ñõåìû:
|
|
xr_logic.subscribe_action_for_events(npc, storage, new_action)
|
|
end
|
|
|
|
function set_scheme(npc, ini, scheme, section, gulag_name)
|
|
local st = xr_logic.assign_storage_and_bind(npc, ini, scheme, section)
|
|
|
|
st.logic = xr_logic.cfg_get_switch_conditions(ini, section, npc)
|
|
st.state = mob_state_mgr.get_state(ini, section, npc)
|
|
st.no_reset = utils.cfg_get_bool(ini, section, "no_reset", npc, false)
|
|
st.path_walk = utils.cfg_get_string(ini, section, "path_walk", npc, true, gulag_name)
|
|
st.path_look = utils.cfg_get_string(ini, section, "path_look", npc, false, gulag_name)
|
|
|
|
if st.path_walk == st.path_look then
|
|
abort("You are trying to set 'path_look' equal to 'path_walk' in section [%s] for npc [%s]", section, npc:name())
|
|
end
|
|
|
|
st.path_walk_info = nil -- Áóäóò èíèöèàëèçèðîâàíû â reset(), ñåé÷àñ ïóòè ìîãóò áûòü åùå
|
|
st.path_look_info = nil -- íå çàãðóæåíû.
|
|
end
|
|
|