Modding Help Is there a way to check if an NPC has a status effect?

Discussion in 'Starbound Modding' started by Artix3, Dec 26, 2016.

  1. Artix3

    Artix3 Scruffy Nerf-Herder

    So I'm setting up a script right now that scans everything in the general area near an NPC. Is there a way I can iterate through that list and run a script on everything that does not have a specific status effect?

    Let's say I want to make a medic NPC that gives a single random boost effect to all NPCs and players near him, but only if they don't already have a boost currently active. I can use world.entityQuery() to find all NPCs and players near him, but is there a way to remove anyone from the list with one of many matching status effects?
     
  2. bk3k

    bk3k Oxygen Tank

    Well you can add a sciptedEntity call to the search.

    Code:
        obj = world.entityQuery(pos, pos,
          {
            callScript = "sameObject",
            callScriptArgs = {storage.objectName},
            withoutEntityId = storage.id,
            boundMode = "metaboundbox"
          })
    In this case, I'm calling sameObject() with storage.objectName as an argument. That function should exist in the target entity rather than the caller(although it could exist in both).

    The entities I'm looking for return true or false depending if their description matches what I'm looking for. I won't recieve that true or false, but world.entityQuery won't return objects that don't return true(unless I specify a different return as a filter).

    I'll have to look and see if a function exists to check for a particular status, else you'd have to add it to the NPCs.

    edit:fixed me accidentally using world.objectQuerry instead. It works the same except for only considering objects. world.npcQuery is probably an even better option in this case
     
  3. Artix3

    Artix3 Scruffy Nerf-Herder

    Alright, so I finally got back to this project, and I think I'm on the right track. It seems to work on other NPCs, but it doesn't appear to successfully complete the check on the player.

    Code:
    local people = world.entityQuery( mcontroller.position(), 7, {
         withoutEntityId = entity.id(),
         includedTypes = {"npc", "player"},
         boundMode = "CollisionArea",
         callScript = "isNotBuffed"
       })
    
    function isNotBuffed()
       effects = status.activeUniqueStatusEffectSummary()
       if (#effects > 0) then
         for i=1, #effects do
           if (effects[i][1] == "healing" or effects[i][1] == "jumpboost" or effects[i][1] == "speedboost") then
             return false
           end
         end     
       end
       return true
    end
    
    It seems to work fine on other NPCs, it doesn't apply the random effect to them unless it doesn't detect any of those effects, but for some reason, when it runs on the player, it returns false no matter what.
     
  4. bk3k

    bk3k Oxygen Tank

    I am not finding isNotBuffed in any .lua file

    Did you spell that correctly? You're calling a script there. It would be called on the target entity(thus can even affect them), and it returns that sort of entity only if that function returns true. I'd have to assume world.entityQuery will only ever return empty tables in this case.


    edit:
    I should scroll down, right?
    Did you add that script to both your NPC and player environments?
     
  5. Artix3

    Artix3 Scruffy Nerf-Herder

    It's only in the NPC's .lua file. How would I go about adding it to the player environment?
     
  6. bk3k

    bk3k Oxygen Tank

    player.config.patch

    Where you see the primary script sources. Can't give as precise an answer from mobile though.

    But you just add another LUA file to add to the environment/hook functions/etc.
     
  7. Artix3

    Artix3 Scruffy Nerf-Herder

    Just to verify I'm doing this right, since it still isn't working: I would add the .lua file with isNotBuffed() to player.config.patch like this?

    Code:
     { "op":"add", "path":"/statusControllerSettings/primaryScriptSources/-", "value":"/scripts/randmed/isbuffedhelper.lua" } 
    Then in entityQuery() all I have to do is callScript "isNotBuffed" and it'd return the player properly?
     
  8. bk3k

    bk3k Oxygen Tank

    Your path is correct. Of course player.config.patch file itself needs to start with [ and end with ]

    For your search I'd pass these parameters
    Code:
    { includedTypes = ["player", "NPC"], callScript = "isNotBuffed" }
    
    assuming you don't need to add more to it. I recommend the includedTypes parameter because you don't want it to look at monsters(who don't have that script) etc.

    I think it would work anyhow. And you might consider Artix3_isNotBuffed as a nameSpace, for example. That makes it much less likely someone else would be added a function with that name. Mod names(perhaps abbreviated) make for good nameSpace appending too. I'm not aware of any mod using isNotBuffed as is, but several mods do add to/hook the player environment, so it doesn't hurt to take the extra step.

    edit:

    I think I steered you wrong. After trying to do something similar, I've concluded that it won't work. Probably client/server context problems where player scripts are concerned. It just won't call the player script. But without leaving an error either, it just will return an empty table every time.

    Using the messaging system would be necessary, and that's a very different implementation.
     
    Last edited: Jun 9, 2017
  9. Artix3

    Artix3 Scruffy Nerf-Herder

    Yeah, I started to get the sense that it was just returning an empty table and never showing the player in that search. How would you go about this with the messaging system? I wasn't aware you could get a true/false returned by sending a message to something.
     
  10. bk3k

    bk3k Oxygen Tank

    Like I say, it is different to use messaging. An example of this is look at the terraformer objects, and the terrformer UI. The UI sends a message to the object. The reply isn't necessarily going to be received that same tick. It is an asynchronous thing.
     

Share This Page