• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
CProgrammer

2 player one computer games

26 posts in this topic

Scorched Earth could do, I think, 8 people on one computer, and all of it was turn-based, save one mode in which everyone is constantly going. I'd love to see how 8 people manage that last one.
0

Share this post


Link to post
Share on other sites
Quote:
Original post by eedok
<sspp*>
you mean like this?
</sspp>

*shameless self-promoting plug

Not a bad game. I tried it and the one comment I have is that bouncing off one another should be affected by tangetial hits. Right now you are modeling as a square I would guess. Try to bounce with regards to a line drawn between the centers.
0

Share this post


Link to post
Share on other sites
Thanks a bunch guys.

Quote:
Original post by eedok
<sspp*>
you mean like this?
</sspp>

*shameless self-promoting plug


Hey great game idea. I like it.

Cheers

-CProgrammer
0

Share this post


Link to post
Share on other sites
Quote:
Original post by eedok
<sspp*>
you mean like this?
</sspp>

*shameless self-promoting plug


Dude thats a really good idea. Now make a 3d version of it. ;)
0

Share this post


Link to post
Share on other sites
Civilisation 3: Play the World
Heroes of Might and Magic 3 & 4
Disciples 2

These turn-based games have a hot seat mode for 2 or more players on the same computer.
0

Share this post


Link to post
Share on other sites
Quote:
Original post by andy-pandy
These turn-based games have a hot seat mode for 2 or more players on the same computer.

So does Wesnoth. ("The Battle for Wesnoth is a free, turn-based strategy game with a fantasy theme.")

More small, funny games:
"Lemming Ball Z is a DBZ-style fighting game with Lemmings."
"Feature Fangis is a funny game for 2-4 players on a single computer."
HaCKeR is a neat Tetris clone including cooperative and competitive multiplayer modes.
0

Share this post


Link to post
Share on other sites
Here's some, you'll need dos-box for some though:

ufo-enemy unknown
x-com apocalypse (dos-box)

Grand theft auto 1 & 2

They can all be found on abandonia or abandonia reloaded.
0

Share this post


Link to post
Share on other sites
Quote:
Original post by I Like Bread
If you have one of the original Doom games, check out the Legacy source port. 2-Player splitscreen!


Cool!

And why has nobody suggested Worms? Does anybody here remember Apocalypse Cow, also?
0

Share this post


Link to post
Share on other sites
Worms all the way! Lots of great fun for up to 6 players. Get one of the 2D versions though (Worms 2, Worms Armageddon or Worms World Party); the 3D versions just don't have the same appeal.
0

Share this post


Link to post
Share on other sites
havent tried on xp, but should work.

I dont suppose anyone will complain about saying downloading as it is so old now, and you probably owned it at one point.

try and download msdos 6? disks, and install on a virtual machine, or a old pc if you have it... or just try and search the disks for a compressed file I think it is, qbasic.ex_, or it could be expanded to .exe if it isnt run the expand comand. then try and find gorrilas or monkeys .vbs I think, not sure on extension.

I had so many fun hours playing that game! I tried throwing a bananna here, but was sadly disappointed when it didnt take a chunk out of a building or explode when touching someone!
0

Share this post


Link to post
Share on other sites
'QBASIC GORILLAS 2.1b3
'Version 1.0 (c)1990 Microsoft Corp and/or IBM Corp
'Version 2.* (c)1997-2005 Daniel Beardsmore
'See http://telcontar.net/Misc/Gorillas/ for more information

'Set default data type to integer for faster game play
DEFINT A-Z

