set display mode 1024,768,32
hide mouse
backdrop on
color backdrop rgb(0,0,150)
set camera range 1,10000
sync on
men=1
animals=10
 
dim body(men) as integer
dim bodydir(men) as float
dim anim(animals) as integer
dim animdir(animals) as float
for x=1 to men
  body(x)=x
  bodydir(x)=0
next x
for x=1 to animals
  anim(x)=x+men
  animdir(x)=rnd(360)
next x
x=men+animals
upperarm=x+1
lowerarm=x+2
upperleg=x+3
lowerleg=x+4
head=x+5
joint=x+6
breast=x+7
 
ground_matrix=1
 
ground_i=1
animal_i=2
 
upperarm_mesh=1
lowerarm_mesh=2
upperleg_mesh=3
lowerleg_mesh=4
head_mesh=5
joint_mesh=6
body_mesh=7
breast_mesh=8
 
hip_l=1
upperleg_l=2
knee_l=3
lowerleg_l=4
hip_r=5
upperleg_r=6
knee_r=7
lowerleg_r=8
shoulder_l=9
upperarm_l=10
elbow_l=11
lowerarm_l=12
shoulder_r=13
upperarm_r=14
elbow_r=15
lowerarm_r=16
head_c=17
breast_f=18
breast_r=19
 
ground_size=30
make matrix ground_matrix,10000,10000,ground_size,ground_size
for x=1 to ground_size
  for y=1 to ground_size
    set matrix height ground_matrix,x,y,sin(x*60)*60
  next y
next x
create bitmap 1,60,60
ink rgb(0,192,0),0
box 0,0,60,60
ink rgb(64,255,64),0
for x=1 to 500
  dot rnd(60),rnd(60)
next x
get image ground_i,0,0,59,59
set current bitmap 0
prepare matrix texture ground_matrix,ground_i,1,1
update matrix ground_matrix
 
rem Make human form
x=1
make object cylinder body(x),40
scale object body(x),50,100,25
make mesh from object body_mesh,body(x)
delete object body(x)
make object body(x),body_mesh,0
make object cylinder upperarm,20:scale object upperarm,25,100,25
make object cylinder lowerarm,20:scale object lowerarm,25,75,25
make object cylinder upperleg,20:scale object upperleg,40,100,40
make object cylinder lowerleg,20:scale object lowerleg,40,100,40
make object sphere head,20
scale object head,80,100,70
make object sphere joint,7
make mesh from object upperarm_mesh,upperarm
make mesh from object lowerarm_mesh,lowerarm
make mesh from object upperleg_mesh,upperleg
make mesh from object lowerleg_mesh,lowerleg
make mesh from object head_mesh,head
make mesh from object joint_mesh,joint
delete object upperarm
delete object lowerarm
delete object upperleg
delete object lowerleg
delete object head
delete object joint
 
add limb body(x),hip_l,joint_mesh
add limb body(x),upperleg_l,upperleg_mesh
link limb body(x),hip_l,upperleg_l
add limb body(x),knee_l,joint_mesh
link limb body(x),upperleg_l,knee_l
add limb body(x),lowerleg_l,lowerleg_mesh
link limb body(x),knee_l,lowerleg_l
 
add limb body(x),hip_r,joint_mesh
add limb body(x),upperleg_r,upperleg_mesh
link limb body(x),hip_r,upperleg_r
add limb body(x),knee_r,joint_mesh
link limb body(x),upperleg_r,knee_r
add limb body(x),lowerleg_r,lowerleg_mesh
link limb body(x),knee_r,lowerleg_r
 
add limb body(x),shoulder_l,joint_mesh
add limb body(x),upperarm_l,upperarm_mesh
link limb body(x),shoulder_l,upperarm_l
add limb body(x),elbow_l,joint_mesh
link limb body(x),upperarm_l,elbow_l
add limb body(x),lowerarm_l,lowerarm_mesh
link limb body(x),elbow_l,lowerarm_l
 
