Modding Help "attempt to call a nil value (field 'breakObject')" from world.breakObject in activeitem lua file

Discussion in 'Starbound Modding' started by Kaonicping, Jul 17, 2018.

  1. Kaonicping

    Kaonicping Scruffy Nerf-Herder

    So I have an activeitem lua script that involves conducting a series of checks on the object the player is clicking on with the item and then doing some stuff if they all pass (namely: spawn a monster, spawn a projectile, destroy the object and then play a sound).
    Code:
    require "/scripts/vec2.lua"
    
    function isUnderground()
      return world.underground(targetPos())
    end
    
    function targetPos()
      return vec2.add(mcontroller.position(), activeItem.handPosition(self.targetOffset))
    end
    
    function targetObject()
      return world.objectAt(targetPos())
    end
    
    function onIxodoomFossil()
      local objectId = targetObject()
      if objectId then
        if world.entityName(objectId) == "fossildisplay5" then
          if world.getObjectParameter(objectId, "fossilComplete") then
            local firstFossilConfig = root.itemConfig(world.getObjectParameter(objectId, "fossilList")[1]).config
            local fossil = firstFossilConfig.setCollectables.fossils
            if fossil == "ixodoom" then
              return true
            end
          end
        end
      end  
      return false
    end
    
    function isThereSpace()
      local ll = vec2.add(targetPos(), {-10.0, 1.0})
      local tr = vec2.add(targetPos(), {10.0, 35.0})
      local bounds = {0, 0, 0, 0}
      bounds[1] = ll[1]
      bounds[2] = ll[2]
      bounds[3] = tr[1]
      bounds[4] = tr[2]
      return not world.rectTileCollision(bounds, {"Null", "Block", "Dynamic", "Slippery"})
    end
    
    function activate(fireMode, shiftHeld)
      if not onIxodoomFossil() then
        sb.logInfo("not on ixodoom fossil")
      elseif not isUnderground() then
        sb.logInfo("not underground")
      elseif not isThereSpace() then
        sb.logInfo("no space")
      else
        world.spawnProjectile("regularexplosionknockback", vec2.add(targetPos(), {0.0, 1.0}))
        world.spawnMonster("spiderboss", vec2.add(targetPos(), {0.0, 15.0}), {level = 6, musicStagehands = {"bossmusic"}})
        world.breakObject(targetObject(), true)
        animator.playSound("shatter")
        item.consume(1)
      end
    end
    


    But I get this error (I haven't included the whole log file since this should be the only bit that is relevant):

    Code:
    [15:34:18.616] [Error] Exception while invoking lua function 'activate'. (LuaException) Error code 2, [string "/items/active/bosssummon/animatedflesh/animat..."]:52: attempt to call a nil value (field 'breakObject')
    I've put the relevant function in italics and the offending line in bold.

    Now, based on my fairly limited knowledge of Lua, 'attempt to call a nil value' means that it thinks that the function doesn't exist (and if I replace 'breakObject' with 'asfsgsdfaf' for example I get the same error). Yet on https://starbounder.org/Modding:Lua/Tables/World we see:

    bool world.breakObject(EntityId entityId, bool smash)
    Breaks the specified object and returns true if successful and false otherwise. If smash is true the object will not (by default) drop any items.​

    As far as I can tell, my usage is consistent with the method definition.

    I checked the vanilla assets to see how world.breakObject is used:
    Code:
    grep -r world.breakObject
    and all I found was:
    Code:
    objects/outpost/signstore/signdispenser.lua:   if matchingEasel ~= nil then world.breakObject(matchingEasel) end
    This breaks EASEL if you break its sign dispenser. Interestingly though, it doesn't include a second argument telling it to drop its item. So I tried my activeitem code without the second argument (which is not the functionality I want, it is important that it doesn't drop the item) and once again it outputs the same error to the logfile.

    I should point out that I also made some changes to EASEL, which involved replacing the Lua files with my own, which did contain world.breakObject in the same way as it is used in signdispenser.lua and those work.

    So at this point, I'm completely stumped. Given that this is an activeitem rather than an object I could see some lua tables not being accessible, but in that case why do all the other world._ functions work?


    Thanks in advance for any help you can give.
     
  2. Kaonicping

    Kaonicping Scruffy Nerf-Herder

    So I made a workaround by sending an entityMessage "kys" which just makes the object call
    Code:
    object.smash(true)
    which works fine, although this does mean I have to replace yet another vanilla .lua which is going to make this even less likely to be compatible with other mods.
     

Share This Page