Modding Help Checking my LUA and NPC spawner.

Discussion in 'Starbound Modding' started by The Observer, Dec 5, 2016.

  1. The Observer

    The Observer Phantasmal Quasar

    Hello there. Had a go at modifying the in-game monster spawner to work with NPCs. Could someone please give this a look-over and see if I did it correctly? I haven't had time to test it out yet, but I would like to get it as correct as possible before beginning testing. With any luck, I want it to spawn NPCs in much the same way as the monster spawner works - being able to define NPC type, race, level, and other parameters on the fly.

    The last bit of the LUA is the main bit which I changed.

    Thanks in advance.

    The object:

    Code:
    {
      "objectName" : "extranpcspawner",
      "colonyTags" : ["misc"],
      "rarity" : "Common",
      "description" : "Spawns npcs in a variety of configurable ways.",
      "shortdescription" : "Npc Spawner",
      "race" : "human",
      "printable" : false,
      "category" : "spawner",
      "price" : 133,
    
      "inventoryIcon" : "extranpcspawnericon.png",
      "orientations" : [
        {
          "image" : "extranpcspawner.png",
          "imagePosition" : [-8, 0],
    
          "spaceScan" : 0.1,
          "anchors" : [ "bottom" ]
        }
      ],
    
      "scripts" : [ "/objects/wired/extranpcspawner/extranpcspawner.lua" ],
      "scriptDelta" : 10,
    
      "inputNodes" : [ [-1, 0] ],
    
      "spawner" : {
        "npcTypes" : ["hostile"], //type of npc to spawn (random from list)
        "npcSpecies" : [ "apex", "avian", "floran", "glitch", "human", "hylotl", "novakid" ], //species of NPC to spawn.
        "npcLevel" : [1, 10], //level of npc to spawn (random within range, or leave blank for world threat level)
        "npcParams" : { //additional parameters of spawned npc
          "aggressive" : true
        },
        "position" : [0, 1], //relative position to spawn at
        "positionVariance" : [10, 0], //[x,y] size of randomized spawn area, centered on position
        "frequency" : [5.0, 5.0], //cooldown time between spawns (random within range)
        "stock" : 5, //total number of spawns, -1 for infinite
        "trigger" : null, //options include "wire", "interact", "break", null (periodic)
        "outOfSight" : false //only spawn where the player can't see
      },
    
      "smashOnBreak" : true
    }
    The LUA:

    Code:
    require "/scripts/util.lua"
    
    function init()
      self = config.getParameter("spawner")
      if not self then
        sb.logInfo("npc spawner at %s is missing configuration! Prepare for some serious Lua errors!", object.position())
        return
      end
    
      object.setInteractive(self.trigger == "interact")
      self.position = object.toAbsolutePosition(self.position)
      storage.cooldown = storage.cooldown or util.randomInRange(self.frequency or {0, 0})
      storage.stock = storage.stock or self.stock
    end
    
    function onInteraction(args)
      if self.trigger == "interact" then
        spawn()
      end
    end
    
    function update(dt)
      if storage.stock ~= 0 then
        if storage.cooldown > 0 then storage.cooldown = storage.cooldown - dt end
    
        if storage.cooldown <= 0 and ((not self.trigger) or (self.trigger == "wire" and object.getInputNodeLevel(0))) then
          spawn()
          storage.cooldown = util.randomInRange(self.frequency or {0, 0})
        end
      end
    end
    
    function die()
      if self.trigger == "break" then
        for i = 1, storage.stock do
          spawn()
        end
      end
    end
    
    function spawn()
      local attempts = 10
      while attempts > 0 do
        local spawnPosition = {}
        for i,val in ipairs(self.positionVariance) do
          if val == 0 then
            spawnPosition[i] = self.position[i]
          else
            spawnPosition[i] = self.position[i] + math.random(val) - (val / 2)
          end
        end
    
        if not self.outOfSight or not world.isVisibleToPlayer({spawnPosition[1] - 3, spawnPosition[2] - 3, spawnPosition[1] + 3, spawnPosition[2] + 3}) then
          local npcType = util.randomFromList(self.npcTypes)
          local npcSpecies = util.randomFromList(self.npcSpecies)     
          self.npcParams.level = self.npcLevel and util.randomInRange(self.npcLevel) or world.threatLevel()
    
          local npcId = world.spawnNpc(spawnPosition, npcSpecies, npcType, self.npcParams.level, nil, npcParameter)
          if npcId ~= 0 then
            storage.stock = storage.stock - 1
            return
          end
        end
    
        attempts = attempts - 1
      end
    end
     

Share This Page