;decals with 3d shapes by RemiD 20230725-14h17m Graphics3D( 854, 480, 32, 2 ) HidePointer() ;input Global mxdiff%, mydiff% ;player Global player_feet = CreatePivot() Global player_eyes = CreatePivot() : PositionEntity( player_eyes, 0, 1.75-0.1, 0 ) : EntityParent( player_eyes, player_feet ) Global player_feetyaw# Global player_eyespitch# ;camera Global camera = CreateCamera() : CameraRange( camera, 0.1, 100 ) ;reticle Global reticle_image = CreateImage(4,4) SetBuffer( ImageBuffer( reticle_image ) ) Color( 250, 250, 250 ) : Rect( 0, 0, 4, 4, True ) ;fartarget (to point the bullet towards) Global fartarget = CreatePivot() MoveEntity( fartarget, 0, 0, +1000 ) EntityParent( fartarget, camera, True ) ;gun Global gun_mesh = CreateCylinder(8) : RotateMesh( gun_mesh, 90, 0, 0 ) : ScaleMesh( gun_mesh, 0.06/2, 0.06/2, 0.4/2 ) : PositionMesh( gun_mesh, 0, 0, +0.4/2 ) EntityColor( gun_mesh, 120, 120, 120 ) PositionEntity( gun_mesh, 0, 1.5, 0, True ) : MoveEntity( gun_mesh, 0, 0, 0 ) EntityParent( gun_mesh, player_eyes, True ) ;bullets Global xbullet = CreateCylinder(8) : RotateMesh( xbullet, 90, 0, 0 ) : ScaleMesh( xbullet, 0.04/2, 0.04/2, 0.08/2 ) : HideEntity( xbullet ) Global bulletscount% Type Tbullet Field mesh Field r%, g%, b% ;Field state% End Type ;holes (3d shape decals) Global xhole = CreateCone(8) : RotateMesh( xhole, 90, 0, 0 ) : ScaleMesh( xhole, 0.04/2, 0.04/2, 0.01/2 ) : PositionMesh( xhole, 0, 0, 0.01/2 ) : HideEntity( xhole ) Global holescount% Type Thole Field mesh Field r%, g%, b% ;Field state% End Type ;room (floor, walls, ceiling) room_mesh = CreateCube() : FlipMesh( room_mesh ) : ScaleMesh( room_mesh, 15.0/2, 3.0/2, 15.0/2 ) : PositionMesh( room_mesh, 15.0/2, 3.0/2,15.0/2 ) EntityColor( room_mesh, 225, 225, 225 ) EntityPickMode( room_mesh, 2 ) ;furnitures Global furniturescount% Dim furniture_mesh(20) For n% = 1 To 20 Step+1 x# = Rand(0,+15-1)+0.5 : y# = 0 : z# = Rand(0,+15-1)+0.5 furniturescount = furniturescount + 1 : i% = furniturescount furniture_mesh(i) = CreateCube() : sy# = Rand( 1, 3 ) : ScaleMesh( furniture_mesh(i), 1.0/2, sy/2, 1.0/2 ) : PositionMesh( furniture_mesh(i), 0, sy/2, 0 ) PositionEntity( furniture_mesh(i), x, y, z ) EntityPickMode( furniture_mesh(i), 2 ) Next ;light olight = CreateLight(2) : LightRange( olight, 3.0 ) : LightColor( olight, 180, 180, 180 ) PositionEntity( olight, 7.5, 1.5, 7.5 ) PositionEntity( player_feet, 7.5, 0, 7.5 ) Global MainTimer = CreateTimer(30) Main() End() Function Main() Repeat mxdiff = MouseXSpeed() : mydiff = MouseYSpeed() update_player() update_gun() update_bullets() update_holes() PositionEntity( camera, EntityX( player_eyes, True ), EntityY( player_eyes, True ), EntityZ( player_eyes, True ), True ) RotateEntity( camera, EntityPitch( player_eyes, True ), EntityYaw( player_eyes, True ), EntityRoll( player_eyes, True ), True ) WireFrame( False ) If( KeyDown(2)=1 ) : WireFrame( True) : EndIf SetBuffer( BackBuffer() ) RenderWorld() DrawImage( reticle_image, GraphicsWidth()/2-2, GraphicsHeight()/2-2 ) Color( 000, 000, 250 ) : CText( bulletscount, 0, 0 ) Color( 000, 000, 250 ) : CText( holescount, 0, 15 ) ;flip( true) WaitTimer(MainTimer) VWait():Flip(False) Until( KeyDown(1)=1 ) End Function Function CText(TextStr$,PX%,PY%) Text(PX,PY,TextStr,False,False) End Function Function Distance2D#(PAX#,PAZ#,PBX#,PBZ#) Distance2D# = Sqr( ( ( PBX - PAX ) * ( PBX - PAX ) ) + ( ( PBZ - PAZ ) * ( PBZ - PAZ ) ) ) Return Distance2D End Function Function Distance3D#(PAX#,PAY#,PAZ#,PBX#,PBY#,PBZ#) Distance3D# = Sqr( ( ( PBX - PAX ) * ( PBX - PAX ) ) + ( ( PBY - PAY ) * ( PBY - PAY ) ) + ( ( PBZ - PAZ ) * ( PBZ - PAZ ) ) ) Return Distance3D End Function Function update_player() MoveMouse(GraphicsWidth()/2,GraphicsHeight()/2) player_eyespitch = player_eyespitch + Float( mydiff )/10 If( player_eyespitch < -89 ) player_eyespitch = -89 Else If( player_eyespitch > 89 ) player_eyespitch = 89 EndIf RotateEntity( player_eyes, player_eyespitch, 0, 0, False ) player_feetyaw = player_feetyaw - Float( mxdiff )/10 RotateEntity( player_feet, 0, player_feetyaw, 0, False ) If( KeyDown(17)=1 ) MoveEntity( player_feet, 0, 0, 0.1 ) Else If( KeyDown(31)=1 ) MoveEntity( player_feet, 0, 0, -0.1 ) EndIf If( KeyDown(30)=1 ) MoveEntity( player_feet, -0.1, 0, 0 ) Else If( KeyDown(32)=1 ) MoveEntity( player_feet, 0.1, 0, 0 ) EndIf End Function Function update_gun() ;if mouse left button is hit If( MouseHit(1)=1 ) ;create a new bullet at gun position bulletscount = bulletscount + 1 bul.Tbullet = New Tbullet bul\mesh = CopyEntity( xbullet ) PositionEntity( bul\mesh, EntityX( gun_mesh, True ), EntityY( gun_mesh, True ), EntityZ( gun_mesh, True ), True ) RotateEntity( bul\mesh, EntityPitch( gun_mesh, True ), EntityYaw( gun_mesh, True ), EntityRoll( gun_mesh, True ), True ) MoveEntity( bul\mesh, 0, 0, 0.4 ) PointEntity( bul\mesh, fartarget, 0 ) bul\r = Rand( 025, 250 ) : bul\g = Rand( 025, 250 ) : bul\b = Rand( 025, 250 ) EntityColor( bul\mesh, bul\r, bul\g, bul\b ) EndIf End Function Function update_bullets() ;for each bullet For bul.Tbullet = Each Tbullet ;check if there is an obstacle in front of the bullet, using linepick TFormVector( 0, 0, +0.2, bul\mesh, 0 ) ;get the global translation vector properties of the bullet pickent% = LinePick( EntityX(bul\mesh,True), EntityY(bul\mesh,True), EntityZ(bul\mesh,True), TFormedX(), TFormedY(), TFormedZ(), 0.04 ) ;linepick from the bullet position orientation to where the bullet will go ;if yes If ( pickent <> 0 ) ;get the picked position (on the surface) pickx# = PickedX() : picky# = PickedY() : pickz# = PickedZ() ;get the picked normal (of the surface) picknx# = PickedNX() : pickny# = PickedNY() : picknz# = PickedNZ() ;get the color of the bullet r% = bul\r : g% = bul\g : b% = bul\b ;destroy the bullet FreeEntity( bul\mesh ) : Delete( bul ) bulletscount = bulletscount - 1 ;create a new hole (3d shape decal) at this position, oriented along this normal, with the color of the bullet holescount = holescount + 1 hol.Thole = New Thole hol\mesh = CopyEntity( xhole ) EntityColor( hol\mesh, r, g , b ) PositionEntity( hol\mesh, pickx, picky, pickz, True ) AlignToVector( hol\mesh, picknx, pickny, picknz, 3, 1.0 ) ;if no Else If( PickEnt = 0 ) ;move the bullet MoveEntity( bul\mesh, 0, 0, +0.2 ) EndIf ;check if the bullet goes outside of the game zone (to prevent a memory leak) If( bul <> Null ) D# = Distance3D( EntityX(bul\mesh,True), EntityY(bul\mesh,True), EntityZ(bul\mesh,True), 7.5, 1.5, 7.5 ) ;if yes If( D > 7.5+5 ) ;destroy the bullet FreeEntity( bul\mesh ) : Delete( bul ) bulletscount = bulletscount - 1 EndIf EndIf Next End Function Function update_holes() ;check how many holes there are (to prevent a memory leak) ;if there are too many holes If( holescount > 30 ) ;destroy the oldest hole hol.Thole = First Thole FreeEntity( hol\mesh ) : Delete( hol ) holescount = holescount - 1 EndIf End Function