Jump to content
IGNORED

BASIC / XB Translator (TidBit)


matthew180

Recommended Posts

PHP is interpreted, and yes it is commonly used as a server-side language. To run PHP on a system, you just need to download a pre-compiled binary (on my Unix machines I typically build from source), no "server" setup is necessary.

 

http://php.net is the main website, hit the download link, then the "windows binary" link. Grab the VC9 x86 Thread Safe version in zip format. Unzip to a directory and add it to your path if you want. Then at the Windows command prompt, you can execute a PHP script like this (assumes you added the PHP dir to your path):

 

php -f whatever_script.php

 

You probably don't even need the -f (which means "file") flag. You can see the php version with:

 

php -v

Edited by matthew180
Link to comment
Share on other sites

  • 1 year later...

Is the TidBit site down? I can't seem to be able to access it and I need it for my current work on Panzer Strike. Help!!!

 

Update: OK the site works fine with IE, but not with Chrome. Come to think of it, Chrome has been acting badly on both my laptop and my desktop, with some sites just refusing to load properly. Has anyone experience this as well?

 

The link for TidBit is http://codehackcreate.com/archives/237

Edited by Vorticon
Link to comment
Share on other sites

Matt, if you are reading this, I have a bug report:

Terminal !'s (comments) are not being removed by TidBit, but rather the ! is being squished to the end of the statement, thus leading to a syntax error.

 

I also have a request:

It would be great if there was a button that would copy the translated code into the clipboard for easy paste and copy. When the code is large, it's a real pain to scroll, select and copy the whole thing.

Link to comment
Share on other sites

Keeping XB REM and ! was a decision based on user feedback (I did a not-so-quick review of this thread to make sure.) I see I did not update my website comments though, I'll get that fixed. If you want to use comments that are stripped from the source and not included in the result, use the // comment syntax.

 

Squished ! comments: I fired up Classic99 and put a ! at the end of a few XB statements without any space before the ! and did not get any errors. Can you post an example where this produces a syntax error?

 

I tried a few variations and TidBit retains the original spacing:

Input:
CALL CLEAR!cls
CALL CLEAR! cls
CALL CLEAR !cls

Output:
100 CALL CLEAR!cls
110 CALL CLEAR! cls
120 CALL CLEAR !cls
.

Note:

Well, it looks like I broke something while messing around with TidBit on my website. I'll have it back up as soon as I can. Sorry.

 

Edit:

I fixed the TidBit page on my website. Ugh. Nothing like simply reviewing a post and then having it break for no apparent reason.

 

Anyway, I'm looking into having the result copied to the clipboard automatically (via JavaScript), however this seems to be a really big deal and a security risk.

Edited by matthew180
Link to comment
Share on other sites

Well it turned out that to be a fluke of XB, not TidBit:

 

100 FOR I=1 to 10
110 READ N
120 NEXT I
130 DATA 1,2,3,4,5,6,7,8,9,10 ! THIS IS THE DATA
This test code gives a DATA ERROR. Apparently terminal comments are not allowed with DATA statements. After all these years of XB programming, I still learn something new every time!
  • Like 1
Link to comment
Share on other sites

Update: for some reason Chrome still refuses to load TidBit's page. I have tried this with multiple computers with similar results. This is a recent issue. IE has no problem with it, but any code copied and pasted directly into Classic 99 from TidBit is degraded and unusable. Again this was not an issue with Chrome previously. Could someone please verify this?

Link to comment
Share on other sites

When the page unexpectedly broke on me the other night, I was testing with FireFox and Chrome. I just tried to pull the page up in Chrome again and it was still a blank page. I changed the URL to http://codehackcreate.com directly and the main page pulled up. I hit "refresh" just to be sure, then I scrolled down to the TidBit post and the page loaded fine this time.

 

I have no idea why copy-n-paste from IE would be a problem, the output is just a plain text box... Ah, I see, it is not a text box, and that make selecting the output a pain in the ass. I'll change it to a text box, which should also prevent IE from including the markup in the copy.

Link to comment
Share on other sites

When the page unexpectedly broke on me the other night, I was testing with FireFox and Chrome. I just tried to pull the page up in Chrome again and it was still a blank page. I changed the URL to http://codehackcreate.com directly and the main page pulled up. I hit "refresh" just to be sure, then I scrolled down to the TidBit post and the page loaded fine this time.

 

I have no idea why copy-n-paste from IE would be a problem, the output is just a plain text box... Ah, I see, it is not a text box, and that make selecting the output a pain in the ass. I'll change it to a text box, which should also prevent IE from including the markup in the copy.

 

OK now the copy and paste functions work as they should. Thanks!

Unfortunately, I still can't get the TidBit page loaded under Chrome, even after accessing from the main page as you mentioned. Since this was working fine about a week ago, it has got to be an issue with Chrome itself. Incidentally it also started having problems displaying my bank website as well. Google must have screwed something up...

Link to comment
Share on other sites

  • 4 months later...

I change the topic title.

 

github: I don't see how putting this on github would help share it any more than posting it here (and I would have yet another place I would have to maintain updates). PHP is a scripting language, the program *is* the source and is part of the .zip file download.

Link to comment
Share on other sites

@Walid: any chance you would post some (or all) of your Panzer Strike TidBit code as an example? I think it would help if people could see how others are formatting their code for better organization and readability.

 

Here is a maze generator I wrote with TidBit and it is included in the .zip file on the first post of this thread:

 

 

 

//
// Hunter-Killer Maze Algorithm
// TI-99/4A Extended BASIC Version
//

// Initialize
CALL CLEAR :: OPTION BASE 0 :: RANDOMIZE
CALL CHAR(96,"0000000000000000")
CALL CHAR(97,"0101010101010101")
CALL CHAR(98,"00000000000000FF")
CALL CHAR(99,"01010101010101FF")
CALL CHAR(100,"017D4545457D01FF")
CALL COLOR(9,2,11)

// Initialize the maze screen offset and starting "hunt" mode coordinate.
OX=10 :: OY=6 :: HX=1 :: HY=1

// Dimension the MAZE array and initialize the border.
SX=12 :: SY=12 :: ..
DIM MAZE(13,13)

FOR I=0 TO SX+1 :: ..
    MAZE(I,0)=-1 :: ..
    MAZE(I,SY+1)=-1 :: ..
NEXT I

FOR I=1 TO SY :: ..
    MAZE(0,I)=-1 :: ..
    MAZE(SX+1,I)=-1 :: ..
NEXT I

// Dimension and initialize the direction-to-offset lookup table.  What
// this does is saves us from having to use IF statements to find out
// what to add to X and Y for a given direction D.
DIM P(4,2)
    P(1,1)=0 :: ..
    P(1,2)=-1 :: ..
    P(2,1)=1 :: ..
    P(2,2)=0
    P(3,1)=0 :: ..
    P(3,2)=1 :: ..
    P(4,1)=-1 :: ..
    P(4,2)=0