add limb body(x),shoulder_r,joint_mesh
add limb body(x),upperarm_r,upperarm_mesh
link limb body(x),shoulder_r,upperarm_r
add limb body(x),elbow_r,joint_mesh
link limb body(x),upperarm_r,elbow_r
add limb body(x),lowerarm_r,lowerarm_mesh
link limb body(x),elbow_r,lowerarm_r
 
add limb body(x),head_c,head_mesh
 
offset limb body(x),shoulder_l,12.5,17.5.0,0.0
offset limb body(x),upperarm_l,0.0,-10.0,0.0
offset limb body(x),elbow_l,0.0,-10.0,0.0
offset limb body(x),lowerarm_l,0.0,-10.0,0.0
offset limb body(x),shoulder_r,-12.5,17.5,0.0
offset limb body(x),upperarm_r,0.0,-10.0,0.0
offset limb body(x),elbow_r,0.0,-10.0,0.0
offset limb body(x),lowerarm_r,0.0,-10.0,0.0
offset limb body(x),hip_l,5.0,-20.0,0.0
offset limb body(x),upperleg_l,0.0,-10.0,0.0
offset limb body(x),knee_l,0.0,-10.0,0.0
offset limb body(x),lowerleg_l,0.0,-7.5,0.0
offset limb body(x),hip_r,-5.0,-20.0,0.0
offset limb body(x),upperleg_r,0.0,-10.0,0.0
offset limb body(x),knee_r,0.0,-10.0,0.0
offset limb body(x),lowerleg_r,0.0,-7.5,0.0
offset limb body(x),head_c,0.0,30.0,0.0
 
rem Make multiple copies of human form
position object 1,800,60,1600
for x=2 to men
  clone object x,1
  position object x,x*50+800,60,x*50+1600
next x
x=1
rem Make animal form
make object cylinder anim(x),40
scale object anim(x),35,100,50
add limb anim(x),hip_l,joint_mesh
add limb anim(x),upperleg_l,upperleg_mesh
link limb anim(x),hip_l,upperleg_l
add limb anim(x),knee_l,joint_mesh
link limb anim(x),upperleg_l,knee_l
add limb anim(x),lowerleg_l,lowerleg_mesh
link limb anim(x),knee_l,lowerleg_l
rotate limb anim(x),hip_l,90,0,0
 
add limb anim(x),hip_r,joint_mesh
add limb anim(x),upperleg_r,upperleg_mesh
link limb anim(x),hip_r,upperleg_r
add limb anim(x),knee_r,joint_mesh
link limb anim(x),upperleg_r,knee_r
add limb anim(x),lowerleg_r,lowerleg_mesh
link limb anim(x),knee_r,lowerleg_r
rotate limb anim(x),hip_r,90,0,0
 
add limb anim(x),shoulder_l,joint_mesh
add limb anim(x),upperarm_l,upperleg_mesh
link limb anim(x),shoulder_l,upperarm_l
add limb anim(x),elbow_l,joint_mesh
link limb anim(x),upperarm_l,elbow_l
add limb anim(x),lowerarm_l,lowerleg_mesh
link limb anim(x),elbow_l,lowerarm_l
rotate limb anim(x),shoulder_l,90,0,0
 
add limb anim(x),shoulder_r,joint_mesh
add limb anim(x),upperarm_r,upperleg_mesh
link limb anim(x),shoulder_r,upperarm_r
add limb anim(x),elbow_r,joint_mesh
link limb anim(x),upperarm_r,elbow_r
add limb anim(x),lowerarm_r,lowerleg_mesh
link limb anim(x),elbow_r,lowerarm_r
rotate limb anim(x),shoulder_r,90,0,0
 
add limb anim(x),head_c,head_mesh
make object sphere breast,40
scale object breast,100,25,100
make mesh from object breast_mesh,breast
delete object breast
add limb anim(x),breast_f,breast_mesh
add limb anim(x),breast_r,breast_mesh
 
offset limb anim(x),shoulder_l,25.0,17.5.0,0.0
offset limb anim(x),upperarm_l,0.0,-10.0,0.0
offset limb anim(x),elbow_l,0.0,-10.0,0.0
offset limb anim(x),lowerarm_l,0.0,-10.0,0.0
offset limb anim(x),shoulder_r,-25.0,17.5,0.0
offset limb anim(x),upperarm_r,0.0,-10.0,0.0
offset limb anim(x),elbow_r,0.0,-10.0,0.0
offset limb anim(x),lowerarm_r,0.0,-10.0,0.0
offset limb anim(x),hip_l,25.0,-20.0,0.0
offset limb anim(x),upperleg_l,0.0,-10.0,0.0
offset limb anim(x),knee_l,0.0,-10.0,0.0
offset limb anim(x),lowerleg_l,0.0,-7.5,0.0
offset limb anim(x),hip_r,-25.0,-20.0,0.0
offset limb anim(x),upperleg_r,0.0,-10.0,0.0
offset limb anim(x),knee_r,0.0,-10.0,0.0
offset limb anim(x),lowerleg_r,0.0,-7.5,0.0
offset limb anim(x),head_c,0.0,25.0,25.0
offset limb anim(x),breast_f,0.0,20.0,0.0
offset limb anim(x),breast_r,0.0,-20.0,0.0
xrotate object anim(x),-90.0
yrotate object anim(x),180.0
fix object pivot anim(x)
create bitmap 1,20,20
ink rgb(240,64,32),0
box 0,0,20,20
ink rgb(255,255,255),0
for i=1 to 60
  dot rnd(19),rnd(19)
next i
get image animal_i,0,0,19,19
set current bitmap 0
delete bitmap 1
texture object anim(x),animal_i
 
position object anim(x),800,50,800
rem Make multiple copies of animal form
for x=2 to animals
  clone object anim(x),anim(1)
  position object anim(x),rnd(5)*100+800,50,rnd(5)*100+800
next x
 
speed#=1.0
dim l_hip(men+animals) as float
dim l_knee(men+animals) as float
dim r_hip(men+animals) as float
dim r_knee(men+animals) as float
dim l_hipdir(men+animals) as float
dim l_kneedir(men+animals) as float
dim r_hipdir(men+animals) as float
dim r_kneedir(men+animals) as float
dim r_shoulder(men+animals) as float
dim r_elbow(men+animals) as float
dim l_shoulder(men+animals) as float
dim l_elbow(men+animals) as float
dim r_shoulderdir(men+animals) as float
dim r_elbowdir(men+animals) as float
dim l_shoulderdir(men+animals) as float
dim l_elbowdir(men+animals) as float
for x=1 to men
  l_hip(x)=-45.0
  l_knee(x)=45.0
  r_hip(x)=45.0
  r_knee(x)=45.0
  l_hipdir(x)=speed#
  l_kneedir(x)=-speed#
  r_hipdir(x)=-speed#
  r_kneedir(x)=speed#
 
  r_shoulder(x)=-45.0
  r_elbow(x)=-45.0
  l_shoulder(x)=45.0
  l_elbow(x)=-45.0
  r_shoulderdir(x)=speed#
  r_elbowdir(x)=-speed#
  l_shoulderdir(x)=-speed#
  l_elbowdir(x)=speed#
next x
for x=1 to animals
  l_hip(x+men)=45.0
  l_knee(x+men)=45.0
  r_hip(x+men)=90.0
  r_knee(x+men)=0.0
  l_hipdir(x+men)=speed#
  l_kneedir(x+men)=speed#
  r_hipdir(x+men)=-speed#
  r_kneedir(x+men)=speed#
 
  r_shoulder(x+men)=160.0
  r_elbow(x+men)=-45.0
  l_shoulder(x+men)=120.0
  l_elbow(x+men)=-15.0
  r_shoulderdir(x+men)=-speed#
  r_elbowdir(x+men)=-speed#
  l_shoulderdir(x+men)=-speed#
  l_elbowdir(x+men)=speed#
next x
 
