Advertisement
Guest User

spawn_manager.script

a guest
Jul 1st, 2012
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.39 KB | None | 0 0
  1. -----------------------------------------
  2. -- spawn_manager.script
  3. --
  4. -- Alundaio
  5. -----------------------------------------
  6.  
  7.  
  8. -- storage for spawned objects
  9. local Objects = {}
  10.  
  11. -- Spawner Table and Index
  12. local SpawnerIndex = {}
  13. local Spawner = {}
  14.  
  15. local ini = ini_file("spawn_manager\\spawn_manager.ltx")
  16. local initialized = false
  17. function init()
  18.     local SpawnerSections = collect_sections(ini,{"sections"})
  19.  
  20.     for k,v in pairs(SpawnerSections) do
  21.         table.insert(SpawnerIndex,k)
  22.         -- Create a spawn manager for each section
  23.         Spawner[k] = SpawnManager(k)
  24.     end
  25.  
  26.     initialized = true
  27. end
  28.  
  29. ---------------------------------------------------
  30. -- class SpawnManager
  31. ---------------------------------------------------
  32. class "SpawnManager"
  33. function SpawnManager:__init(section)
  34.     self.section = section
  35.     self.loaded = false
  36. end
  37.  
  38. function SpawnManager:initialize()
  39.     local section = self.section
  40.     -- Inherit data from ini
  41.     self.sections =     str_explode(read_from_ini(  ini,    section, "sections",        "string",   "stalker"), ","     )
  42.     self.respawn =                  read_from_ini(  ini,    section, "respawn",         "string",   "true"              )
  43.     self.respawn_delta = str_explode(read_from_ini( ini,    section, "respawn_delta",   "string",   "60,120"), ","      )
  44.     self.respawn_radius =           read_from_ini(  ini,    section, "respawn_radius",  "float",    0                   )
  45.     self.count =                    read_from_ini(  ini,    section, "count",           "float",    0                   )
  46.     self.position =     str_explode(read_from_ini(  ini,    section, "position",        "string",   "0,0,0"), ","       )
  47.     self.level_vertex_id =          read_from_ini(  ini,    section, "level_vertex_id", "float",    0                   )
  48.     self.game_vertex_id =           read_from_ini(  ini,    section, "game_vertex_id",  "float",    0                   )
  49.  
  50.     -- set respawn timer
  51.     self.respawn_delta[1] = tonumber(self.respawn_delta[1])
  52.     self.respawn_delta[2] = tonumber(self.respawn_delta[2])
  53.  
  54.     self.delta = math.random(self.respawn_delta[1],self.respawn_delta[2])
  55.  
  56.     -- create position vector
  57.     self.position = vector():set( tonumber(self.position[1]) , tonumber(self.position[2]), tonumber(self.position[3]))
  58.  
  59.     -- create table to hold ids of spawned sections
  60.     self.ids = {}
  61.  
  62.     self.loaded = true
  63. end
  64.  
  65. function SpawnManager:finalize()
  66.     self:clear_dead()
  67. end
  68.  
  69. function SpawnManager:update(game_time)
  70.     -- Check if time to call a respawn
  71.  
  72.     if (self.last_respawn_update == nil or game_time:diffSec(self.last_respawn_update) > self.delta) then
  73.  
  74.         -- Clear Dead
  75.         self:clear_dead()
  76.  
  77.         -- Set last update
  78.         self.last_respawn_update = game_time
  79.  
  80.         -- check if max population reached
  81.         if (#self.ids == self.count) then
  82.             return
  83.         end
  84.  
  85.         -- Parse conditions to allow a respawn
  86.         local actor = alife():actor()
  87.         --if (xr_logic.pick_section_from_condlist(actor, actor, xr_logic.parse_condlist(actor,"","",self.respawn) ) ~= "true") then
  88.             --return
  89.         --end
  90.  
  91.         -- If actor is on same level, then respawn only if actor outside of respawn raidus
  92.         if (self.respawn_radius > 0 and game_graph():vertex(self.game_vertex_id):level_id() == game_graph():vertex(actor.m_game_vertex_id):level_id()) then
  93.             if (actor.position:distance_to_sqr(self.position) < self.respawn_radius) then
  94.                 return
  95.             end
  96.         end
  97.  
  98.         -- randomize delta
  99.         self.delta = math.random(self.respawn_delta[1],self.respawn_delta[2])
  100.  
  101.         -- Spawn section for each available slot
  102.         self:spawn()
  103.     end
  104. end
  105.  
  106. function SpawnManager:spawn()
  107.     local se_obj
  108.     local amt = self.count-#self.ids
  109.     for i=1,amt,1 do
  110.         -- Create sections
  111.         se_obj = alife():create(self.sections[math.random(1, #self.sections)],self.position,self.level_vertex_id,self.game_vertex_id)
  112.  
  113.         -- Remember spawned objects by id
  114.         table.insert(self.ids, se_obj.id)
  115.  
  116.         register_object(se_obj.id)
  117.  
  118.         set_object_info(se_obj,"alive",true)
  119.     end
  120. end
  121.  
  122. function SpawnManager:clear_dead()
  123.     if (#self.ids < 1) then
  124.         return
  125.     end
  126.  
  127.     local se_obj
  128.  
  129.     local _temp = {}
  130.     for i=1,#self.ids,1 do
  131.         se_obj = alife():object(self.ids[i])
  132.  
  133.         -- Check if alive or deleted
  134.         if (se_obj == nil or get_object_info(se_obj,"alive") == false) then
  135.  
  136.             -- unregister object
  137.             unregister_object(self.ids[i])
  138.  
  139.         else
  140.             table.insert(_temp,self.ids[i])
  141.         end
  142.         self.ids[i] = nil
  143.     end
  144.  
  145.     self.ids = nil
  146.     self.ids = _temp
  147. end
  148.  
  149. function SpawnManager:save(packet)
  150.     set_save_marker(packet, "save", false, "SpwnManager")
  151.     if (self.last_respawn_update) then
  152.         utils.w_CTime(packet, self.last_respawn_update)
  153.     else
  154.         packet:w_u8(0)
  155.     end
  156.     packet:w_u32(#self.ids)
  157.     for i=1,#self.ids,1 do
  158.         packet:w_u32(self.ids[i])
  159.     end
  160.     set_save_marker(packet, "save", true, "SpwnManager")
  161. end
  162.  
  163. function SpawnManager:load(packet)
  164.     set_save_marker(packet, "load", false, "SpwnManager")
  165.     self.last_respawn_update = utils.r_CTime(packet)
  166.  
  167.     local count = packet:r_u32()
  168.     for i=1,count,1 do
  169.         self.ids[i] = packet:r_u32()
  170.     end
  171.     set_save_marker(packet, "load", true, "SpwnManager")
  172. end
  173.  
  174. function set_object_info(se_obj,info,val)
  175.     if (Objects[se_obj.id]) then
  176.         --printf("Set[%s] %s = %s",se_obj.id,info,val)
  177.         Objects[se_obj.id][info] = val
  178.     end
  179. end
  180.  
  181. function get_object_info(se_obj,info)
  182.     if (Objects[se_obj.id]) then
  183.         --printf("Get[%s] %s = %s",se_obj.id,info,Objects[se_obj.id][info])
  184.         return Objects[se_obj.id][info]
  185.     end
  186. end
  187.  
  188. function register_object(id)
  189.     --printf("Object registered %s",se_obj.id)
  190.     if not (Objects[se_obj.id]) then
  191.         Objects[id] = {}
  192.     end
  193. end
  194.  
  195. function unregister_object(id)
  196.     --printf("Object unregistered %s",se_obj.id)
  197.     Objects[id] = nil
  198. end
  199. ---------------------------------------------------
  200. -- Callbacks
  201. ---------------------------------------------------
  202.  
  203. -- Callback actor_binder:net_spawn()
  204. function on_game_load()
  205.     if not (initialized) then
  206.         init()
  207.     end
  208. end
  209.  
  210. -- Callback actor_binder:update()
  211. function on_actor_update()
  212.     local gt = game.get_game_time()
  213.     for i=1,#SpawnerIndex,1 do
  214.         if not (Spawner[SpawnerIndex[i]].loaded) then
  215.             Spawner[SpawnerIndex[i]]:initialize()
  216.         end
  217.         Spawner[SpawnerIndex[i]]:update(gt)
  218.     end
  219. end
  220.  
  221. -- Callback actor_binder:save()
  222. function on_actor_save(actor,packet)
  223.     for i=1,#SpawnerIndex,1 do
  224.         Spawner[SpawnerIndex[i]]:finalize()
  225.         Spawner[SpawnerIndex[i]]:save(packet)
  226.     end
  227. end
  228.  
  229. -- Callback actor_binder:load()
  230. function on_actor_load(actor,reader)
  231.     if not (initialized) then
  232.         init()
  233.     end
  234.  
  235.     for i=1,#SpawnerIndex,1 do
  236.         Spawner[SpawnerIndex[i]]:initialize()
  237.         Spawner[SpawnerIndex[i]]:load(reader)
  238.     end
  239.     initialized = true
  240. end
  241.  
  242. -- Callback se_stalker:on_death()       Can be called also in se_monster
  243. function on_npc_death(se_obj,who)
  244.  
  245.     -- flag object as dead
  246.     if (get_object_info(se_obj,"alive")) then
  247.         set_object_info(se_obj,"alive",false)
  248.     end
  249. end
  250.  
  251. --------------------------
  252. -- Utils
  253. --------------------------
  254. function collect_sections(ini,sections)
  255.     local r,p = {},{}
  256.     for k,v in ipairs(sections) do
  257.         if ini:section_exist(v) then
  258.             local n = ini:line_count(v)
  259.             if n > 0 then
  260.                 for i = 0,n-1 do
  261.                     local res,id,val = ini:r_line(v,i,"","")
  262.                     if r[id] == nil then
  263.                         r[id] = val
  264.                     end
  265.                 end
  266.             end
  267.             p[k] = n
  268.         else
  269.             p[k] = 0
  270.         end
  271.     end
  272.     return r,p
  273. end
  274.  
  275. function read_from_ini(ini,section,line,var_type,default)
  276.     if not (ini) then
  277.         ini = system_ini()
  278.     end
  279.  
  280.     if (section and line and ini:section_exist(section) and ini:line_exist(section,line)) then
  281.         if (var_type == "bool") then
  282.             return ini:r_bool(section,line)
  283.         elseif (var_type == "string") then
  284.             return ini:r_string(section,line)
  285.         elseif (var_type == "float") then
  286.             return ini:r_float(section,line)
  287.         else
  288.             return ini:r_string_wq(section,line)
  289.         end
  290.     else
  291.         return default
  292.     end
  293. end
  294.  
  295. function string:split(pat)
  296.   local st, g = 1, self:gmatch("()("..pat..")")
  297.   local function getter(self, segs, seps, sep, cap1, ...)
  298.     st = sep and seps + #sep
  299.     return self:sub(segs, (seps or 0) - 1), cap1 or sep, ...
  300.   end
  301.   local function splitter(self)
  302.     if st then return getter(self, st, g()) end
  303.   end
  304.   return splitter, self
  305. end
  306.  
  307. function str_explode(str,pattern)
  308.     local t = {}
  309.     if (type(str) ~= "string") then return end
  310.     for word, pat, start in str:split(pattern) do
  311.         t[#t+1] = word
  312.         if (start and pat == pattern) then
  313.             t[#t+1] = str:sub(start)
  314.             break
  315.         end
  316.     end
  317.     return t
  318. end
  319.  
  320. function printf(txt,...)
  321.     if not (text) then return end
  322.     local i = 0
  323.     local p = {...}
  324.     local function sr(a)
  325.         i = i + 1
  326.         return tostring(p[i])
  327.     end
  328.     local output = string.gsub(text,"%%s",sr)
  329.     get_console():execute("load ~#I#:"..output)
  330.     --get_console():execute("flush")
  331. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement