Modding Help Issue with lineTileCollision

Discussion in 'Starbound Modding' started by Yukiara, Oct 31, 2024.

  1. Yukiara

    Yukiara Space Hobo

    Hello, I'm using this line of code to find out if any blocks are above the player in order to apply a bonus and the problem is that it apparently detects a collision in the sky. So I'm wondering if it's not the ship that's following the player in a fixed way, or if there's some kind of invisible block in the sky (this second point seems impossible to me, as I've seen a player go into space from the ground). Do you have any idea where this might come from? I'd like to be able to increase the +50 detection limit, but if it detects a collision when nothing is above it, that's a problem for the mod I want to make for vampires.

    Code:
    local position = mcontroller.position()
    local isUnderRoof = world.lineTileCollision(position, {position[1], position[2] + 50})
    Edit : It's the asteroids that are the problem, I don't know how to exclude this material without it breaking the stat variables.
     
    Last edited: Oct 31, 2024
  2. Lemon drops

    Lemon drops Cosmic Narwhal

    Why do you need to detect if there's a roof specifically?

    Maybe you could detect something else that gives a similar if not perfect result by detecting things such as light levels, depth levels, if you're behind a background wall, a combination, or other detecting thingies.
     
  3. Rezetrx

    Rezetrx Void-Bound Voyager

    Here a function I use in my mod. It returns true when there is a collision except if the collision material is inside the exceptionlist. It resumes the scan with the remaining scan range if there is a collision with an excluded material.

    Code:
    
    function RoofDetection(position, scanHeight, materialExceptions)
        local roofCollisionPoint = world.lineTileCollisionPoint(position, vec2.add(position, {0, scanHeight}))
        if roofCollisionPoint then
            local roofMaterial = world.material(vec2.add(roofCollisionPoint[1], {0,.25}), "foreground")
            if roofMaterial then
                for i, mat in ipairs(materialExceptions) do
                    if roofMaterial == mat then
                        local newstartPos = vec2.add(roofCollisionPoint[1], {0, 1.5})
                        local newScanHeight = math.max(0, scanHeight - (world.distance( roofCollisionPoint[1], position)[2]))
                        if newScanHeight >= 1 then
                            return RoofDetection(newstartPos, newScanHeight, materialExceptions)
                        end
                        return false
                    end
                end
                return true
            end
        end
        return false
    end
    
    

    Example call using your scan range and materials (plus glass):

    Code:
    
    local isUnderRoof = RoofDetection(mcontroller.position(), 50, {"meteoriterock", "magmarock", "glassmaterial"})
    
    
    Visualization of how it works:
    upload_2024-11-22_12-27-26.png
    pink dot = collision point, yellow dot = new start position, yellow text = remaining scan range, white text = debug output based on isUnderRoof (following the example call)
     

Share This Page