position camera 0.0,390.0,200.0
point camera 1000.0,0.0,1000.0
while not escapekey()
  control camera using arrowkeys 0,3.0,1.0
  for x=1 to men
    rotate limb body(x),hip_l,l_hip(x),0.0,0.0
    rotate limb body(x),knee_l,l_knee(x),0.0,0.0
    rotate limb body(x),hip_r,r_hip(x),0.0,0.0
    rotate limb body(x),knee_r,r_knee(x),0.0,0.0
    rotate limb body(x),shoulder_l,l_shoulder(x),0.0,0.0
    rotate limb body(x),elbow_l,l_elbow(x),0.0,0.0
    rotate limb body(x),shoulder_r,r_shoulder(x),0.0,0.0
    rotate limb body(x),elbow_r,r_elbow(x),0.0,0.0
    l_hip(x)=l_hip(x)+l_hipdir(x)
    if (l_hip(x)<=-45.0 or l_hip(x)>=45.0)
      l_hipdir(x)=-l_hipdir(x)
    endif
    l_knee(x)=l_knee(x)+l_kneedir(x)
    if (l_knee(x)<=0.0 or l_knee(x)>=90.0)
      l_kneedir(x)=-l_kneedir(x)
    endif
    r_hip(x)=r_hip(x)+r_hipdir(x)
    if (r_hip(x)<=-45.0 or r_hip(x)>=45.0)
      r_hipdir(x)=-r_hipdir(x)
    endif
    r_knee(x)=r_knee(x)+r_kneedir(x)
    if (r_knee(x)<=0.0 or r_knee(x)>=90.0)
      r_kneedir(x)=-r_kneedir(x)
    endif
    l_shoulder(x)=l_shoulder(x)+l_shoulderdir(x)
    if (l_shoulder(x)<=-45.0 or l_shoulder(x)>=45.0)
      l_shoulderdir(x)=-l_shoulderdir(x)
    endif
    l_elbow(x)=l_elbow(x)-l_elbowdir(x)
    if (l_elbow(x)<=-90.0 or l_elbow(x)>=0.0)
      l_elbowdir(x)=-l_elbowdir(x)
    endif
    r_shoulder(x)=r_shoulder(x)+r_shoulderdir(x)
    if (r_shoulder(x)<=-45.0 or r_shoulder(x)>=45.0)
      r_shoulderdir(x)=-r_shoulderdir(x)
    endif
    r_elbow(x)=r_elbow(x)-r_elbowdir(x)
    if (r_elbow(x)<=-90.0 or r_elbow(x)>=0.0)
      r_elbowdir(x)=-r_elbowdir(x)
    endif
    if object angle y(body(x))>bodydir(x) then yrotate object body(x),object angle y(body(x))-0.5
    if object angle y(body(x))<bodydir(x) then yrotate object body(x),object angle y(body(x))+0.5
    move object body(x),0.5
    distance#=10000
    hunt=0
    for i= 1 to animals
      dist#=sqrt((object position x(body(x))-object position x(anim(i)))^2+(object position z(body(x))-object position z(anim(x)))^2)
      if dist#<distance#
        distance#=dist#
        hunt=i
      endif
    next i
    if hunt>0
      curx#=object angle x(body(x))
      cury#=object angle y(body(x))
      curz#=object angle z(body(x))
      point object body(x),object position x(anim(hunt)),object position y(anim(hunt)),object position z(anim(hunt))
      bodydir(x)=object angle y(body(x))
      rotate object body(x),curx#,cury#,curz#
    endif
    curx#=object position x(body(x))
    curz#=object position z(body(x))
    if curx#>=0.0 and curx#<=5000.0 and curz#>=0.0 and curz#<=5000.0
      newy#=get ground height(ground_matrix,curx#,curz#)+60.0
    else
      newy#=object position y(body(x))
    endif
    position object body(x),curx#,newy#,curz#
  next x
  for x=1 to animals
    rotate limb anim(x),hip_l,l_hip(x+men),0.0,0.0
    rotate limb anim(x),knee_l,l_knee(x+men),0.0,0.0
    rotate limb anim(x),hip_r,r_hip(x+men),0.0,0.0
    rotate limb anim(x),knee_r,r_knee(x+men),0.0,0.0
    rotate limb anim(x),shoulder_l,l_shoulder(x+men),0.0,0.0
    rotate limb anim(x),elbow_l,l_elbow(x+men),0.0,0.0
    rotate limb anim(x),shoulder_r,r_shoulder(x+men),0.0,0.0
    rotate limb anim(x),elbow_r,r_elbow(x+men),0.0,0.0
    l_hip(x+men)=l_hip(x+men)+l_hipdir(x+men)
    if (l_hip(x+men)<=45.0 or l_hip(x+men)>=135.0)
      l_hipdir(x+men)=-l_hipdir(x+men)
    endif
    l_knee(x+men)=l_knee(x+men)+l_kneedir(x+men)
    if (l_knee(x+men)<=0.0 or l_knee(x+men)>=90.0)
      l_kneedir(x+men)=-l_kneedir(x+men)
    endif
    r_hip(x+men)=r_hip(x+men)+r_hipdir(x+men)
    if (r_hip(x+men)<=45.0 or r_hip(x+men)>=135.0)
      r_hipdir(x+men)=-r_hipdir(x+men)
    endif
    r_knee(x+men)=r_knee(x+men)+r_kneedir(x+men)
    if (r_knee(x+men)<=0.0 or r_knee(x+men)>=90.0)
      r_kneedir(x+men)=-r_kneedir(x+men)
    endif
    l_shoulder(x+men)=l_shoulder(x+men)+l_shoulderdir(x+men)
    if (l_shoulder(x+men)<=70.0 or l_shoulder(x+men)>=160.0)
      l_shoulderdir(x+men)=-l_shoulderdir(x+men)
    endif
    l_elbow(x+men)=l_elbow(x+men)-l_elbowdir(x+men)
    if (l_elbow(x+men)<=-90.0 or l_elbow(x+men)>=0.0)
      l_elbowdir(x+men)=-l_elbowdir(x+men)
    endif
    r_shoulder(x+men)=r_shoulder(x+men)+r_shoulderdir(x+men)
    if (r_shoulder(x+men)<=70.0 or r_shoulder(x+men)>=160.0)
      r_shoulderdir(x+men)=-r_shoulderdir(x+men)
    endif
    r_elbow(x+men)=r_elbow(x+men)-r_elbowdir(x+men)
    if (r_elbow(x+men)<=-90.0 or r_elbow(x+men)>=0.0)
      r_elbowdir(x+men)=-r_elbowdir(x+men)
    endif
    if object angle y(anim(x))>animdir(x) then yrotate object anim(x),object angle y(anim(x))-0.5
    if object angle y(anim(x))<animdir(x) then yrotate object anim(x),object angle y(anim(x))+0.5
    move object anim(x),0.5
    distance#=1000
    flee=0
    for i=1 to men
      dist#=sqrt((object position x(body(i))-object position x(anim(x)))^2+(object position z(body(i))-object position z(anim(x)))^2)
      if dist#<distance#
        distance#=dist#
        flee=i
      endif
    next i
    if flee<0
      curx#=object angle x(anim(x))
      cury#=object angle y(anim(x))
      curz#=object angle z(anim(x))
      point object anim(x),object position x(body(flee)),object position y(body(flee)),object position z(body(flee))
      newy#=object angle y(anim(x))
      rotate object anim(x),curx#,cury#,curz#
      animdir(x)=newy#+180
      if animdir(x)>360 then animdir(x)=animdir(x)-360
    endif
    curx#=object position x(anim(x))
    curz#=object position z(anim(x))
    if curx#>=0.0 and curx#<=5000.0 and curz#>=0.0 and curz#<=5000.0
      newy#=get ground height(ground_matrix,curx#,curz#)+30.0
    else
      newy#=object position y(anim(x))
    endif
    position object anim(x),curx#,newy#,curz#
  next x
  sync
endwhile
end