This code is brilliant, there was one thing which prevented me using levels which have minus y co-ordinates (The camera doesn't go below the specified camera height.) so I fixed it for you.
I have basically made my own ramp code based on the supplied, I left the original in there and it can be activated again by removing the remark (so long as you rem out my part). I also added some different movement controlls so that its more fps orientated and a variable to edit the gravity.
You won't notice any difference on the map supplied as its lowest point is 0. Here is the map I tested it with and found the problem, try both ramp codes and try walking off the bridge from the side.
http://stateproperty.users.btopenworld.com/xcol.zip
Very small (250kb) contains the map and the source not required, i'll post the source here too.
`***************************
`.X Model sliding collision
`By Kensupen and Lokidecat
`Nerdsoft Creations (C) 2003
`***************************
`This uses all native DBPro commands to give a user sliding collision
`against ANY .X model to slide on ANY angle. It works almost as good as BSP
`collision, except for height. If you can walk onto an object, it just
`puts you at that height. I might try to advance the code later to give
`a smooth height adjustment.
`***************************
`Edited by RefuG :)
`***************************
rem Main Program Setup
sync on : sync rate 60 : autocam off : hide mouse : position mouse 320,240
set camera range 1,5000 : set ambient light 75
set image colorkey 255,0,255
rem load level
load object "mslevel.x",1
set object light 1,0
set object transparency 1,1
rem Main Program Variables
rem camera height from ground
cameraheight# = 50 : rem For RefuG's Ramp Code (I like readable variables :p)
charht#=50 : rem For Kensupen's Ramp Code
rem camera speed
movespeed# = 3
rem collision radius
radius# = 10.0
rem gravity
gravity# = 5
rem Set The Initial Camera Position And Rotation
position camera 0,50,0
rotate camera 0,180,0
rem Number Of Checks
`the lower this number is, the more off the collisions will be vs. any rotated object.
`also, the lower the number, the more speed it runs at.
`lowest for rotated collision is 4(non rotated/box collision) max is 360, but 360 is WAAAY slow
`I'd advide is you play with this number to keep with a multiple of 4
checks=8
if checks<4 then checks=4
if checks>360 then checks=360
`width of the angles
angwidth=360/checks
`make arrays for collision data
dim ang#(checks-1,2)
dim sort#(checks-1,2)
rem Main Loop
do
set cursor 0,0
rem Centers Mouse
position mouse 320,240
rem Get Initial Positions And A Revert Set
oldx#=camera position x()
oldz#=camera position z()
cx#=camera position x()
cy#=camera position y()
cz#=camera position z()
cay#=camera angle y()
rem Camera Movement
`forwards (w)
if keystate(17)=1
cx# = newxvalue(cx#,wrapvalue(cay#),movespeed#)
cz# = newzvalue(cz#,wrapvalue(cay#),movespeed#)
endif
`backwards (s)
if keystate(31)=1
cx# = newxvalue(cx#,wrapvalue(cay#-180),movespeed#)
cz# = newzvalue(cz#,wrapvalue(cay#-180),movespeed#)
endif
`left (a)
if keystate(30)=1
cx# = newxvalue(cx#,wrapvalue(cay#-90),movespeed#)
cz# = newzvalue(cz#,wrapvalue(cay#-90),movespeed#)
endif
`right (d)
if keystate(32)=1
cx# = newxvalue(cx#,wrapvalue(cay#+90),movespeed#)
cz# = newzvalue(cz#,wrapvalue(cay#+90),movespeed#)
endif
rem camera rotation
yrotate camera camera angle y() + mousemovex()*0.3
xrotate camera camera angle x() + mousemovey()*0.3
rem stops mouse from going upside down
if wrapvalue(camera angle x(0))>90 and wrapvalue(camera angle x(0))<180 then xrotate camera 0,90
if wrapvalue(camera angle x(0))>180 and wrapvalue(camera angle x(0))<280 then xrotate camera 0,280
rem Camera Position + Gravity
position camera cx#,cy#-gravity#,cz#
rem Refresh And Debugging
rem Show the camera angle
print "Camera angle:",camera angle y()
rem The main sliding collision code
gosub _collision
rem Kensupen Ramp Code
`gosub _ramp
rem RefuG Ramp Code
gosub _gravity
rem A just in case reset
if spacekey()=1 then position camera 0,200,0
set cursor 0,100 : print camera position x();" : ";camera position y();" : ";camera position z()
sync
loop
_collision:
rem Get Positions Again
cx#=camera position x()
cy#=camera position y()
cz#=camera position z()
`make 72 collision points. You can use more or less, but this number seems to work good.
`These are vectors every 5 degrees from the camera position out.
`They return the distance when they hit an object
for x=0 to checks-1
chx#=newxvalue(cx#,x*angwidth,100)
chz#=newzvalue(cz#,x*angwidth,100)
ang#(x,1)=intersect object(1,cx#,cy#,cz#,chx#,cy#,chz#)
if ang#(x,1)=0 then ang#(x,1)=999999
ang#(x,2)=x*angwidth
sort#(x,1)=ang#(x,1)
sort#(x,2)=ang#(x,2)
next x
rem sort the array to find the closest object and it's degrees
for x=0 to checks-2
for y=x+1 to checks-1
if ang#(x,1)>ang#(y,1)
temp#=ang#(x,1)
temp2#=ang#(x,2)
ang#(x,1)=ang#(y,1)
ang#(x,2)=ang#(y,2)
ang#(y,1)=temp#
ang#(y,2)=temp2#
endif
next x
next y
`This is the closest wall and what degrees you would face to see it
print "Angle to closest wall:",ang#(0,2)
print "Distance to that wall:",ang#(0,1)
`find +-90 degrees from the closest one for when you walk into a corner so it doesn't shake
prev=wrapvalue(ang#(0,2)-90)/angwidth
nxt=wrapvalue(ang#(0,2)+90)/angwidth
newd#=radius#-ang#(0,1)
newa#=wrapvalue(ang#(0,2)-180)
newd1#=radius#-sort#(prev,1)
newa1#=wrapvalue(sort#(prev,2)-180)
newd2#=radius#-sort#(nxt,1)
newa2#=wrapvalue(sort#(nxt,2)-180)
`if you are less than radius from a wall, push you out to 20 from it
if ang#(0,1)<radius# and ang#(0,1)>0.0
repx#=newxvalue(cx#,newa#,newd#)
repz#=newzvalue(cz#,newa#,newd#)
position camera repx#,cy#,repz#
endif
cx#=camera position x()
cz#=camera position z()
`this is if you are coming into a corner, this pushes you sideways
if sort#(prev,1)<radius# and sort#(prev,1)>0.0
repx1#=newxvalue(cx#,newa1#,newd1#)
repz1#=newzvalue(cz#,newa1#,newd1#)
position camera repx1#,cy#,repz1#
endif
cx#=camera position x()
cz#=camera position z()
`and the other way. above is left, this is right
if sort#(nxt,1)<radius# and sort#(nxt,1)>0.0
repx2#=newxvalue(cx#,newa2#,newd2#)
repz2#=newzvalue(cz#,newa2#,newd2#)
position camera repx2#,cy#,repz2#
endif
return
rem Kensupen Ramp Code
_ramp:
rem get positions again
cx#=camera position x()
cz#=camera position z()
rem Get your old height
oldht#=camera position y()
rem calc new height using intersect object from the old height down charht# units
sub#=intersect object(1,cx#,oldht#,cz#,cx#,oldht#-(charht#*2),cz#)
ht#=(oldht#+charht#)-sub#
if sub#=0 then ht#=charht#
rem do some gravity
grav#=grav#-0.25
rem if you are going up a ramp
if oldht#+grav#<ht#
grav#=0.0
position camera cx#,ht#,cz#
else
`if you are falling
ht#=oldht#+grav#
position camera cx#,ht#,cz#
endif
return
rem RefuG Ramp Code
_gravity:
rem Get Positions Again
cx#=camera position x()
cz#=camera position z()
rem Get Your Old Height
oldht#=camera position y()
`cy#=camera position y()
rem Finds The Distance From The Camera To The Floor
sub#=intersect object(1,cx#,oldht#,cz#,cx#,oldht#-cameraheight#,cz#)
rem If A Number Smaller Than The Specified Floor Height Is Returned Then...
if sub# < cameraheight#
cy#=(oldht#+cameraheight#)-sub#
rem reposition camera
position camera cx#,cy#,cz#
endif
rem If The Camera Is Not "Touching" The Floor (i.e. Floor Height + Specified Camera Heght) Then
if sub# = 0
rem reset camera position
position camera cx#,oldht#,cz#
endif
rem debugging
set cursor 0,80 : print sub#
return
[Edit] The Source Button didnt work and I can't edit it so ^^ hopefully this will + A Quick Fix now in the above zip too