DIM DBIT(4) :: ..
    DBIT(1)=1 :: ..
    DBIT(2)=2 :: ..
    DBIT(3)=4 :: ..
    DBIT(4)=8

DIM DINV(4) :: ..
    DINV(1)=4 :: ..
    DINV(2)=8 :: ..
    DINV(3)=1 :: ..
    DINV(4)=2

// Draw the initial maze, all walls up.
FOR I=OY TO OY+SY-1
    CALL HCHAR(I,OX,99,SX)
NEXT I

// Pick a random starting point and enter Kill mode.
KillMode:

    X=INT(RND*SX)+1 :: ..
    Y=INT(RND*SY)+1 :: ..
    IF MAZE(X,Y)<>0 THEN ..
        KillMode

    DISPLAY AT(1,1):"KILL"

    // Pick a random direction D (1-4) and remember it (D1) so we know when we
    // have tried all 4 directions for this cell.  RND is a very expensive
    // instruction, as is the multiplication.
    PickRandomDirection:

        D=INT(RND*3)+1 :: ..
        D1=D

        CheckNewCell:
            // Generate a new cell location (NX,NY) and see if it is okay to move there.
            NX=X+P(D,1) :: ..
            NY=Y+P(D,2)

            IF MAZE(NX,NY)<>0 THEN InvalidDirection

            // Drop the wall in the current cell for the direction in which we are
            // leaving the cell.  Then display the proper wall character for this cell.
            MAZE(X,Y)=MAZE(X,Y) OR DBIT(D)
            C=99

            IF (MAZE(X,Y) AND 2)=2 THEN ..
                C=98

            IF (MAZE(X,Y) AND 4)=4 THEN ..
                IF C=98 THEN ..
                    C=96 ..
                ELSE ..
                    C=97

            CALL HCHAR(OY+Y-1,OX+X-1,C)

            // Set X and Y to the new cell and drop the wall for the direction in which
            // we just entered the cell.
            X=NX :: ..
            Y=NY :: ..
            MAZE(X,Y)=DINV(D)

    GOTO PickRandomDirection

    InvalidDirection:

        D=D+1 :: ..
        IF D>4 THEN ..
            D=1

    IF D<>D1 THEN ..
        CheckNewCell

// Begin "hunt" mode.  Displays the proper character for the current cell
// and marks the cell as "complete".
HuntMode:

    C=99
    IF (MAZE(X,Y) AND 2)=2 THEN ..
        C=98

    IF (MAZE(X,Y) AND 4)=4 THEN ..
        IF C=98 THEN ..
            C=96 ..
        ELSE ..
            C=97

    CALL HCHAR(OY+Y-1,OX+X-1,C)
    MAZE(X,Y)=MAZE(X,Y) OR 16

    // Set up the hunt loops.  Hunting is a sequential scan over the maze,
    // looking for a cell that has been visited but is not yet complete.
    // Once the whole maze has been scanned in hunt mode and all cells are
    // found to be "complete", the maze is done.

    RESET=0

    FOR J=HY TO SY :: ..
        DISPLAY AT(1,1):"HUNT: ";J

        FOR I=HX TO SX

            // Looking for a visited cell to being Kill mode again.  All cells that
            // are either 0 or >=16 are unvisited or complete, and are skipped.

            // If an unvisited cell (0) is found, the next time we enter hunting mode,
            // we must begin at the beginning (indicated by the RESET variable.)
            // However, if there are no unvisited cells up to the next cell to
            // continue with, we can pick up hunting were we left off.

            IF MAZE(I,J)=0 THEN ..
                RESET=1 :: ..
                GOTO Next_I

            IF MAZE(I,J)>=16 THEN ..
                Next_I

            // A valid cell was found, so set that as the current cell.  The direction
            // is set instead of chosen again at random since 1. this cell already had
            // a random direction chosen for it once before, and 2. choosing a random
            // number is expensive and we want to avoid it if possible.  This is why
            // we jump back to the line just following the random direction generation.

            X=I :: Y=J

            IF RESET=0 THEN ..
                HX=I :: ..
                HY=J ..
            ELSE ..
                HX=1 :: ..
                HY=1

            DISPLAY AT(1,1):"KILL"
            D=4 :: ..
            D1=4

            // Hmm, jumping out of a FOR - NEXT loop is not really good
            // programming practice.
            GOTO CheckNewCell

        // Hunting loop iterators.  If we picked up hunting where we had left off
        // on a previous hunting loop, the hunting column (HX) must be reset back
        // to 1, otherwise hunting would miss chunks of the maze if we hunt past
        // the current line during this hunting iteration.
        Next_I:
        NEXT I

        HX=1

    NEXT J

DISPLAY AT(1,1):"DONE"
KeyWait: CALL KEY(0,K,S) :: IF S=0 THEN KeyWait

END

 

Link to comment
Share on other sites

Sure. Here it is. It's quite a bit of code, so knock yourself out :-D

 

 

 

// Panzer Strike
// By Walid Maalouli
// February 2015

// Initialization

