Blitz3D+ Command Reference

TerrainIsHole ( terrain,terrain_x,terrain_z )

Parameters

terrain - terrain entity to query

terrain_x - cell column, 0 to TerrainSize(terrain)-1

terrain_z - cell row, 0 to TerrainSize(terrain)-1

Description

Returns True if a terrain cell has been opened into a hole.

This is the question the height queries cannot answer. TerrainY, TerrainHeight and their relatives always report the height the ground would have had if the cell were solid, because they have no "there is nothing here" value to return. A character snapped to TerrainY therefore strolls straight across a hole as though the cave mouth were paved. Ask TerrainIsHole first, and let them fall.

The same check belongs in anything that places things by hand: spawn points, dropped loot, camera collision probes, an AI that samples the ground ahead before walking onto it. (ScatterTerrain already does this for you and skips holes automatically.)

The engine's own systems do respect holes: rendering, shadows, Blitz ray and sphere collision, EntityPick and LinePick, and Box3D height fields created or refreshed after the edit. So a physics body or a pick ray falls through a hole correctly without this command - it exists for the height-sampling code you write yourself.

Gotcha: the coordinates address cells, not samples, so the valid range is 0 to TerrainSize-1 and going outside it raises "Terrain hole coordinates are outside the terrain cell area". If you are working from a world position, convert it into the terrain's local grid space first and take the whole part of each coordinate; a position exactly on a cell boundary belongs to the cell it rounds down into.

See also: ModifyTerrainHole, TerrainY, TerrainHeight, TerrainSize, ScatterTerrain.

Example

; TerrainIsHole Example
; ---------------------

Graphics3D 640,480,0,2
SetBuffer BackBuffer()

camera=CreateCamera()
PositionEntity camera,0,6,-40
CameraClsColor camera,110,150,200

light=CreateLight(1)
RotateEntity light,50,-30,0

; Rolling hills built from a sine-wave height field
terrain=CreateTerrain(128)
For z=0 To 127
    For x=0 To 127
        ModifyTerrain terrain,x,z,0.2+Sin(x*10)*Cos(z*10)*0.12
    Next
Next
ScaleEntity terrain,0.5,20,0.5
PositionEntity terrain,-32,-5,-32
TerrainShading terrain,True
TerrainDetail terrain,8000,True

; Plain grass texture drawn in code
grass=CreateTexture(8,8,1+8)
SetBuffer TextureBuffer(grass) : ClsColor 75,135,60 : Cls : SetBuffer BackBuffer()
EntityTexture terrain,grass

; Punch four square holes for the probe to fly over
For patch=0 To 3
    px=64+Cos(patch*90)*20
    pz=64+Sin(patch*90)*20
    For z=pz-3 To pz+3
        For x=px-3 To px+3
            ModifyTerrainHole terrain,x,z,True
        Next
    Next
Next

; A probe sphere that circles the terrain and tests each cell it passes
probe=CreateSphere(8)
ScaleEntity probe,0.8,0.8,0.8

orbit#=0

While Not KeyDown(1)

    ; The probe's orbit crosses all four holes
    orbit=orbit+0.4
    cx=64+Cos(orbit)*20
    cz=64+Sin(orbit)*20
    wx#=-32+cx*0.5
    wz#=-32+cz*0.5

    ; TerrainY still reports the underlying height, even over a hole
    PositionEntity probe,wx,TerrainY(terrain,wx,0,wz)+1,wz

    ; Query the cell under the probe - red means it is over a hole
    hole=TerrainIsHole(terrain,cx,cz)
    If hole
        EntityColor probe,255,60,40
    Else
        EntityColor probe,80,220,80
    EndIf

    ; Arrow keys move the camera
    If KeyDown(200) Then MoveEntity camera,0,0,0.1
    If KeyDown(208) Then MoveEntity camera,0,0,-0.1
    If KeyDown(203) Then TurnEntity camera,0,1,0
    If KeyDown(205) Then TurnEntity camera,0,-1,0

    RenderWorld

    Text 0,0,"Arrow keys: move camera   Esc: exit"
    Text 0,20,"TerrainIsHole(terrain,"+cx+","+cz+") = "+hole

    Flip

Wend

End

Index