If you will be using decals here is some "schizo" code.
Doesn't really work well with curved surfaces
Cheers
Rem Project: shoot-bullets_decal hits
rem by Scorpyo
Rem Created: 08/12/03 14.14.03
Rem ***** Main Source File *****
rem ********** INITIALIZATION ****************
set display mode 1920,1080,32
hide mouse
set global collision off
autocam off
backdrop on
sync on
sync rate 0
cls
landsize=20000
grid=40
mtxrandomize=3
gx#=10000.0
gy#=200
gz#=10500.0
bulletnumber=53
shootcount=3
gosub makematrix
gosub makeobjects
gosub Resetcam
gosub reset_shoot
position mouse 400,300
rem *********MAIN LOOP**********
do
set cursor 5,0
print screen fps()
gosub gunwalk
gosub movegun
gosub movetarget
gosub check_hitspot
if mouseclick()=1 and shootcount<bulletnumber then gosub shoot
if shiftkey()=1 then gosub reset_shoot
gosub camera_controls
gosub update_camera
gosub check_distance
gosub bulletangles
gosub printdata
sync
loop
check_hitspot:
rem check target hit spot distance from gun (gun range: 3000)
ifarx#=newxvalue(gx#,gay#,3000)
ifarz#=newzvalue(gz#,gay#,3000)
ifary#=newyvalue(gy#,gax#,3000)
hit#=intersect object(2,gx#,gy#,gz#,ifarx#,ifary#,ifarz#)
if hit#=0 then return
newbx#=newxvalue(gx#,gay#,hit#)
newbz#=newzvalue(gz#,gay#,hit#)
newby#=newyvalue(gy#,gax#,hit#)
position object 100,newbx#,newby#,newbz#
return
shoot:
rem shoot routine
if hit#=0.0 then return
if hit#>0.0 then shootcount=shootcount+1
gosub position_bullet
gosub bullet_ytilt
gosub bullet_xtilt
gosub moveback
wait 100
return
position_bullet:
if hit#=0 then return
rem adjust parallax error to make bullet plane center
rem to exactly hit the target surface (needed for correct tiltint)
hit2#=intersect object(2,newbx#,newby#,newbz#-100,newbx#,newby#,newbz#+100)
hit3#=intersect object(shootcount,newbx#,newby#,newbz#-100,newbx#,newby#,newbz#+100)
adjustz#=100-(hit2#-hit3#)
rem position bullet plane at world coord at correct hit spot
position object shootcount,newbx#,newby#,newbz#-adjustz#
return
bullet_ytilt:
if hit#=0 then return
rem y rotation
rem check bullet to target distance 10 units beside hit spot (x axis)
ydistbullet#=intersect object(2,newbx#-10,newby#,newbz#-100,newbx#-10,newby#,newbz#+100)
ydisttarget#=intersect object(shootcount,newbx#-10,newby#,newbz#-100,newbx#-10,newby#,newbz#+100)
deltay#=ydistbullet#-ydisttarget#
rem translate found value to y tilt angle for bullet plane
bay#=atan(deltay#/10)
yrotate object shootcount,bay#
return
bullet_xtilt:
if hit#=0 then return
rem find intersect direction for x rotation
rem the new intersect ray
rem MUST BE y angle ortogonal to bullet plane
rem put new "from" spot 100 units before hit point
newfrombix#=newxvalue(newbx#,bay#,-100)
newfrombiz#=newzvalue(newbz#,bay#,-100)
rem put new "to" coords 200 units beyond hit spot
newtobix#=newxvalue(newbx#,bay#,200)
newtobiz#=newzvalue(newbz#,bay#,200)
rem cast intersect line 10 units above hit spot (y axis)
rem and get bullet plane to target plane distance
xdistbullet#=intersect object(2,newfrombix#,newby#+10,newfrombiz#,newtobix#,newby#+10,newtobiz#)
xdisttarget#=intersect object(shootcount,newfrombix#,newby#+10,newfrombiz#,newtobix#,newby#+10,newtobiz#)
deltax#=xdistbullet#-xdisttarget#
rem translate found value to x tilt angle for bullet plane
bax#=atan(deltax#/10)
xrotate object shootcount,bax#
return
rem move bullet back (z axis) in order to avoid flickering
moveback:
move object shootcount,-1
return
reset_shoot:
gosub reset_bullets
rem reset shoot conditions
shootcount=3
deltay#=0
deltax#=0
bay#=0
bax#=0
return
reset_bullets:
for n=3 to bulletnumber
position object n,n*10,100,10
yrotate object n,0.0
xrotate object n,0.0
next n
return
movetarget:
if shootcount<bulletnumber and shootcount>3 then return
gosub reset_shoot
rem use arrow keys to rotate target cube
if inkey$()="e" then oaz#=wrapvalue(oaz#-1)
if inkey$()="d" then oaz#=wrapvalue(oaz#+1)
if inkey$()="w" then oax#=wrapvalue(oax#-1)
if inkey$()="q" then oax#=wrapvalue(oax#+1)
if inkey$()="s" then oay#=wrapvalue(oay#-1)
if inkey$()="a" then oay#=wrapvalue(oay#+1)
rotate limb 2,0,oax#,oay#,oaz#
return
movegun:
gay#=wrapvalue(mousex())
gax#=wrapvalue(mousey())
rotate object 1,gax#,gay#,0
wait 20
return
targetangles:
rem monitor target angles
rem (not working cause target cube is rotated via limb angles)
tax#=object angle x(2)
tay#=object angle y(2)
taz#=object angle z(2)
return
bulletangles:
rem monitor bullet plane angles
buax#=object angle x(shootcount)
buay#=object angle y(shootcount)
buaz#=object angle z(shootcount)
return
gunwalk:
gx#=newxvalue(gx#,gay#,s#)
gz#=newzvalue(gz#,gay#,s#)
if upkey()=1 and s#<8 then s#=s#+0.2
if downkey()=1 and s#>-8 then s#=s#-0.2
if leftkey()=1 then ay#=wrapvalue(gay#-0.5)
if rightkey()=1 then ay#=wrapvalue(gay#+0.5)
if inkey$()="ù" then s#=0.0
position object 1,gx#,gy#,gz#
return
check_distance:
diffposx#=abs(object position x(1)-object position x(2))
diffposz#=abs(object position z(1)-object position z(2))
collsqrt#=sqrt((diffposx#*diffposx#)+(diffposz#*diffposz#))
if collsqrt#<300 then s#=-0.1
return
camera_controls:
if inkey$()="z" then camdist=camdist+5
if inkey$()="x" then camdist=camdist-5
if inkey$()="c" then camhgt=camhgt+2
if inkey$()="v" then camhgt=camhgt-2
if inkey$()="b" then camrot#=wrapvalue(camrot#+2)
if inkey$()="n" then camrot#=wrapvalue(camrot#-2)
if inkey$()=">" then gosub Resetcam
return
rem camera update
update_camera:
cx#=newxvalue(gx#,gay#,camdist)
cz#=newzvalue(gz#,gay#,camdist)
cy#=get ground height(1,x#,z#)
position camera cx#,cy#+camhgt,cz#
rem Point camera at object
rem point camera gx#,cy#+camhgt+camlen,gz#
yrotate camera gay#+camrot#
return
Resetcam:
set camera range 1,20000
camdist=-400
camhgt=300
camrot=20
camlen=0
cx#=9600
cz#=9700
return
printdata:
set cursor 0,0
set text opaque
rem debug check
print " polygons= ",statistic(1)
print " Fps= ",screen fps()
print
print " --- gun coords--- "
print " gx#= ",gx#
print " gy#= ",gy#
print " gz#= ",gz#
print
print "---bullet gross coords on target---"
print " newbx#= ",newbx#
print " newby#= ",newby#
print " newbz#= ",newbz#
print
print "---correction for above---"
print " adjustz#= ",adjustz#
print
print "---gun angles---"
print " gax#= ",gax#
print " gay#= ",gay#
print
print "---bullet angles---"
print " buax#= ",buax#
print " buay#= ",buay#
print " buaz#= ",buaz#
print " hit#= ",hit#
print
print "---bullet target displaced y values---"
print " ydistbullet#= ",ydistbullet#
print " ydisttarget#= ",ydisttarget#
print
print "---bullet - target displaced x values---"
print " xdistbullet#= ",xdistbullet#
print " xdisttarget#= ",xdisttarget#
print
print " hit2#-hit3# (adjustz#)= ",hit2#-hit3#
print
print "---calculate difference of above---"
print " deltay#= ",deltay#
print " deltax#= ",deltax#
print
print "---bullet y and x angles---"
print " bay#= ",bay#
print " bax#= ",bax#
print
print " shootcount= ",shootcount
print " L-mouse = Shoot"
print " Shiftkey = Reset Shooting"
print " q w e a s d to rotate target cube"
print " z,x,c,v,b,n and < control camera"
print " mouse rotate gun "
return
rem ****** CREATE LEVEL ******
makematrix:
rem Load and create images
rem textures
rem create ground texture
cls rgb(0,100,20)
inkcolor#=rgb(255,255,255)
for n=1 to 50 step 10
line n,0,n,50
line 0,n,50,n
next n
get image 2,0,0,50,50
rem create bullet plane texture
cls rgb(0,100,100)
inkcolor#=rgb(255,255,255)
get image 1,0,0,50,50
rem create pointer texture
cls rgb(0,0,100)
inkcolor#=rgb(255,255,255)
get image 5,0,0,50,50
rem Make landscape
make matrix 1,landsize,landsize,grid,grid
rem set matrix 1,1,0,0,1,1,1,1
prepare matrix texture 1,2,1,1
randomize matrix 1,mtxrandomize
rem get ground done
update matrix 1
return
rem make gun,target,bullet
makeobjects:
rem make gun
make object cone 1,40
scale object 1,100,500,100
set object cull 1,0
position object 1,gx#,gy#,gz#
xrotate object 1,90
fix object pivot 1
rem make target
make object cube 2,300
position object 2,10000,200,11000
xrotate object 2,60
yrotate object 2,40
zrotate object 2,40
rem make bullets
rem load image "bullhole02.bmp",4
for n=3 to bulletnumber
make object plain n,80,80
yrotate object n,180
fix object pivot n
set object transparency n,1
rem use image 4 if using bullet hole bmp
texture object n,1
position object n,n*10,100,10
next n
rem make pointer
make object sphere 100,30
texture object 100,5
return
end