CALL CLEAR:: ..
CALL SCREEN(6):: ..
RANDOMIZE:: ..
CALL SPRITE(#2,105,10,200,1)

OPTION BASE 1
DIM PTANK(10,13),CTANK(10,13),TTYPE$(11),MX(,MY(,MT(,MC(,MF(,XO(,YO(

FOR I=1 TO 8:: ..
	READ XO(I),YO(I):: ..
NEXT I

OPEN #1:"DSK1.CHARDEF",INTERNAL,INPUT

FOR I=1 TO 45:: ..
	INPUT #1:CH,DEF$:: ..
	CALL CHAR(CH,DEF$):: ..
NEXT I

CLOSE #1

Restart:
PRECON=1:: ..
CRECON=1:: ..
GUARDTANK=0:: ..
GATEFLAG=0:: ..
GAMETURN=0:: ..
OCOUNT=0

// Load scenario

DISPLAY AT(10,1)BEEP:"PLEASE ENTER SCENARIO NAME":: ..
ACCEPT AT(12,5)VALIDATE(UALPHA,DIGIT,"_")SIZE(10):FNAME$
OPEN #1:"DSK1."&FNAME$,INTERNAL,INPUT

CALL CLEAR

FOR I=1 TO 10:: ..
	INPUT #1:DESC$:: ..
	DISPLAY AT(6+I,3):DESC$:: ..
NEXT I

DISPLAY AT(24,2)BEEP:"PRESS ANY KEY TO CONTINUE"
GOSUB WaitForKey

INPUT #1:PLAINFLAG,OBJCOUNT

CALL CLEAR

DISPLAY AT(23,3):"LOADING. PLEASE WAIT..."

IF PLAINFLAG=1 THEN ..
	BCOLOR=4:: ..
	CALL COLOR(9,13,4)..
ELSE ..
	BCOLOR=12:: ..
	CALL COLOR(9,2,12)
	
CALL COLOR(10,7,BCOLOR,11,5,BCOLOR,12,15,BCOLOR,13,2,BCOLOR,14,14,BCOLOR)

CALL HCHAR(1,1,110,32):: ..
CALL VCHAR(2,1,110,20):: ..
CALL HCHAR(21,2,110,30):: ..
CALL VCHAR(2,32,110,20)

FOR I=2 TO 20:: ..
	CALL HCHAR(I,2,96,30):: ..
NEXT I

FOR I=1 TO OBJCOUNT STEP 3
	INPUT #1:X,Y,CH
	IF CH=140 THEN ..
		CH=96 
				
	IF CH=104 THEN ..
		TARGETX=X:: ..
		TARGETY=Y
			
	CALL HCHAR(Y,X,CH)
NEXT I

FOR ID=1 TO 10
	FOR N=1 TO 13
		INPUT #1:PTANK(ID,N):: ..
		INPUT #1:CTANK(ID,N):: ..
		IF N=3 THEN ..
			PINITMOVE(ID)=PTANK(ID,3):: ..
			CINITMOVE(ID)=CTANK(ID,3)
	NEXT N
NEXT ID

FOR I=1 TO 11:: ..
	INPUT #1:TTYPE$(I):: ..
NEXT I

CLOSE #1

// Reconnaissance phase

PlayerRecon:
GAMETURN=GAMETURN+1:: ..

IF PRECON=0 THEN ..
	GOTO ComputerRecon
	
GOSUB ClearTextArea:: ..
DISPLAY AT(23,2)BEEP:"RECON AVAILABLE: LAUNCH?":: ..
GOSUB WaitForKey

IF K<>89 THEN ..
	ComputerRecon

PRECON=0

GOSUB ClearTextArea:: ..

CALL SPRITE(#1,107,5,80,8,0,10):: ..

GOSUB CheckFlak

PlayerFly:
CALL POSITION(#1,Y,X):: ..
CALL SOUND(100,-3,0)

IF FLAKHIT=1 AND X>=118 AND X<=138 THEN ..
	GOSUB ReconDestroyed:: ..
	GOTO ComputerRecon
	
IF X<248 THEN ..
	GOTO PlayerFly
	
CALL DELSPRITE(#1)

FOR ID=1 TO 10
	IF CTANK(ID,11)=0 OR CTANK(ID,9)=97 THEN ..
		DeadComputerTank
	CTANK(ID,10)=1:: ..
	CALL HCHAR(CTANK(ID,2),CTANK(ID,1),CTANK(ID,13)+136)
DeadComputerTank:
NEXT ID
	
ComputerRecon:
IF CRECON=0 OR GAMETURN<6 THEN ..
	PlayerMove

VISIBLECNT=0
FOR ID=1 TO 10:: ..
	IF PTANK(ID,10)=1 AND PTANK(ID,11)=1 THEN ..
		VISIBLECNT=VISIBLECNT+1
NEXT ID
IF VISIBLECNT>3 THEN ..
	PlayerMove
	
GOSUB ClearTextArea

DISPLAY AT(23,4)BEEP:"ENEMY RECON AIRBORNE!":: ..
CALL SPRITE(#1,108,5,80,248,0,-10):: ..
CRECON=0:: ..
CRECONFLAG=1

GOSUB CheckFlak

ComputerFly:
CALL POSITION(#1,Y,X):: ..
CALL SOUND(100,-3,0)

IF FLAKHIT=1 AND X>=118 AND X<=138 THEN ..
	GOSUB ReconDestroyed:: ..
	GOTO PlayerMove

IF X>8 THEN ..
	GOTO ComputerFly
	
CALL DELSPRITE(#1):: ..

FOR ID=1 TO 10
	IF PTANK(ID,11)=1 AND PTANK(ID,9)<>97 THEN ..
		PTANK(ID,10)=1
NEXT ID

// Player movement phase

PlayerMove:	
GOSUB ClearTextArea
DISPLAY AT(23,2)BEEP:"PLEASE PLOT YOUR TANK MOVES":: ..
GOSUB Delay

ID=1:: ..
CALL SPRITE(#1,105,10,200,1):: ..

GOSUB FindNextAliveTank

SelectTank:
CALL LOCATE(#1,PTANK(ID,2)*8-7,PTANK(ID,1)*8-7):: ..
CALL TANKSTAT(PTANK(,),TTYPE$(),ID)

GetAnotherKey:
GOSUB WaitForKey

IF K<>13 AND K<>83 AND K<>68 AND K<>12 THEN ..
	GetAnotherKey
	
IF K=13 THEN ..
	TankSelected
	
IF K=12 THEN ..
	CALL LOCATE(#1,200,1):: ..
	GOTO ComputerMove
	
IF K<>68 THEN ..
	PreviousTank
	
NextID:
ID=ID+1
IF ID>10 THEN ..
	ID=FIRSTALIVE
IF PTANK(ID,11)=0 THEN ..
	NextID
	
GOTO SelectTank

PreviousTank:
ID=ID-1
IF ID<FIRSTALIVE THEN ..
	ID=10
IF PTANK(ID,11)=0 THEN ..
	PreviousTank
	
GOTO SelectTank

TankSelected:
IF PTANK(ID,3)=0 THEN ..
	GetAnotherKey
	
CALL COLOR(#1,5)
MVTCOUNT=0

GetAnotherKey1:
GOSUB WaitForKey
IF K<>83 AND K<>68 AND K<>69 AND K<>13 AND K<>6 THEN ..
	GetAnotherKey1

IF K<>13 THEN ..
	MoveForward ..
ELSE ..
	CALL COLOR(#1,10):: ..
	GOTO GetAnotherKey
	
MoveForward:
IF K<>69 THEN ..
	RotateLeft
	
CALL TERRAIN(PTANK(ID,1)+XO(PTANK(ID,13)+1),PTANK(ID,2)+YO(PTANK(ID,13)+1),COST,NEWTER,1)
IF COST=0 OR PTANK(ID,3)-COST<0 THEN ..
	GetAnotherKey1

X=PTANK(ID,1)+XO(PTANK(ID,13)+1):: ..
Y=PTANK(ID,2)+YO(PTANK(ID,13)+1)

CALL HIDDEN(X,Y,HFLAG,DID)
IF HFLAG=1 THEN ..
	CALL HCHAR(CTANK(DID,2),CTANK(DID,1),136+CTANK(DID,13)):: ..
	CTANK(DID,10)=1:: ..
	GOTO GetAnotherKey1
	
GOSUB UpdateMoveHistory:: ..

PTANK(ID,3)=PTANK(ID,3)-COST

CALL LOCATE(#1,Y*8-7,X*8-7)
CALL HCHAR(PTANK(ID,2),PTANK(ID,1),PTANK(ID,9))
CALL GCHAR(Y,X,C):: ..
CALL HCHAR(Y,X,PTANK(ID,13)+128)
DISPLAY AT (23,4)SIZE(3):USING "#.#":PTANK(ID,3)
DISPLAY AT(23,22):"  TER:";CHR$(C)

PTANK(ID,1)=X:: ..
PTANK(ID,2)=Y:: ..
PTANK(ID,9)=NEWTER

GOTO GetAnotherKey1

RotateLeft:
IF K<>83 THEN ..
	RotateRight
	
IF PTANK(ID,3)=0 THEN ..
	GetAnotherKey1
	
ROTATEFLAG=1
GOSUB UpdateMoveHistory
	
PTANK(ID,13)=PTANK(ID,13)+1
IF PTANK(ID,13)>7 THEN ..
	PTANK(ID,13)=0

GOTO RotateTank

RotateRight:
IF K<>68 THEN ..
	TakeBackMove
	
ROTATEFLAG=1
GOSUB UpdateMoveHistory
	
PTANK(ID,13)=PTANK(ID,13)-1
IF PTANK(ID,13)<0 THEN ..
	PTANK(ID,13)=7
	
RotateTank:
ROTATEFLAG=0:: ..
PTANK(ID,3)=PTANK(ID,3)-0.5:: ..
CALL HCHAR(PTANK(ID,2),PTANK(ID,1),PTANK(ID,13)+128)
DISPLAY AT (23,4)SIZE(3):USING "#.#":PTANK(ID,3)

GOTO GetAnotherKey1
	
TakeBackMove:
IF MVTCOUNT=0 THEN ..
	GetAnotherKey1
	
CALL HCHAR(PTANK(ID,2),PTANK(ID,1),PTANK(ID,9)):: ..
PTANK(ID,1)=MX(MVTCOUNT)
PTANK(ID,2)=MY(MVTCOUNT):: ..
PTANK(ID,9)=MT(MVTCOUNT):: ..
PTANK(ID,3)=PTANK(ID,3)+MC(MVTCOUNT):: ..
PTANK(ID,13)=MF(MVTCOUNT)

CALL LOCATE(#1,PTANK(ID,2)*8-7,PTANK(ID,1)*8-7)
CALL GCHAR(PTANK(ID,2),PTANK(ID,1),C)
CALL HCHAR(PTANK(ID,2),PTANK(ID,1),PTANK(ID,13)+128)	
DISPLAY AT (23,4)SIZE(3):USING "#.#":PTANK(ID,3)
DISPLAY AT(23,22):"  TER:";CHR$(C)
MVTCOUNT=MVTCOUNT-1

GOTO GetAnotherKey1

// Computer movement phase

ComputerMove:
CALL COLOR(#1,5):: ..
GOSUB ClearTextArea
DISPLAY AT(23,2)BEEP:"ENEMY IS PLOTTING MOVEMENT"

GOSUB ComputerLOSCheck

IF GATEFLAG=1 THEN ..
	SearchForEnemyTanks

FOR X=-3 TO 3
	IF TARGETX+X>31 THEN ..
		NextX
	FOR Y=-3 TO 3
		IF(TARGETY+Y>20) OR (TARGETY+Y<2) THEN ..
			NextY
		CALL GCHAR(TARGETY+Y,TARGETX+X,CH):: ..
		IF CH>127 AND CH<136 THEN ..
			GOSUB EnemyAtGate:: ..
			GATEFLAG=1:: ..
			GOTO SearchForEnemyTanks
	NextY:
	NEXT Y
NextX:
NEXT X

IF GUARDTANK<>0 THEN ..
	IF CTANK(GUARDTANK,11)=1 THEN ..
		SearchForEnemyTanks

FDIST=1000
FOR CID=1 TO 10
	IF CTANK(CID,11)=0 THEN ..
		NextTank1
		
	DIST=(CTANK(CID,1)-TARGETX)^2+(CTANK(CID,2)-TARGETY)^2
	
	IF DIST<FDIST THEN ..
		GUARDTANK=CID:: ..
		FDIST=DIST

NextTank1:
NEXT CID

SearchForEnemyTanks:

FOR CID=1 TO 10
	IF CTANK(CID,11)=0 THEN ..
		NextFriendlyTank
		
	IF CTANK(CID,10)=1 THEN ..
		GOSUB MarkTank:: ..
		CALL TANKSTAT(CTANK(,),TTYPE$(),CID)
		
	IF CTANK(CID,1)<15 THEN ..
		TooFar
	
	FDIST=1000:: ..
	CLOSEST=0
	
	FOR PID=1 TO 10
		IF PTANK(PID,10)=0 OR PTANK(PID,11)=0 THEN ..
			EnemyTankNotVisible
		
		DIST=(CTANK(CID,1)-PTANK(PID,1))^2+(CTANK(CID,2)-PTANK(PID,2))^2
		
		IF DIST>=FDIST THEN ..
			EnemyTankNotVisible
		
		IF TARGETCOUNT(PID)>1 THEN ..
			EnemyTankNotVisible
			
		FDIST=DIST:: ..
		CLOSEST=PID
		
	EnemyTankNotVisible:
	NEXT PID
	
	IF CLOSEST<>0 THEN ..
		TargetFound
		
	IF GUARDTANK=CID THEN ..
		NextFriendlyTank
		
	IF CTANK(CID,9)<>97 AND (CTANK(CID,13)<3 OR CTANK(CID,13)>5) THEN ..
		UntargetedMove
		
	GOTO CheckForestEdge
		
	TooFar:
	CALL DIRECTMOVE(CTANK(CID,1),CTANK(CID,2),CTANK(CID,3),CTANK(CID,13),CTANK(CID,9),CTANK(CID,10),TARGETX,TARGETY)
	GOTO NextFriendlyTank
		
	CheckForestEdge:
	IF CTANK(CID,9)<>97 THEN ..
		LookForForest
		
	FACING=CTANK(CID,13)
	IF FACING=3 THEN ..
		DY=-1 ..
	ELSE ..
		IF FACING=4 THEN ..
			DY=0 ..
		ELSE ..
			DY=1
	
	CALL GCHAR(CTANK(CID,2)+DY,CTANK(CID,1)-1,CH)
	IF CH<>97 THEN ..
		NextFriendlyTank
	
	CALL DIRECTMOVE(CTANK(CID,1),CTANK(CID,2),CTANK(CID,3),CTANK(CID,13),CTANK(CID,9),CTANK(CID,10),CTANK(CID,1)-1,CTANK(CID,2)+DY)
	GOTO NextFriendlyTank
			
	LookForForest:
	FOR X=-1 TO -3 STEP -1
		FOR Y=-2 TO 2
			IF CTANK(CID,2)+Y<2 OR CTANK(CID,2)+Y>20 THEN ..
				NextYPos
			CALL GCHAR(CTANK(CID,2)+Y,CTANK(CID,1)+X,C)
			IF C<>97 THEN ..
				NextYPos
				
			CALL DIRECTMOVE(CTANK(CID,1),CTANK(CID,2),CTANK(CID,3),CTANK(CID,13),CTANK(CID,9),CTANK(CID,10),CTANK(CID,1)+X,CTANK(CID,2)+Y)
			GOTO NextFriendlyTank
			
		NextYPos:
		NEXT Y
	NEXT X
		
	UntargetedMove:
	CALL GCHAR(CTANK(CID,2),CTANK(CID,1)-1,C):: ..
	IF C<>96 AND C<>97 AND C<>120 OR (C=120 AND CTANK(CID,3)<3) THEN .. 
		X=TARGETX:: ..
		Y=TARGETY ..
	ELSE ..
		X=CTANK(CID,1)-6:: ..
		Y=CTANK(CID,2)
		
	CALL DIRECTMOVE(CTANK(CID,1),CTANK(CID,2),CTANK(CID,3),CTANK(CID,13),CTANK(CID,9),CTANK(CID,10),X,Y)
	GOTO NextFriendlyTank
	
	TargetFound:
	TARGETTANK(CID)=CLOSEST:: ..
	TARGETCOUNT(CLOSEST)=TARGETCOUNT(CLOSEST)+1
	CALL DIRECTMOVE(CTANK(CID,1),CTANK(CID,2),CTANK(CID,3),CTANK(CID,13),CTANK(CID,9),CTANK(CID,10),PTANK(CLOSEST,1),PTANK(CLOSEST,2)) 
		
NextFriendlyTank:
NEXT CID	

GOSUB DetermineLOS

// Fire phase

PCOMBATFLAG=0:: ..
CCOMBATFLAG=0

IF RND<=0.5 THEN ..
	GOTO FirePhase ..
ELSE ..
	GOTO ComputerCombat

FirePhase:
// Player combat phase

PCOMBATFLAG=1:: ..
CID=1
KeepSearching:
IF CTANK(CID,10)=0 OR CTANK(CID,11)=0 THEN ..
	CID=CID+1:: ..
	IF CID>10 THEN ..
		Cleanup ..
	ELSE ..
		KeepSearching

GOSUB ClearTextArea
DISPLAY AT(22,5)BEEP:"UNITS READY TO FIRE"
DISPLAY AT(23,7):"AT YOUR COMMAND!"
GOSUB Delay:: ..
GOSUB ClearTextArea

ID=1
GOSUB FindNextAliveTank
IF ID>10 THEN ..
	CheckVictory

CALL LOCATE(#1,200,1):: ..
CALL COLOR(#1,7)	

DisplayCombatTank:
CALL LOCATE(#2,PTANK(ID,2)*8-7,PTANK(ID,1)*8-7):: ..
CALL TANKSTAT(PTANK(,),TTYPE$(),ID)

ScanForKey:
GOSUB WaitForKey

IF K=13 THEN ..
	CombatTankSelected
	
IF K=68 THEN ..
	NextCombatTank
	
IF K=83 THEN ..
	PreviousCombatTank
	
IF K=12 THEN ..
	IF CCOMBATFLAG=0 THEN ..
		ComputerCombat ..
	ELSE ..
		Cleanup
	
GOTO ScanForKey

NextCombatTank:
ID=ID+1:: ..
IF ID>10 THEN ..
	ID=FIRSTALIVE
	
IF PTANK(ID,11)=0 THEN ..
	NextCombatTank
	
GOTO DisplayCombatTank

PreviousCombatTank:
ID=ID-1:: ..
IF ID<FIRSTALIVE THEN ..
	ID=10
	
IF PTANK(ID,11)=0 THEN ..
	PreviousCombatTank
	
GOTO DisplayCombatTank

CombatTankSelected:
IF COMBATFLAG(ID)=1 THEN ..
	ScanForKey
	
CALL COLOR(#2,5)

CID=1

AliveCTank:
IF CTANK(CID,11)=0 OR CTANK(CID,10)=0 THEN ..
	CID=CID+1:: ..
	GOTO AliveCTank
	
CFIRSTALIVE=CID
	
SelectComputerTank:	
CALL LOCATE(#1,CTANK(CID,2)*8-7,CTANK(CID,1)*8-7):: ..
CALL TANKSTAT(CTANK(,),TTYPE$(),CID)

ScanForAKey:
GOSUB WaitForKey

IF K=32 THEN ..
	NextTarget

IF K=70 THEN ..
	PlayerFire
	
IF K=13 THEN ..
	CALL LOCATE(#1,200,1):: ..
	CALL COLOR(#2,10):: ..
	GOTO DisplayCombatTank
	
GOTO ScanForAKey

NextTarget:
CID=CID+1:: ..
IF CID>10 THEN ..
	CID=CFIRSTALIVE
IF CTANK(CID,11)=0 OR CTANK(CID,10)=0 THEN ..
	NextTarget
	
GOTO SelectComputerTank

PlayerFire:
CALL BALLISTICS(PTANK(ID,1),PTANK(ID,2),CTANK(CID,1),CTANK(CID,2),PTANK(ID,5),CTANK(CID,13),HFACING,HIT,HITMOD)
GOSUB ClearTextArea

IF HIT=0 THEN ..
	DISPLAY AT(23,5)BEEP:"NO LINE OF SIGHT!" ..
ELSE IF HIT=1 THEN ..
		DISPLAY AT(23,4)BEEP:"ENEMY OUT OF RANGE!" ..
	 ELSE ..
		TargetInRange

GOSUB Delay:: ..
GOSUB ClearTextArea:: ..
GOTO ScanForAKey
	
TargetInRange:
IF HIT=2 THEN ..
	CALL SOUND(300,-7,0):: ..
	DISPLAY AT(23,7):"TARGET MISSED!":: ..
	GOSUB Delay:: ..
	COMBATFLAG(ID)=1:: ..
	GOTO TankFired
	
IF PTANK(ID,4)*(1-HITMOD)>CTANK(CID,HFACING) THEN ..
	TankDestroyed

CALL SOUND(300,-7,0):: ..
DISPLAY AT(23,2):"ARMOR PENETRATION FAILED!":: ..
GOSUB Delay:: ..
COMBATFLAG(ID)=1:: ..
GOTO TankFired

TankDestroyed:	
CALL SOUND(1000,-7,0)

CALL HCHAR(CTANK(CID,2),CTANK(CID,1),106):: ..
DISPLAY AT(23,3):"ENEMY TANK DESTROYED!":: ..
CTANK(CID,11)=0:: ..
GOSUB Delay:: ..
CALL HCHAR(CTANK(CID,2),CTANK(CID,1),109)

COMBATFLAG(ID)=1

TankFired:
CALL LOCATE(#1,200,1):: ..
CALL COLOR(#2,10):: ..
GOTO DisplayCombatTank

// Computer combat phase

ComputerCombat:	
CALL LOCATE(#1,200,1,#2,200,1):: ..
CALL COLOR(#1,5,#2,7)

CCOMBATFLAG=1

PID=1
CheckPlayerVisibility:
IF PTANK(PID,10)=0 OR PTANK(PID,11)=0 THEN ..
	PID=PID+1 ..
ELSE ..
	CombatPossible
	
IF PID>10 THEN ..
	CheckPlayerPhase ..
ELSE ..
	CheckPlayerVisibility

CombatPossible:	
GOSUB ClearTextArea:: ..
DISPLAY AT(22,4)BEEP:"ENEMY IS CALCULATING":: ..
DISPLAY AT(23,5):"FIRING SOLUTIONS!":: ..

FOR CID=1 TO 10
	IF CTANK(CID,11)=0 OR TARGETTANK(CID)=0 THEN ..
		NotFired ..
	ELSE ..
		PID=TARGETTANK(CID)
		
	IF PTANK(PID,11)=0 THEN ..
		NotFired
		
	IF CTANK(CID,10)=0 THEN ..
		CheckFireResult
		
	CALL LOCATE(#1,CTANK(CID,2)*8-7,CTANK(CID,1)*8-7,#2,PTANK(PID,2)*8-7,PTANK(PID,1)*8-7)
	CALL TANKSTAT(CTANK(,),TTYPE$(),CID):: ..
	GOSUB ClearTextArea
	
CheckFireResult:	
	CALL BALLISTICS(CTANK(CID,1),CTANK(CID,2),PTANK(PID,1),PTANK(PID,2),CTANK(CID,5),PTANK(PID,13),HFACING,HIT,HITMOD)
	IF HIT<2 THEN ..
		NotFired
	
	IF HIT=2 THEN ..
		CALL SOUND(300,-7,0):: ..
		DISPLAY AT(23,7):"TARGET MISSED!":: ..
		GOTO Fired
	
	IF CTANK(CID,4)*(1-HITMOD)<=PTANK(PID,HFACING) THEN ..
		CALL SOUND(300,-7,0):: ..
		DISPLAY AT(23,2):"ARMOR PENETRATION FAILED!":: ..
		GOTO Fired
		
	CALL SOUND(1000,-7,0)
	CALL HCHAR(PTANK(PID,2),PTANK(PID,1),106)
	DISPLAY AT(23,2):"YOUR TANK WAS DESTROYED!":: ..
	PTANK(PID,11)=0:: ..
	CALL HCHAR(PTANK(PID,2),PTANK(PID,1),109)
	IF PTANK(PID,1)=TARGETX AND PTANK(PID,2)=TARGETY THEN ..
		GOSUB Delay:: ..
		CALL HCHAR(TARGETY,TARGETX,104)
		
Fired:
CALL HCHAR(CTANK(CID,2),CTANK(CID,1),CTANK(CID,13)+136)
NotFired:
GOSUB Delay:: ..
GOSUB ClearTextArea:: ..


NEXT CID

CheckPlayerPhase:
IF PCOMBATFLAG=0 THEN ..
	FirePhase
	
Cleanup:
FOR ID=1 TO 10:: ..
	CTANK(ID,3)=CINITMOVE(ID):: ..
	PTANK(ID,3)=PINITMOVE(ID):: ..
	TARGETTANK(ID)=0:: ..
	TARGETCOUNT(ID)=0:: ..
	COMBATFLAG(ID)=0:: ..
NEXT ID

CALL LOCATE(#1,200,1,#2,200,1)

// Check for victory conditions

CheckVictory:
PCOUNT=0:: ..
CCOUNT=0

GOSUB ClearTextArea

CALL GCHAR(TARGETY,TARGETX,C):: ..
IF C>127 AND C<137 THEN ..
	OCOUNT=OCOUNT+1 ..
ELSE ..
	OCOUNT=0

FOR ID=1 TO 10:: ..
	IF PTANK(ID,11)=0 THEN ..
		PCOUNT=PCOUNT+1
	IF CTANK(ID,11)=0 THEN ..
		CCOUNT=CCOUNT+1
NEXT ID

IF PCOUNT=10 AND CCOUNT=10 THEN ..
	DISPLAY AT(10,3)BEEP:"THE BATTLE IS A DRAW!":: ..
	GOTO PlayAgain
	
IF PCOUNT=10 THEN ..
	DISPLAY AT(10,1)BEEP:"THE ENEMY HAS WON THE DAY!!!":: ..
	GOTO PlayAgain
	
IF CCOUNT=10 OR OCOUNT=3 THEN ..
	DISPLAY AT(10,1)BEEP:"YOU HAVE WON THE BATTLE!!!":: ..
	GOTO PlayAgain ..	
ELSE ..
	PlayerRecon

PlayAgain:
GOSUB Delay:: ..
DISPLAY AT(23,1)BEEP:"DO YOU WISH TO PLAY AGAIN?":: ..
GOSUB WaitForKey

IF K<>89 THEN ..
	STOP ..
ELSE ..
	CALL CLEAR:: ..
	CALL DELSPRITE(ALL):: ..
	GOTO Restart

// Data

Data:
DATA 1,0,1,-1,0,-1,-1,-1,-1,0,-1,1,0,1,1,1	
	
// Subroutines

// Key scan subroutine 

WaitForKey:
CALL KEY(0,K,S):: ..
IF S=0 THEN WaitForKey
RETURN

// Clear text area subroutine

ClearTextArea:
DISPLAY AT(22,1):RPT$(" ",28):: ..
DISPLAY AT(23,1):RPT$(" ",28):: ..
DISPLAY AT(24,1):RPT$(" ",28):: ..
RETURN

// Check for flak hit subroutine

CheckFlak:
FLAKHIT=0

IF RND<=0.25 THEN ..
	FLAKHIT=1

RETURN

// Recon plane destroyed routine

ReconDestroyed:
CALL SPRITE(#1,106,9,Y,X,0,0):: ..
CALL SOUND(1000,-7,0)
DISPLAY AT(23,4):"RECON PLANE SHOT DOWN!":: ..
GOSUB Delay:: ..
CALL DELSPRITE(#1):: ..
GOSUB ClearTextArea

RETURN
	

// Delay subroutine

Delay:
FOR DELAY=1 TO 500:: ..
NEXT DELAY

RETURN

// Line of sight dertermination for both sides

DetermineLOS:
GOSUB ClearTextArea
DISPLAY AT(23,3)BEEP:"CHECKING LINE OF SIGHT"

FOR ID=1 TO 10:: ..
	CTANK(ID,10)=0:: ..
	PTANK(ID,10)=0:: ..
NEXT ID
	
FOR PID=1 TO 10
	IF PTANK(PID,11)=0 THEN ..
		DoneOuterLoopPlayer
	FOR CID=1 TO 10
		IF CTANK(CID,11)=0 THEN ..
			DoneInnerLoopPlayer
		IF CTANK(CID,9)=97 THEN ..
			CTANK(CID,10)=0:: ..
			GOTO DoneInnerLoopPlayer
		CALL LOS((PTANK(PID,1)),(PTANK(PID,2)),CTANK(CID,1),CTANK(CID,2),VISIBLE)
		IF VISIBLE=1 THEN ..
			CTANK(CID,10)=1
	DoneInnerLoopPlayer:
	NEXT CID
DoneOuterLoopPlayer:
NEXT PID

GOSUB AdjustForLOS

ComputerLOSCheck:
CALL LOCATE(#1,200,1)
	
FOR CID=1 TO 10
	IF CTANK(CID,11)=0 THEN ..
		DoneOuterLoopComputer
	FOR PID=1 TO 10
		IF PTANK(PID,11)=0 THEN ..
			DoneInnerLoopComputer
		IF PTANK(PID,9)=97 THEN ..
			PTANK(PID,10)=0:: ..
			GOTO DoneInnerLoopComputer
		IF CRECONFLAG=1 THEN ..
			PTANK(PID,10)=1:: ..
			GOTO DoneInnerLoopComputer
		CALL LOS((CTANK(CID,1)),(CTANK(CID,2)),PTANK(PID,1),PTANK(PID,2),VISIBLE)
		IF VISIBLE=1 THEN ..
			PTANK(PID,10)=1
	DoneInnerLoopComputer:
	NEXT PID
DoneOuterLoopComputer:
NEXT CID
CRECONFLAG=0

RETURN

// Update player movement history routine

UpdateMoveHistory:
MVTCOUNT=MVTCOUNT+1:: ..
MX(MVTCOUNT)=PTANK(ID,1):: ..
MY(MVTCOUNT)=PTANK(ID,2):: ..
MT(MVTCOUNT)=PTANK(ID,9)
IF ROTATEFLAG=0 THEN ..
	MC(MVTCOUNT)=COST ..
ELSE ..
	MC(MVTCOUNT)=0.5
MF(MVTCOUNT)=PTANK(ID,13)

RETURN

// Adjust computer tank visibility per LOS

AdjustForLOS:
FOR ID=1 TO 10

	IF CTANK(ID,10)=1 AND CTANK(ID,11)=1 THEN ..
		CALL HCHAR(CTANK(ID,2),CTANK(ID,1),136+CTANK(ID,13)):: ..
		GOTO NextComputerTank
		
	IF CTANK(ID,11)=1 THEN ..
		CALL HCHAR(CTANK(ID,2),CTANK(ID,1),CTANK(ID,9))

NextComputerTank:		
NEXT ID

RETURN

// Protect target routine

EnemyAtGate:
GUARDTANK=0

FOR CID=1 TO 10
	IF CTANK(CID,11)=0 THEN ..
		NextTank
		
	IF CTANK(CID,10)=1 THEN ..
		GOSUB MarkTank:: ..
		CALL TANKSTAT(CTANK(,),TTYPE$(),CID)
		
	CALL DIRECTMOVE(CTANK(CID,1),CTANK(CID,2),CTANK(CID,3),CTANK(CID,13),CTANK(CID,9),CTANK(CID,10),TARGETX,TARGETY)
	
NextTank:
NEXT CID

RETURN 

// Mark active computer tank routine

MarkTank:
CALL LOCATE(#1,CTANK(CID,2)*8-7,CTANK(CID,1)*8-7):: ..

RETURN

// Find the next alive player tank

FindNextAliveTank:
IF PTANK(ID,11)=0 THEN ..
	ID=ID+1:: ..
	IF ID>10 THEN ..
		RETURN ..
	ELSE ..
		GOTO FindNextAliveTank
		
FIRSTALIVE=ID

RETURN

// Line of sight subroutine

SUB LOS(X1,Y1,X2,Y2,V)

DIST=SQR(((X2-X1)^2)+((Y2-Y1)^2))
	
IF DIST>10 THEN ..
	V=0:: ..
	SUBEXIT
	
IF DIST<1.42 THEN ..
	V=1:: ..
	SUBEXIT
	
DX = ABS(X2 - X1):: ..
SX = -1:: ..
IF X1 < X2 THEN ..
	SX = 1
	
DY = ABS(Y2 - Y1):: ..
SY = -1:: ..
IF Y1 < Y2 THEN ..
	SY = 1
	
ER = -DY:: ..
IF DX > DY THEN ..
	ER = DX
ER = INT(ER / 2)

NextPlotPoint:
E2 = ER

IF E2 > -DX THEN ..
	ER = ER - DY:: ..
	X1 = X1 + SX
	
IF E2 < DY THEN ..
	ER = ER + DX:: ..
	Y1 = Y1 + SY
	
IF X1=X2 AND Y1=Y2 THEN ..
	V=1:: ..
	SUBEXIT
	
CALL GCHAR(Y1,X1,CH):: ..
IF CH<>96 AND CH<>112 AND CH<>113 AND CH<>114 AND CH<>115 AND CH<>104 THEN ..
	V=0:: ..
	SUBEXIT

GOTO NextPlotPoint

SUBEND

// Terrain movement costs subroutine

SUB TERRAIN(TX,TY,COST,C,SIDE)

COST=0

IF TX<2 OR TX>31 OR TY<2 OR TY>20 THEN ..
	SUBEXIT
	
CALL GCHAR(TY,TX,C)

IF C=96 OR C=104 THEN ..
	COST=1:: ..
	SUBEXIT
	
IF C=120 THEN ..
	COST=3:: ..
	SUBEXIT
	 
IF C=97 THEN ..
	COST=2:: ..
	SUBEXIT
	
SUBEND
	
// Computer tank targeted movement routine
	
SUB DIRECTMOVE(X,Y,MVT,FACING,TER,VISIBLE,OBJX,OBJY)

ContinueMovement:
IF MVT=0 THEN ..
	SUBEXIT
	
IF X<OBJX THEN ..
	DX=1 ..
ELSE ..
	IF X>OBJX THEN ..
		DX=-1 ..
	ELSE ..
		DX=0
			
IF Y<OBJY THEN ..
	DY=1 ..
ELSE ..
	IF Y>OBJY THEN ..
		DY=-1 ..
	ELSE ..
		DY=0
	
CheckPath:
CALL HIDDEN(X+DX,Y+DY,HFLAG,ID)
CALL GCHAR(Y+DY,X+DX,CH)
IF (CH>127 AND CH<144) OR (CH>111 AND CH<116) OR CH=109 OR CH=104 OR HFLAG=1 THEN ..
	BlockedPath ..
ELSE ..
	OpenPath
		
BlockedPath:
IF RND>0.5 THEN ..
	DY=1 ..
ELSE ..
	DY=-1
	
IF RND>0.5 THEN ..
	DX=1 ..
ELSE ..
	DX=-1
	
GOTO CheckPath
	
OpenPath:		
ON ABS(DX+DY)+1 GOTO Diagonal1,Cartesian,Diagonal2

Diagonal1:
IF DY=-1 THEN ..
	DF=1 ..
ELSE ..
	DF=5
GOTO AdjustFacing

Cartesian:
IF DY=0 THEN ..
	Horizontal
IF DY=-1 THEN ..
	DF=2 ..
ELSE ..
	DF=6
GOTO AdjustFacing

Horizontal:
IF DX=-1 THEN ..
	DF=4 ..
ELSE ..
	DF=0
GOTO AdjustFacing

Diagonal2:
IF DY=-1 THEN ..
	DF=3 ..
ELSE ..
	DF=7
	
AdjustFacing:
IF FACING=DF THEN ..
	MoveTank

IF ABS(DF-FACING)=4 THEN ..
	FACING=FACING+1

IF ABS(DF-FACING)<4 THEN ..
	IF DF>FACING THEN ..
		FACING=FACING+1 ..
	ELSE ..
		FACING=FACING-1
		
IF ABS(DF-FACING)>4 THEN ..
	IF DF>FACING THEN ..
		FACING=FACING-1 ..
	ELSE ..
		FACING=FACING+1
		
IF FACING>7 THEN ..
	FACING=0 ..
ELSE ..
	IF FACING<0 THEN ..
		FACING=7

MVT=MVT-0.5
IF VISIBLE=1 THEN ..
	CALL HCHAR(Y,X,FACING+136):: ..
	DISPLAY AT (23,4)SIZE(3):USING "#.#":MVT
GOTO ContinueMovement
	
MoveTank:
CALL TERRAIN(X+DX,Y+DY,COST,C,2)
IF MVT-COST<0 THEN ..
	SUBEXIT

CALL HCHAR(Y,X,TER):: ..	
MVT=MVT-COST:: ..
X=X+DX:: ..
Y=Y+DY:: ..
TER=C
IF VISIBLE=0 THEN ..
	ContinueMovement

CALL HCHAR(Y,X,FACING+136):: ..
CALL LOCATE(#1,Y*8-7,X*8-7)
DISPLAY AT (23,4)SIZE(3):USING "#.#":MVT
DISPLAY AT(23,22):"  TER:";CHR$(C)

	
GOTO ContinueMovement
		
SUBEND

// Check if projected move square empty

SUB HIDDEN(X,Y,HFLAG,ID)

HFLAG=0

FOR ID=1 TO 10
	IF (CTANK(ID,1)=X AND CTANK(ID,2)=Y) OR (PTANK(ID,1)=X AND PTANK(ID,2)=Y) THEN ..
		HFLAG=1:: ..
		SUBEXIT	
NEXT ID

SUBEND

// Ballistics calculations routine

SUB BALLISTICS(X1,Y1,X2,Y2,GRANGE,DFACING,HFACING,HIT,HITMOD)

CALL LOS((X1),(Y1),X2,Y2,V)
IF V=0 THEN ..
	HIT=0:: ..
	SUBEXIT

DIST=SQR((X1-X2)^2+(Y1-Y2)^2)
IF DIST>GRANGE THEN ..
	HIT=1:: ..
	SUBEXIT

IF RND>=(DIST*3/GRANGE)*0.15 THEN ..
	HIT=3:: ..
	HITMOD=DIST/GRANGE*0.30:: ..
	GOTO HitAngle
	
HIT=2:: ..
SUBEXIT
	
HitAngle:
DX=X2-X1:: ..
DY=Y2-Y1

IF DX=0 THEN ..
	IF DY>0 THEN ..
		AANGLE=270 ..
	ELSE ..
		AANGLE=90
		
IF DY=0 THEN ..
	IF DX>0 THEN ..
		AANGLE=0 ..
	ELSE ..
		AANGLE=180
		
DANGLE=DFACING*45

IF DX=0 OR DY=0 THEN ..
	FinalHitAngle

AANGLE=INT(ATN(DY/DX)*180/PI)

IF DX<0 AND DY>0 THEN ..
	AANGLE=ABS(AANGLE)+180:: ..
	DANGLE=DANGLE+180
	
IF DX<0 AND DY<0 THEN ..
	AANGLE=ABS(AANGLE)+90:: ..
	DANGLE=DANGLE+180
	
IF DX>0 AND DY>0 THEN ..
	AANGLE=ABS(AANGLE)+270:: ..
	DANGLE=DANGLE+360
		
FinalHitAngle:
HANGLE=ABS(AANGLE-DANGLE)

IF HANGLE<=15 OR HANGLE>345 THEN ..
	HFACING=8:: ..
	SUBEXIT
	
IF HANGLE>164 AND HANGLE<196 THEN ..
	HFACING=6:: ..
	SUBEXIT
	
HFACING=7

SUBEND

// Display tank statistics

SUB TANKSTAT(TANK(,),TTYPE$(),ID)

GOSUB ClearTextArea

DISPLAY AT(22,1)BEEP:"TANK: ";TTYPE$(TANK(ID,12))
DISPLAY AT(23,1):"M:"
DISPLAY AT (23,4):USING "#.#":TANK(ID,3)
DISPLAY AT(23,:"  R:";TANK(ID,5);" P:";TANK(ID,4)
DISPLAY AT(23,22):"  TER:";CHR$(TANK(ID,9))
DISPLAY AT(24,1):"FA:";TANK(ID,6);" SA:";TANK(ID,7);" RA:";TANK(ID,

SUBEND

 

 

  • Like 1
Link to comment
Share on other sites

I have some stuff in my GOSUBs that I am a bit perplexed on how to translate.

 

Perhaps I just need to tinker.

 

On my phone here at work it is impossible to post code examples, but basically I have conditional GOTOs to different parts of other subs... Its a but of a mess, but I understand it. I have a block that first clears the screen and THEN wipes out a section of the screen that contains player data.

 

If certain conditions are met, I go to the beginning of that chunk (that clears tge whole bit) where if a different condition is met, it goes to the subsequent line number, clearing just data but leaving the screen in tact.

 

It is a bit convoluted until I can post code, and it might require a whole reorganization, then again, it may not.

 

I think when I did my Beryl menu in TIdBiT, I used something like

 

 

//Clear routine

T1: Clear Screen

T2: Clear top 4 rows

.

.

.

LATER CODE: If X=1 THEN T1 ELSE T2

 

Something like that. Ill get my code out tonight and post something meaningful.

Link to comment
Share on other sites

Owen, a quick suggestion. Labels can be very long and don't cost you anything (unlike variable names). You should use label names that are descriptive as to what is going on or what will happen, instead of seemingly meaningless names like "T1" or "T2".

 

Also, once you get things transitioned to TidBit, you should certainly find things that can and should be reorganized.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...