REM ***********************************************
REM Title: Throw Object
REM Author: Phaelax
REM Downloaded from: http://dbcc.zimnox.com/
REM ***********************************************
 
REM Coded by: Phaelax (Phaelax@hotmail.com)
REM Demonstrates how to throw and object through the air
REM using projectile motion.
 
autocam off
sync on
sync rate 60
hide mouse
 
player_height# = 100.0 : rem height of the player's eyes
grav_str# = 1.0        : rem gravity strength
obj_size# = 10.0       : rem size of throwing object (in this case, the sphere's radius)
 
make matrix 1, 1000,1000,40,40
 
make object sphere 1, obj_size#*2
 
DO
 
   gosub player_controls
   gosub camera_status
 
 
   rem if left mouse button clicked, initialize the variables for
   rem throwing the object.
   rem tx#,ty#,tz# are the object's starting positon (character's current position).
   rem tYA# is the character's Y rotation.
   rem tPitch# is the characters X rotation or the angle at which the character
   rem is looking either up or down.
   rem T# is the time index. Since the object is just starting to be thrown,
   rem current time is 0 seconds.
   rem F# is the amount of force that's used to throw the object.
   rem tpx# is just a temp variable that needs to be reset.
   if mouseclick() and throw = 0
      throw=1
      tx# = x#
      tz# = z#
      ty# = get ground height(1,x#,z#)+player_height#
      tYA# = a#
      tPitch# = 360.0-camera angle x()
      T# = 0.0
      F# = 40.0
      tpx# = 0
   endif
 
   if throw = 1 then gosub throw_translocator
 
   sync
LOOP
 
 
REM control player's movement
PLAYER_CONTROLS:
  runspeed#=0.0
  if shiftkey()=1 then runspeed#=6.0
  if upkey()=1
    x#=newxvalue(x#,a#,6+runspeed#)
    z#=newzvalue(z#,a#,6+runspeed#)
  endif
  if downkey()=1
    x#=newxvalue(x#,a#,-6-runspeed#)
    z#=newzvalue(z#,a#,-6-runspeed#)
  endif
  if leftkey()=1
    x#=newxvalue(x#,wrapvalue(a#-90.0),5.0+runspeed#)
    z#=newzvalue(z#,wrapvalue(a#-90.0),5.0+runspeed#)
  endif
  if rightkey()=1
    x#=newxvalue(x#,wrapvalue(a#+90.0),5.0+runspeed#)
    z#=newzvalue(z#,wrapvalue(a#+90.0),5.0+runspeed#)
  endif
 
RETURN
 
 
REM control player's angle of site/rotation and position
CAMERA_STATUS:
  rem rotate camera according to mouse
  a#=wrapvalue(a#+(mousemovex()/3.0))
  rem position and rotate camera
  cxa#=cxa#+(mousemovey()/3.0)
  if cxa#<-90.0 then cxa#=-90.0
  if cxa#>90.0 then cxa#=90.0
  position camera x#,get ground height(1,x#,z#)+player_height#,z#
  rotate camera wrapvalue(cxa#),a#,0
RETURN
 
 
REM iterator sub to constantly update position of thrown object
throw_translocator:
   rem store old positions
   oldtpx#=tpx#
   oldtx#=tx#
   oldtz#=tz#
   rem TPX# is the distance the object has traveled from the origin
   TPX#=F#*COS(tPitch#)*T#
   rem TPY# is the height of the object's arc.
   TPY#=F#*SIN(tPitch#)*T#-(0.5*grav_str#)*(T#^2)
   rem dist# is the distance that the object has traveled during this iteration
   dis#=abs(oldtpx#-tpx#)
   rem tx# and tz# transforms that distance from 2D into a 3D distance based
   rem on the character's Y rotation.
   tx#=newxvalue(tx#,tYA#,dis#)
   tz#=newzvalue(tz#,tYA#,dis#)
   rem increment time index
   inc T#
   rem positions the object
   position object 1,tx#,ty#+TPY#,tz#
   rem stop movement if object hits ground
   if object position y(1)<=obj_size#
      throw=0
      rem make sure object's last position is above ground
      position object 1,oldtx#,obj_size#,oldtz#
   endif
RETURN