'Sub Declarations
DECLARE SUB restReal (t#)
DECLARE SUB alertSnd ()
DECLARE SUB LoadSettings ()
DECLARE SUB Center (Row, Text$)
DECLARE SUB DoBeep ()
DECLARE SUB DoExplosion (x#, y#)
DECLARE SUB DoSun (Mouth)
DECLARE SUB DrawBan (xc#, yc#, r, bc)
DECLARE SUB DrawGorilla (x, y, arms)
DECLARE SUB ExplodeGorilla (x#, y#, PlayerHit)
DECLARE SUB Extro ()
DECLARE SUB GetInputs (player$(), NumGames, P)
DECLARE SUB GorillaIntro (player$(), cIntro)
DECLARE SUB Intro ()
DECLARE SUB MakeCityScape (BCoor() AS ANY)
DECLARE SUB PlaceGorillas (BCoor() AS ANY)
DECLARE SUB rest (t#)
DECLARE SUB SetScreen ()
DECLARE SUB ShowPrompts (fieldNum AS INTEGER)
DECLARE SUB Slidy ()
DECLARE SUB SparklePause (opt AS INTEGER)
DECLARE SUB Stats (Wins(), name$(), Ban!(), P, abortYN)
DECLARE SUB VictoryDance (player)

DECLARE FUNCTION CalcDelay# ()
DECLARE FUNCTION DoShot (PlayerNum, x, y, turn, othX, othY)
DECLARE FUNCTION GET$ (Row, Col, Prev$, Typ, Max, Esc)
DECLARE FUNCTION PlayGame (player$(), NumGames, P)
DECLARE FUNCTION PlotShot (StartX, StartY, angle#, velocity, PlayerNum, othX, othY)
DECLARE FUNCTION Scl (N!)
DECLARE FUNCTION WHEREX (num)
DECLARE FUNCTION WHEREY (num)

'Make all arrays Dynamic
'$DYNAMIC

' User-Defined TYPEs

TYPE settings
useSound AS INTEGER
useOldExplosions AS INTEGER
newExplosionRadius AS INTEGER
useSlidingText AS INTEGER
defaultGravity AS INTEGER
defaultRoundQty AS INTEGER
showIntro AS INTEGER
END TYPE

TYPE XYPoint
XCoor AS INTEGER
YCoor AS INTEGER
END TYPE

TYPE PlayerData
PNam AS STRING * 17
Rounds AS INTEGER
Won AS INTEGER
Accu AS SINGLE
END TYPE

' Constants
CONST NPLAYERS = 20
CONST TRUE = -1
CONST FALSE = NOT TRUE
CONST HITSELF = 1
CONST BACKATTR = 0
CONST OBJECTCOLOR = 1
CONST WINDOWCOLOR = 14
CONST SUNHAPPY = FALSE
CONST SUNSHOCK = TRUE
CONST RIGHTUP = 1
CONST LEFTUP = 2
CONST ARMSDOWN = 3

' Global Variables
DIM SHARED GSettings AS settings

DIM SHARED lastErrCode

DIM SHARED SLIDECONST AS LONG

DIM SHARED GorillaX(1 TO 2) 'Location of the two gorillas
DIM SHARED GorillaY(1 TO 2)
DIM SHARED LastBuilding

DIM SHARED pi#
DIM SHARED LBan&(x), RBan&(x), UBan&(x), DBan&(x) 'Graphical picture of banana
DIM SHARED GorD&(120) 'Graphical picture of Gorilla arms down
DIM SHARED GorL&(120) 'Gorilla left arm raised
DIM SHARED GorR&(120) 'Gorilla right arm raised

DIM SHARED Gravity
DIM SHARED Wind
DIM SHARED GLeftAngle#
DIM SHARED GRightAngle#
DIM SHARED GLeftVeloc
DIM SHARED GRightVeloc

'Screen Mode Variables
DIM SHARED ScrHeight
DIM SHARED ScrWidth
DIM SHARED Mode
DIM SHARED MaxCol

' Screen Color Variables
DIM SHARED ExplosionColor
DIM SHARED SUNATTR
DIM SHARED BackColor

DIM SHARED SunHt
DIM SHARED GHeight
DIM SHARED MachSpeed AS DOUBLE

DIM SHARED PDefs(1 TO 2)
DIM player$(1 TO 2)
DIM SHARED PDat(1 TO NPLAYERS) AS PlayerData
DIM SHARED GamePlayedYN

DIM SHARED DoesFileExist

DIM NumGames

' Check for league table file, and load table entries

DoesFileExist = 1
ON ERROR GOTO IsThereNoFile
OPEN "GORILLAS.LGE" FOR INPUT AS #1
ON ERROR GOTO CorruptFile
IF DoesFileExist = 1 THEN
INPUT #1, count
FOR l = 1 TO count
INPUT #1, PDat(l).PNam, PDat(l).Rounds, PDat(l).Won, PDat(l).Accu
NEXT
CLOSE #1
ON ERROR GOTO 0
ELSE
count = 0
END IF

DEF FNRan (x) = INT(RND(1) * x) + 1
DEF SEG = 0 ' Set NumLock to ON
KeyFlags = PEEK(1047)
IF (KeyFlags AND 32) = 0 THEN
POKE 1047, KeyFlags OR 32
END IF
DEF SEG

' Initialisation and sliding text speed calculation

GOSUB InitVars
MachSpeed = CalcDelay
IF MachSpeed < 1000 THEN
SLIDECONST = (4 * MachSpeed) - 1250
IF SLIDECONST < 0 THEN SLIDECONST = 0
ELSE
SLIDECONST = 2.929 * MachSpeed
END IF

' Program outline
LoadSettings
Gravity = GSettings.defaultGravity
NumGames = GSettings.defaultRoundQty

' Init screen
SCREEN 0
WIDTH 80, 25
MaxCol = 80
COLOR 15, 0
CLS

GamePlayed = 0
IF GSettings.showIntro THEN Intro
more = 1: DO
GetInputs player$(), NumGames, count
GorillaIntro player$(), DoesFileExist
more = PlayGame(player$(), NumGames, count)
LOOP UNTIL more = 0
Extro

DEF SEG = 0 ' Restore NumLock state
POKE 1047, KeyFlags
DEF SEG
SYSTEM

' Banana sprite definitions

CGABanana:
'BananaLeft
DATA 327686, -252645316, 60
'BananaDown
DATA 196618, -1057030081, 49344
'BananaUp
DATA 196618, -1056980800, 63
'BananaRight
DATA 327686, 1010580720, 240

EGABanana:
'BananaLeft
DATA 458758,202116096,471604224,943208448,943208448,943208448,471604224,202116096,0
'BananaDown
DATA 262153, -2134835200, -2134802239, -2130771968, -2130738945,8323072, 8323199, 4063232, 4063294
'BananaUp
DATA 262153, 4063232, 4063294, 8323072, 8323199, -2130771968, -2130738945, -2134835200,-2134802239
'BananaRight
DATA 458758, -1061109760, -522133504, 1886416896, 1886416896, 1886416896,-522133504,-1061109760,0

' Initialise graphics mode and sprites

InitVars:
pi# = 4 * ATN(1#)

This is a clever way to pick the best graphics mode available
ON ERROR GOTO ScreenModeError
Mode = 9
SCREEN Mode
ON ERROR GOTO PaletteError
IF Mode = 9 THEN PALETTE 4, 0 'Check for 64K EGA
ON ERROR GOTO 0

IF Mode = 1 THEN
PRINT "Sorry, but CGA is not currently supported. If you want to run Gorillas"
PRINT "in CGA then let me know, and I'll fix the program to support it."
PRINT : SYSTEM
END IF

IF Mode = 9 THEN
ScrWidth = 640
ScrHeight = 350
GHeight = 25
SUNATTR = 3
RESTORE EGABanana
REDIM LBan&(8), RBan&(8), UBan&(8), DBan&(8)

FOR i = 0 TO 8
READ LBan&(i)
NEXT i
FOR i = 0 TO 8
READ DBan&(i)
NEXT i
FOR i = 0 TO 8
READ UBan&(i)
NEXT i
FOR i = 0 TO 8
READ RBan&(i)
NEXT i

SunHt = 43
ELSE
ScrWidth = 320
ScrHeight = 200
GHeight = 12
SUNATTR = 3
RESTORE CGABanana
REDIM LBan&(2), RBan&(2), UBan&(2), DBan&(2)
REDIM GorL&(20), GorD&(20), GorR&(20)

FOR i = 0 TO 2
READ LBan&(i)
NEXT i
FOR i = 0 TO 2
READ DBan&(i)
NEXT i
FOR i = 0 TO 2
READ UBan&(i)
NEXT i
FOR i = 0 TO 2
READ RBan&(i)
NEXT i

MachSpeed = MachSpeed * 1.3
SunHt = 20
END IF
RETURN

FuckOff:
lastErrCode = ERR
RESUME NEXT

ScreenModeError:
IF Mode = 1 THEN
CLS
LOCATE 10, 5
PRINT "Sorry, you must have CGA, EGA color or VGA graphics to play Gorillas"
PRINT
SYSTEM
ELSE
Mode = 1
RESUME
END IF

PaletteError:
Mode = 1 '64K EGA cards will run in CGA mode.
RESUME NEXT

' Message displayed when league table absent

IsThereNoFile:
'CLS
'BEEP
'PRINT "League table (GORILLAS.LGE) not found. A new league table file will"
'PRINT "be created after the first match. DON'T PANIC!"
'SLEEP 3
DoesFileExist = 0
RESUME NEXT

NoSaveStats:
COLOR 7: CLS
COLOR 12: PRINT "An error occurred trying to save the stats file GORILLAS.LGE"
PRINT "The statistics have not been saved.": COLOR 7: PRINT
CLOSE
SYSTEM

CorruptFile:
PRINT
BEEP
COLOR 12: PRINT "An error occurred while attempting to read data from the league"
PRINT "table file, GORILLAS.LGE. Fix it, get it fixed, or delete it. Simple."
COLOR 7: PRINT
SYSTEM

' Sliding text data store

SlidyText:
DATA 6
DATA " Q B a s i c G O R I L L A S v2.1b3",15,1,4
DATA "ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ",7,-1,5
DATA "DELUXE EDITION",15,1,6
DATA "Original program (c)1990 Microsoft Corporation",4,1,10
DATA "Gorillas Deluxe (c)1997-2005 Daniel Beardsmore",12,-1,12
DATA "Dedicated to all the Gorillas and Gorillas Deluxe fans",2,1,16
DATA 10
DATA "INSTRUCTIONS",9,1,8
DATA "Your mission is to hit your opponent with an exploding",11,1,10
DATA "banana by varying the angle and power of your throw, taking",11,-1,11
DATA "into account wind speed, gravity, and the city skyline.",11,1,12
DATA "The wind speed is shown by a directional arrow at the bottom",11,-1,14
DATA "of the playing field, its length relative to its strength.",11,1,15
DATA "Zero degrees is horizontal, towards your opponent, with 90 degrees",11,-1,16
DATA "being vertically upwards, and so on. Angles can be from 0 to",11,1,17
DATA "360 degrees and velocity can range from 1 to 200.",11,-1,18
DATA "Press any key to continue...",15,1,20
PartingMessage:
DATA 1
DATA "Thank you for playing Gorillas!",11,1,8
'Next number is the number of final phrases
DATA 5
DATA 1,"May the Schwarz be with you!",14,-1,14
DATA 1,"Live long and prosper.",14,-1,14
DATA 1,"Goodbye!",14,-1,14
DATA 1,"So long!",14,-1,14
DATA 1,"Adios!",14,-1,14
Ready:
DATA 1,"Prepare for battle!",12,1,1
Setup:
DATA 1,"Game Setup",14,-1,1
GameOver:
DATA 1,"Game Over!",14,-1,3
Aborted:
DATA 1,"Game aborted",12,-1,3
NowWhat:
DATA 1,"Now What?",14,1,1

VectorData:
DATA 39
DATA 0.582,0.988, 0.608,0.850, 0.663,0.788, 0.738,0.800
DATA 0.863,0.838, 0.813,0.713, 0.819,0.650, 0.875,0.588
DATA 1.000,0.563, 0.850,0.450, 0.825,0.400, 0.830,0.340
DATA 0.925,0.238, 0.775,0.243, 0.694,0.225, 0.650,0.188, 0.630,0.105
DATA 0.625,0.025, 0.535,0.150, 0.475,0.175, 0.425,0.150
DATA 0.325,0.044, 0.325,0.150, 0.315,0.208, 0.288,0.250, 0.225,0.275
DATA 0.053,0.288, 0.150,0.392, 0.175,0.463, 0.144,0.525
DATA 0.025,0.638, 0.163,0.650, 0.225,0.693, 0.250,0.775
DATA 0.225,0.905, 0.360,0.825, 0.450,0.823, 0.525,0.863
DATA 0.582,0.988

REM $STATIC
SUB alertSnd
IF GSettings.useSound THEN PLAY ">>B10<<"
END SUB

'CalcDelay:
' Checks speed of the machine.
FUNCTION CalcDelay#

s# = TIMER
DO
i# = i# + 1
LOOP UNTIL TIMER - s# >= .5
CalcDelay# = i#

END FUNCTION

' Center:
' Centers and prints a text string on a given row
' Parameters:
' Row - screen row number
' Text$ - text to be printed
'
SUB Center (Row, Text$)

Col = MaxCol \ 2
LOCATE Row, Col - (LEN(Text$) / 2) + 1
PRINT Text$;

END SUB

SUB DoBeep
IF GSettings.useSound THEN PLAY "O2A24"
END SUB

' DoExplosion:
' Produces explosion when a shot is fired
' Parameters:
' x#, y# - location of explosion
'
SUB DoExplosion (x#, y#)
DIM radii(1 TO 4, 1 TO 2), colors(1 TO 4)

IF GSettings.useOldExplosions THEN
IF GSettings.useSound THEN PLAY "MBO0L32EFGEFDC"
Radius = ScrHeight / 50
IF Mode = 9 THEN Inc# = .5 ELSE Inc# = .41
FOR c# = 0 TO Radius STEP Inc#
CIRCLE (x#, y#), c#, ExplosionColor
NEXT c#
FOR c# = Radius TO 0 STEP (-1 * Inc#)
CIRCLE (x#, y#), c#, BACKATTR
FOR i = 1 TO 100
NEXT i
rest .005
NEXT c#

ELSE
radii(1, 1) = GSettings.newExplosionRadius
radii(2, 1) = .9 * radii(1, 1)
radii(3, 1) = .6 * radii(1, 1)
radii(4, 1) = .45 * radii(1, 1)
FOR i = 1 TO 4
radii(i, 2) = .825 * radii(i, 1)
NEXT
colors(1) = 4: colors(2) = 2
colors(3) = 3: colors(4) = 9

'þ Draw grey smoke
IF GSettings.useSound THEN PLAY "MBO0L32EFGEFDC"
CIRCLE (x#, y#), 1.175 * radii(1, 1), 10
PAINT (x#, y#), 10, 10

FOR i = 1 TO 4
Iwidth = 2 * radii(i, 1): Iheight = 2 * radii(i, 2)
locX = x# - radii(i, 1): locY = y# - radii(i, 2)
imageCol = colors(i)

IF MachSpeed > 700 THEN
GOSUB DrawShape
Delay = .5
ELSE
CIRCLE (x#, y#), radii(i, 1), imageCol: PAINT (x#, y#), imageCol, imageCol
Delay = .9
END IF
NEXT

timeStay! = TIMER: DO: LOOP UNTIL TIMER > timeStay! + .1 '.08
CIRCLE (x#, y#), 1.175 * radii(1, 1), 0
PAINT (x#, y#), 0, 0
END IF

EXIT SUB

DrawShape:
RESTORE VectorData
READ noOfPoints, initX!, initY!
initX! = (initX! * Iwidth) + locX
initY! = (initY! * Iheight) + locY
FOR lVar = 1 TO noOfPoints - 1
READ toX!, toY!
toX! = (toX! * Iwidth) + locX
toY! = (toY! * Iheight) + locY
IF lVar = 1 THEN
LINE (initX!, initY!)-(toX!, toY!), imageCol
ELSE
LINE -(toX!, toY!), imageCol
END IF
NEXT
PAINT (locX + (Iwidth / 2), locY + (Iwidth / 2)), imageCol, imageCol
RETURN

END SUB

' DoShot:
' Controls banana shots by accepting player input and plotting
' shot angle
' Parameters:
' PlayerNum - Player
' x, y - Player's gorilla position
' turn - do not show zeroes at input prompts on first turn
'
FUNCTION DoShot (PlayerNum, x, y, turn, othX, othY)

'Input shot
IF PlayerNum = 1 THEN
LocateCol = 2
ELSE
IF Mode = 9 THEN
LocateCol = 67
ELSE
LocateCol = 26
END IF
END IF

IF PlayerNum = 1 THEN
PrevA# = GLeftAngle#: PrevV# = GLeftVeloc
ELSE
IF PlayerNum = 2 THEN
PrevA# = GRightAngle#: PrevV# = GRightVeloc
END IF
END IF

GAng$ = "": Velo$ = ""

LOCATE 2, LocateCol + 3: PRINT "Angle:";
LOCATE 3, LocateCol: PRINT "Velocity:";
IF turn > 2 THEN
PRINT PrevV#
Pa$ = LTRIM$(STR$(PrevA#))
Pv$ = LTRIM$(STR$(PrevV#))
ELSE
Pa$ = "": Pv$ = ""
END IF

WHILE INKEY$ <> "": WEND
DO: pass = 1
DO
GAng$ = GET$(2, LocateCol + 10, Pa$, 0, 360, 1)
IF GAng$ = "" THEN GOSUB AbortGame
LOOP UNTIL GAng$ <> ""
IF LEFT$(GAng$, 1) = "*" THEN GAng$ = RIGHT$(GAng$, LEN(GAng$) - 1)
angle# = VAL(GAng$)

'LOCATE 3, LocateCol
'PRINT "Velocity:";
DO
Velo$ = GET$(3, LocateCol + 10, Pv$, 1, -200, 1)
IF Velo$ = "" THEN GOSUB AbortGame
LOOP UNTIL Velo$ <> ""
IF LEFT$(Velo$, 1) = "*" THEN
pass = 0: Velo$ = RIGHT$(Velo$, LEN(Velo$) - 1)
PrevA# = angle#
PrevV# = CINT(VAL(Velo$))
Pa$ = GAng$
Pv$ = Velo$
END IF
velocity = CINT(VAL(Velo$))
LOOP UNTIL pass = 1

IF PlayerNum = 1 THEN
GLeftAngle# = angle#: GLeftVeloc = velocity
ELSE
IF PlayerNum = 2 THEN
GRightAngle# = angle#: GRightVeloc = velocity
END IF
END IF

IF PlayerNum = 2 THEN
angle# = 180 - angle#
END IF

'Erase input
FOR i = 1 TO 4
LOCATE i, 1
PRINT SPACE$(30 \ (80 \ MaxCol));
LOCATE i, (50 \ (80 \ MaxCol))
PRINT SPACE$(30 \ (80 \ MaxCol));
NEXT

PlayerHit = PlotShot(x, y, angle#, velocity, PlayerNum, othX, othY)
IF PlayerHit = 0 THEN
DoShot = FALSE
ELSE
DoShot = TRUE
IF PlayerHit <> PlayerNum AND turn < 3 THEN
'þ Killed opponent in one shot message
tpause! = TIMER: DO: LOOP UNTIL TIMER > tpause! + .8
IF GSettings.useSound THEN PLAY "MFO2L24A+>DFA+FD<A+>DFA+FD<A+>DFA+FD<A+4MB"
COLOR 12
FOR msg = 1 TO 3
Center 1, "IN ONE THROW!": tpause! = TIMER: DO: LOOP UNTIL TIMER > tpause! + .25
Center 1, SPACE$(14): GOSUB DSRestoreSun: tpause! = TIMER: DO: LOOP UNTIL TIMER > tpause! + .25
NEXT
ELSE tpause! = TIMER: DO: LOOP UNTIL TIMER > tpause! + .9
END IF
IF PlayerHit = PlayerNum THEN PlayerNum = 3 - PlayerNum
VictoryDance PlayerNum
END IF

EXIT FUNCTION

AbortGame:
cont = FALSE: cval = 1: tpause! = TIMER - 2
DO
IF TIMER > tpause! + .5 THEN
tpause! = TIMER
cval = 15 / cval: COLOR cval - 1: Center 1, " Abort game? [Y/N]"
IF cval = 1 THEN GOSUB DSRestoreSun
END IF
resp$ = UCASE$(INKEY$)
IF resp$ = "Y" THEN cont = 1
IF resp$ = "N" THEN cont = 2
LOOP UNTIL NOT (cont = FALSE)
IF cont = 1 THEN
DoShot = 1: EXIT FUNCTION
ELSE
IF cval = 15 THEN COLOR 1: Center 1, SPACE$(18)
DoSun SUNHAPPY: COLOR 15: RETURN
END IF
EXIT FUNCTION

DSRestoreSun:
sunX = ScrWidth \ 2: sunY = Scl(25)
LINE (sunX, sunY - Scl(15))-(sunX, sunY), SUNATTR
LINE (sunX - Scl(8), sunY - Scl(13))-(sunX, sunY), SUNATTR
LINE (sunX, sunY)-(sunX + Scl(8), sunY - Scl(13)), SUNATTR
RETURN

END FUNCTION

' DoSun:
' Draws the sun at the top of the screen.
' Parameters:
' Mouth - If TRUE draws "O" mouth else draws a smile mouth.
'
SUB DoSun (Mouth)

'set position of sun
x = ScrWidth \ 2: y = Scl(25)

'clear old sun
LINE (x - Scl(22), y - Scl(18))-(x + Scl(22), y + Scl(18)), BACKATTR, BF

'draw new sun:
'body
CIRCLE (x, y), Scl(12), SUNATTR
PAINT (x, y), SUNATTR

'rays
LINE (x - Scl(20), y)-(x + Scl(20), y), SUNATTR
LINE (x, y - Scl(15))-(x, y + Scl(15)), SUNATTR

LINE (x - Scl(15), y - Scl(10))-(x + Scl(15), y + Scl(10)), SUNATTR
LINE (x - Scl(15), y + Scl(10))-(x + Scl(15), y - Scl(10)), SUNATTR

LINE (x - Scl(8), y - Scl(13))-(x + Scl(8), y + Scl(13)), SUNATTR
LINE (x - Scl(8), y + Scl(13))-(x + Scl(8), y - Scl(13)), SUNATTR

LINE (x - Scl(18), y - Scl(5))-(x + Scl(18), y + Scl(5)), SUNATTR
LINE (x - Scl(18), y + Scl(5))-(x + Scl(18), y - Scl(5)), SUNATTR

'mouth
IF Mouth THEN 'draw "o" mouth
CIRCLE (x, y + Scl(5)), Scl(2.9), 0
PAINT (x, y + Scl(5)), 0, 0
ELSE 'draw smile
CIRCLE (x, y), Scl(8), 0, (210 * pi# / 180), (330 * pi# / 180)
END IF

'eyes
CIRCLE (x - 3, y - 2), 1, 0
CIRCLE (x + 3, y - 2), 1, 0
PSET (x - 3, y - 2), 0
PSET (x + 3, y - 2), 0

END SUB

'DrawBan:
' Draws the banana
'Parameters:
' xc# - Horizontal Coordinate
' yc# - Vertical Coordinate
' r - rotation position (0-3). ( \_/ ) /-' bc - if TRUE then DrawBan draws the banana ELSE it erases the banana
SUB DrawBan (xc#, yc#, r, bc)

SELECT CASE r
CASE 0
IF bc THEN PUT (xc#, yc#), LBan&, PSET ELSE PUT (xc#, yc#), LBan&, XOR
CASE 1
IF bc THEN PUT (xc#, yc#), UBan&, PSET ELSE PUT (xc#, yc#), UBan&, XOR
CASE 2
IF bc THEN PUT (xc#, yc#), DBan&, PSET ELSE PUT (xc#, yc#), DBan&, XOR
CASE 3
IF bc THEN PUT (xc#, yc#), RBan&, PSET ELSE PUT (xc#, yc#), RBan&, XOR
END SELECT

END SUB

'DrawGorilla:
' Draws the Gorilla in either CGA or EGA mode
' and saves the graphics data in an array.
'Parameters:
' x - x coordinate of gorilla
' y - y coordinate of the gorilla
' arms - either Left up, Right up, or both down
SUB DrawGorilla (x, y, arms)
DIM i AS SINGLE ' Local index must be single precision

'draw head
LINE (x - Scl(4), y)-(x + Scl(2.9), y + Scl(6)), OBJECTCOLOR, BF
LINE (x - Scl(5), y + Scl(2))-(x + Scl(4), y + Scl(4)), OBJECTCOLOR, BF

'draw eyes/brow
LINE (x - Scl(3), y + Scl(2))-(x + Scl(2), y + Scl(2)), 0

'draw nose if ega
IF Mode = 9 THEN
FOR i = -2 TO -1
PSET (x + i, y + 4), 0
PSET (x + i + 3, y + 4), 0
NEXT i
END IF

'neck
LINE (x - Scl(3), y + Scl(7))-(x + Scl(2), y + Scl(7)), OBJECTCOLOR

'body
LINE (x - Scl(8), y + Scl(8))-(x + Scl(6.9), y + Scl(14)), OBJECTCOLOR, BF
LINE (x - Scl(6), y + Scl(15))-(x + Scl(4.9), y + Scl(20)), OBJECTCOLOR, BF

'legs
FOR i = 0 TO 4
CIRCLE (x + Scl(i), y + Scl(25)), Scl(10), OBJECTCOLOR, 3 * pi# / 4, 9 * pi# / 8
CIRCLE (x + Scl(-6) + Scl(i - .1), y + Scl(25)), Scl(10), OBJECTCOLOR, 15 * pi# / 8, pi# / 4
NEXT

'chest
CIRCLE (x - Scl(4.9), y + Scl(10)), Scl(4.9), 0, 3 * pi# / 2, 0
CIRCLE (x + Scl(4.9), y + Scl(10)), Scl(4.9), 0, pi#, 3 * pi# / 2

FOR i = -5 TO -1
SELECT CASE arms
CASE 1
'Right arm up
CIRCLE (x + Scl(i - .1), y + Scl(14)), Scl(9), OBJECTCOLOR, 3 * pi# / 4, 5 * pi# / 4
CIRCLE (x + Scl(4.9) + Scl(i), y + Scl(4)), Scl(9), OBJECTCOLOR, 7 * pi# / 4, pi# / 4
GET (x - Scl(15), y - Scl(1))-(x + Scl(14), y + Scl(28)), GorR&
CASE 2
'Left arm up
CIRCLE (x + Scl(i - .1), y + Scl(4)), Scl(9), OBJECTCOLOR, 3 * pi# / 4, 5 * pi# / 4
CIRCLE (x + Scl(4.9) + Scl(i), y + Scl(14)), Scl(9), OBJECTCOLOR, 7 * pi# / 4, pi# / 4
GET (x - Scl(15), y - Scl(1))-(x + Scl(14), y + Scl(28)), GorL&
CASE 3
'Both arms down
CIRCLE (x + Scl(i - .1), y + Scl(14)), Scl(9), OBJECTCOLOR, 3 * pi# / 4, 5 * pi# / 4
CIRCLE (x + Scl(4.9) + Scl(i), y + Scl(14)), Scl(9), OBJECTCOLOR, 7 * pi# / 4, pi# / 4
GET (x - Scl(15), y - Scl(1))-(x + Scl(14), y + Scl(28)), GorD&
END SELECT
NEXT i
END SUB

'ExplodeGorilla:
' Causes gorilla explosion when a direct hit occurs
'Parameters:
' X#, Y# - shot location
SUB ExplodeGorilla (x#, y#, PlayerHit)
YAdj = Scl(12)
XAdj = Scl(5)
SclX# = ScrWidth / 320
SclY# = ScrHeight / 200

IF GSettings.useSound THEN PLAY "MBO0L16EFGEFDC"

' FOR i = 1 TO 8 * SclX#
' CIRCLE (GorillaX(PlayerHit) + 3.5 * SclX# + XAdj, GorillaY(PlayerHit) + 7 * SclY# + YAdj), i, ExplosionColor, , , -1.57
' 'LINE (GorillaX(PlayerHit) + 7 * SclX#, GorillaY(PlayerHit) + 9 * SclY# - i)-(GorillaX(PlayerHit), GorillaY(PlayerHit) + 9 * SclY# - i), ExplosionColor
' NEXT i

FOR i = 1 TO 16 * SclX#
' IF i < (8 * SclX#) THEN CIRCLE (GorillaX(PlayerHit) + 3.5 * SclX# + XAdj, GorillaY(PlayerHit) + 7 * SclY# + YAdj), (8 * SclX# + 1) - i, BACKATTR, , , -1.57
CIRCLE (GorillaX(PlayerHit) + 3.5 * SclX# + XAdj, GorillaY(PlayerHit) + YAdj), i, i MOD 2 + 1, , , -1.57
NEXT i

' DO: LOOP UNTIL INKEY$ <> ""

FOR i = 24 * SclX# TO 1 STEP -1
CIRCLE (GorillaX(PlayerHit) + 3.5 * SclX# + XAdj, GorillaY(PlayerHit) + YAdj), i, BACKATTR, , , -1.57
FOR count = 1 TO 200
NEXT
NEXT i

END SUB

SUB Extro

RESTORE PartingMessage
Slidy
READ num
num = CINT(RND * (num - 1))
IF num > 0 THEN FOR l = 1 TO num: READ pnum, pmsg$, pnum, pnum, pnum: NEXT
Slidy

t! = TIMER: DO: LOOP UNTIL TIMER > t! + 3.8 OR INKEY$ <> ""
COLOR 7: CLS

END SUB

FUNCTION GET$ (Row, Col, Prev$, Typ, Max, Esc)

' Row,Col : position
' Prev$ : the previous value of the number or string.
' Typ : the type of input required: TRUE for string, FALSE for numeric
' and 1 for numerical, tabbable while empty
' Max : the maximum number of characters for string or the maximum
' value for numeric. For numeric, a negative maximum means that the minimum
' value is to be one not zero and the maximum value is the absolute value
' of Max.
' Esc : TRUE if Escape key permitted, FALSE if not permitted, 1 if Escape
' clears input rather then undoes

SpecTab = 0: IF Typ = 1 THEN Typ = FALSE: SpecTab = 1
IF NOT Typ THEN
IF Max < 0 THEN Zero = 0 ELSE Zero = -1
Max = ABS(Max)
END IF

Hold$ = Prev$
cont = 0: Lett$ = "": Curs = 0: Timo! = 0
Valid$ = "1234567890" + CHR$(8) + CHR$(9) + CHR$(13) + CHR$(27)
IF Typ THEN Valid$ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ- .'!" + Valid$
LOCATE Row, Col:
IF Typ THEN
Bck = Max - LEN(Hold$) + 1
ELSE
Bck = LEN(STR$(Max)) - LEN(Hold$)
END IF
PRINT Hold$; SPC(Bck);

DO
DO
Timo! = TIMER: Curs = 0: LOCATE Row, Col + LEN(Hold$): IF LEN(Hold$) = Max THEN PRINT "Û" ELSE PRINT "_"
DO: LOOP UNTIL INKEY$ = ""
DO
IF TIMER > Timo! + .5 THEN
LOCATE Row, Col + LEN(Hold$)
IF Curs <> 1 THEN
PRINT " "
ELSE
IF Typ AND LEN(Hold$) = Max THEN PRINT "Û" ELSE PRINT "_"
END IF
Curs = 1 - Curs
Timo! = TIMER
END IF
Lett$ = INKEY$
LOOP UNTIL Lett$ <> ""
LOCATE Row, Col + LEN(Hold$): PRINT " "
Intra = INSTR(Valid$, UCASE$(Lett$))
IF Lett$ = CHR$(0) + CHR$(83) THEN Intra = 50 ' DEL key
IF Intra = 0 THEN DoBeep: DO: LOOP UNTIL INKEY$ = ""
LOOP UNTIL Intra > 0

SELECT CASE Intra

CASE 50
DELETE key
LOCATE Row, Col: PRINT STRING$(LEN(Hold$), " ");
Hold$ = ""

CASE 1 TO LEN(Valid$) - 4 'þ Letter, number or symbol
'þ Numeric field
IF NOT Typ THEN 'þ Number
IF NOT ((Lett$ = "0" AND (NOT Zero AND Hold$ = "")) OR Hold$ = "0") THEN
IF VAL(Hold$ + Lett$) <= Max THEN
Hold$ = Hold$ + Lett$
LOCATE Row, Col: PRINT Hold$
ELSE DoBeep
END IF
ELSE DoBeep
END IF
ELSE 'þ Text field
IF LEN(Hold$) < Max THEN
Hold$ = Hold$ + Lett$
LOCATE Row, Col: PRINT Hold$
ELSE DoBeep
END IF
END IF

CASE LEN(Valid$) - 3
'þ BACKSPACE key
IF LEN(Hold$) > 0 THEN
Hold$ = LEFT$(Hold$, LEN(Hold$) - 1)
LOCATE Row, Col: PRINT Hold$; " ";
ELSE DoBeep
END IF

CASE LEN(Valid$) - 2
'þ TAB key
IF (LEN(Hold$) > 0 AND NOT Typ) OR SpecTab = 1 THEN Hold$ = "*" + Hold$: cont = 1 ELSE DoBeep

CASE LEN(Valid$) - 1
RETURN key
IF LEN(Hold$) > 0 THEN cont = 1 ELSE DoBeep

CASE LEN(Valid$)
'þ ESCAPE key
IF Esc = TRUE THEN Hold$ = Prev$: cont = 1
IF Esc = 1 THEN Hold$ = "": cont = 1

END SELECT
DO: LOOP UNTIL INKEY$ = ""

LOOP UNTIL cont = 1

GET$ = Hold$
END FUNCTION

'GetInputs:
' Gets competing players and game configuration play at beginning of game
' and manages players list
'Parameters:
' Player$() - player names
' NumGames - number of games to play
' P - number of stored players
SUB GetInputs (player$(), NumGames, P)

' Lay out screen

CLS : RESTORE Setup: Slidy: COLOR 2: LOCATE 2, 1: PRINT STRING$(80, "Í") 'þ Show screen title
active = 0: FOR fld = 1 TO 4: GOSUB SetupFields: NEXT 'þ Display fields
fld = 0: GOSUB SetupFields 'þ Display player names

' Fill in players box

cStat = 0: FOR N = 1 TO P: GOSUB Curs: NEXT
'þ Must highlight opponent player (normally done after [ENTER] or [TAB]
IF PDefs(2) > 0 THEN N = PDefs(2): cStat = 2: GOSUB Curs

' Process fields loop
' complete: ready to start the game
' fld: which field is being processed
' numG$: text field to hold number of games
' grav$: text field to hold gravity

complete = 0: fld = 1: numG$ = LTRIM$(STR$(NumGames)): grav$ = LTRIM$(STR$(Gravity))
DO
'þ Highlight current field if there are enough players. Player field not
' highlighted until there is a player which can be assigned to it, and the
' last two fields are unselectable unless there are enough players
active = 1: IF P >= 2 THEN GOSUB SetupFields

SELECT CASE fld
CASE 1 TO 2
GOSUB ManagePlayers
CASE IS = 3
GOSUB Rounds
CASE IS = 4
GOSUB Gravity
END SELECT
active = 0: GOSUB SetupFields 'þ Unhighlight current field
IF NOT complete THEN fld = fld + 1: IF fld = 5 THEN fld = 1
IF complete AND (PDefs(1) = 0 OR PDefs(2) = 0) THEN fld = 1: complete = 0
LOOP UNTIL complete

player$(1) = RTRIM$(PDat(PDefs(1)).PNam)
player$(2) = RTRIM$(PDat(PDefs(2)).PNam)
NumGames = VAL(numG$)
Gravity = VAL(grav$)

'þ Clear most of the screen
COLOR , 0: FOR l = 3 TO 24: LOCATE l, 1: PRINT STRING$(80, " "); : NEXT

EXIT SUB

'þþþþþþþþþþþþþþþþþþþþ
'þ FIELDS SUBROUTINES

ManagePlayers:
cre = 0
WHILE P < 2 'þ Ensure enough players for the game (only used before league table created)
cre = 1: GOSUB CreatePlayer
IF P = 2 THEN GOSUB SetupFields 'þ Finally ready to highlight Player field
WEND
cre = 0

'þ OK. Assuming that there are enough players to select.
opp = 2 / fld 'þ PDefs array number of opposite player
ShowPrompts fld
IF PDefs(fld) > 0 THEN 'þ Put cursor bar on currently selected player
x = ((PDefs(fld) - 1) MOD 4) + 1: y = INT((PDefs(fld) - 1) / 4) + 1
ELSE 'þ Otherwise choose free player
IF PDefs(opp) <> 1 THEN
x = 1: y = 1
ELSE
'IF PDefs(opp) = 1 AND P > 1 THEN
x = 2: y = 1
END IF
END IF

finished = 0: mov = 0: IF P > 1 THEN mov = 1
DO
defSwap = 0 'þ Flag for player definition swapping
N = (y - 1) * 4 + x 'þ Convert cursor bar position into player number
LOCATE 8 + (fld * 2 - 2), 22
Do not display player name if it is taken and swap is not permitted
IF NOT ((PDefs(fld) = 0 OR PDefs(opp) = 0) AND PDefs(opp) = N) THEN
COLOR 2, 0: PRINT PDat(N).PNam;
ELSE
COLOR 12, 0: PRINT "Can't have. "
END IF
IF (PDefs(opp)) = N AND PDefs(fld) > 0 THEN
LOCATE 8 + (opp * 2 - 2), 23 + LEN(RTRIM$(PDat(PDefs(opp)).PNam))
COLOR 2, 0: PRINT "("; CHR$(26); " "; RTRIM$(PDat(PDefs(fld)).PNam); ")";
COLOR 2: LOCATE 7, 3: PRINT "": COLOR 9: LOCATE 7, 5
PRINT "Pressing [ENTER] now will switch the players over."
defSwap = 1
END IF
IF mov = 1 THEN cur = 1: GOSUB Move
DO
key$ = INKEY$
LOOP UNTIL key$ <> ""
COLOR 1, 0
IF defSwap = 1 THEN
LOCATE 8 + (opp * 2 - 2), 23 + LEN(RTRIM$(PDat(PDefs(opp)).PNam))
PRINT STRING$(21, " ")
LOCATE 7, 3: PRINT STRING$(52, " ")
END IF

'þ Move cursor bar, manipulate players, and select a player to compete
SELECT CASE UCASE$(key$)
CASE CHR$(0) + CHR$(72)
IF y > 1 THEN cur = 0: GOSUB Move: y = y - 1: mov = 1 ELSE alertSnd
CASE CHR$(0) + CHR$(80)
IF (y * 4 + x) <= P THEN cur = 0: GOSUB Move: y = y + 1: mov = 1 ELSE alertSnd
CASE CHR$(0) + CHR$(75)
IF x > 1 THEN
cur = 0: GOSUB Move: x = x - 1: mov = 1
ELSE
IF y > 1 THEN
cur = 0: GOSUB Move: mov = 1: x = 4: y = y - 1
ELSE
alertSnd
END IF
END IF
CASE CHR$(0) + CHR$(77)
IF x < 4 AND ((y - 1) * 4 + (x + 1)) <= P THEN
cur = 0: GOSUB Move: x = x + 1: mov = 1
ELSE
IF (y * 4 + 1) <= P THEN
cur = 0: GOSUB Move: mov = 1: x = 1: y = y + 1
ELSE
alertSnd
END IF
END IF
CASE CHR$(9), CHR$(13)
IF key$ = CHR$(13) THEN 'þ Only update player defs if ENTER pressed
IF PDefs(opp) = N AND PDefs(fld) > 0 THEN
'þ Swap player definitions
SWAP PDefs(1), PDefs(2): COLOR , 0: finished = 1
cStat = 2: GOSUB Curs
IF fld = 2 THEN N = PDefs(opp): GOSUB Curs
ELSEIF PDefs(opp) <> N THEN
'þ Define player
IF PDefs(fld) <> N THEN 'þ Remove green highlight and define PDefs
IF PDefs(fld) > 0 THEN Nt = N: N = PDefs(fld): cStat = 0: GOSUB Curs: N = Nt
PDefs(fld) = N
END IF
finished = 1
cStat = 2: GOSUB Curs
ELSE
alertSnd
END IF
ELSE
IF PDefs(fld) > 0 THEN
'þ Abort change to definition, and move to next field
finished = 1
cur = 0: GOSUB Move 'þ Remove cursor bar
N = PDefs(fld): cStat = 2: GOSUB Curs 'þ Red highlight
ELSEIF PDefs(fld) = 0 AND PDefs(opp) <> N THEN
'þ Player undefined, so define it
PDefs(fld) = N: finished = 1
cStat = 2: GOSUB Curs
ELSE
alertSnd
END IF
END IF
IF finished = 1 THEN
LOCATE 8 + (fld * 2 - 2), 22: COLOR 10, 0: PRINT PDat(PDefs(fld)).PNam;
IF defSwap = 1 THEN LOCATE 8 + (opp * 2 - 2), 22: PRINT PDat(PDefs(opp)).PNam;
END IF
CASE "N"
GOSUB CreatePlayer
CASE "R"
GOSUB RenamePlayer
CASE CHR$(0) + CHR$(83)
GOSUB DeletePlayer
CASE ELSE
'þ Incorrect key pressed
alertSnd
END SELECT

'Player chosen
LOOP UNTIL finished

RETURN

CreatePlayer:
IF P < NPLAYERS THEN
IF cre = 1 THEN ShowPrompts -12 ELSE ShowPrompts 12
nx = WHEREX(P + 1): ny = WHEREY(P + 1)
cStat = 0: GOSUB Curs: COLOR 10, 1
PDat(P + 1).PNam = " "
DO: cont = 1
IF P < 2 THEN Esc = FALSE ELSE Esc = TRUE 'þ Prevent ESCAPE key when players not yet created
PDat(P + 1).PNam = RTRIM$(GET$(ny, nx, RTRIM$(PDat(P + 1).PNam), -1, 17, Esc))

IF LTRIM$(PDat(P + 1).PNam) = "" THEN
cont = 2
ELSE
FOR inl = 1 TO P
IF PDat(inl).PNam = PDat(P + 1).PNam THEN alertSnd: cont = 0
NEXT
END IF
LOOP UNTIL cont > 0
IF cont = 1 THEN
P = P + 1: DoBeep: x = ((P - 1) MOD 4) + 1: y = INT((P - 1) / 4) + 1
IF P > 1 THEN N = P - 1: cur = 0: GOSUB Move
N = (y - 1) * 4 + x: cStat = 0: GOSUB Curs
ELSEIF cont = 2 THEN
Nt = N: N = P + 1: cStat = 0: GOSUB Curs
N = Nt: GOSUB Move
END IF
ShowPrompts fld
ELSE
alertSnd
END IF
RETURN

RenamePlayer:
ShowPrompts 13
nx = WHEREX(P + 1): ny = WHEREY(P + 1)
cStat = 0: GOSUB Curs: COLOR 10, 1
DO: cont = 1: count = 0
PDat(N).PNam = GET$(WHEREY(N), WHEREX(N), RTRIM$(PDat(N).PNam), -1, 17, TRUE)
IF LEFT$(PDat(N).PNam, 1) = "*" THEN PDat(N).PNam = RIGHT$(PDat(N).PNam, LEN(PDat(N).PNam) - 1)
FOR inl = 1 TO P
IF PDat(inl).PNam = PDat(N).PNam THEN count = count + 1
NEXT: IF count > 1 THEN alertSnd: cont = 0
LOOP UNTIL cont = 1: DoBeep
cStat = 1: GOSUB Curs: ShowPrompts fld: upd = 0
IF PDefs(1) = N THEN
upd = 1
ELSEIF PDefs(2) = N THEN
upd = 2
END IF
IF upd > 0 THEN
COLOR 10, 0: LOCATE 8 + (upd * 2 - 2), 22
PRINT PDat(PDefs(upd)).PNam;
END IF
RETURN

DeletePlayer:
'þ What to do after the delete
nextAction = 0
IF N = PDefs(opp) THEN 'þ Opposite player redefined
IF NOT (fld = 1 AND P > 2) THEN 'þ But not in this situation
nextAction = 1
END IF
END IF

IF PDefs(fld) > 0 THEN COLOR 10, 0: LOCATE 8 + (fld * 2 - 2), 22: PRINT PDat(PDefs(fld)).PNam;
COLOR 0, 0
FOR l = 3 TO 7: LOCATE l, 1: PRINT STRING$(80, " "); : NEXT
ShowPrompts 11
LOCATE 3, 3: COLOR 4
PRINT "Do you want to delete the player `" + RTRIM$(PDat(N).PNam) + "'?"
BEEP: DO: DO
i$ = INKEY$
LOOP UNTIL i$ <> "": i$ = UCASE$(i$): LOOP UNTIL i$ = "Y" OR i$ = "N"
COLOR 0, 0: LOCATE 3: PRINT STRING$(80, " ")
IF i$ = "Y" THEN
'þ Corrects PDefs (selected players) values and display
IF fld = 2 AND PDefs(fld) = 0 AND N = PDefs(opp) THEN
COLOR 8, 0: LOCATE 10, 22
PRINT "<undefined> ";
END IF

FOR upd = 1 TO 2
IF PDefs(upd) = N THEN
COLOR 8, 0: LOCATE 8 + (upd * 2 - 2), 22
PRINT "<undefined> ";
PDefs(upd) = 0
ELSEIF PDefs(upd) > N THEN
PDefs(upd) = PDefs(upd) - 1
END IF
NEXT

IF P = 2 AND PDefs(fld) = 0 AND PDefs(opp) > 0 THEN
COLOR 8, 0: LOCATE 8 + (fld * 2 - 2), 22
PRINT "<undefined> ";
END IF


'þ Tidies up PDat (array of players)
Pt = P: P = P - 1: Nt = N
IF N < Pt THEN
FOR N = N TO P
PDat(N).PNam = PDat(N + 1).PNam
PDat(N).Rounds = PDat(N + 1).Rounds
PDat(N).Won = PDat(N + 1).Won
PDat(N).Accu = PDat(N + 1).Accu
IF PDefs(2 * (1 / fld)) = N THEN cStat = 2 ELSE cStat = 0
GOSUB Curs
NEXT
END IF

This wipes all trace of the deleted player
PDat(Pt).Won = 0
PDat(Pt).PNam = "": PDat(Pt).Accu = 0: PDat(Pt).Rounds = 0

N = Pt: cStat = 0: GOSUB Curs
N = Nt
IF N > P THEN
N = N - 1: x = x - 1: IF x = 0 THEN x = 1: y = y - 1: IF y = 0 THEN y = 1
END IF
IF P > 0 THEN ShowPrompts fld

IF nextAction > 0 THEN
cStat = 0: GOSUB Curs 'þ Remove cursor bar
END IF

IF PDefs(fld) > 0 THEN
x = ((PDefs(fld) - 1) MOD 4) + 1: y = INT((PDefs(fld) - 1) / 4) + 1
ELSEIF N = PDefs(opp) THEN
IF N > 1 THEN
x = x - 1: IF x = 0 THEN y = y - 1: x = 4 'þ Back one player
ELSEIF N < P THEN
x = x + 1: IF x = 5 THEN y = y + 1: x = 1 'þ Fwd one player
END IF
END IF

IF nextAction = 1 THEN
active = 0: GOSUB SetupFields
SWAP fld, opp: active = 1: GOSUB SetupFields
END IF

'þ Ensure always 2 players minimum
IF P = 1 THEN cre = 1: GOSUB CreatePlayer: cre = 0

ELSE
ShowPrompts fld
END IF

RETURN

Rounds:
ShowPrompts 3
COLOR 15, 9: numG$ = GET$(20, 51, numG$, 0, -99, FALSE): COLOR 15, 0
IF LEFT$(numG$, 1) = "*" THEN numG$ = RIGHT$(numG$, LEN(numG$) - 1)
LOCATE 20, 51: PRINT numG$; SPC(3 - LEN(numG$));
RETURN

Gravity:
ShowPrompts 4
COLOR 15, 9: grav$ = GET$(22, 51, grav$, 0, -99, FALSE): COLOR 15, 0
IF LEFT$(grav$, 1) = "*" THEN grav$ = RIGHT$(grav$, LEN(grav$) - 1) ELSE complete = 1
LOCATE 22, 51: PRINT grav$; SPC(4 - LEN(grav$));
RETURN

'þþþþþþþþþþþþþþþþþþþþþ
'þ SUPPORT SUBROUTINES

' field display

SetupFields:
IF fld = 1 AND active THEN GOSUB DrawBox
IF fld = 2 AND NOT active THEN GOSUB DrawBox
IF active THEN COLOR 15 ELSE COLOR 8
SELECT CASE fld
CASE IS = 0
FOR upd = 1 TO 2
LOCATE 8 + (upd * 2 - 2), 22
IF PDefs(upd) > 0 THEN
COLOR 10, 0: PRINT PDat(PDefs(upd)).PNam;
ELSE
COLOR 8, 0: PRINT "<undefined>"
END IF
NEXT
CASE IS = 1
LOCATE 8, 11: PRINT "Player 1 ="
CASE IS = 2
LOCATE 10, 11: PRINT "Player 2 ="
CASE IS = 3
tStr$ = "Maximum rounds? (1 - 99, Default =" + STR$(GSettings.defaultRoundQty) + "):"
LOCATE 20, 50 - LEN(tStr$): PRINT tStr$
CASE IS = 4
LOCATE 22, 13: PRINT "Gravity in m/sý (1 - 99, Earth = 10):"
END SELECT
RETURN

DrawBox:
COLOR 2, 0
IF active THEN
LOCATE 12, 1: PRINT "É"; STRING$(78, "Í"); "»";
LOCATE 18, 1: PRINT "È"; STRING$(78, "Í"); "¼";
FOR l = 13 TO 17: LOCATE l, 1: PRINT "º"; : LOCATE l, 80: PRINT "º"; : NEXT
ELSE
LOCATE 12, 1: PRINT "Ú"; STRING$(78, "Ä"); "¿";
LOCATE 18, 1: PRINT "À"; STRING$(78, "Ä"); "Ù";
FOR l = 13 TO 17: LOCATE l, 1: PRINT "³"; : LOCATE l, 80: PRINT "³"; : NEXT
END IF
RETURN

' cursor display

Move: 'þ Displays or removes cursor bar, calculating highlight colour
which = 1
IF PDefs(2 / fld) = N THEN which = 0
IF PDefs(fld) = N THEN which = 2
SELECT CASE cur 'þ Blue (1) or black (0) background
CASE 1
IF which = 1 THEN
cStat = 1: GOSUB Curs
ELSEIF which = 0 THEN
cStat = 3: GOSUB Curs
ELSE
cStat = 5: GOSUB Curs
END IF
CASE 0
IF which = 1 THEN
cStat = 0: GOSUB Curs
ELSEIF which = 0 THEN
cStat = 2: GOSUB Curs
ELSE
cStat = 4: GOSUB Curs
END IF
END SELECT
RETURN

Curs: 'þ Displays or removes cursor bar, being told the highlight colour
SELECT CASE cStat
CASE 0
COLOR 15, 0
CASE 1
COLOR 11, 1
CASE 2
COLOR 4, 0
CASE 3
COLOR 4, 1
CASE 4
COLOR 2, 0
CASE 5
COLOR 2, 1
END SELECT
LOCATE WHEREY(N), WHEREX(N): PRINT RTRIM$(PDat(N).PNam);
IF N < P THEN
PRINT ",";
ELSEIF N = P THEN
PRINT ".";
ELSE
PRINT " ";
END IF
PRINT SPC(17 - LEN(RTRIM$(PDat(N).PNam)));
RETURN

END SUB

'GorillaIntro:
' Displays gorillas on screen for the first time
' allows the graphical data to be put into an array
'Parameters:
' Player$() - The names of the players
' cIntro - Is introduction compulsory? (Yes for first ever game)
'
SUB GorillaIntro (player$(), cIntro)
IF cIntro = 1 THEN 'þ cIntro = 0 means introduction compulsory
LOCATE 1, 36: PRINT STRING$(10, " ")
RESTORE Ready: Slidy
COLOR 2: LOCATE 15, 31: PRINT "ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ"
COLOR 9: LOCATE 17, 34: PRINT "= View Intro"
LOCATE 18, 34: PRINT "= Play Game"
LOCATE 19, 34: PRINT "= Quit Gorillas"
LOCATE 21, 34: PRINT "Your Choice?"
COLOR 12: LOCATE 17, 32: PRINT "V": LOCATE 18, 32: PRINT "P"
LOCATE 19, 32: PRINT "Q"
DO
Char$ = UCASE$(INKEY$)
LOOP UNTIL Char$ <> "" AND INSTR("QVP", Char$)
IF Char$ = "V" THEN cIntro = 0
IF Char$ = "Q" THEN
IF GamePlayedYN = 1 THEN Extro
COLOR 7: CLS : SYSTEM
END IF
END IF

IF Mode = 1 THEN
x = 125
y = 100
ELSE
x = 286
y = 175
END IF

SCREEN Mode
SetScreen

IF Mode = 1 THEN Center 5, "Please wait while gorillas are drawn."

VIEW PRINT 9 TO 24

IF Mode = 9 THEN PALETTE OBJECTCOLOR, BackColor

DrawGorilla x, y, ARMSDOWN
CLS 2
DrawGorilla x, y, LEFTUP
CLS 2
DrawGorilla x, y, RIGHTUP
CLS 2

VIEW PRINT 1 TO 25
IF Mode = 9 THEN PALETTE OBJECTCOLOR, 46

IF cIntro = 0 THEN
IF Mode = 9 THEN
Rad! = 100: yStep! = 1: DO
CIRCLE (319, 190), Rad!, 8, , , .5
CIRCLE (319, 187), Rad!, 11, , , .5
Rad! = Rad! + yStep!: yStep! = yStep! * 1.1
LOOP UNTIL 320 + Rad! >= 640
PAINT (0, 0), 8, 11
LINE (142, 20)-(491, 20), 3
LINE (491, 20)-(491, 95), 3
LINE (491, 95)-(317, 156), 3
LINE (317, 156)-(142, 95), 3
LINE (142, 95)-(142, 20), 3
PAINT (317, 40), 0, 3
END IF

COLOR 11: Center 2, " QBasic G O R I L L A S "
COLOR 9: Center 4, "STARRING:"
P$ = player$(1) + " AND " + player$(2)
COLOR 3: Center 5, STRING$(LEN(P$), "Ä")
COLOR 2: Center 6, P$: COLOR 9

PUT (x - 13, y), GorD&, PSET
PUT (x + 47, y), GorD&, PSET
rest 1

IF INKEY$ <> "" GOTO GetThisOverWith

PUT (x - 13, y), GorL&, PSET
PUT (x + 47, y), GorR&, PSET
IF GSettings.useSound THEN PLAY "t120o1l16b9n0baan0bn0bn0baaan0b9n0baan0b" ELSE restReal .18
rest .3

IF INKEY$ <> "" GOTO GetThisOverWith

PUT (x - 13, y), GorR&, PSET
PUT (x + 47, y), GorL&, PSET
IF GSettings.useSound THEN PLAY "o2l16e-9n0e-d-d-n0e-n0e-n0e-d-d-d-n0e-9n0e-d-d-n0e-" ELSE restReal .18
rest .3

IF INKEY$ <> "" GOTO GetThisOverWith

PUT (x - 13, y), GorL&, PSET
PUT (x + 47, y), GorR&, PSET
IF GSettings.useSound THEN PLAY "o2l16g-9n0g-een0g-n0g-n0g-eeen0g-9n0g-een0g-" ELSE restReal .18
rest .3

IF INKEY$ <> "" GOTO GetThisOverWith

PUT (x - 13, y), GorR&, PSET
PUT (x + 47, y), GorL&, PSET
IF GSettings.useSound THEN PLAY "o2l16b9n0baan0g-n0g-n0g-eeen0o1b9n0baan0b" ELSE restReal .18
rest .3

IF INKEY$ <> "" GOTO GetThisOverWith

FOR i = 1 TO 4
PUT (x - 13, y), GorL&, PSET
PUT (x + 47, y), GorR&, PSET
IF GSettings.useSound THEN PLAY "T160O0L32EFGEFDC" ELSE restReal .18
rest .1
PUT (x - 13, y), GorR&, PSET
PUT (x + 47, y), GorL&, PSET
IF GSettings.useSound THEN PLAY "T160O0L32EFGEFDC" ELSE restReal .18
rest .1

IF INKEY$ <> "" GOTO GetThisOverWith
NEXT

rest 1
END IF

GetThisOverWith:
' Finally, the intro can be aborted
END SUB

'Intro:
' Displays game introduction
SUB Intro

IF GSettings.useSound THEN PLAY "MBT160O2" ' Initialise sound
WHILE INKEY$ <> "": WEND 'Clear keyboard buffer
RESTORE SlidyText
Slidy
SparklePause (3)
t$ = STRING$(80, " ")
FOR s = 5 TO 8: LOCATE s * 2, 1: PRINT t$; : NEXT
LOCATE 1, 1: PRINT t$: LOCATE 22, 1: PRINT t$
FOR s = 1 TO 22: LOCATE s, 1: PRINT " "; : LOCATE s, 80: PRINT " "; : NEXT
Slidy
SparklePause (0)

IF Mode = 1 THEN MaxCol = 40

END SUB

SUB LoadSettings
DIM currLine$, eqPos, key$, value$, nBool

'þ set default settings
GSettings.useSound = 1
GSettings.useOldExplosions = 0
GSettings.newExplosionRadius = 40
GSettings.useSlidingText = 0 '1
GSettings.defaultGravity = 17
GSettings.defaultRoundQty = 4
GSettings.showIntro = 1

lastErrCode = 0
ON ERROR GOTO FuckOff
OPEN "GORILLAS.INI" FOR INPUT AS #1
IF lastErrCode > 0 THEN EXIT SUB
WHILE NOT EOF(1)
LINE INPUT #1, currLine$
IF lastErrCode > 0 THEN CLOSE #1: EXIT SUB
GOSUB processLine
WEND
CLOSE #1
ON ERROR GOTO 0

EXIT SUB

processLine:
eqPos = INSTR(currLine$, "=")
IF eqPos = 0 THEN
RETURN
END IF
key$ = RTRIM$(LTRIM$(MID$(currLine$, 1, eqPos - 1)))
value$ = RTRIM$(LTRIM$(RIGHT$(currLine$, LEN(currLine$) - eqPos)))

SELECT CASE UCASE$(key$)
CASE "USESOUND"
GOSUB getBool
IF nBool > -1 THEN GSettings.useSound = nBool
CASE "USEOLDEXPLOSIONS"
GOSUB getBool
IF nBool > -1 THEN GSettings.useOldExplosions = nBool
CASE "NEWEXPLOSIONRADIUS"
GSettings.newExplosionRadius = VAL(value$)
CASE "USESLIDINGTEXT"
GOSUB getBool
IF nBool > -1 THEN GSettings.useSlidingText = nBool
CASE "DEFAULTGRAVITY"
tVal = VAL(value$)
IF tVal > 0 AND tVal < 100 THEN GSettings.defaultGravity = tVal
CASE "DEFAULTROUNDQTY"
tVal = VAL(value$)
IF tVal > 0 AND tVal < 100 THEN GSettings.defaultRoundQty = tVal
CASE "SHOWINTRO"
GOSUB getBool
IF nBool > -1 THEN GSettings.showIntro = nBool
END SELECT
RETURN

getBool:
IF UCASE$(value$) = "YES" OR value$ = "1" OR UCASE$(value$) = "TRUE" THEN
nBool = 1
ELSEIF UCASE$(value$) = "NO" OR value$ = "0" OR UCASE$(value$) = "FALSE" THEN
nBool = 0
ELSE
nBool = -1
END IF
RETURN

leave:

END SUB

'MakeCityScape:
' Creates random skyline for game
'Parameters:
' BCoor() - a user-defined type array which stores the coordinates of
' the upper left corner of each building.
SUB MakeCityScape (BCoor() AS XYPoint)

x = 2

'Set the sloping trend of the city scape. NewHt is new building height
Slope = FNRan(6)
SELECT CASE Slope
CASE 1: NewHt = 15 'Upward slope
CASE 2: NewHt = 130 'Downward slope
CASE 3 TO 5: NewHt = 15 '"V" slope - most common
CASE 6: NewHt = 130 'Inverted "V" slope
END SELECT

IF Mode = 9 THEN
BottomLine = 335 'Bottom of building
HtInc = 10 'Increase value for new height
DefBWidth = 37 'Default building height
RandomHeight = 120 'Random height difference
WWidth = 3 'Window width
WHeight = 6 'Window height
WDifV = 15 'Counter for window spacing - vertical
WDifh = 10 'Counter for window spacing - horizontal
ELSE
BottomLine = 190
HtInc = 6
NewHt = NewHt * 20 \ 35 'Adjust for CGA
DefBWidth = 18
RandomHeight = 54
WWidth = 1
WHeight = 2
WDifV = 5
WDifh = 4
END IF

CurBuilding = 1
DO

SELECT CASE Slope
CASE 1
NewHt = NewHt + HtInc
CASE 2
NewHt = NewHt - HtInc
CASE 3 TO 5
IF x > ScrWidth \ 2 THEN
NewHt = NewHt - 2 * HtInc
ELSE
NewHt = NewHt + 2 * HtInc
END IF
CASE 4
IF x > ScrWidth \ 2 THEN
NewHt = NewHt + 2 * HtInc
ELSE
NewHt = NewHt - 2 * HtInc
END IF
END SELECT

'Set width of building and check to see if it would go off the screen
BWidth = FNRan(DefBWidth) + DefBWidth
IF x + BWidth > ScrWidth THEN BWidth = ScrWidth - x - 2

'Set height of building and check to see if it goes below screen
BHeight = FNRan(RandomHeight) + NewHt
IF BHeight < HtInc THEN BHeight = HtInc

'Check to see if Building is too high
IF BottomLine - BHeight <= MaxHeight + GHeight THEN BHeight = MaxHeight + GHeight - 5

'Set the coordinates of the building into the array
BCoor(CurBuilding).XCoor = x
BCoor(CurBuilding).YCoor = BottomLine - BHeight

IF Mode = 9 THEN BuildingColor = FNRan(3) + 4 ELSE BuildingColor = 2

'Draw the building, outline first, then filled
LINE (x - 1, BottomLine + 1)-(x + BWidth + 1, BottomLine - BHeight - 1), BACKGROUND, B
LINE (x, BottomLine)-(x + BWidth, BottomLine - BHeight), BuildingColor, BF

'Draw the windows
c = x + 3
DO
FOR i = BHeight - 3 TO 7 STEP -WDifV
IF Mode <> 9 THEN
WinColr = (FNRan(2) - 2) * -3
ELSEIF FNRan(4) = 1 THEN
WinColr = 8
ELSE
WinColr = WINDOWCOLOR
END IF
LINE (c, BottomLine - i)-(c + WWidth, BottomLine - i + WHeight), WinColr, BF
NEXT
c = c + WDifh
LOOP UNTIL c >= x + BWidth - 3

x = x + BWidth + 2

CurBuilding = CurBuilding + 1

LOOP UNTIL x > ScrWidth - HtInc

LastBuilding = CurBuilding - 1

'Set Wind speed
Wind = FNRan(10) - 5
IF FNRan(3) = 1 THEN
IF Wind > 0 THEN
Wind = Wind + FNRan(10)
ELSE
Wind = Wind - FNRan(10)
END IF
END IF

'Draw Wind speed arrow
IF Wind <> 0 THEN
WindLine = Wind * 3 * (ScrWidth \ 320)
LINE (ScrWidth \ 2, ScrHeight - 5)-(ScrWidth \ 2 + WindLine, ScrHeight - 5), ExplosionColor
IF Wind > 0 THEN ArrowDir = -2 ELSE ArrowDir = 2
LINE (ScrWidth / 2 + WindLine, ScrHeight - 5)-(ScrWidth / 2 + WindLine + ArrowDir, ScrHeight - 5 - 2), ExplosionColor
LINE (ScrWidth / 2 + WindLine, ScrHeight - 5)-(ScrWidth / 2 + WindLine + ArrowDir, ScrHeight - 5 + 2), ExplosionColor
END IF
END SUB

'PlaceGorillas:
' PUTs the Gorillas on top of the buildings. Must have drawn
' Gorillas first.
'Parameters:
' BCoor() - user-defined TYPE array which stores upper left coordinates
' of each building.
SUB PlaceGorillas (BCoor() AS XYPoint)

IF Mode = 9 THEN
XAdj = 14
YAdj = 30
ELSE
XAdj = 7
YAdj = 16
END IF
SclX# = ScrWidth / 320
SclY# = ScrHeight / 200

'Place gorillas on second or third building from edge
FOR i = 1 TO 2
IF i = 1 THEN BNum = FNRan(2) + 1 ELSE BNum = LastBuilding - FNRan(2)

BWidth = BCoor(BNum + 1).XCoor - BCoor(BNum).XCoor
GorillaX(i) = BCoor(BNum).XCoor + BWidth / 2 - XAdj
GorillaY(i) = BCoor(BNum).YCoor - YAdj
PUT (GorillaX(i), GorillaY(i)), GorD&, PSET
NEXT i

END SUB

'PlayGame:
' Main game play routine
'Parameters:
' Player$() - player names
' NumGames - number of games to play
FUNCTION PlayGame (player$(), NumGames, P)

DIM BCoor(0 TO 30) AS XYPoint
DIM minRounds
DIM totalWins(1 TO 2)
DIM avBan!(1 TO 2) ' mean accuracy
DIM Throw(1 TO 2) ' throw counter
DIM numHits(1 TO 2, 1 TO NumGames) ' number of throws needed to kill
' opponent per win for each player
J = 1
abortYN = FALSE
minRounds = FIX(NumGames / 2) + 1

i = 1
DO
CLS
RANDOMIZE (TIMER)
CALL MakeCityScape(BCoor())
CALL PlaceGorillas(BCoor())
DoSun SUNHAPPY
GLeftAngle# = 0: GRightAngle# = 0
GLeftVeloc = 0: GRightVeloc = 0
Hit = FALSE: IF GSettings.useSound THEN PLAY "MBT160O1L8<G>CDEDCDL4ECC"
go = 1
DO WHILE Hit = FALSE
J = 1 - J
LOCATE 1, 2
IF Mode = 9 THEN COLOR 12
PRINT player$(1);
LOCATE 1, (MaxCol - LEN(player$(2)))
PRINT player$(2);
IF Mode = 9 THEN COLOR 9
Center 23, STR$(totalWins(1)) + " > Score < " + LTRIM$(STR$(totalWins(2)) + " ")
Tosser = J + 1: Tossee = 2 - J

'Plot the shot. Hit is true if Gorilla gets hit.
Hit = DoShot(Tosser, GorillaX(Tosser), GorillaY(Tosser), go, GorillaX(Tossee), GorillaY(Tossee))
IF Hit = 1 THEN abortYN = TRUE: EXIT DO
'If the throw was fatal, Tosser now contains the player who WON

'If not hit self then increase number of hits
IF (J + 1) = Tosser THEN Throw(Tosser) = Throw(Tosser) + 1

IF Hit = TRUE THEN
'Update scores
totalWins(Tosser) = totalWins(Tosser) + 1
IF (J + 1) = Tosser THEN numHits(Tosser, totalWins(Tosser)) = Throw(Tosser)
END IF

go = go + 1

LOOP

IF abortYN THEN EXIT DO

Throw(1) = 0: Throw(2) = 0
SLEEP 1

i = i + 1
LOOP UNTIL i > NumGames OR totalWins(1) >= minRounds OR totalWins(2) >= minRounds

If game played out then go through end game sequence
IF NOT abortYN THEN
GamePlayedYN = 1
FOR l = 1 TO 2: Kills = 0
IF totalWins(l) > 0 THEN
FOR m = 1 TO totalWins(l)
IF numHits(l, m) > 0 THEN
avBan!(l) = avBan!(l) + numHits(l, m): Kills = Kills + 1
END IF
NEXT
IF avBan!(l) > 0 THEN avBan!(l) = avBan!(l) / Kills
END IF
NEXT
END IF

SCREEN 0
WIDTH 80, 25
COLOR 7, 0
MaxCol = 80
CLS
Stats totalWins(), player$(), avBan!(), P, abortYN
CLS : RESTORE NowWhat: Slidy
LOCATE 2, 1: COLOR 2: PRINT STRING$(80, "Í")
LOCATE 4, 4: PRINT "Another game? [Y/N]";
DO
in$ = UCASE$(INKEY$)
LOOP UNTIL in$ = "Y" OR in$ = "N"
IF in$ = "Y" THEN PlayGame = 1 ELSE PlayGame = 0

END FUNCTION

'PlayGame:
' Plots banana shot across the screen
'Parameters:
' StartX, StartY - starting shot location
' Angle - shot angle
' Velocity - shot velocity
' PlayerNum - the banana thrower
FUNCTION PlotShot (StartX, StartY, angle#, velocity, PlayerNum, othX, othY)

angleChk = angle#: IF PlayerNum = 2 THEN angleChk = 180 - angleChk

angle# = angle# / 180 * pi# 'Convert degree angle to radians
InitXVel# = COS(angle#) * velocity
InitYVel# = SIN(angle#) * velocity
oldx# = StartX
oldy# = StartY

' draw gorilla toss
IF PlayerNum = 1 THEN
PUT (StartX, StartY), GorL&, PSET
ELSE
PUT (StartX, StartY), GorR&, PSET
END IF
' throw sound
IF GSettings.useSound THEN PLAY "MBO0L32A-L64CL16BL64A+"
rest .1
' redraw gorilla
PUT (StartX, StartY), GorD&, PSET

adjust = Scl(4) 'For scaling CGA

xedge = Scl(9) * (2 - PlayerNum) 'Find leading edge of banana for check

Impact = FALSE
SunHit = FALSE
ShotInSun = FALSE
OnScreen = TRUEFALSE if the banana is off side
PlayerHit = 0
NeedErase = FALSE
Bounced = FALSE
'þ Set up banana sound effect
DoooMinVeloc = 40
pitch! = 9800
pitchDec! = 100
pitchDecDec! = (((InitYVel# - DoooMinVeloc) / (200 - DoooMinVeloc)) * 1.2) - .5

t2b# = 9999 'þ Used to store the time when the banana is to stop moving
' when continuing off screen. 9999 means unused.

StartXPos = StartX
StartYPos = StartY - adjust - 3

IF PlayerNum = 2 THEN
StartXPos = StartXPos + Scl(25)
Direction = Scl(4)
ELSE
Direction = Scl(-4)
END IF

IF velocity < 2 THEN 'Shot too slow - hit self
x# = StartX
y# = StartY
pointval = OBJECTCOLOR
END IF

'þ Obtain predicted x-coordinate when banana reaches bottom of screen
GOSUB PredictBottomOfScreen
'þ See if banana will overshoot (direction is +ve for left & -ve for right)
'þ MissedDist# is -ve for miss, and +ve for hit
IF Direction > 0 THEN
MissedDist# = XPredicted#
ELSE
MissedDist# = ScrWidth - XPredicted#
END IF
If shot is going backwards, then turns it into a miss
IF SGN(Direction) = SGN(InitXVel#) THEN MissedDist# = 0 - MissedDist#

DO WHILE (NOT Impact) AND OnScreen
rest .02

'Erase old banana, if necessary
IF NeedErase THEN
NeedErase = FALSE
CALL DrawBan(oldx#, oldy#, oldrot, FALSE)
END IF

x# = StartXPos + (InitXVel# * t#) + (.5 * (Wind / 5) * t# ^ 2)
y# = StartYPos + ((-1 * (InitYVel# * t#)) + (.5 * Gravity * t# ^ 2)) * (ScrHeight / 350)

IF y# > oldy# AND InitYVel# > DoooMinVeloc AND NOT Bounced AND MissedDist# > -175 THEN
'þ Play banana sound effect
IF GSettings.useSound THEN SOUND pitch!, 1
'þ Decrement banana sound effect pitch
IF (pitch! - pitchDec! >= 37) THEN
pitch! = pitch! - pitchDec!: pitchDec! = pitchDec! - pitchDecDec!
END IF
END IF

IF y# >= ScrHeight - 7 THEN
If velocity is still high enough to bounce, and banana is on screen
IF InitYVel# > 2 AND t2b# = 9999 THEN
Bounced = TRUE
IF GSettings.useSound THEN PLAY "O4A64"
InitYVel# = SQR(InitYVel# ^ 2 - (2 * Gravity * (StartYPos - (ScrHeight - 7)))) * .4
StartXPos = x#
y# = ScrHeight - 7: StartYPos = y#
t# = 0
ELSE
'þ Terminate banana motion
OnScreen = FALSE
DoSun SUNHAPPY
IF t2b# = 9999 THEN 'þ Because its velocity ran out
IF GSettings.useSound THEN PLAY "O0A4"
ELSE 'þ Or because it bounced when off screen
IF SGN(Direction) <> SGN(InitXVel#) THEN GOSUB FailureMessage
END IF
END IF
END IF

If banana leaves the screen
IF (x# >= ScrWidth - Scl(10)) OR (x# <= 3) THEN
'þ And banana will not return to the screen
IF (XPredicted# >= ScrWidth - Scl(10)) OR (XPredicted# <= 3) THEN
IF t# > t2b# THEN
OnScreen = FALSE
'þ Redraw sun as soon as poss
' Ignore SunHit: bananas can still take pieces out of the sun unnoticed
DoSun SUNHAPPY
IF SGN(Direction) <> SGN(InitXVel#) THEN
GOSUB FailureMessage
END IF
ELSEIF t2b# = 9999 THEN
IF y# <= 0 THEN t2b# = t# + 1.5 ELSE t2b# = t# + 4
END IF
END IF
END IF

IF OnScreen AND y# > 0 AND (x# > 3 AND x# < (ScrWidth - Scl(10))) THEN
'check it
LookY = 0
LookX = Scl(8 * (2 - PlayerNum))

DO
pointval = POINT(x# + LookX, y# + LookY)
IF pointval = 0 THEN
Impact = FALSE
IF ShotInSun = TRUE THEN
IF ABS(ScrWidth \ 2 - x#) > Scl(20) OR y# > SunHt THEN ShotInSun = FALSE
END IF
ELSEIF pointval = SUNATTR AND y# < SunHt THEN
IF NOT SunHit THEN DoSun SUNSHOCK
SunHit = TRUE
ShotInSun = TRUE
ELSE
Impact = TRUE
DoSun SUNHAPPY
END IF
LookX = LookX + Direction
LookY = LookY + Scl(6)
LOOP UNTIL Impact OR LookX <> Scl(4)

IF NOT ShotInSun AND NOT Impact THEN
'plot it
rot = (t# * 10) MOD 4
CALL DrawBan(x#, y#, rot, TRUE)
NeedErase = TRUE
END IF

oldrot = rot

END IF

oldx# = x#
oldy# = y#
t# = t# + .1
LOOP

IF pointval = OBJECTCOLOR THEN
IF x# < ScrWidth / 2 THEN PlayerHit = 1 ELSE PlayerHit = 2
IF PlayerHit = PlayerNum THEN COLOR 2: Center 1, "Now that was pretty dumb."
ExplodeGorilla x#, y#, PlayerHit
IF PlayerHit = PlayerNum THEN
tpause! = TIMER: DO: LOOP UNTIL TIMER > tpause! + .75
Center 1, SPACE$(25): GOSUB RestoreSun
END IF
ELSEIF pointval <> OBJECTCOLOR AND Impact THEN
CALL DoExplosion(x# + adjust, y# + adjust)
'þ Reset values for shot's initial stage (before any bouncing)
InitXVel# = COS(angle#) * velocity
InitYVel# = SIN(angle#) * velocity
StartXPos = StartX: IF PlayerNum = 2 THEN StartXPos = StartXPos + Scl(25)
StartYPos = StartY - adjust - 3
GOSUB PredictReturnToHeight
If shot went the right direction...
IF SGN(Direction) <> SGN(InitXVel#) THEN
'þ ...and if shot was too low powered:
IF (ABS(XPredicted# - StartX) < ABS((othX - StartX) / 3) AND angleChk > 60) OR ABS(XPredicted# - StartX) < ABS((othX - StartX) / 6) THEN
SELECT CASE FNRan(3)
CASE 1: Message$ = "Aren't your little muscles strong enough?"
CASE 2: Message$ = "Now that was feeble."
CASE 3: Message$ = "You can do better than that!"
END SELECT
IF GSettings.useSound THEN PLAY "MBO2L24BAGFEDCO1C2"
GOSUB DoMessage
GOSUB RestoreSun
END IF
END IF
END IF

'redraw gorillas
IF PlayerHit = 0 THEN
PUT (StartX, StartY), GorD&, PSET
PUT (othX, othY), GorD&, PSET
END IF

'þ Message for backwards-tossed shot
IF SGN(Direction) = SGN(InitXVel#) AND PlayerHit <> PlayerNum THEN
IF GSettings.useSound THEN PLAY "MBO1L24BAGFEDCO0C2"
Message$ = "You're not supposed to throw it that way."
GOSUB DoMessage
GOSUB RestoreSun
END IF

PlotShot = PlayerHit

EXIT FUNCTION

' When doing position calculation, don't forget -Gravity and Wind/5

PredictReturnToHeight:
' Prediction of the banana's x-coordinate when it has come down to a level
' horizontally equal with the gorilla that fired it.
t2# = (2 * InitYVel#) / Gravity
XPredicted# = (InitXVel# * t2#) + (.5 * (Wind / 5) * t2# ^ 2) + StartXPos
IF PlayerNum = 2 THEN XPredictedRet# = XPredictedRet# + Scl(25)
RETURN

PredictBottomOfScreen:
' Prediction of the x-coordinate of the shot when it reaches the bottom of
' the screen
fallDist = StartYPos - (ScrHeight - 7)
t2# = (-InitYVel# - SQR((InitYVel# ^ 2) + (2 * (-Gravity) * fallDist))) / (-Gravity)
XPredicted# = (InitXVel# * t2#) + ((t2# ^ 2 * Wind) / 10) + StartXPos
IF PlayerNum = 2 THEN XPredicted# = XPredicted# + Scl(25)
RETURN

FailureMessage:
'þ Select message based on distance beyond screen edge
'þ NOT calibrated for CGA

GiveDist = 0 'þ Flag to indicate whether to show distance travelled

If the player saw the banana leave the screen
MissedDist# = ABS(MissedDist#)
IF y# > 0 THEN
SELECT CASE MissedDist#
CASE 1 TO 155
SELECT CASE FNRan(2)
CASE 1: Message$ = "That went a wee bit far, didn't it?"
CASE 2: Message$ = "It seems you overdid that a little."
END SELECT
CASE 156 TO 640
SELECT CASE FNRan(4)
CASE 1: Message$ = "I think you need glasses."
CASE 2 TO 4: Message$ = "Hmmm...that wasn't good."
END SELECT
CASE 641 TO 1500: Message$ = "WHAT? That went MILES OFF!"
CASE IS > 1500
SELECT CASE FNRan(2)
CASE 1: Message$ = "WHAT ARE YOU PLAYING AT?"
CASE 2: Message$ = "Temper temper"
END SELECT
END SELECT
ELSE
SELECT CASE MissedDist#
CASE 1 TO 155: Message$ = "A little nearer and you might stand a chance"
CASE 156 TO 640:
SELECT CASE FNRan(2)
CASE 1: Message$ = "Nope. That was too far off."
CASE 2: Message$ = CHR$(34) + "Hello? I'm over here!" + CHR$(34)
END SELECT
CASE 640 TO 1500
SELECT CASE FNRan(2)
CASE 1: Message$ = "Whoa! Go easy with it!"
CASE 2: Message$ = "You must be JOKING!"
END SELECT
CASE IS > 1500: Message$ = "You weren't supposed to put it into orbit."
END SELECT
END IF

IF GSettings.useSound THEN PLAY "MBO1L24BAGFEDCO0C2"
COLOR 13
GOSUB DoMessage
GOSUB RestoreSun
RETURN

DoMessage:
COLOR 2
Center 1, Message$
tpause! = TIMER: DO: LOOP UNTIL TIMER > tpause! + 2
Center 1, SPACE$(LEN(Message$))
RETURN

RestoreSun:
sunX = ScrWidth \ 2: sunY = Scl(25)
LINE (sunX, sunY - Scl(15))-(sunX, sunY), SUNATTR
LINE (sunX - Scl(8), sunY - Scl(13))-(sunX, sunY), SUNATTR
LINE (sunX, sunY)-(sunX + Scl(8), sunY - Scl(13)), SUNATTR
RETURN

END FUNCTION

'Rest:
' pauses the program
SUB rest (t#)
s# = TIMER
t2# = 0
' t2# = MachSpeed * t#' / SPEEDCONST
'þ Speed calibration disabled
DO
LOOP UNTIL TIMER - s# > t2#
END SUB

SUB restReal (t#)
s# = TIMER
DO
LOOP UNTIL TIMER - s# > t#
END SUB

'Scl:
' Pass the number in to scaling for cga. If the number is a decimal, then we
' want to scale down for cga or scale up for ega. This allows a full range
' of numbers to be generated for scaling.
' (i.e. for 3 to get scaled to 1, pass in 2.9)
FUNCTION Scl (N!)

IF N! <> INT(N!) THEN
IF Mode = 1 THEN N! = N! - 1
END IF
IF Mode = 1 THEN
Scl = CINT(N! / 2 + .1)
ELSE
Scl = CINT(N!)
END IF

END FUNCTION

'SetScreen:
' Sets the appropriate color statements
SUB SetScreen

IF Mode = 9 THEN
ExplosionColor = 2
BackColor = 1
PALETTE 0, 1
PALETTE 1, 46
PALETTE 2, 44
PALETTE 3, 54
PALETTE 5, 7
PALETTE 6, 4
PALETTE 7, 3
PALETTE 9, 63 'Display Color
PALETTE 10, 24
PALETTE 14, 55
ELSE
ExplosionColor = 2
BackColor = 0
COLOR BackColor, 2
END IF

END SUB

SUB ShowPrompts (fieldNum)

SELECT CASE fieldNum
CASE 1 TO 2
GOSUB pPlayers ' player list manipulation
CASE 11
GOSUB pDeletePlayer
CASE 12, -12
GOSUB pCreatePlayer
CASE 13
GOSUB pRenamePlayer
CASE 3
GOSUB pRounds
CASE 4
GOSUB pGravity
END SELECT

EXIT SUB

pPlayers:
COLOR , 0
FOR l = 3 TO 6: LOCATE l, 1: PRINT STRING$(80, " "); : NEXT
noOfDiams = 4: GOSUB Diamonds
IF fieldNum = 1 THEN LOR$ = "LEFT" ELSE IF fieldNum = 2 THEN LOR$ = "RIGHT"
COLOR 9: LOCATE 3, 5
PRINT "Use arrow keys to choose " + LOR$ + " HAND player and press [ENTER] to confirm."
LOCATE 4, 5: PRINT "Type [N] to create a new player (up to 20 players)."
LOCATE 5, 5: PRINT "Type [R] to rename a player."
LOCATE 6, 5: PRINT "Type [DELETE] to delete a player."
RETURN

pDeletePlayer:
noOfDiams = 3: GOSUB Diamonds
LOCATE 4, 5: COLOR 9: PRINT "Press [Y] to delete the player, OR"
LOCATE 5, 5: PRINT "Press [N] to cancel"
RETURN

pCreatePlayer:
COLOR , 0
FOR l = 3 TO 6: LOCATE l, 1: PRINT STRING$(80, " "): NEXT
noOfDiams = 1: GOSUB Diamonds
'þ Used if the ESCAPE prompt is to be given
IF fieldNum = 12 THEN LOCATE 6, 3: PRINT ""
COLOR 9
LOCATE 3, 5: PRINT "Enter name of new player and press [ENTER] when done. You may as well"
LOCATE 4, 5: PRINT "specify the player's full name as you only ever have to enter it"
LOCATE 5, 5: PRINT "once."
'þ Signals whether ESCAPE can be pressed
IF fieldNum = 12 THEN LOCATE 6, 5: PRINT "Or press [ESC] to cancel."
RETURN

pRenamePlayer:
COLOR , 0
FOR l = 3 TO 6
LOCATE l, 1: PRINT STRING$(80, " ")
NEXT
noOfDiams = 3: GOSUB Diamonds: COLOR 9
LOCATE 3, 5: PRINT "Edit name of player and press [ENTER] when done."
LOCATE 4, 5: PRINT "Pressing [DELETE] will clear the name field."
LOCATE 5, 5: PRINT "Press [ESC] if you want to undo the changes."
RETURN

'

pRounds:
COLOR , 0
FOR l = 3 TO 6: LOCATE l, 1: PRINT STRING$(80, " "); : NEXT
noOfDiams = 1: GOSUB Diamonds
COLOR 9
LOCATE 3, 5: PRINT "Enter input and press [ENTER] for the next field."
RETURN

pGravity:
noOfDiams = 2: GOSUB Diamonds
COLOR 9
LOCATE 3, 5: PRINT "Enter input and press [ENTER] to finish and play the game."
LOCATE 4, 5: PRINT "Or press [TAB] to return to the first entry."
LOCATE 6, 5: PRINT "Competition gravity is 17 m/sý."
RETURN

'

Diamonds:
COLOR 2
FOR l = 3 TO (3 + (noOfDiams - 1))
LOCATE l, 3: PRINT ""
NEXT
RETURN

END SUB

SUB Slidy

DIM q AS LONG

READ N

DIM t$(1 TO N): DIM i(1 TO N, 1 TO 3)
FOR l = 1 TO N
READ P$: x = 40 - LEN(P$) / 2
P$ = STRING$(x, " ") + P$ + STRING$(x, " ")
READ i(l, 1), i(l, 2), i(l, 3)
t$(l) = P$
NEXT

IF GSettings.useSlidingText THEN
FOR la = 1 TO 80
FOR lb = 1 TO N
IF i(lb, 2) < 0 THEN
P$ = LEFT$(t$(lb), la): x = 81 - la
ELSE
P$ = RIGHT$(t$(lb), la): x = 1
END IF
LOCATE i(lb, 3), x: COLOR i(lb, 1): PRINT P$;
NEXT
FOR q = 1 TO SLIDECONST: NEXT
NEXT

ELSE
FOR lb = 1 TO N
LOCATE i(lb, 3), 1: COLOR i(lb, 1): PRINT t$(lb)
NEXT
END IF

END SUB

'SparklePause:
' Creates flashing border for intro and statistics screens
SUB SparklePause (opt AS INTEGER)

DO: LOOP UNTIL INKEY$ = "" 'þ Clear keyboard buffer
COLOR 12, 0
a$ = "* * * * * * * * * * * * * * * * * "
t! = TIMER
DO
FOR a = 1 TO 5
t1! = TIMER: DO: LOOP UNTIL TIMER > t1! + .001
LOCATE 1, 1 'print horizontal sparkles
PRINT MID$(a$, a, 80);
LOCATE 22, 1
PRINT MID$(a$, 6 - a, 80);

FOR b = 2 TO 21 'Print Vertical sparkles
c = (a + b) MOD 5
IF c = 1 THEN
LOCATE b, 80
PRINT "*";
LOCATE 23 - b, 1
PRINT "*";
ELSE
LOCATE b, 80
PRINT " ";
LOCATE 23 - b, 1
PRINT " ";
END IF
NEXT b
NEXT a
LOOP UNTIL INKEY$ <> "" OR (opt > 0 AND TIMER > t! + opt)

END SUB

SUB Stats (Wins(), nam$(), Ban!(), P, abortYN)

IF abortYN THEN
RESTORE Aborted: Slidy
LOCATE 4, 3: COLOR 2: PRINT STRING$(76, "Í")
ELSE
'þ Update and sort the league table
RESTORE GameOver: Slidy
LOCATE 4, 3: COLOR 2: PRINT STRING$(76, "Í")
FOR l = 1 TO 2
PDat(PDefs(l)).Rounds = PDat(PDefs(l)).Rounds + Wins(1) + Wins(2)
PDat(PDefs(l)).Won = PDat(PDefs(l)).Won + Wins(l)
IF Ban!(l) > 0 THEN
IF PDat(PDefs(l)).Accu > 0 THEN
PDat(PDefs(l)).Accu = CINT(((PDat(PDefs(l)).Accu + Ban!(l)) / 2) * 10) / 10
ELSE
PDat(PDefs(l)).Accu = CINT(Ban!(l) * 10) / 10
END IF
END IF
NEXT

'þ routine to sort the player list
DO
complete = 1: tempW1 = 0: tempW2 = 0
FOR l = 1 TO P - 1
IF PDat(l).Rounds > 0 THEN tempW1 = (PDat(l).Won / PDat(l).Rounds * 100)
IF PDat(l + 1).Rounds > 0 THEN tempW2 = (PDat(l + 1).Won / PDat(l + 1).Rounds * 100)
IF (tempW1 < tempW2) OR (tempW1 = tempW2 AND PDat(l).Accu > PDat(l + 1).Accu) THEN
SWAP PDat(l).PNam, PDat(l + 1).PNam
SWAP PDat(l).Rounds, PDat(l + 1).Rounds
SWAP PDat(l).Won, PDat(l + 1).Won
SWAP PDat(l).Accu, PDat(l + 1).Accu
FOR PDl = 1 TO 2
IF PDefs(PDl) = l THEN
PDefs(PDl) = PDefs(PDl) + 1
ELSEIF PDefs(PDl) = l + 1 THEN
PDefs(PDl) = PDefs(PDl) - 1
END IF
NEXT

complete = 0
END IF
NEXT
LOOP UNTIL complete

FOR l = 1 TO 2
IF Wins(1) <> Wins(2) THEN
D = (Wins(l) >= Wins(2 / l))
COLOR (D + 2) * 2: LOCATE 6 + D, 7
ELSE
COLOR 9: LOCATE 4 + l, 7
END IF
PRINT nam$(l); " "; STRING$(20 - LEN(nam$(l)), "Ä"); ""; Wins(l);
IF (Wins(1) <> Wins(2)) THEN
IF D = -1 THEN PRINT CHR$(27); "ÄÄÄÄ Winner!";
ELSEIF l = 1 THEN
PRINT " (The game was a draw)";
END IF
posn = 0: DO: posn = posn + 1: LOOP UNTIL nam$(l) = RTRIM$(PDat(posn).PNam)
IF posn > 10 THEN PRINT TAB(54); "(position"; RTRIM$(STR$(posn)); "th)"
NEXT
END IF

'þ Show league table no matter what
LOCATE 8, 20: COLOR 9: PRINT "STATISTICS";
LOCATE 9, 3: COLOR 2: PRINT "Ú"; STRING$(74, "Ä"); "¿";
FOR l = 10 TO 20: LOCATE l, 3: PRINT "³"; TAB(78); "³"; : NEXT
LOCATE 21, 3: PRINT "À"; STRING$(74, "Ä"); "Ù";
COLOR 3
LOCATE 9, 5: PRINT "Place";
LOCATE 9, 12: PRINT "Player";
LOCATE 9, 32: PRINT "Rounds";
LOCATE 9, 54: PRINT "Mean Accuracy";
LOCATE 9, 40: PRINT "Won";

COLOR 5: IF P > 9 THEN lim = 10 ELSE lim = P
FOR l = 1 TO lim
LOCATE l + 10, 6:
IF (PDefs(1) = l OR PDefs(2) = l) AND NOT abortYN THEN COLOR 11 ELSE COLOR 5
IF l < 10 THEN PRINT "0";
PRINT LTRIM$(STR$(l)); " ÄÄ "; TAB(12); PDat(l).PNam
COLOR 5: LOCATE l + 10, 31: PRINT PDat(l).Rounds; TAB(39); PDat(l).Won; TAB(45);
IF PDat(l).Rounds = 0 THEN
PRINT "-"; TAB(53);
ELSE
IF (PDefs(1) = l OR PDefs(2) = l) AND NOT abortYN THEN COLOR 11 ELSE COLOR 13
PRINT ; "("; LTRIM$(RTRIM$(STR$(CINT(PDat(l).Won / PDat(l).Rounds * 100)))); "%)"; TAB(53);
END IF
COLOR 5
IF PDat(l).Accu = 0 THEN
PRINT ; " -"
ELSE
PRINT ; PDat(l).Accu;
IF PDat(l).Accu > 1! THEN PRINT "bananas" ELSE PRINT "banana"
END IF
NEXT

'þ Only save stats if they have changed or if file absent
IF NOT abortYN OR DoesFileExist = 0 THEN
COLOR 5: LOCATE 24, 3: PRINT "Saving stats...";

ON ERROR GOTO NoSaveStats
IF DoesFileExist = 1 THEN KILL "GORILLAS.LGE"
OPEN "GORILLAS.LGE" FOR OUTPUT AS #1
PRINT #1, P
FOR l = 1 TO P
PRINT #1, PDat(l).PNam
PRINT #1, PDat(l).Rounds, PDat(l).Won, PDat(l).Accu
NEXT
CLOSE #1
DoesFileExist = 1
END IF

COLOR 15: LOCATE 24, 3: PRINT "Press a key... ";
SparklePause (0)

END SUB

'VictoryDance:
' gorilla dances after he has eliminated his opponent
'Parameters:
' Player - which gorilla is dancing
SUB VictoryDance (player)
FOR i# = 1 TO 4
PUT (GorillaX(player), GorillaY(player)), GorL&, PSET
IF GSettings.useSound THEN PLAY "MFO0L32EFGEFDC" ELSE restReal .2
rest .2
PUT (GorillaX(player), GorillaY(player)), GorR&, PSET
IF GSettings.useSound THEN PLAY "MFO0L32EFGEFDC" ELSE restReal .2
rest .2
NEXT
END SUB

FUNCTION WHEREX (num)

WHEREX = ((num - 1) MOD 4) * 19 + 3

END FUNCTION

FUNCTION WHEREY (num)

WHEREY = INT((num - 1) / 4) + 13

END FUNCTION
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0