Modding Help object collision detection

Discussion in 'Starbound Modding' started by Custos_Aeternam, Feb 21, 2017.

  1. Custos_Aeternam

    Custos_Aeternam Void-Bound Voyager

    I have been working on a mod to have a switch of sorts be triggered by a collision event, but all the resources I have found make it look like this is not possible. The closest I have so far is a modified trap door that scans for projectiles, but I can't get the detection area small enough. I need it just outside the blocks bounding box, but the smallest detection box I have made for it is two blocks out from all sides of the object, even after copying the proximityswitch.lua and making a modified version; so the player would simply need to shoot next to it in any direction. Even weather in general could trigger that switch. I may be doing the numbers wrong on that though.

    Anyway, am I missing something or does starbound not have collision detection / collision events available for objects?
    I need an extra pair of eyes to find what must be right under my nose.
    I have looked into smash-able objects, but they do not link to anything in the LUA api; they have a "smashable" tag, but they don't link to a LUA script, and that means the tag goes directly to the game engine.
    Thanks in advance for any help you provide.
     
  2. The | Suit

    The | Suit Agent S. Forum Moderator

    I think you are trying to do it the wrong way.

    Just make the object have health, and make it activate when it loses health.
    When it loses health make it instantly restores back to 100.

    If you want to see objects with health - check the tentacles in the intro mission.
     
    Custos_Aeternam likes this.
  3. bk3k

    bk3k Oxygen Tank

    The health thing probably makes more sense for detecting a projectile collision, but you know.
    mcontroller.isColliding() can tell you this. I believe you can call that from the projectile.
    From an object, world.entityQuery() has some great options.

    Code:
    #### `List<EntityId>` world.entityQuery(`Vec2F` position, `Variant<Vec2F, float` positionOrRadius, [`Json` options])
    
    Queries for entities in a specified area of the world and returns a list of their entity ids. Area can be specified either as the `Vec2F` lower left and upper right positions of a rectangle, or as the `Vec2F` center and `float` radius of a circular area. The following additional parameters can be specified in options:
    
    * __withoutEntityId__ - Specifies an `EntityId` that will be excluded from the returned results
    * __includedTypes__ - Specifies a list of one or more `String` entity types that the query will return. In addition to standard entity type names, this list can include "mobile" for all mobile entity types or "creature" for players, monsters and NPCs.
    * __boundMode__ - Specifies the bounding mode for determining whether entities fall within the query area. Valid options are "position", "collisionarea", "metaboundbox". Defaults to "collisionarea" if unspecified.
    * __order__ - A `String` used to specify how the results will be ordered. If this is set to "nearest" the entities will be sorted by ascending distance from the first positional argument. If this is set to "random" the list of results will be shuffled.
    * __callScript__ - Specifies a `String` name of a function that should be called in the script context of all scripted entities matching the query.
    * __callScriptArgs__ - Specifies a list of arguments that will be passed to the function called by callScript.
    * __callScriptResult__ - Specifies a `LuaValue` that the function called by callScript must return; entities whose script calls do not return this value will be excluded from the results. Defaults to `true`.
    There you are
    Code:
    local matches = world.entityQuery( SW_corner, NE_corner, {
        boundmode = "collisionarea",
        includedTypes = { "projectile" },
        callScript = "theProjectile_iAm_lookingFor",
        callScriptArgs = { 
          entity.id,
          "target_projectileName",
          otherParams,
          {"etc", etc}
        }
      } )
    
    If you want, check out Automatic Doors. Borrow any code you like.
     
    Custos_Aeternam likes this.
  4. Custos_Aeternam

    Custos_Aeternam Void-Bound Voyager

    Thank you guys, I knew I was overlooking something; I just couldn't put my finger on it.
     
  5. Custos_Aeternam

    Custos_Aeternam Void-Bound Voyager

    From what I see, the switch having health is an easy way to have all attacks activate it, whereas using the example quoted above you can specify what weapon activates it; e.g. a bow, grenade, or sword. Is that a correct analysis?
    I am far more use to Minecraft LUA, from OpenComputers; for lengthy reasons that bore most people.
     
  6. bk3k

    bk3k Oxygen Tank

    world.entityQuery(and several similar functions) just detect things. The options about what to detect and how are nice when you want to be pretty specific. I'm not sure if you can detect a sword per say... you might if it is an activeitem but I haven't tried. Many of the special attacks from melee weapons are technically projectiles spawned from it.

    Anyhow the query functions allow you to call functions from potential detection targets. Those functions could do anything but the query functions are looking for a return that matches the "LuaValue" it expects(by default true) and if that isn't returned, that entity will not be included in the results. You can add a function to objects you might want to only conditionally be included in the results. A good vanilla example is in

    /objects/wired/door/door.lua:hasCapability() starting on line 92
    This is something NPCs call through a query.

    The function right below it is the same.
    doorOccupiesSpace() is called by colony deeds.
     

Share This Page