` Mine Avoidance Updated
` Cory Thornsberry
` 7/23/07 Updated 7/31/07
 
Rem I've included two passwords (hit control during the game and type them in)
Rem For Invincibility Mode type "CORYRULES" WARNING: Cancels your score
Rem For Insane Difficulty Mode type "INSANE"
Rem I haven't worked all the bugs out of INSANE MODE yet
 
window=1
 
Rem Start-Up 
Sync On : Sync Rate 40 : CLS 0 : Sync
If window = 1
   Set Window On
   Set Window Size Screen Width(),Screen Height()
   Set Window Title "Mine Avoidance"
   Set Window Position Screen Width()/4,Screen Height()/4
   Set Window Layout 1,1,1
EndIf
Set Camera Range 1,1000
Backdrop Off
Always Active Off
Autocam Off
 
Rem Main Arrays
Rem Time(1)=min, Time(2)=sec, Time(3)=system time, Time(4)=Game Start Count Down
Rem Max game time: 59 min and 59 sec
Dim Time(4)
Dim Selected(5)
Dim Health(20)
Dim EnemyHealth(5)
Dim PlayerPos(20)
Dim EnemyPos(20)
Dim Mines(10)
Alive=5
EnemyAlive=5
AngX=25
 
Rem Setup-World
GoSub Info_Screen
For n=1 to 5
   Health(n)=100
   EnemyHealth(n)=(20*Difficulty)
Next n
Time(1)=11-Difficulty
If Time(1) > 59 then Time(1)=59
If Time(2) > 59 then Time(2)=59
Time(4)=15
Create_Image(1,20,70,15,30,90,25,100,2)
Create_Image(2,190,190,190,210,210,210,100,2)
GoSub Setup_Scene
GoSub Setup_Players
 
Position Camera 0,55,0
Rotate Camera AngX,0,0
Time(3)=(Timer()/1000)
 
Rem Main-Loop
Do
   Set Cursor 1,1
   Sprite 1,307.5,202.5,3
   PosX#=Camera Position X()
   PosY#=Camera Position Y()
   PosZ#=Camera Position Z()
   AngY#=Camera Angle Y()
   GoSub Bound_Camera
   GoSub Control_Players
   GoSub Get_Game_Time
   If activemines > 0 then GoSub Handle_Mines
   If UpKey()=1 then PosX#=NewXValue(PosX#,AngY#,5) : PosZ#=NewZValue(PosZ#,AngY#,5)
   If DownKey()=1 then PosX#=NewXValue(PosX#,AngY#,-5) : PosZ#=NewZValue(PosZ#,AngY#,-5)
   If LeftKey()=1 then AngY#=Wrapvalue(AngY#-5)
   If RightKey()=1 then AngY#=Wrapvalue(AngY#+5)
   If Scancode()=12
      PosX#=NewXValue(PosX#,AngY#,-5)
      PosY#=NewYValue(PosY#,AngX,-5)
      PosZ#=NewZValue(PosZ#,AngY#,-5)
   EndIf
   If Scancode()=13 and PosY# > 55
      PosX#=NewXValue(PosX#,AngY#,5)
      PosY#=NewYValue(PosY#,AngX,5)
      PosZ#=NewZValue(PosZ#,AngY#,5)
   EndIf
   If Scancode() = 51 and AngX > 25 then AngX=Wrapvalue(AngX-2)
   If Scancode() = 52 and AngX < 45 then AngX=Wrapvalue(AngX+2)
   If AngX < 25 then AngX=25 : If AngX > 45 then AngX=45
   If Mouseclick()=1 and Selecting=0 then Selecting=1 : OMX=MouseX() : OMY=MouseY()
   If Selecting=1 then GoSub Control_Select_Box else GoSub Check_Selections
   If Mouseclick()=2 then GoSub Give_Command
   INK RGB(0,255,0),0
   If InsaneMode = 1 then Print "INSANE MODE!"
   If GodMode = 1 then Print "GOD MODE!"
   INK RGB(255,255,255),0
   Print "Difficulty Level: ",Difficulty
   Print "Running @ ",Screen FPS()," FPS"
   Print "Time:   ";
   Print Time(1)," : ";
   If Time(2) < 10 then Print "0",Time(2) else Print Time(2)
   INK RGB(0,0,255),0 : Print "Score: ",score
   INK RGB(255,0,0),0 : Print "Score: ",enemyscore
   INK RGB(255,255,255),0
   Position Camera PosX#,PosY#,PosZ#
   XRotate Camera AngX
   YRotate Camera AngY# : Print Width#
   If controlkey()=1 then GoSub Cheat
   If activemines < 0 then activemines = 0
   If activemines > 10 then activemines = 10
   Sync
   If activemines < difficulty and Time(4) <= 0 then INC activemines : Arm_Mine(RND(500)-250,RND(500)-250,Difficulty)
Loop
 
Rem Sub-Routines
Info_Screen:
   Cls 0 : Sync
   Set Cursor 1,1
   Print "Mine Avoidance"
   Print : Print "     All you have to do is control your team and dodge the mines."
   Print "     simple right?  Click and drag to select team members.  Right"
   Print "     click to command your selected team members to move.  Got It?"
   Print : Print "     Once the game starts you will have 15 seconds to split up your"
   Print "     team.  After that the game time will start and you'll only need"
   Print "     to survive.  Good Luck (I recommend starting on LVL 3 or 4)"
   Print : Print
   Print "Instructions:"
   Print "     Survive for the required time or until the other team is dead"
   Print "     Press - to zoom out and + to zoom in"
   Print "     (NEW) Press < to Rotate Camera Up and > to Rotate Down"
   Print "     Move the Camera with the arrow keys"
   Print "     Select team members by clicking and dragging with LMB"
   Print "     Command team members by selecting them then using RMB"
   Print "     Selected members will move to the green crosshairs"
   Print "     Mines will explode when they become bright red"
   Print : Print : Print "Input Difficulty Level (1-10)"
   Input Difficulty
   If Difficulty < 1 Then Difficulty=1
   If Difficulty > 10 then Difficulty=10
Return
 
Setup_Scene:
   Make Object Plain 1,502,502
   XRotate Object 1,90
   Texture Object 1,1
   Make Object Plain 2,502,502
   Position Object 2,0,250,250
   Make Object Plain 3,502,502
   Position Object 3,0,250,-250
   Make Object Plain 4,502,502
   Position Object 4,-250,250,0
   YRotate Object 4,90
   Make Object Plain 5,502,502
   Position Object 5,250,250,0
   YRotate Object 5,90
   For n=2 to 5
      Texture Object n,2
   Next n
   Rem Make Mines (300-310)(310-320)
   For n=0 to 9
      If n <= Difficulty-1
         Make Object Cube 300+n,10
         Color Object 300+n,RGB(0,0,0)
         Scale Object 300+n,100,50,100
         Hide Object 300+n
         Make Object Sphere 310+n,100
         Color Object 310+n,RGB(255,255,0)
         Position Object 310+n,0,(100*(n+1)),0
         Hide Object 310+n
      EndIf
   Next n
   Create Bitmap 31,25,25
   Set Current Bitmap 31
   Ink RGB(0,255,0),0
   Line 0,13,25,13
   Line 13,0,13,25
   Get Image 3,0,0,25,25
   Delete Bitmap 31
Return
 
Setup_Players:
   Rem Allies (100-105)
   For n=0 to 4
      Make Object Sphere 100+n,20 : Color Object 100+n,RGB(0,0,255)
      Position Object 100+n,-200,10,0+(n*-40)
      Make Object Collision Box 100+n,-10,-10,-10,+10,+10,+10,0
   next n
   Rem Enemies (200-205)
   For n=0 to 4
      Make Object Sphere 200+n,20 : Color Object 200+n,RGB(255,0,0)
      Position Object 200+n,200,10,0+(n*40)
      Set Object Collision On 200+n
      Make Object Collision Box 100+n,-10,-10,-10,+10,+10,+10,0
   next n
Return
 
Bound_Camera:
   Rem Create Invisible Camera Boundaries
   If PosX# > 240 then PosX# = 240
   If PosX# < -240 then PosX# = -240
   If PosZ# > 240 then PosZ# = 240
   If PosZ# < -240 then PosZ# = -240
   If PosY# > 425 then PosY# = 425
Return
 
Control_Select_Box:
   If MouseClick()=1
      NMX=MouseX() : NMY=MouseY()
      Line OMX,OMY,OMX,NMY
      Line OMX,OMY,NMX,OMY
      Line NMX,NMY,OMX,NMY
      Line NMX,NMY,NMX,OMY
   Else
      For n=1 to 5
         Rem Object Detection System
         Selected(n)=0
         If Object in Screen(99+n)=1 and Health(n) > 0
            Width#=Find_Pixel_Width(99+n,PosX#,PosY#,PosZ#)
            ScreenX=(Object Screen X(99+n))
            ScreenY=(Object Screen Y(99+n))
            If ScreenX > OMX-Width# and ScreenX < NMX+Width#
               If ScreenY > OMY-Width# and ScreenY < NMY+Width#
                  Selected(n)=1
               EndIf
               If ScreenY < OMY+Width# and ScreenY > NMY-Width#
                  Selected(n)=1
               EndIf
            EndIf
            If ScreenX < OMX+Width# and ScreenX > NMX-Width#
               If ScreenY > OMY-Width# and ScreenY < NMY+Width#
                  Selected(n)=1
               EndIf
               If ScreenY < OMY+Width# and ScreenY > NMY-Width#
                  Selected(n)=1
               EndIf
            EndIf
         EndIf
         If Selected(n)=1 then Color Object 99+n,RGB(0,255,0)
         If Selected(n)=0 then Color Object 99+n,RGB(0,0,255)
      next n
      Selecting=0
   EndIf
Return
 
Check_Selections:
   For n=1 to 5
      If Selected(n) = 1 and Health(n) > 0
         If Object in Screen(99+n)=1
            ScreenX=Object Screen X(99+n)
            ScreenY=Object Screen Y(99+n)
            Center Text ScreenX,ScreenY-75,STR$(Health(n))
         EndIf
      EndIf
   next n
Return
 
Rem Main AI
Control_Players:
   score=(20*Difficulty)*5
   enemyscore=500
   For n=1 to 5
      Rem Allys
      If GodMode=0 then score=score-EnemyHealth(n)
      If Health(n+5) > 0
         NewX#=0 : NewZ#=0
         Point Object 99+n,Health(n+10),10,Health(n+15)
         NewX#=NewXValue(Object Position X(99+n),Object Angle Y(99+n),5)
         NewZ#=NewZValue(Object Position Z(99+n),Object Angle Y(99+n),5)
         If Object Collision(99+n,0) > 0
            NewX#=NewX#-Get Object Collision X()
            NewZ#=NewZ#-Get Object Collision Z()
         EndIf
         Health(n+5)=Health(n+5)-5
         If Health(n+5) < 0 then Health(n+5)=0
         If NewX# > 240 then NewX#=240
         If NewX# < -240 then NewX#=-240
         If NewZ# > 240 then NewZ#=240
         If NewZ# < -240 then NewZ#=-240
         Position Object 99+n,NewX#,10,NewZ#
      EndIf
      Rem Enemies
      enemyscore=enemyscore-Health(n)
      If Time(4) <= 0
         If RND(100) <= 10
            If RND(2) = 1
               YRotate Object 199+n,Wrapvalue(Object Angle Y(199+n)+5)
            Else
               YRotate Object 199+n,Wrapvalue(Object Angle Y(199+n)-5)
            EndIf
         EndIf
         NewX#=NewXValue(Object Position X(199+n),Object Angle Y(199+n),5)
         NewZ#=NewZValue(Object Position Z(199+n),Object Angle Y(199+n),5)
         If Object Collision(199+n,0) > 0
            NewX#=NewX#-Get Object Collision X()
            NewZ#=NewZ#-Get Object Collision Z()
         EndIf
         If NewX# > 240 then NewX#=240 : YRotate Object 199+n,Wrapvalue(Object Angle Y(199+n)+RND(180))
         If NewX# < -240 then NewX#=-240 : YRotate Object 199+n,Wrapvalue(Object Angle Y(199+n)+RND(180))
         If NewZ# > 240 then NewZ#=240 : YRotate Object 199+n,Wrapvalue(Object Angle Y(199+n)+RND(180))
         If NewZ# < -240 then NewZ#=-240 : YRotate Object 199+n,Wrapvalue(Object Angle Y(199+n)+RND(180))
         Position Object 199+n,NewX#,10,NewZ#
      EndIf
      If Health(n) < 0 then Hide Object 99+n : Health(n)=0 : DEC Alive
      If EnemyHealth(n) < 0 then Hide Object 199+n : EnemyHealth(n)=0 : DEC EnemyAlive
   Next n
   If Alive = 0 then Game_Over("",0,0,0,0)
   If EnemyAlive = 0 then Game_Over("win",score,difficulty,InsaneMode,GodMode)
Return
 
Give_Command:
   Rem I would like to move players to where user clicks
   Rem however using DBC I can't find a useful command
   Rem other than ObjectX and ObjectY
   Distance#=(PosY#/Sin(AngX))
   MoveX#=NewXValue(PosX#,AngY#,Distance#)
   MoveZ#=NewZValue(PosZ#,AngY#,Distance#)
   Command_MoveTo(MoveX#,MoveZ#)
Return
 
Get_Game_Time:
   If Time(4) <= 0
      Rem Main Game Time Control (You shouldn't need to adjust this)
      Time(2)=(Time(2)-((Timer()/1000)-Time(3)))
      If Time(2) < 0 then Time(2)=59 : Time(1)=Time(1)-1
      If Time(1) = 0 and Time(2) = 0
         If enemyscore > score then Game_Over("",0,0,0,0)
         If score >= enemyscore then Game_Over("win",score,difficulty,InsaneMode,GodMode)
      EndIf
      Time(3)=(Timer()/1000)
   Else
      Time(4)=(Time(4)-((Timer()/1000)-Time(3)))
      Set Text Size 40
      If Time(4) <= 5 then Ink RGB(255,0,0),0
      Center Text 320,240,STR$(Time(4))
      Time(3)=(Timer()/1000)
      Set Text Size 10 : Ink RGB(255,255,255),0
   EndIf
Return
 
Handle_Mines:
   For n=1 to 10
      If Mines(n) <= 0 and Object Exist(299+n) = 1
         If Object Visible(299+n)
            Mines(n)=0 : DEC activemines
            Hide Object 299+n
            KABOOM(Object Position X(299+n),Object Position Z(299+n),Difficulty,n)
         EndIf
      EndIf
      If Mines(n) > 0
         If InsaneMode = 0 then Mines(n)=Mines(n)-1 : Else Mines(n)=Mines(n)-2
         Color Object 299+n,RGB(255-Mines(n),0,0)
      EndIf
   next n
Return
 
Cheat:
   Print "Insert Password"
   Input CHEAT$
   If Upper$(CHEAT$) = "CORYRULES"
      GodMode=1
      For n=0 to 4
         Ghost Object On 100+n
      Next n
   EndIf
   If Upper$(CHEAT$) = "INSANE" then InsaneMode=1
Return
 
Rem Main Functions
Function Create_Image(ImageNumber,MinRed,MinGreen,MinBlue,MaxRed,MaxGreen,MaxBlue,Blend,Blur)
   Randomize 10
   If Bitmap Exist(31)=1 then Delete Bitmap 31
   RedRange=MaxRed-MinRed
   GreenRange=MaxGreen-MinGreen
   BlueRange=MaxBlue-MinBlue
   Rem Make a Small Box
   Create Bitmap 31,Blend,Blend
   Set Current Bitmap 31
   X=-1 : Y=0
   For n=1 to (Blend^2)
      Rem Create Bitmap
      If X > Blend Then Inc Y : X = 0 : else Inc X
      If RedRange > 0 Then Red=(RND(RedRange)+MinRed) else Red=0
      If GreenRange > 0 Then Green=(RND(GreenRange)+MinGreen) else Green=0
      If BlueRange > 0 Then Blue=(RND(BlueRange)+MinBlue) else Blue=0
      Ink RGB(Red,Green,Blue),0 : Dot X,Y
   next n
   Ink RGB(255,255,255),0
   Blur Bitmap 31,Blur
   Get Image ImageNumber,2,2,Blend-2,Blend-2
   Delete Bitmap 31
EndFunction
 
Function Game_Over(class$,scr,diff,InsaneMode,GodMode)
   If class$ = "win"
      For n=1 to 5
         bonus=bonus+Health(n)
      Next n
      Repeat
         Center Text 320,240,"Congratulations, You Win!"
         Center Text 320,260,"Press Enter to Proceed"
      Until ReturnKey() = 1
      display=0
      Repeat
         Center Text 320,220,"Score"
         Center Text 320,240,STR$(display)
         display=display+5
         Sync
      Until display >= scr
      display=scr
      Repeat
         Center Text 320,220,"Sub-Total Score = Score + Bonus Team Health Score"
         Center Text 320,240,STR$(display)
         display=display+10
         Sync
      Until display >= scr+bonus
      display=scr+bonus
      If GodMode = 0
         If diff > 1
            Repeat
               Center Text 320,220,"Final Score = Score X Difficulty"
               Center Text 320,240,STR$(display)
               display=display+(10*diff) : Sync
            Until display >= (scr+bonus)*diff
         EndIf
         display=(scr+bonus)*diff
         If InsaneMode=1
            Repeat
               Center Text 320,220,"Insane Mode Bonus = Score X 1000"
               Center Text 320,240,STR$(display)
               display=display+10 : Sync
            Until display >= ((scr+bonus)*diff)+1000
            display=((scr+bonus)*diff)+1000
         EndIf
         Repeat
            Center Text 320,220,"Total Score"
            Center Text 320,240,STR$(display)
            Center Text 320,260,"Press Enter to Exit"
            Sync
         Until ReturnKey() = 1
      Else
         Repeat
            Center Text 320,220,"Cheat Code Used :( Your Final Score is"
            Center Text 320,240,STR$(scr)
            Center Text 320,260,"Press Enter to Exit"
         Until ReturnKey() = 1
      EndIf
   Else
      Repeat
         Center Text 320,220,"Sorry You Lose.  Please Play Again!"
         Center Text 320,240,"Press Enter to Exit"
      Until ReturnKey() = 1
   EndIf
   End
EndFunction
 
Function Command_MoveTo(PosX#,PosZ#)
   For n=1 to 5
      If Selected(n)=1
         Point Object 99+n,PosX#,10,PosZ#
         Health(n+5)=SQRT((ABS(PosX#-Object Position X(99+n))^2)+(ABS(PosZ#-Object Position Z(99+n))^2))
         Health(n+10)=PosX#
         Health(n+15)=PosZ#
      EndIf
   next n
EndFunction
 
Function Arm_Mine(PosX,PosZ,diff)
   For n=0 to 9
      If Mines(n+1) = 0 and Object Exist(300+n) = 1 then MineNumber=n
   Next n
   Position Object 300+MineNumber,PosX,0,PosZ
   Color Object 300+MineNumber,RGB(255,0,0)
   Show Object 300+MineNumber
   If Object Exist(310+MineNumber) = 1
      If Object Visible(310+MineNumber) = 1 then Hide Object 310+MineNumber
   EndIf
   Mines(MineNumber+1)=255
EndFunction
 
Function Find_Pixel_Width(OB,PosX#,PosY#,PosZ#)
   DISTANCE#=SQRT((ABS(Object Position X(OB)-PosX#)^2)+(ABS(Object Position Y(OB)-PosY#)^2)+(ABS(Object Position Z(OB)-PosZ#)^2))
   ANGLE#=ATAN(20/DISTANCE#)
   REALWIDTH#=(Tan(ANGLE#)*250)
EndFunction REALWIDTH#
 
Function KABOOM(PosX#,PosZ#,Diff,MineNumber)
   Range=100 : If InsaneMode=1 then Range=250
   If Object Exist(309+MineNumber) = 1
      If Object Visible(309+MineNumber) = 0 then Show Object 309+MineNumber
      Position Object 309+MineNumber,PosX#,0,PosZ#
   EndIf
   For n=1 to 5
      Rem Allies
      If GodMode = 0
         distance#=SQRT((ABS(Object Position X(99+n)-PosX#)^2)+(ABS(Object Position Z(99+n)-PosZ#)^2))
         If distance# <= Range then Health(n)=Health(n)-(Range-Distance#)
      EndIf
      Rem Enemies
      distance#=SQRT((ABS(Object Position X(199+n)-PosX#)^2)+(ABS(Object Position Z(199+n)-PosZ#)^2))
      If distance# <= Range then EnemyHealth(n)=EnemyHealth(n)-((Range-Distance#)/Diff)
   Next n
EndFunction