add game&rawdata
This commit is contained in:
parent
0133cd976c
commit
49b34b5546
45731 changed files with 709831 additions and 0 deletions
432
gamedata/scripts/xr_kamp.script
Normal file
432
gamedata/scripts/xr_kamp.script
Normal file
|
|
@ -0,0 +1,432 @@
|
|||
----------------------------------------------------------------------------------------------------------------------
|
||||
-- Схема лагерь. Чудак(и) у костра.
|
||||
-- автор: Диденко Руслан (Stohe)
|
||||
-- TODO:
|
||||
----------------------------------------------------------------------------------------------------------------------
|
||||
--function printf()
|
||||
--end
|
||||
|
||||
local ActionToStateTable = {
|
||||
idle = {director = { "sit", "sit_ass", "sit_knee", "eat_bread", "eat_kolbasa", "eat_vodka", "eat_energy"}, listener = {"sit", "sit_ass", "sit_knee", "eat_bread", "eat_kolbasa", "eat_vodka", "eat_energy"}},
|
||||
harmonica = {director = {"harmonica"}, listener = {"sit", "sit_ass", "sit_knee", "eat_bread", "eat_kolbasa", "eat_vodka", "eat_energy"}},
|
||||
guitar = {director = {"guitar"}, listener = {"sit", "sit_ass", "sit_knee", "eat_bread", "eat_kolbasa", "eat_vodka", "eat_energy"}},
|
||||
story = {director = {"sit", "sit_ass", "sit_knee"}, listener = {"sit", "sit_ass", "sit_knee", "eat_bread", "eat_kolbasa", "eat_vodka", "eat_energy"}},
|
||||
}
|
||||
|
||||
local ActionAvailabilityTable = {
|
||||
eat_bread = "kamp_eat_bread",
|
||||
eat_kolbasa = "kamp_eat_kolbasa",
|
||||
eat_vodka = "kamp_drink_vodka",
|
||||
eat_energy = "kamp_drink_energy",
|
||||
}
|
||||
|
||||
local ActionTimingTable = {
|
||||
sit = {min = 60*2*1000,max = 60*10*1000},
|
||||
sit_ass = {min =60*2*1000,max = 60*10*1000},
|
||||
sit_knee = {min = 60*2*1000,max = 60*10*1000}
|
||||
}
|
||||
|
||||
|
||||
kamps = {}
|
||||
---------------------------------------------------------------------------------------------------------------------
|
||||
--Evaluators
|
||||
----------------------------------------------------------------------------------------------------------------------
|
||||
--' Условие завершения скрипта
|
||||
class "evaluator_kamp_end" (property_evaluator)
|
||||
function evaluator_kamp_end:__init(name, storage) super (nil, name)
|
||||
self.a = storage
|
||||
end
|
||||
function evaluator_kamp_end:evaluate()
|
||||
return not xr_logic.is_active(self.object, self.a)
|
||||
end
|
||||
--' Находимся ли мы на заданной позиции
|
||||
class "evaluator_on_position" (property_evaluator)
|
||||
function evaluator_on_position:__init(name, storage) super (nil, name)
|
||||
self.a = storage
|
||||
end
|
||||
function evaluator_on_position:evaluate()
|
||||
if self.object:level_vertex_id() == self.a.pos_vertex then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
----------------------------------------------------------------------------------------------------------------------
|
||||
--Actions
|
||||
----------------------------------------------------------------------------------------------------------------------
|
||||
--' Идет в заданную область
|
||||
class "action_go_position" (action_base)
|
||||
function action_go_position:__init (npc_name,action_name,storage) super (nil,action_name)
|
||||
self.a = storage
|
||||
end
|
||||
function action_go_position:initialize()
|
||||
action_base.initialize(self)
|
||||
-- self.object:set_node_evaluator()
|
||||
-- self.object:set_path_evaluator()
|
||||
self.object:set_desired_position()
|
||||
self.object:set_desired_direction()
|
||||
|
||||
self.a.pos_vertex = nil
|
||||
self.a.npc_position_num = nil
|
||||
self.a.signals = {}
|
||||
end
|
||||
function action_go_position:execute ()
|
||||
action_base.execute (self)
|
||||
|
||||
-- Спрашиваем где сидеть
|
||||
local tmp_pos_vertex, npc_position_num = kamps[self.a.center_point]:getDestVertex(self.object, self.a.radius)
|
||||
|
||||
if tmp_pos_vertex == nil then
|
||||
return
|
||||
end
|
||||
|
||||
if self.a.npc_position_num ~= npc_position_num then
|
||||
self.a.npc_position_num = npc_position_num
|
||||
self.a.pos_vertex = tmp_pos_vertex
|
||||
|
||||
--' Определяем куда смотреть.
|
||||
self.a.pp = patrol(self.a.center_point):point(0)
|
||||
|
||||
local dir = vector():set(math.random(-1,1), 0, math.random(-1,1))
|
||||
dir:normalize()
|
||||
|
||||
local delta_dist = math.random(0,0.5)
|
||||
self.a.pp.x = self.a.pp.x + dir.x * delta_dist
|
||||
self.a.pp.z = self.a.pp.z + dir.z * delta_dist
|
||||
|
||||
|
||||
|
||||
self.object:set_dest_level_vertex_id(self.a.pos_vertex)
|
||||
--printf("vertex_position")
|
||||
local desired_direction = vector():sub(self.a.pp,level.vertex_position(self.a.pos_vertex))
|
||||
--printf("desired_direction = %s", vec_to_str(desired_direction))
|
||||
if desired_direction ~= nil and not utils.vector_cmp(desired_direction, vector():set(0,0,0)) then
|
||||
desired_direction:normalize()
|
||||
self.object:set_desired_direction(desired_direction)
|
||||
end
|
||||
self.object:set_path_type(game_object.level_path)
|
||||
state_mgr.set_state(self.object, self.a.def_state_moving)
|
||||
end
|
||||
end
|
||||
function action_go_position:finalize ()
|
||||
action_base.finalize (self)
|
||||
end
|
||||
|
||||
--' Просто сидит и втыкает
|
||||
class "action_wait" (action_base)
|
||||
function action_wait:__init (npc_name,action_name,storage) super (nil,action_name)
|
||||
self.a = storage
|
||||
end
|
||||
function action_wait:initialize()
|
||||
action_base.initialize(self)
|
||||
-- self.object:set_node_evaluator()
|
||||
-- self.object:set_path_evaluator()
|
||||
self.object:set_desired_position()
|
||||
self.object:set_desired_direction()
|
||||
|
||||
local avail_actions = xr_animpoint_predicates.associations[self.a.description]
|
||||
self.a.approved_actions = {}
|
||||
|
||||
for k,v in pairs(avail_actions) do
|
||||
-- Убираем те действия, которые не подходят по прекондишну
|
||||
if v.predicate(self.object:id(),true)==true then
|
||||
table.insert(self.a.approved_actions, v)
|
||||
kamps[self.a.center_point]:AddAvailableAction(self.object,v.name)
|
||||
end
|
||||
end
|
||||
|
||||
kamps[self.a.center_point]:increasePops(self.object)
|
||||
|
||||
end
|
||||
function action_wait:activate_scheme()
|
||||
self.a.signals = {}
|
||||
end
|
||||
function action_wait:execute()
|
||||
-- action_base.execute (self)
|
||||
|
||||
-- --' повернуть его лицом к центру
|
||||
-- state_mgr.set_state(self.object, "sit", nil, nil, {look_position = self.a.pp})
|
||||
|
||||
action_base.execute (self)
|
||||
local state = kamps[self.a.center_point]:updateNpc(self.object)
|
||||
|
||||
--' повернуть его лицом к центру
|
||||
state_mgr.set_state(self.object, state, nil, nil, {look_position = self.a.pp})
|
||||
end
|
||||
function action_wait:finalize()
|
||||
kamps[self.a.center_point]:decreasePops(self.object)
|
||||
action_base.finalize (self)
|
||||
end
|
||||
function action_wait:deactivate(npc)
|
||||
kamps[self.a.center_point]:removeNpc(npc)
|
||||
end
|
||||
function action_wait:death_callback(npc)
|
||||
kamps[self.a.center_point]:removeNpc(npc)
|
||||
end
|
||||
function action_wait:net_destroy(npc)
|
||||
kamps[self.a.center_point]:removeNpc(npc)
|
||||
end
|
||||
|
||||
|
||||
class "CKampManager"
|
||||
function CKampManager:__init(path)
|
||||
self.kamp_name = path
|
||||
self.patrol = patrol(path)
|
||||
--self.center = self.patrol:level_vertex_id(0)
|
||||
self.position = {{dir = vector():set(1, 0, 0), used = nil},
|
||||
{dir = vector():set(1, 0, 1), used = nil},
|
||||
{dir = vector():set(0, 0, 1), used = nil},
|
||||
{dir = vector():set(-1, 0, 1), used = nil},
|
||||
{dir = vector():set(-1, 0, 0), used = nil},
|
||||
{dir = vector():set(-1, 0, -1),used = nil},
|
||||
{dir = vector():set(0, 0, -1), used = nil},
|
||||
{dir = vector():set(1, 0, -1), used = nil}}
|
||||
self.npc = {}
|
||||
self.population = 0
|
||||
end
|
||||
function CKampManager:selectPosition(npc_id)
|
||||
-- создаем список доступных позиций
|
||||
--printf("KAMP. [%s] called select position", npc_id)
|
||||
local free = {}
|
||||
for k,v in pairs(self.position) do
|
||||
if v.used == nil then
|
||||
table.insert(free, k)
|
||||
end
|
||||
end
|
||||
--' затем из доступных позиций выбрать рандомно одну.
|
||||
if #free > 0 then
|
||||
--printf("KAMP [%s] free node > 0", npc_id)
|
||||
local rr = math.random(#free)
|
||||
self.position[free[rr]].used = npc_id
|
||||
self.npc[npc_id].position = free[rr]
|
||||
end
|
||||
--printf("KAMP [%s] npc table", npc_id)
|
||||
--print_table(self.npc)
|
||||
--printf("KAMP [%s] position table", npc_id)
|
||||
--print_table(self.position)
|
||||
end
|
||||
function CKampManager:getDestVertex(npc, radius)
|
||||
local npc_id = npc:id()
|
||||
--printf("get dest Vertex called [%s]", npc_id)
|
||||
if self.npc[npc_id].position == nil then
|
||||
--printf("-------debug_info------------- %s", self.kamp_name)
|
||||
--print_table(self.npc)
|
||||
--printf("-------debug_info------------- %s", self.kamp_name)
|
||||
--print_table(self.position)
|
||||
--printf("-------debug_info------------- %s", self.kamp_name)
|
||||
abort("get dest Vertex: nil [%s]", npc_id)
|
||||
return nil
|
||||
end
|
||||
|
||||
-- высчитываем вертех по направлению
|
||||
-- Берем позицию в заданном направлении, затем берем ниарест точку от нее.
|
||||
|
||||
local pp = self.patrol:point(0)
|
||||
local dir = self.position[self.npc[npc_id].position].dir
|
||||
|
||||
-- Считаем рандомное отклонение направления.
|
||||
dir.x = dir.x + math.random(-1,1)/5
|
||||
dir.z = dir.z + math.random(-1,1)/5
|
||||
dir:normalize()
|
||||
|
||||
radius = radius + math.random(-0.3,0.3)
|
||||
|
||||
local dest_vertex = 4294967295
|
||||
|
||||
while dest_vertex == 4294967295 do
|
||||
local tmp_pos = vector():set(0,0,0)
|
||||
tmp_pos.x = pp.x + dir.x * radius
|
||||
tmp_pos.z = pp.z + dir.z * radius
|
||||
tmp_pos.y = pp.y
|
||||
dest_vertex = level.vertex_id(tmp_pos)
|
||||
if dest_vertex == 4294967295 then
|
||||
if radius < 1 then
|
||||
SemiLog("Invalid AI map at kamp point ["..self.kamp_name.."]")
|
||||
return nil
|
||||
else
|
||||
radius = radius - 0.5
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if not npc:accessible(dest_vertex) then
|
||||
--printf("vertex_position %s", tostring(dest_vertex))
|
||||
local vp = level.vertex_position(dest_vertex)
|
||||
--printf("Nearest for npc[%s] kamp [%s] position [%s:%s:%s]", npc:name(), tostring(self.kamp_name),tostring(vp.x), tostring(vp.y), tostring(vp.z))
|
||||
local nearest_vertex = npc:accessible_nearest(vp, vector():set(0,0,0))
|
||||
--printf("Nearest for npc[%s] kamp [%s] position [%s:%s:%s]", npc:name(), tostring(self.kamp_name), vec_to_str(nearest_vertex))
|
||||
return nearest_vertex, self.npc[npc_id].position
|
||||
end
|
||||
|
||||
return dest_vertex, self.npc[npc_id].position
|
||||
end
|
||||
|
||||
function CKampManager:updateNpc(npc)
|
||||
|
||||
local tbl = {}
|
||||
local npc_id = npc:id()
|
||||
local camp_action, is_director
|
||||
|
||||
if not self.camp then
|
||||
camp_action = "idle"
|
||||
is_director = false
|
||||
else
|
||||
camp_action, is_director = self.camp:get_camp_action(npc_id)
|
||||
end
|
||||
|
||||
|
||||
if(is_director) then
|
||||
tbl = ActionToStateTable[camp_action].director
|
||||
else
|
||||
tbl = ActionToStateTable[camp_action].listener
|
||||
end
|
||||
|
||||
if self.npc[npc_id].begin == nil or time_global() - self.npc[npc_id].begin >= self.npc[npc_id].state_idle or self.npc[npc_id].is_director ~= is_director then
|
||||
self.npc[npc_id].begin = time_global()
|
||||
if (self.npc[npc_id].camp_action == "story" or self.npc[npc_id].camp_action == "idle") and (camp_action =="idle" or camp_action == "story") and self.npc[npc_id].is_director ~= is_director then
|
||||
self.npc[npc_id].is_director = is_director
|
||||
self.npc[npc_id].camp_action = camp_action
|
||||
return self.npc[npc_id].state_selected
|
||||
end
|
||||
local Action = "kamp"
|
||||
repeat
|
||||
local rnd = math.random(#tbl)
|
||||
self.npc[npc_id].state_selected = tbl[rnd]
|
||||
if ActionAvailabilityTable[self.npc[npc_id].state_selected] then
|
||||
Action = ActionAvailabilityTable[self.npc[npc_id].state_selected]
|
||||
else
|
||||
Action = "kamp"
|
||||
end
|
||||
until self.npc[npc_id].AvailableActions[Action]
|
||||
|
||||
if ActionTimingTable[self.npc[npc_id].state_selected] ~= nil then
|
||||
self.npc[npc_id].state_idle = math.random(ActionTimingTable[self.npc[npc_id].state_selected].min,ActionTimingTable[self.npc[npc_id].state_selected].max)
|
||||
else
|
||||
self.npc[npc_id].state_idle = math.random(15*1000,60*1000)
|
||||
end
|
||||
self.npc[npc_id].is_director = is_director
|
||||
self.npc[npc_id].camp_action = camp_action
|
||||
end
|
||||
return self.npc[npc_id].state_selected
|
||||
|
||||
end
|
||||
|
||||
function CKampManager:addNpc(npc)
|
||||
if self.npc[npc:id()] ~= nil then
|
||||
return
|
||||
end
|
||||
|
||||
self.npc[npc:id()] = {name = npc:name(), position = nil, AvailableActions = {}}
|
||||
self:selectPosition(npc:id())
|
||||
|
||||
end
|
||||
function CKampManager:removeNpc(npc)
|
||||
local npc_id = npc:id()
|
||||
if self.npc[npc_id] ~= nil then
|
||||
self.position[self.npc[npc_id].position].used = nil
|
||||
self.npc[npc_id] = nil
|
||||
end
|
||||
|
||||
if self.camp ~= nil then
|
||||
self.camp:unregister_npc(npc:id())
|
||||
end
|
||||
end
|
||||
|
||||
function CKampManager:increasePops(npc)
|
||||
self.population = self.population + 1
|
||||
|
||||
if not self.camp then
|
||||
self.camp = sr_camp.get_current_camp(self.patrol:point(0))
|
||||
end
|
||||
|
||||
if self.camp ~= nil then
|
||||
self.camp:register_npc(npc:id())
|
||||
end
|
||||
-- local campfire = bind_campfire.campfire_table[self.kamp_name.."_campfire"]
|
||||
-- if self.population > 0 and campfire ~= nil and not campfire:is_on() then
|
||||
-- campfire:turn_on()
|
||||
-- end
|
||||
end
|
||||
function CKampManager:decreasePops(npc)
|
||||
self.population = self.population - 1
|
||||
-- local campfire = bind_campfire.campfire_table[self.kamp_name.."_campfire"]
|
||||
-- if self.population < 1 and campfire ~= nil and campfire:is_on() then
|
||||
-- campfire:turn_off()
|
||||
-- end
|
||||
end
|
||||
|
||||
function CKampManager:AddAvailableAction(NPC,StateName)
|
||||
self.npc[NPC:id()].AvailableActions[StateName] = true
|
||||
end
|
||||
|
||||
|
||||
|
||||
----------------------------------------------------------------------------------------------------------------------
|
||||
--Kamp binder
|
||||
----------------------------------------------------------------------------------------------------------------------
|
||||
function add_to_binder(object, ini, scheme, section, storage)
|
||||
local operators = {}
|
||||
local properties = {}
|
||||
|
||||
local manager = object:motivation_action_manager()
|
||||
|
||||
properties["kamp_end"] = xr_evaluators_id.stohe_kamp_base + 1
|
||||
properties["on_position"] = xr_evaluators_id.stohe_kamp_base + 2
|
||||
properties["contact"] = xr_evaluators_id.stohe_meet_base + 1
|
||||
|
||||
operators["go_position"] = xr_actions_id.stohe_kamp_base + 1
|
||||
operators["wait"] = xr_actions_id.stohe_kamp_base + 3
|
||||
properties["state_mgr_logic_active"] = xr_evaluators_id.state_mgr + 4
|
||||
|
||||
-- Evaluators
|
||||
manager:add_evaluator (properties["kamp_end"], this.evaluator_kamp_end ("kamp_end", storage, "kamp_end"))
|
||||
manager:add_evaluator (properties["on_position"], this.evaluator_on_position ("kamp_on_position", storage, "kamp_on_position"))
|
||||
|
||||
-- Actions
|
||||
local action = this.action_wait (object:name(),"action_kamp_wait", storage)
|
||||
action:add_precondition (world_property(stalker_ids.property_alive, true))
|
||||
action:add_precondition (world_property(stalker_ids.property_danger,false))
|
||||
action:add_precondition (world_property(stalker_ids.property_enemy, false))
|
||||
action:add_precondition (world_property(stalker_ids.property_anomaly,false))
|
||||
xr_motivator.addCommonPrecondition(action)
|
||||
action:add_precondition (world_property(properties["on_position"], true))
|
||||
action:add_effect (world_property(properties["kamp_end"], true))
|
||||
action:add_effect (world_property(properties["state_mgr_logic_active"], false))
|
||||
manager:add_action (operators["wait"], action)
|
||||
xr_logic.subscribe_action_for_events(object, storage, action)
|
||||
|
||||
action = this.action_go_position (object:name(),"action_go_kamp", storage)
|
||||
action:add_precondition (world_property(stalker_ids.property_alive, true))
|
||||
action:add_precondition (world_property(stalker_ids.property_danger,false))
|
||||
action:add_precondition (world_property(stalker_ids.property_enemy, false))
|
||||
action:add_precondition (world_property(stalker_ids.property_anomaly,false))
|
||||
xr_motivator.addCommonPrecondition(action)
|
||||
action:add_precondition (world_property(properties["on_position"], false))
|
||||
action:add_effect (world_property(properties["on_position"], true))
|
||||
action:add_effect (world_property(properties["state_mgr_logic_active"], false))
|
||||
manager:add_action (operators["go_position"], action)
|
||||
|
||||
action = manager:action (xr_actions_id.alife)
|
||||
action:add_precondition (world_property(properties["kamp_end"], true))
|
||||
|
||||
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.center_point = utils.cfg_get_string(ini, section, "center_point", npc, true, gulag_name)
|
||||
st.radius = utils.cfg_get_number(ini, section, "radius", npc, false, 2)
|
||||
st.description = "kamp"
|
||||
st.base_action = "kamp"
|
||||
|
||||
|
||||
|
||||
if kamps[st.center_point] == nil then
|
||||
kamps[st.center_point] = CKampManager(st.center_point)
|
||||
end
|
||||
kamps[st.center_point]:addNpc(npc)
|
||||
st.pos_vertex = nil
|
||||
|
||||
st.def_state_moving = utils.cfg_get_string(ini, section, "def_state_moving", npc, false, "", "walk")
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue