Jump to content
IGNORED

New 32k XB Game:ZOMBi (work in progress)


Sinphaltimus

Recommended Posts

Huge performance gains yooze geyez!

I completely rewrote all coinc routines and broke everything again but piecing it back together is revealing huge performance gains.
Right now I'm attempting to make the actual coinc more efficient.

I've pretty much got it so the entire level can be zombies and run great but as soon as any of them have a coinc=true moment, it all slows to a crawl. Which wouldn't even be noticeable if I can get it to ignore certain coincs when using (ALL,C). or at least filter out the useless COINCs detections so fast it doesn't affect performance.

Well, back to it.

  • Like 2
Link to comment
Share on other sites

Huge performance gains excitement is off set by a bug I've been hunting for 3 days now. I know it's a typo, or wrong variable being used or wrong value being stored in an array someplace. I just don't know where yet.

I'm crunching the code every second of every spare moment. *sigh* I really wanted to get this new version out to everyone. It completely revitalized my enthusiasm that this can be done in under 32k.

But I'm running out of space just writing debugging code to hunt this thing down.

Anywayz, any day now and I'll release the final alpha version just before going beta. I still need to get that new zombi "crawler" in game before beta. But that part is easy.

Edited by Sinphaltimus
Link to comment
Share on other sites

This is the second release of 0.49, first release had player stuck and only able to move left and right by jumping. This version 0.49 is fixed from that. I got too hasty in uploading that I did not test a minor change I didn't think could go wrong. It did. No worries now. Go enjoy all the work I put in to this version...


OK, Here's the >>>new ZOMBI game version 0.49 alpha<<<

 

V0.49 changes:

More code optimizations. Namely in cleaning up and reducing variables.
More source code comments.
Removed looting delay for all items.
Adjusted jump delay to discourage jump abuse.
Increased player running speed by 2 (Doubling it).
Adjusted Zombie hole collision turn around distance.
Found and removed zombi random speed change at every cycle. This code was supposed to only be present when a Zombi is created
and when a Zombi hits a hole to turn around or fall.
Fixed Melee attack animation frame issue.
Complete rework of all coinc routines resulting in huge performance gains.
Number of Zombis no longer crushes performance.
New arrays, one per loot item and one for all loot.
KNOWN ISSUES:
NOT ALL FUNCTIONALITY OR GAME MECHANICS HAVE BEEN DEVELOPED AS OF THIS VERSION.
Zombies are not doing damage to the player.
Player can hold jump button and skip across holes. I don't recall if I fixed this but it's untested so here it stays until tested.
Edited by Sinphaltimus
Link to comment
Share on other sites

Jumping to the right has frames facing left. Everything seems to slow down with more than one zombie.

 

;)

 

I now zombies aren't causing damage yet. But check out the performance now. I'm already working on 0.50. I'm going to introduce the new zombi type and that will pretty much conclude all game mechanics. It's just cleaning upand tweaking to bring the last few enhancements like level bonus' and such to the game. So once I get this new Zombi in game, it'll go BETA!

 

Yeah. So excited.

Link to comment
Share on other sites

Yes, I tried walking and was stuck. Walking animation was good though. The new version, which I almost missed, has a blank screen and irritating sounds. Downloaded twice and started Classic99 twice.

 

Old version.

 

Jumping was too fast for one to enjoy any animation (if there was any).

 

There was some smaller problems here and there. Like shots starting somewhere else or not appearing at all (may be due to more than 4 sprites horizontally).

 

Still the zombies stop, start, rush etc. I think all the smaller local delay adjustments may drive you mad. You should have one master delay, maybe attached to the frame update using CALL SOUND which I believe senior_falcon also suggested. I used it in Shooting Stars (XB source available) and have the player, shots etc. running at the same speeds while the stars appear faster and faster. I simply have counters on the master delay (add 1 per frame to a variable and test if it has reached a certain amount, if so, do some stuff and reset).

 

;)

Edited by sometimes99er
  • Like 1
Link to comment
Share on other sites

Thanks for all that info.

 

I'll get to all the issues once I get the new zombie in and go beta. I was worried about the performance issues and getting the game back to Stable state after the rewrite. 3 steps forward two steps back.

 

Coding in the fly like this (no fans plan from the start) can be both fun and very frustrating for someone nor used to it. But I'm learning a lot and challenged to get it all done in under 32k. :)

 

I'm gonna have to put all if you in the credits! :)

Edited by Sinphaltimus
  • Like 1
Link to comment
Share on other sites

Thanks for all that info.

 

Think carefully about attaching everything to one master delay. I'm not sure how GameMaker does it, apart from triggers, the overall speed of a game is timed (maybe not entirely exposed to the programmer).

 

3 steps forward two steps back.

 

Yep. When you loose control, you have to step back and rewrite stuff to make it more clear, separated and / or obvious.

 

I'm gonna have to put all if you in the credits! :)

 

It could be a long list. I think, and hope, that crediting "AtariAge" may cover tools used, useful comments etc.

 

;)

 

  • Like 1
Link to comment
Share on other sites

There was some smaller problems here and there. Like shots starting somewhere else or not appearing at all (may be due to more than 4 sprites horizontally).

Yes, this is something I've been meaning to ask about.

 

The 4 sprite per line thing. Is that per "pixel" line? I ask because I've attempted to mitigate this. The player sprite, bullet sprite and zombi sprites share y values but as far as I can see, nothing else does. I give the loot a lower y value (raising it up a little) to try and avoid this.

 

It's something I'm leaving more towards the end of development. I still have mechanics to compete and hopefully get music in too before I really dig in and clean up everything and troubleshoot a thousand times.

 

 

  • Like 1
Link to comment
Share on other sites

OMG! What the heck? Why in the world would the bin file be doing that and not the ea5 file?

Also, not sure which delays are being an issues. I use 3 delays in the game. I'm not using a sound delay method because I don't want to cause sound issues especially if I paln to add music.

EDIT1:I found a double delay in the instruction screen - that's fixed in 0.50 along with zed player COINC (typo) and I changed the jumping animation back to my original method (I changed a lot of things just for testing and some haven't been changed back). I've not yet tested the new jumping animation, if I don't get to it in a few minutes, it'll have to wait until after werk.

I am using a call link delay for the title and instruction screens because when you hit enter or move the joystick to go from title to instructions or instruction to game, the sensitivity is too tight and a player can easily go from title to playing without ever seeing the instruction screen. So I put delay after title before input accepted and a delay after instructions after the instructions for input to avoid this. That's one type of delay.

Then I put a delay for Zombi vs. Player COINC. This is to avoid a zombi killing a plpayer in seconds. It spreads out the timing between Zed attacks.

That delay is a manual counter using variables and checking certain conditions. If the player and ZED are COINC, the timer begins and continues to count as long as they remain in COINC. When it resets the Zed attacks again. The timer is also reset as soon as there is no COINC between player and ZED.

 

The final type of delay I put is a for next loop when the player starts a jump. This is to avoid jumping abuse because a player can traverse a level faster if they just jump instead of running.
I agree the jump is too fast, yes there is an animation frame in there.

In game maker, the game engine has cycles, like CPU cycles that trigger events. The event timing is under very tight control of the engine so it's important to know the order you need specific events to happen. The actual ticks that run through out control the action. Gamemaker has an actual timer function with many triggers to choose from and result to apply. I've had to pretty much unlearn gamemaker to be able to code in extended basic. There are some basic commands I wish I had in extended basic. Namely switch statements. That would make life so much easier. I also wish we had a CALL COINC(#sprtie, ALL,8,c) function. That too would maker life so much easier. But I'm for the challenge.

I honestly lost hope several times during this endeavor. Performance issues, low ram issues, all of it. I had to forget all the bad habits I picked up being an extremely messy coder (programming is something I'm learning slowly as I'm primarily a digital artist (art, animation, etc..) But I've always seemed to find a way around the limitation. It's one thing to code a retro game on a new engine and to code a retro game on original hardware (or emulation of such) so I am in completely unfamiliar territory. I owe all of it to this community helping me at every bump in the road.

 

I've never used Extended Basic prior to my joining Atari Age. As a kid in the early 80s, it was a console, a tape deck and some cartridge games and manuals. So straight up BASIC back then.

All of this, all of it, have made me a lot better than I was when I came here, a lot better in thinking about how to code in gamemaker as well. Which is something I am going to do when ready. I'm going to make a modern day equivalent to ZOMBi on the PC as a free game. And since I use GameMaker for Android as well, I will also port it to Android. But that's still a bit far off in to the future. I still have a lot of work to do on Jouncey in building 2 more worlds to complete that adventure....https://play.google.com/store/apps/details?id=org.SYMMLLC.JounceyFree


One thing I know for sure. I'm back to the TI for the long haul. I want to use it as a platform for learning assembly. I've discovered I'm no good at jumping in to the high level programming engines without intricate knowledge of the underlying processes. Mainly because, as programming goes, I'm homebrewed and not formerly educated. I often think maybe I should go for my computer science degree instead of the Game Art and Design Degree I achieved. But, my primary passion is creating art. Perhaps someday I can take a real low level programming course.

Edited by Sinphaltimus
Link to comment
Share on other sites

Yes, this is something I've been meaning to ask about.

 

The 4 sprite per line thing. Is that per "pixel" line? I ask because I've attempted to mitigate this. The player sprite, bullet sprite and zombi sprites share y values but as far as I can see, nothing else does. I give the loot a lower y value (raising it up a little) to try and avoid this.

 

It's something I'm leaving more towards the end of development. I still have mechanics to compete and hopefully get music in too before I really dig in and clean up everything and troubleshoot a thousand times.

 

Yes, is the simple answer. One horizontal line of pixels can only display up to 4 sprites. The rest is ignored. You can turn this limitation off in Classic99 and with the F18A. Could however make your game hard to play on original hardware. Having 3 sprites at horizontal line 120 and 3 sprites at 124 will still have these occupy some horizontal lines. If you operate with 8x8 pixel sprites, lines 124-127 will have 6 sprites and only 4 will show. 2 sprites will appear chopped.

 

You could place loot in the ceiling (having to jump and only checking when high), and it wouldn't then conflict with player, zombies and bullets. Even the bullets could be background characters. Bullets move fast and you could have 1 or 2 characters define the bullet (1 character moves 8 pixels and 2 characters can move 4 pixels - per something).

 

Phew. A lot of info.

 

I guess, and understand, you might want to get things working, add your other ideas, and get it like done. So taking steps back is like ... not really desirable. So for this one, you should absolutely consider ignoring the sprite limit. One day you could revisit the game and make it all more streamlined etc.

 

;)

 

Link to comment
Share on other sites

Also, not sure which delays are being an issues. I use 3 delays in the game. I'm not using a sound delay method because I don't want to cause sound issues especially if I paln to add music.

Well, maybe Harry could add a delay routine that simply waits for the next frame update. Think I read something about having music playing in 2 channels and another channel and noise for effects ?

 

Yeah, 3 delays should be manageable.

 

I am using a call link delay for the title and instruction screens because when you hit enter or move the joystick to go from title to intructions or instruction to game, the sensitivity is too tight and a player can easily go from title to playing without ever seeing the instruction screen. So I put delay after title before input accepted and a delay after instructions after the instructions for input to avoid this. That's one type of delay.

Yep. When you go from title to instructions, show the instruction, then test for joystick and keys not being pressed, then go to a routine that do test for joystick or key pressed.

 

Then I put a delay for Zombi vs. Player COINC. This is to avoid a zombi killing a plpayer in seconds. It spreads out the timing between Zed attacks.

I would have a counter for the player (and probably also one per zombie). When the counter hits 20, the player dies. When a counter hits 5, the zombie dies. No delay with COINC, but only COINC once per pixel move ... (per frame - shlt I said it again)

 

;)

Link to comment
Share on other sites

 

Yes, is the simple answer. One horizontal line of pixels can only display up to 4 sprites. The rest is ignored. You can turn this limitation off in Classic99 and with the F18A. Could however make your game hard to play on original hardware. Having 3 sprites at horizontal line 120 and 3 sprites at 124 will still have these occupy some horizontal lines. If you operate with 8x8 pixel sprites, lines 124-127 will have 6 sprites and only 4 will show. 2 sprites will appear chopped.

OOOOOOOOH!!!!!!!!!! - Wow, I assumed the same pixel line meant the top left pixel from which position is drawn.

 

You could place loot in the ceiling (having to jump and only checking when high), and it wouldn't then conflict with player, zombies and bullets. Even the bullets could be background characters. Bullets move fast and you could have 1 or 2 characters define the bullet (1 character moves 8 pixels and 2 characters can move 4 pixels - per something).

DULY NOTED...

"Phew. A lot of info."

YEAH, I'm TMI kind of guy. Too much is always better than not enough.. ;)

I guess, and understand, you might want to get things working, add your other ideas, and get it like done. So taking steps back is like ... not really desirable. So for this one, you should absolutely consider ignoring the sprite limit. One day you could revisit the game and make it all more streamlined etc.

 

I'm not sure. I started this game on the wrong assumption about sprite lines. There are some tweaks I can pull off now that could help fix this. The bullet doesn't have to be a sprite and doesn't need COINC if I make a percentage chance to hit within a certain distance from the player. Say 5 - 11 char spaces is 100% hit rate, beyond 11 char spaces we have 50% chance to miss, closer than 5 char spaces is a miss (because we want the ranged weapon ranged only and not to replace a melee weapon). That would mean I can eliminate COINC and Sprite for bullet easily.

 

And it just occured to me that this will be an issue when zombies are able to drop down levels later in the game. Yeah. I'm going to put this 4 sprite limit on the back burner for a while and let it remain glitchy (after I fix the bullet issue as described above)

 

I also suck at this multi-quote thing. Obviously. LOL

 

 

Phew. A lot of info.

I guess, and understand, you might want to get things working, add your other ideas, and get it like done. So taking steps back is like ... not really desirable. So for this one, you should absolutely consider ignoring the sprite limit. One day you could revisit the game and make it all more streamlined etc.

;)

Link to comment
Share on other sites

I am using a call link delay for the title and instruction screens because when you hit enter or move the joystick to go from title to instructions or instruction to game, the sensitivity is too tight and a player can easily go from title to playing without ever seeing the instruction screen. So I put delay after title before input accepted and a delay after instructions after the instructions for input to avoid this. That's one type of delay.

How about this:

10 PRINT TITLE SCREEN

20 CALL KEY(0,K,S)::IF S<1 THEN 20

30 PRINT INTRUCTIONS

40 CALL KEY(0,K,S)::IF S<1 THEN 40

50 START GAME

Link to comment
Share on other sites

I am doing exactly that but it's too fast and sensitive so I put the call link delay before that.

I don't think you are doing exactly that. What I have shown forces the program to wait at lines 20 and 40 until a new key is pressed. It may be that you need to have:

5 CALL KEY(0,K,S) at the beginning in case you are holding a key down when the program starts up.

Link to comment
Share on other sites

I'll have to review my code when I get home.

 

What happens is, when you press a key to go from the title to the instruction screen, the key release isn't fast enough because the instruction screen loads so fast due to your most excellent compressor.

 

So I drop a call link delay right before the call key to allow a couple of seconds to release the key then repress.

 

My "merged" text file in the zip can be reviewed for that. Unfortunately, I can't from work or I'll stop working.

 

All the lines starting at 30000 are the title screens and related delays/call keys/joyst statements.

Edited by Sinphaltimus
Link to comment
Share on other sites

Senior Falcon is referring to checking that the Status from CALL KEY is less than 1. There are three possible values:

 

0 = no key pressed

-1 = same key as last time STILL pressed

1 = new key pressed

 

Most of the time, people tend to check for <> 0, which would catch both cases. But ignoring -1 as suggested should make it stop and wait for you to release the key, and then press anew.

Link to comment
Share on other sites

Senior Falcon is referring to checking that the Status from CALL KEY is less than 1. There are three possible values:

 

0 = no key pressed

-1 = same key as last time STILL pressed

1 = new key pressed

 

Most of the time, people tend to check for <> 0, which would catch both cases. But ignoring -1 as suggested should make it stop and wait for you to release the key, and then press anew.

 

Oh. Well that makes total sense.

 

I suppose it saves some bytes so that's a good thing.

 

I wanted to add the joyst so folks don't have to lean over to press a key. I like to play sitting back from the console a bit.

 

Now that I'm home, this is what I use - and I'm wondering why this would be an issue or unfavorable?

 

 
30320 CALL LINK("DELAY",200)
30330 CALL KEY(0,K,S):: CALL JOYST(1,X,Y)
30340 IF K=-1 AND S=0 AND X=0 AND Y=0 THEN 30330
 
Link to comment
Share on other sites

OK, this version works. :)

 

New ZOMBIv050 AVAILABLE >>HERE<<

V0.50 changes:
Fixed player/zombi collisions.
Adjusted jumping animation
Fixed double delay On instruction screen.
Fixed .bin file issue that would crash classic99 and real iron upon load.
It was a typo that made it through the assembly process.
KNOWN ISSUES:
NOT ALL FUNCTIONALITY OR GAME MECHANICS HAVE BEEN DEVELOPED AS OF THIS VERSION.
Player can hold jump button and skip across holes.
Edited by Sinphaltimus
Link to comment
Share on other sites

There is no "status" for joystick position like there is for CALL KEY so if you are moving the joystick to advance through the menu you are liable to skip ahead when you don't want to. Try using the joystick fire button which is read with CALL KEY. Something like this:

10 CALL KEY(1,K,S1)::CALL KEY(2,K,S2)::IF S1<1 AND S2<1 THEN 10

Nice and neat. No need for a delay which could be annoyingly long or annoyingly short. CALL KEY(1,K,S1) scans the left side of the keyboard and the fire button on joystick #1. CALL KEY(2,K,S2) scans the right side of the keyboard and the fire button on joystick #2. (The spacebar cannot be seen with the split keyboard scan)

By the way, the key value returned when you press the fire button is 18. This is hard to find in the docs.

  • Like 1
Link to comment
Share on other sites

There is no "status" for joystick position like there is for CALL KEY so if you are moving the joystick to advance through the menu you are liable to skip ahead when you don't want to. Try using the joystick fire button which is read with CALL KEY. Something like this:

10 CALL KEY(1,K,S1)::CALL KEY(2,K,S2)::IF S1<1 AND S2<1 THEN 10

Nice and neat. No need for a delay which could be annoyingly long or annoyingly short. CALL KEY(1,K,S1) scans the left side of the keyboard and the fire button on joystick #1. CALL KEY(2,K,S2) scans the right side of the keyboard and the fire button on joystick #2. (The spacebar cannot be seen with the split keyboard scan)

By the way, the key value returned when you press the fire button is 18. This is hard to find in the docs.

Thanks, I'll give that a shot in the next version (0.51). And yep on the button = 18. I use it for jumping/dodging. I have to write code every time that will print K on a CALL KEY for me to find these things out. :)

Edited by Sinphaltimus
Link to comment
Share on other sites

Just because I'm going to end up crediting the entire TI-99/4a community anyway... LOL :)

Here my Source for v0.51 which is not ready for release as I'm currently working on it:

 

//ZOMB51 - ZOMBI V 0.51 ALPHA BY LEONARD RIVERA AND THE ATARIAGE TI-99/4A CREW
// NOTES: EDIT LAST FEW LINES OF MAIN PROGRAM AFTER PASTE FROM TIDBIT TO MERGE WITH ZOMBITS3-M AND UNREMARK LINES 100 AND 1040. 
//MUST BE LOADED WITH XB256 RUNNING IF YOU PLAN TO RUN IT IN XB. 
//FOR MORE SIDE NOTES AND REFERENCE SCROLL TO BOTTOM PAST THE END OF THE MAIN PROGRAM,
_START:
! GOSUB 30000 //GFX AND TITLE SCREENS *ALSO EDIT THE GOSUB RIGHT AFTER _DEAD (APROX L95 IN NP++)
_GAMESTART:
 
     SCORE=5 :: HEALTH=5 :: BOARD=99 :: MELEE=5 :: RANGED=5 :: BULL=1 :: MAXHEALTH=10 :: MAXZHELTH=4
     ZEDPERC=20 :: ZEDSTEPL=0 :: ZEDSETPR=0 :: JDELAY = 8 :: MAXMELEE=10 :: MAXRANGED=10
     ATDELAY=10 :: ZSS=3 //ZED ATTACK DELAY, ZED MAX SPEED
_NEWBOARD:
     RANDOMIZE
     SLOT=10
     OPTION BASE 1
     DIM LO0T(2,14) //ARRAY TO STORE SPRITE NUMBER AND CHAR CODE FOR ALL 14 LOOT ITEMS SPAWNED.
     DIM HART(3,14) //ARRAY TO STORE SPRITE NUMBER, Y POS, X POS FOR ALL HEART ITEMS SPAWNED.
     DIM RANG(1,14) //ARRAY TO STORE SPRITE NUMBER FOR ALL RANGED ITEMS SPAWNED.
     DIM MELE(1,14) //ARRAY TO STORE SPRITE NUMBER FOR ALL MELEE ITEMS SPAWNED.
     DIM ZEDZ(14,6) //ARRAY TO STORE ZED SPRITE NUMBER, ZED HOLE NUMBER, ZED DIRECTION, ZED SPEED, ZED HEALTH, ZED ACTIVE
//GRND = 17 BECAUSE 9=PLAYER GROUND AND 17=REAL GROUND (9 PLUS 8PIXEL BOX)
     LTN=1 :: LAB=1 :: SHL=2 :: GRND=17 :: ZHELTH=4 :: YP=9 :: XP=8 :: PD=1 :: PS=2 //LOOT NUMBER, LOOT LABEL, GROUND, ZOMBI HEALTH, PLAYER Y POS, PLAYER X POS, PLAYER DIRECTION, PLAYER SPEED
     JMP=0 :: ZOMBEZ=0 :: ZDR=1 :: HCLR=1 :: TYMER=BOARD*2 //JUMPING STATUS, ZOMBI COUNT, ZOMBI DIRECTION, HOLE COLOR
     RLUT=1 :: MLUT=1 :: HLUT=1 :: HARTZ=0 :: RANGZ=0 :: MELEZ=0 :: PFALLIN=O //FOR _LDS ARRAY POPULATION OF LOOT. AND PLAYER FALLING STATUS
     ZHOL=2
_CREATELEVEL:
     CALL COLOR(1,12,1,2,12,1,3,12,1,4,12,1,5,12,1,6,12,1,7,12,1,8,15,1,14,10,1)  :: CALL CLEAR :: CALL SCREEN(2)
     GOSUB _GUI
     HLE=INT((RND*15)+5) :: FOR LVL=1 TO 8 :: IF LVL<>1 THEN _GSLDS ELSE _910 //HLE = HOLE COORDINATE IN X PER LEVEL. WE SKIP LOOT DISTRIBUTION ON LEVEL 1
_GSLDS:
     GOSUB _LDS
_910:
     CALL VCHAR(1,1,94,24) :: CALL VCHAR(1,32,94,24) :: CALL HCHAR(LVL*3,1,94,HLE-1)//LEFT WALL, RIGHT WALL, LEFT SIDE OF HOLE FLOOR
     IF LVL=8 THEN _920 ELSE _915 //LAST LEVEL WE HAVE TO HIDE HOLE SO USER EXITS AT DOOR
_915:
     CALL SPRITE(#SHL,95,HCLR,GRND-7,(HLE*+1) :: SHL=SHL+1 //SHL = SPRITE NUMBER FOR HOLE 2 AT START OF BOARD - HERE WE MAKE BLACK HOLES
     NHLE=INT((GRND+1)/8)
     CALL HCHAR(NHLE+1,HLE+1,95) //GRAPHICS TO REPLACE BLACK HOLE.
_920:
     LASTHLE=(HLE*+1 :: CALL HCHAR(LVL*3,HLE+3,94,32-(HLE+3)) //LAST HOLE DEFINITION AND LEFT SIDE OF HOLE GROUND.
     IF LVL=8 THEN _970 ELSE _921 // IF THIS IS LAST HOLE WE NEED TO TREAT IT DIFFERENTLY SO PLAYER WONT FALL.
_921:
     CALL HCHAR(LVL*3,HLE,93) :: CALL HCHAR(LVL*3,HLE+2,93) :: GRND=GRND+24 //FLOOR ON RIGHT SIDE OF HOLE
_940:
     HOL=INT((RND*15)+5) //DETERMINES LOCATION OF NEXT HOLE
     IF HOL=HLE THEN _940 ELSE _945 //ENSURE NEXT HOLE IS NOT DIRECTLY NDER PREVIOUS ONE. 
_945:
     HLE=HOL
_970:
     NEXT LVL
     FOR EXTX=1 TO 31 STEP 30 :: FOR EXTY=2 TO 23 STEP 3 :: CALL HCHAR(EXTY,EXTX,143) :: NEXT EXTY :: NEXT EXTX
     CALL HCHAR(24,1,94,31) :: GOTO _SPIDLE //CREATE GIRDER 
_LDS:
//SIDEZ DETERMINES WHAT SIDE OF THE HOLE A PARTICULAR LOOT ITEM WILL APPEAR. NEG#=LEFT POS#=RIGHT
     SIDEZ=-40 //START ON LEFT SIDE OF HOLE
     FOR REPT=1 TO 2 //ONCE FOR LEFT, ONCE FOR RIGHT SIDE OF HOLE
     IF LVL=8 AND ZOMBEZ=0 THEN _DOZED
     LDSN=INT(RND*100)+(1+ZEDPERC) //PICK A RANDOM NUMBER FROM 1-100 -- FIRST DISTRIBUTION NUMBER TO DETERMINE 
//HEARTS/ZEDS VS WEAPONS.
     IF LDSN<BOARD THEN _MR //IF THE RANDOM NUMBER IS HIGHER THAN THE PERCENTILE (60(LDSV) AT START OF GAME) THEN WEAPONS WIN
// SO GO DETERMINE IF IT IS A MELEE WEAPON OR A RANGED WEAPON (_MR)
_HZL: //LDSN (RANDOMLY SELECTED NUMBER) IS NOT HIGHER THAN THE PERCENTILE THRESHOLD (LDSV)
     LDSN=INT(RND*100)+(1+ZEDPERC)
     IF LDSN>BOARD THEN _DOZED // NUMBER BY MY ZEDPERCENTAGE INCREASE. IF THIS NEW NUMBER IS GREATER THAN THE CURRENT BOARD (START AT 99 END AT 0)
_DOHART: // THEN GO DO ZED (_DOZED) ELSE DO HEARTS (_DOHART)
     CALL SPRITE(#SLOT,90,7,GRND-9,((HLE+1)*+SIDEZ) :: CALL POSITION(#SLOT,HY,HX) :: HART(2,HLUT)=HY :: HART(3,HLUT)=HX 
     HART(1,HLUT)=SLOT :: SLOT=SLOT+1 ::  HLUT=HLUT+1 :: HARTZ=HARTZ+1
     LO0T(LAB,LTN)=90 :: LAB=LAB+1 :: LO0T(LAB,LTN)=SLOT-1 :: LAB=1 :: LTN=LTN+1
     GOTO _NEXLDS
 
_DOZED:
     IF BOARD>=51 THEN _NOUPZHELTH
_NOUPZHELTH:
     CALL SPRITE(#SLOT,96,4,GRND-8,((HLE+1)*+SIDEZ)
//ZED TABLE POPULATION PER LEVEL 
     ZHELTH=MAXZHELTH //SETS ZED HEALTH FOR THIS ZED
     ZOMBEZ=ZOMBEZ+1 //UPS THE TOTAL ZED COUNT BY 1
     ZEDZ(ZOMBEZ,1)=SLOT //ZED SPRITE NUMBER FOR THIS ZED
     ZHOLX=((HLE+1)*
     ZEDZ(ZOMBEZ,2)=ZHOLX //ZED HOLE X POSITION FOR THIS ZED
     ZEDZ(ZOMBEZ,3)=ZDR
     ZS=INT((RND*ZSS)+1) //SETS RANDOM ZED SPEED
     ZEDZ(ZOMBEZ,4)=ZS //STORE SPEED FOR THIS ZED
     ZEDZ(ZOMBEZ,5)=ZHELTH //STORE HEALTH FOR THIS ZED
     ZEDZ(ZOMBEZ,6)=1 //MAKE THIS ZED ACTIVE (CHANGE TO -1 WHEN ZED KILLED)
     SLOT=SLOT+1 //MOVE TO NEXT SPRITE NUBER SLOT FOR NEXT LOOT TO SPAWN.
     LO0T(LAB,LTN)=96 :: LAB=LAB+1 :: LO0T(LAB,LTN)=SLOT-1 :: LAB=1  :: LTN=LTN+1
     IF BOARD>33 THEN _NEXLDS
     GOSUB _CREATECRAWLER
     GOTO _NEXLDS
 
_MR:
     LDSN=INT(RND*100)+1 
     LDSN=LDSN+ZEDPERC //REGENERATE A RANDOM NUMBER TO DETERMINE RANGE OR MELEE WEAPON SPAWN.
     IF LDSN<BOARD THEN _DORAN //IF THE NUMBER IS GREATER THAN LDSV (60 PERCENT AT BOARD99) THEN DO RANGED (_DORAN) ELSE DO MELEE (_DOMEL)
  
_DOMEL:
     MELE(1,MLUT)=SLOT :: MLUT=MLUT+1 :: MELEZ=MELEZ+1
     CALL SPRITE(#SLOT,91,8,GRND-9,((HLE+1)*+SIDEZ) :: SLOT=SLOT+1 :: LO0T(LAB,LTN)=91 :: LAB=LAB+1 :: LO0T(LAB,LTN)=SLOT-1 :: LAB=1 :: LTN=LTN+1
     GOTO _NEXLDS
 
_DORAN:
     RANG(1,RLUT)=SLOT :: RLUT=RLUT+1 :: RANGZ=RANGZ+1
     CALL SPRITE(#SLOT,92,14,GRND-9,((HLE+1)*+SIDEZ) :: SLOT=SLOT+1 :: LO0T(LAB,LTN)=92 :: LAB=LAB+1 :: LO0T(LAB,LTN)=SLOT-1 :: LAB=1 :: LTN=LTN+1
 
_NEXLDS:
     SIDEZ=40 :: NEXT REPT //DONE WITH LEFT SIDE LOOT, BO BACK AND DO RIGHT SIDE OF HOLE.
     RETURN
_CREATECRAWLER:
//CREATE THE CRAWLEER AT THE EXIT. LOCATE A HEART IF ANY, GO FOR IT IN THE AI. IF NO HEART GO FOR THE PLAYER IN THE AI.
     RETURN
_GUI: ////OUTPUT GUI
     DISPLAY AT(1,3):SCORE :: DISPLAY AT(1,10):BOARD :: DISPLAY AT(1,15):HEALTH :: DISPLAY AT(1,21):MELEE :: DISPLAY AT(1,26):RANGED
     CALL VCHAR(1,3,75) :: CALL VCHAR(1,4,76) :: CALL VCHAR(1,5,77) :: CALL VCHAR(1,12,79) :: CALL VCHAR(1,17,64) :: CALL VCHAR(1,23,64)
     CALL VCHAR(1,28,64) :: CALL VCHAR(1,11,78) :: CALL VCHAR(1,16,90) :: CALL VCHAR(1,22,91) :: CALL VCHAR(1,27,92) ::RETURN
_BOARDPROG:
     IF BOARD<=20 THEN _ZPA //I LOWER THE ZED SPAWN PERCENTILE SINCXE THE CHANCES ARE VERY HIGH ANYWAY.
_MHC:
     IF BOARD<=75 THEN _MXHLT //POWER UP MAX HEALTH FOR PLAYER
_MRC:
     IF BOARD<=50 THEN _MXRNG //POWER UP MAX RANGE FOR PLAYER
_MMC:
     IF BOARD<=25 THEN _MXMEL  ELSE _BPC //POWER UP MAX MELEE FOR PLAYER
_ZPA:
     ZEDPERC=0 :: GOTO _MHC
_MXHLT:
     MAXHEALTH=20 :: GOTO _MRC
_MXRNG:
     MAXRANGED=20 :: MAXZHELTH=6 :: GOTO _MMC
_MXMEL:
     MAXMELEE=20 
_BPC:
     CALL DELSPRITE(ALL) :: BOARD=BOARD-1 :: IF SCORE>HSCORE THEN _HSCOR ELSE _DSPLAYHS
_HSCOR:
     HSCORE=SCORE
_DSPLAYHS:
     CALL SCREEN(2) :: FOR CCLOR=0 TO 14 :: CALL COLOR(CCLOR,16,1) :: NEXT CCLOR :: HCLR=2 :: CALL CLEAR
     CALL VCHAR(11,12,47) :: CALL VCHAR(11,13,36) :: CALL VCHAR(11,14,34) :: CALL VCHAR(11,15,47)
     CALL VCHAR(11,16,73) :: CALL VCHAR(11,17,40) :: CALL VCHAR(11,18,66) :: CALL VCHAR(11,19,71)
     CALL VCHAR(11,20,72) :: DISPLAY AT(12,13):HSCORE
     CALL LINK("DELAY",200)
_HOLDHS:
     CALL KEY(1,K,S) :: IF S=0 THEN _HOLDHS
     GOTO _NEWBOARD
_DEAD:
     CALL SCREEN(10) :: CALL CLEAR :: CALL DELSPRITE(ALL)
     ! GOSUB 30270
     FOR CCLOR=0 TO 14 :: CALL COLOR(CCLOR,16,10) :: NEXT CCLOR
     DISPLAY AT(7,13):HSCORE :: DISPLAY AT(21,13):SCORE
     CALL SCREEN(2) :: CALL LINK("DELAY",200)
_YADINPUT:
     CALL KEY(1,K,S) :: CALL JOYST(1,X,Y) :: IF K<>-1 OR S<>0 OR X<>0 OR Y<>0 THEN _NEWGAME 
     GOTO _YADINPUT
_NEWGAME:
     CALL DELSPRITE(ALL) :: GOTO _GAMESTART
 
_RESET:
     CALL DELSPRITE(ALL) :: GOTO _START
_QUIT:
     CALL CLEAR :: END :: RETURN
 
_SPIDLE:
     CALL SPRITE(#1,104,6,YP,XP)
     CALL COINC(ALL,C) :: IF C=0 THEN _ZKIP
     GOSUB _PCD
     IF ZOMBEZ=0 THEN _JOYCHK
     CALL COINC(ALL,C) :: IF C=0 THEN _ZKIP
     GOSUB _ZCD
_ZKIP:
     IF ZOMBEZ=0 THEN _JOYCHK
     GOSUB _ZEDAI
_JOYCHK:
     CALL JOYST(1,JX,JY) :: CALL KEY(1,K,S) :: IF K=0 AND S=-1 THEN _QUIT
     IF K=16 THEN _BOARDPROG //DEVELOPER CHEAT TO TEST _LDS
     IF K=6 THEN _RESET // :: IF K=3 THEN GOSUB _DEBUGGER
     IF K=18 OR K=74 OR K=106 THEN _GSJMP 
     IF JX<>0 OR JY<>0 THEN _JOYACTION ELSE _SPIDLE
_GSJMP: 
     JMP=1 :: GOSUB _JUMP :: JMP=0 :: GOTO _JOYACTION 
 
_JOYACTION:
     IF JY=0 THEN _MOVEIT ELSE _ATTACKIT
_ATTACKIT:
     GOSUB _COMBAT
_MOVEIT:
     CALL KEY(1,K,S) :: IF K=16 THEN _BOARDPROG
     IF K=18 OR K=74 OR K=106 THEN _JUMPER ELSE _JOYST
_JUMPER:
     JMP=1 :: GOSUB _JUMP :: JMP=0 // :: IF K=3 THEN GOSUB _DEBUGGER
 
_JOYST:
     IF JX<>0 THEN _SPRUN
     IF JY<>0 THEN _GSCBT ELSE _CONT
_GSCBT:
     GOSUB _COMBAT
_CONT:
     GOTO _SPIDLE
_SPRUN:
//CHCKL - CHECK LEFT
     IF JX=-4 THEN _GSSPL ELSE _CHCKR
_GSSPL:
     GOSUB _SPLEFT
_CHCKR:
     IF JX=4 THEN _GSSPR ELSE _SPIDLE
_GSSPR:
     GOSUB _SPRIGHT
     CALL KEY(1,K,S) :: IF K=16 THEN _BOARDPROG
     IF K=18 OR K=74 OR K=106 THEN _RJUMPER ELSE _RJOYST
_RJUMPER:
     JMP=1 :: GOSUB _JUMP :: JMP=0 // :: IF K=3 THEN GOSUB _DEBUGGER
_RJOYST:
     IF JX<>0 THEN _SPRUN
     IF JY<>0 THEN _RGSCBT ELSE _RCONT
_RGSCBT:
     GOSUB _COMBAT
_RCONT:
     GOTO _SPIDLE
_SPRIGHT:
     IF XP>=250 THEN _FLIPL ELSE _RUNR
_FLIPL:
     XP=2
_RUNR:
     PD=1 :: CALL SPRITE(#1,105,6,YP,XP)
     FOR PATR=105 TO 110 :: CALL PATTERN(#1,PATR) :: CALL SOUND(1,-2,20) :: XP=XP+PS
     IF XP>=250 THEN _FLIPL2 ELSE _MOVEIT2
_FLIPL2:
     XP=2
_MOVEIT2: 
     CALL LOCATE(#1,YP,XP) :: CALL KEY(1,K,S)// :: IF K=3 THEN GOSUB _DEBUGGER
     IF K=18 THEN _GOJMP 
     IF K=74 THEN _GOJMP 
     IF K=106 THEN _GOJMP ELSE _NOGOJMP 
_GOJMP:
     JMP=1 :: PATR=110 :: GOTO _CHECKCOLLISIONRUNRIGHT
_NOGOJMP:
     CALL JOYST(1,JX,JY) :: IF JY=0 THEN _KEEPRUNR ELSE _GOSCOM1
_GOSCOM1:
     GOSUB _COMBAT
_KEEPRUNR:
     IF JX<>0 THEN _CHECKRUNR
     CALL SPRITE(#1,104,6,YP,XP) :: RETURN
_CHECKRUNR:
     IF JX=4 THEN _CHECKCOLLISIONRUNRIGHT
     IF JX=-4 THEN _GORET ELSE _CHECKCOLLISIONRUNRIGHT
_CHECKCOLLISIONRUNRIGHT:
     CALL COINC(ALL,C) :: IF C=0 THEN _ZKIP1
     GOSUB _PCD
     IF ZOMBEZ=0 THEN _SKIPZEDZ2
     CALL COINC(ALL,C) :: IF C=0 THEN _ZKIP1
     GOSUB _ZCD
_ZKIP1:
     IF ZOMBEZ=0 THEN _SKIPZEDZ2
     GOSUB _ZEDAI
_SKIPZEDZ2:
     NEXT PATR
     IF JMP=1 THEN _GOSUBJUMPRUNRIGHT ELSE _NOGOSUBJUMPRUNRIGHT
_GOSUBJUMPRUNRIGHT:
     GOSUB _JUMP ::JMP=0
_NOGOSUBJUMPRUNRIGHT: 
     IF JX=4 THEN _SPRIGHT ELSE _GORET 
_SPLEFT:
     IF XP<=1 THEN _FLIPR ELSE _RUNL
_FLIPR:
     XP=249
_RUNL:
     PD=-1 :: CALL SPRITE(#1,113,6,YP,XP)
     FOR PATL=113 TO 118 :: CALL PATTERN(#1,PATL) :: CALL SOUND(1,-2,20) :: XP=XP-PS
     IF XP<=1 THEN _FLIPR2 ELSE _MOVEIT3
_FLIPR2:
     XP=249
_MOVEIT3:
     CALL LOCATE(#1,YP,XP) :: CALL KEY(1,K,S)// :: IF K=3 THEN GOSUB _DEBUGGER
     IF K=18 THEN _GORLJMP
     IF K=74 THEN _GORLJMP
     IF K=106 THEN _GORLJMP ELSE _NOGORLJMP
_GORLJMP:
     JMP=1 :: PATL=118 :: GOTO _CHECKCOLLISIONRUNLEFT
_NOGORLJMP:
     CALL JOYST(1,JX,JY) :: IF JY=0 THEN _KEEPRUNL ELSE _GOSCOM2
_GOSCOM2:
     GOSUB _COMBAT
_KEEPRUNL:
     IF JX<>0 THEN _CHECKRUNL
     CALL SPRITE(#1,44,6,YP,XP) :: RETURN
_CHECKRUNL:
     IF JX=-4 THEN _CHECKCOLLISIONRUNLEFT
     IF JX=4 THEN _GORET ELSE _CHECKCOLLISIONRUNLEFT
_CHECKCOLLISIONRUNLEFT:
     CALL COINC(ALL,C) :: IF C=0 THEN _ZKIP2
     GOSUB _PCD
     IF ZOMBEZ=0 THEN _SKIPZEDZ3
     CALL COINC(ALL,C) :: IF C=0 THEN _ZKIP2
     GOSUB _ZCD
_ZKIP2:
     IF ZOMBEZ=0 THEN _SKIPZEDZ3
     GOSUB _ZEDAI
_SKIPZEDZ3: 
     NEXT PATL
     IF JMP=1 THEN _GSJRUNLFT ELSE _NOGSJRUNLFT
_GSJRUNLFT:
     GOSUB _JUMP :: JMP=0
     CALL COINC(ALL,C) :: IF C=0 THEN _ZKIP3
     GOSUB _PCD
     IF ZOMBEZ=0 THEN _NOGSJRUNLFT
     CALL COINC(ALL,C) :: IF C=0 THEN _ZKIP3
     GOSUB _ZCD
_ZKIP3:
     IF ZOMBEZ=0 THEN _NOGSJRUNLFT
     GOSUB _ZEDAI 
_NOGSJRUNLFT:
     IF JX=-4 THEN _SPLEFT ELSE _GORET
_JUMP:
//// ********JUMP ROUTINE CHECK********
     JMP=0
     IF PD<>-1 THEN _5710
     S1=128 :: J1=131 :: L1=134 :: JSND=18 :: S2=130 :: J2=133 :: L2=135 :: JMPDIS=-1//JUMPLEFT
     GOTO _5750
_5710:
     IF PD<>1 THEN _GORET
     S1=120 :: J1=123 :: L1=126 :: JSND=10 :: S2=122 :: J2=125 :: L2=127 :: JMPDIS=1 //JUMP RIGHT
_5750:
     CALL LOCATE(#1,YP,XP)  //FROM RUNNING TO STOPPING LEFT
     FOR PTS=S1 TO S2 :: CALL SOUND(1,(PTS-JSND),5) :: CALL PATTERN(#1,PTS) :: NEXT PTS
     FOR UDELAY=1 TO JDELAY :: 
     IF ZOMBEZ=0 THEN _SKIPZEDZ5
     GOSUB _ZEDAI :: CALL COINC(ALL,C) :: IF C=0 THEN _SKIPZEDZ5
     GOSUB _ZCD 
_SKIPZEDZ5:
     NEXT UDELAY // CALL COINC(ALL,C) :: IF C<>0 THEN _ZCD :: NEXT UDELAY
     YP=YP-3 :: CALL LOCATE(#1,YP,XP)
     JMP=1
     FOR PTJ=J1 TO J2  //JUMP (JUMPING)
     FOR PTJP=1 TO 7
     XP=XP+JMPDIS
     IF XP<=1 THEN _CREATEPLAYERRIGHT ELSE _CHECKPLAYERRIGHT
_CREATEPLAYERRIGHT:
     XP=248 :: GOTO _NOMOREEDGES
_CHECKPLAYERRIGHT:
     IF XP>=249 THEN _CREATEPLAYERLEFT ELSE _NOMOREEDGES
_CREATEPLAYERLEFT:
     XP=2
_NOMOREEDGES:
     CALL PATTERN(#1,PTJ) :: CALL SOUND(1,(PTJ-JSND),5) :: CALL LOCATE(#1,YP,XP)
     NEXT PTJP
     NEXT PTJ 
     YP=YP+3 :: CALL LOCATE(#1,YP,XP) 
     FOR PTL=L1 TO L2
     IF PTL=L1 THEN _NXTPTL // SKIP THE DELAY UNTIL LAST FRAME
     IF ZOMBEZ=0 THEN _NXTPTL
     GOSUB _ZEDAI :: CALL COINC(ALL,C) :: IF C=0 THEN _NXTPTL
     GOSUB _ZCD 
_NXTPTL:
     CALL PATTERN(#1,PTL) :: CALL SOUND(1,(PTL-JSND),5) :: NEXT PTL
     CALL COINC(ALL,C) :: IF C<>0 THEN _GSCOLDET ELSE _GORESET
_GSCOLDET:
     RETURN 
_GORESET:
     ATDELAY=10 :: RETURN 
_COMBAT:
////*****JOYS COMBAT CHOICE*****
     IF JY=4 AND MELEE>=1 THEN _5360 :: IF JY=4 AND MELEE<=0 THEN _5350
     IF JY=-4 THEN _5330 ELSE _GORET
_5330:
     GOSUB _ATTACKR :: RETURN
_5350:
     CALL SOUND(100,-3,0) :: RETURN
_5360:
     MELEE=MELEE-1 :: GOSUB _GUI
     GOSUB _ATTACKM :: RETURN
     IF JY=-4 THEN _5400 ELSE _5405
_5405:
     CALL SOUND(100,-6,0) :: RETURN
_5400:
     GOSUB _ATTACKR :: RETURN
_ATTACKM:
     CALL PATTERN(#1,136) 
     IF XP+8>=250 THEN _S2OTHER1 
     CALL SPRITE(#24,82,12,YP,XP+ ::  GOTO _S2SOWND
_S2OTHER1:
     CALL SPRITE(#24,82,12,YP,XP)
_S2SOWND:
     CALL SOUND(125,-5,0)
     GOSUB _MELCOLLOO
     IF XP+8>=250 THEN _S2OTHER2 //SKIP TO SOUND
     CALL DELSPRITE(#24) :: IF XP-8<=1 THEN _S2OTHER2
     CALL SPRITE(#25,82,12,YP,XP- :: GOTO _S2SOWND2
_S2OTHER2:
     CALL SPRITE(#25,82,12,YP,XP)
_S2SOWND2:
     CALL SOUND(125,-6,0)
     GOSUB _COLCKM2
     CALL DELSPRITE(#25) :: CALL PATTERN(#1,136) //:: CALL COLOR(#DET,4)
     RETURN
_MELCOLLOO:
     FOR DET=10 TO 23 :: CALL COINC(#24,#DET,7,C) :: IF C<>0 THEN _5470
     NEXT DET :: RETURN
_COLCKM2:
     FOR DET=10 TO 23 :: CALL COINC(#25,#DET,7,C) :: IF C<>0 THEN _5470
     NEXT DET :: RETURN
_5470:
     TLOOP1=DET-9
_5490:
     IF LO0T(1,TLOOP1)<>96 THEN _LOOTCOL //NOT A ZED HIT
_ZOMBIEHITMELEE: //WHAT ZOMBIE IS HIT? 
     CALL COLOR(#DET,7) :: LSPRN=LO0T(2,TLOOP1) //GETS SPRITE NUMBER OF LOOT HIT TO CHECK
     FOR ZCHEK=1 TO 14 //NEED TO FIND ZOMBIE IN ZOMBIE ARRAY FOR STATS
     ZPRN=ZEDZ(ZCHEK,1)
     IF LSPRN<>ZPRN THEN _NXZCK
     ZHELTH=ZEDZ(ZCHEK,5) :: ZHELTH=ZHELTH-1 :: ZEDZ(ZCHEK,5)=ZHELTH //GET ZOMBIE CURRENT HEALTH - HEALTH PENALTY TO ZED FOR MELEE HIT. - STORE ZOMBIE NEW HEALTH
     IF ZHELTH>=1 THEN _GORET // :: IF ZOMBIE STILL STANDING END THE ATTACK ROUND OR ELSE KILL IT.
     SCORE=SCORE+15 :: ZEDZ(ZCHEK,6)=-1 :: CALL DELSPRITE(#LSPRN) :: ZOMBEZ=ZOMBEZ-1 :: RETURN
_NXZCK:
     NEXT ZCHEK
     RETURN
_LOOTCOL: //OTHER THAN ZED LOOT HIT BY MELEE
     IF LO0T(1,TLOOP1)<>90 THEN _5540 ELSE _5560
_5540:
     IF LO0T(1,TLOOP1)<>91 THEN _5550 ELSE _5560
_5550:
     IF LO0T(1,TLOOP1)<>92 THEN _GORET
_5560:
     FOR LCHEK=1 TO 14 :: IF DET=LO0T(LCHEK,2) THEN _WRLC5 ELSE _NXTLCHEK4
_WRLC5:
     LCHEK=14 
_NXTLCHEK4:
     NEXT LCHEK :: CALL DELSPRITE(#DET)
_5570:
     RETURN 
_ATTACKR:
     IF RANGED<=0 THEN _CLSND ELSE _3570
_CLSND:
     CALL SOUND(100,-3,0) :: RETURN 
_3570:
     RANGED=RANGED-1 :: CALL SOUND(100,-6,0) :: GOSUB _GUI
     YB=YP
//*********************************SHOOT RIGHT
     IF PD<>1 THEN _4210
     CALL PATTERN(#1,138)
     BULL=1
     XB=XP+32
     GOTO _BULFIRE
//*********************************SHOOT LEFT
_4210:
     IF PD<>-1 THEN _GORET
     CALL PATTERN(#1,137)
     BULL=-1
     XB=XP-32 
//*********************************BULLET FIRE RIGHT
_BULFIRE:
_BVH:
     CALL SPRITE(#26,83,6,YB,XB)
     FOR BHCK=2 TO 8
_BHCKCONT:
     CALL COINC(#26,#BHCK,8,C) :: IF C=0 THEN _NEXTBHCK
     XB=XB+BULL :: CALL LOCATE(#26,YB,XB) :: IF XB<=2 OR XB>=249 THEN _ATTACKEND ELSE _BHCKCONT
_NEXTBHCK:
     NEXT BHCK
_4910:
     CALL COINC(ALL,C) :: IF C<>0 THEN _BULHIT
_BULLCONT:
     XB=XB+BULL :: IF XB<=2 OR XB>=249 THEN _ATTACKEND ELSE _BVH 
_BULHIT:  //WHAT DID THE BULLET HIT?
     CALL LOCATE(#26,YB,XB) :: FOR LCHECK=1 TO 14 :: LSPRN=LO0T(2,LCHECK) :: LCHKB=LO0T(1,LCHECK) //GETS SPRITE NUMBER OF LOOT HIT TO CHECK - GETS CHARCODE OF LOOT HIT TO CHECK
_BUHOCK: //BULLET HOLE CHECK
     IF LSPRN<=9 OR LSPRN>=24 THEN _GSBULCON ELSE _CONLC  //MAKE SURE IT IS A PROPER LOOT HIT AND NOT A HOLE HIT.
_GSBULCON:  // THIS IS MEANT TO SPEED UP THE BULLET WHEN IN COTACT WITH A HOLE SPRITE INSTEAD OF _BULLCONT
     XB=XB+BULL :: CALL LOCATE(#26,YB,XB) :: CALL COINC(#26,#LSPRN,8,C) :: IF C<>0 THEN _BUHOCK
_CONLC: //CONTINUE LOOT CHECK (NOT A HOLE)
     CALL COINC(#26,#LSPRN,8,C)  //CHECK FOR COLLISION WITH SAID LOOT.
     IF C=0 THEN _NEXTCOLCHECKLB  // NO COLLISION BETWEEN THIS GUY AND THE NEXT.
     IF LCHKB=96 THEN _ZOMBIEHIT ELSE _LOOTHIT  //IF IT EQUALS A ZOMBIE, GOTO ZOMBIE HIT
_ZOMBIEHIT:  //WHAT ZOMBIE IS HIT? 
     CALL COLOR(#LSPRN,7)
     FOR ZCHEK=1 TO 14 :: AZED=ZEDZ(ZCHEK,6) :: IF AZED=-1 THEN _NXTZCHEK //NEED TO FIND ZOMBIE IN ZOMBIE ARRAY FOR STATS AND SKIP ON NO OR INACTIVE ZEDS
     ZPRN=ZEDZ(ZCHEK,1) :: IF LSPRN<>ZPRN THEN _NXTZCHEK
     ZHELTH=ZEDZ(ZCHEK,5) :: ZHELTH=ZHELTH-2 :: ZEDZ(ZCHEK,5)=ZHELTH //GET ZOMBIE CURRENT HEALTH - HEALTH PENALTY TO ZED FOR BULLET HIT. - STORE ZOMBIE NEW HEALTH
     IF ZHELTH>=1 THEN _ATTACKEND  // IF ZOMBIE STILL STANDING END THE ATTACK ROUND OR ELSE KILL IT.
     SCORE=SCORE+15 :: ZEDZ(ZCHEK,6)=-1 :: CALL DELSPRITE(#LSPRN) :: ZOMBEZ=ZOMBEZ-1 :: GOTO _ATTACKEND
_LOOTHIT:  //DESTROY HIT LOOT 
     CALL COLOR(#LSPRN,7) :: CALL DELSPRITE(#LSPRN) :: LO0T(2,LCHECK)=1 :: GOTO _ATTACKEND
_NXTZCHEK:
     NEXT ZCHEK :: GOTO _ATTACKEND
_NEXTCOLCHECKLB:
     NEXT LCHECK :: GOTO _BULLCONT
_ATTACKEND:  // ATTACK RANGED AGAIN OR END *********************
     CALL DELSPRITE(#26) :: GOSUB _GUI :: CALL JOYST(1,JX,JY) :: IF JY=0 THEN _GORET
     IF JY-4 THEN _GSATTR ELSE _GORET
_GSATTR:
     GOSUB _ATTACKR :: RETURN
_PCD:  //PLAYER COLLISION DETECTION 
//CHECK COLLISIONS AGAINST HEARTS
     IF JMP=1 THEN _GORET
     IF HARTZ<=0 THEN _PLMLCO
     FOR HCOINC=1 TO 14
     AHART=HART(1,HCOINC)
     IF AHART=-1 THEN _NXTHCO
     IF AHART=0 THEN _ENDHCO
     CALL COINC(#1,#AHART,8,C)
     IF  C=0 THEN _NXTHCO
     SCORE=SCORE+10 :: CALL SOUND(1,500,5) :: CALL SOUND(1,600,2)
     IF HEALTH<MAXHEALTH THEN _GSHEL ELSE _GSGUI2
_GSHEL:
     HEALTH=HEALTH+1
_GSGUI2:
     GOSUB _GUI :: CALL DELSPRITE(#AHART) :: HART(1,HCOINC)=-1 :: HARTZ=HARTZ-1 :: GOTO _NXTHCO
_ENDHCO:
     HCOINC=14
_NXTHCO:
     NEXT HCOINC
//CHECK MELEE COLLISIONS IF ANY 
_PLMLCO:
     IF MELEZ=0 THEN _PLRGCO
     FOR MCOINC=1 TO 14
     AMELE=MELE(1,MCOINC)
     IF AMELE=-1 THEN _NXTMCO
     IF AMELE=0 THEN _ENDMCO
     CALL COINC(#1,#AMELE,8,C)
     IF  C=0 THEN _NXTMCO
     SCORE=SCORE+3 :: IF MELEE<MAXMELEE THEN _COLM ELSE _CONCOLM
_COLM:
     MELEE=MELEE+1
_CONCOLM:
     CALL SOUND(1,1500,5) :: CALL SOUND(1,1600,2) :: GOSUB _GUI :: CALL DELSPRITE(#AMELE) :: MELE(1,MCOINC)=-1 :: MELEZ=MELEZ-1
_ENDMCO:
     MCOINC=14
_NXTMCO:
     NEXT MCOINC
//CHECK RANGED COLLISIONS IF ANY
_PLRGCO:
     IF RANGZ=0 THEN _HOLEPCHEKR
     FOR RCOINC=1 TO 14
     ARANG=RANG(1,RCOINC)
     IF ARANG=-1 THEN _NXTRCO
     IF ARANG=0 THEN _ENDRCO
     CALL COINC(#1,#ARANG,8,C)
     IF  C=0 THEN _NXTRCO
     SCORE=SCORE+5 :: IF RANGED<MAXRANGED THEN _CRAN ELSE _CONCRAN
_CRAN:
     RANGED=RANGED+1
_CONCRAN:
     CALL SOUND(1,1000,5) :: CALL SOUND(1,1200,2) :: GOSUB _GUI :: CALL DELSPRITE(#ARANG) :: RANG(1,RCOINC)=-1 :: RANGZ=RANGZ-1
_ENDRCO:
     RCOINC=14
_NXTRCO:
     NEXT RCOINC
_HOLEPCHEKR: 
//THERE ARE 7 HOLES TO CHECK AGAINST.
     FOR HOLDET=2 TO 8 
     CALL COINC(#1,#HOLDET,10,C)
     IF C=0 THEN _NEXTHOLEDETECT
     FOR FALLIN=12 TO 1 STEP -1 :: YP=YP+2 :: CALL SOUND(1,FALLIN*110,5) :: CALL SPRITE(#1,104,6,YP,XP) ::  PFALLIN=1 :: GOSUB _ZEDAI :: NEXT FALLIN :: PFALLIN=0 
_NEXTHOLEDETECT:
     NEXT HOLDET
_EXITCHK:
     CALL POSITION(#1,YP,XP) :: IF YP=177 AND XP>=235 THEN _BOARDPROG
     IF YP=177 AND XP<=8 THEN _BOARDPROG
_GORET:
     RETURN
_ZEDAI:
//GOSUB _CRAWLERAI
_ZEDCC:
     IF ZOMBEZ=0 THEN _GORET  //NO NEED TO CHECK ANY ZEDAI IF THERE ARE NO ZEDS
     TZEDZ=ZEDZ(1,1) :: ZHOLX=ZEDZ(1,2) :: ZDR=ZEDZ(1,3) :: ZS=ZEDZ(1,4) :: AZED=ZEDZ(1,6)
     FOR ZCK=1 TO 14  //UP TO 14 ZEDS POSSIBLE TO CHECK AGAINST
_ZOMB2:
     TZEDZ=ZEDZ(ZCK,1) :: ZHOLX=ZEDZ(ZCK,2) :: ZDR=ZEDZ(ZCK,3) :: ZS=ZEDZ(ZCK,4) :: AZED=ZEDZ(ZCK,6)//SPRITE NUMBER:NEIGHBORING HOLE X POSITION:DIRECTION:SPEED:ACTIVE OR DEAD
     IF AZED=-1 THEN _NEXTZED  // IF A ZED IS NOT ACTIVE SKIP TO NEXT ZED CHECK.
     IF TZEDZ=0 THEN _ALLDONE ELSE _CONZAI  // TZEDZ IS A SPRITE NUMBER. IF IT EQUALS 0 THEN IT'S THE END OF THE LIST IN THE ARRAY.
_ALLDONE:
     ZCK=14 :: GOTO _NEXTZED  //END THE LOOPED ZED CHECK.
_CONZAI:
     CALL POSITION(#TZEDZ,ZY,ZX)  // THE ONLY POINT TO THIS CALL POSITIN IS TO GET THE XY FOR THIS PARTICULAR ZED STRAIGHT.
_NOGSCZ:
//*************************************CHECK FOR ZED CHASE LEVEL AND CODE HERE************************
     CALL POSITION(#1,YP,XP)
     IF BOARD>66 THEN _CONZMOV  //IF LEVEL IS 66 OR LOWER, ENABLE CHASING ZEDS.
     IF YP<>ZY AND BOARD >33 THEN _CONZMOV  // IF BOARD >33 AND ZED/PLAYER NOT SAME LEVEL, DO NOT CHASE (CHASE LEVEL 33 DOWN REGARDLESS OF ZED/PLAYER LEVEL)
     IF ZX<XP THEN _CHCD  //IF ZED IS LEFT OF PLAYER SET POSITIVE DIR TO CHASE PLAYER ELSE KEEP GOING IN SAME DIRECTION.
     ZDR=-1 :: ZEDZ(ZCK,3)=-1 :: GOTO _CONZMOV
_CHCD:
     ZDR=1 :: ZEDZ(ZCK,3)=1 //:: print "5aZDR:";ZDR
_CONZMOV:
     GOSUB _ZEDPATTERN :: GOTO _ZEDMOVE //UPDATE ANIMATION FRAMES THEN MOVE THE ZED
_ZEDPATTERN:
     IF ZDR=1 THEN _ZPATR ELSE _ZPATL //FIGURE OUT WHICH DIRECTION THE ZED IS MOVING
_ZPATR:
     IF ZEDSTEPR=0 THEN _ZPRSW1 ELSE _ZPRSW2 //FIGURE OUT WHICH ANIMATION FRAME THE ZED IS CURRENTLY ON
_ZPRSW1:
     CALL SPRITE(#TZEDZ,100,4,ZY,ZX) :: ZEDSTEPR=1 :: RETURN //CHANGE TO APPROPRIATE PATTERN AND LOCATION, RECALL SPRITE AND CHANGE PATTERN RECORD FOR NEXT CHECK
_ZPRSW2:
     CALL SPRITE(#TZEDZ,99,4,ZY,ZX) :: ZEDSTEPR=0 :: RETURN //SAME AS PREVIOUS COMMENT
_ZPATL:
     IF ZEDSTEPL=0 THEN _ZPLSW1 ELSE _ZPLSW2 //FIGURE OUT WHICH ANIMATION FRAME THE ZED IS CURRENTLY ON
_ZPLSW1:
     CALL SPRITE(#TZEDZ,98,4,ZY,ZX) :: ZEDSTEPL=1 :: RETURN //CHANGE TO APPROPRIATE PATTERN AND LOCATION, RECALL SPRITE AND CHANGE PATTERN RECORD FOR NEXT CHECK
_ZPLSW2:
     CALL SPRITE(#TZEDZ,97,4,ZY,ZX) :: ZEDSTEPL=0 :: RETURN //SAME AS PREVIOUS COMMENT
_ZEDMOVE:
     IF ZDR=1 THEN _MOVER ELSE _MOVEL  //ADVANCE THE ZED'S MOVEMENT IN THE APPROPRIATE DIRECTION
_MOVER:  //MOVE RIGHT
     ZX=ZX+ZS :: IF ZX>=250 THEN _JMPZED1 ELSE _ZEDZCONT //WRAP AROUND FROM RIGHT TO LEFT IF EDGE OF LEVEL REACHED. 
_JMPZED1:  //RESET XP POSTION TO COMPLETE WRAP AROUND
     ZX=2 :: GOTO _ZEDZCONT  //CONTINUE ZED ADVANCEMENT
_MOVEL:  //MOVE LEFT
     ZX=ZX-ZS :: IF ZX<=1 THEN _JMPZED2 ELSE _ZEDZCONT //WRAP AROUND FROM LEFT TO RIGHT IF EDGE OF LEVEL REACHED.
_JMPZED2:
     ZX=249  //RESET XP POSTION TO COMPLETE WRAP AROUND
_ZEDZCONT:  //CONTINUE ZED ADVANCEMENT
     CALL LOCATE(#TZEDZ,ZY,ZX)
     CALL CHARPAT(97,ZPL1$) :: CALL CHARPAT(98,ZPL2$) //ZP=ZOMBIE PATTERN
     CALL CHARPAT(99,ZPR1$) :: CALL CHARPAT(100,ZPR2$)
_NEXTZED:
     NEXT ZCK
     RETURN
_ZCD:  //ZOMBI COLLISION DETECTION 
     IF ZOMBEZ<=0 THEN _GORET
     TZEDZ=ZEDZ(1,1) :: ZHOLX=ZEDZ(1,2) :: ZDR=ZEDZ(1,3) :: ZS=ZEDZ(1,4) :: AZED=ZEDZ(1,6)
//ZOMBI TO PLAYER COINC
     FOR ZHCK=1 TO 14
     TZEDZ=ZEDZ(ZHCK,1) :: ZHOLX=ZEDZ(ZHCK,2) :: ZDR=ZEDZ(ZHCK,3) :: ZS=ZEDZ(ZHCK,4) :: AZED=ZEDZ(ZHCK,6)//SPRITE NUMBER:ZEDHOL XPOS:DIRECTION:SPEED:ACTIVE? 
     IF AZED=-1 THEN _NXTHCOZ
     IF AZED=0 or TZEDZ=0 or ZS=0 or ZDR=0 or ZHOLX=0 THEN _ENDZHCZ
     IF PFALLIN<>0 or JMP=1 THEN _SKIPPLAYR
     CALL POSITION(#1,YP,XP) :: CALL POSITION(#TZEDZ,ZY,ZX)
     IF YP<>ZY THEN _SKIPPLAYR
     CALL COINC(#TZEDZ,#1,8,C) :: IF C<>0 THEN _GSPHIT ELSE _GORESET2 //CHECK FOR ZED COLLISION WITH PLAYER. IF NO COLLISION, RESET THE ATSPEED COUNTER AND CONTINUE.
_GSPHIT: //CHECK IF PLAYER DODGES FIRST AND OTHER KEYBOARD INPUTS.
//print "0085ZDR:";ZDR :: 
     CALL KEY(1,K,S) :: IF S=0 THEN _GSCZ :: IF K=0 AND S=-1 THEN _QUIT
     IF K=16 THEN _BOARDPROG //DEVELOPER CHEAT TO TEST _LDS
     IF K=6 THEN _RESET // :: IF K=3 THEN GOSUB _DEBUGGER
     IF K=18 OR K=74 OR K=106 THEN _GSAJMP  //PLAYER DODGES/JUMPS
     GOTO _GSCZ
_GSAJMP: 
     JMP=1 :: GOSUB _JUMP :: JMP=0 :: GOTO _SKIPPLAYR
_GSCZ: //THERE IS A COINC BETWEEN PLAYER AND ZED
     IF ATDELAY=10 THEN _NOATDELAY
     ATDELAY=ATDELAY-1 :: IF ATDELAY>=1 THEN _SKIPPLAYR
     ATDELAY=10
_NOATDELAY: 
     ATDELAY=ATDELAY-1 :: CALL SOUND(100,-4,0,110,0,1000,0) :: HEALTH=HEALTH-1 :: IF HEALTH<=0 THEN _DEAD :: GOSUB _GUI
     GOTO _SKIPPLAYR // CHECK FOR COINC BETWEEN ZED AND HOLE
_GORESET2:
     ATDELAY=10 //RESET ZOMBIE ATTACK DELAY
//ZOMBI TO HEART COINC
_SKIPPLAYR: 
     IF ZHOL<>0 THEN _NOCALPOS //THIS IS A PATCH TO CORRECT A GLITCH WHERE ZHOL=0
     TZEDZ=ZEDZ(ZHCK,1) :: IF TZEDZ=0 THEN _ENDZHCZ :: CALL POSITION(#TZEDZ,ZY,ZX)
_NOCALPOS:
     IF ZY=33 THEN _ZY33
     IF ZY=57 THEN _ZY57
     IF ZY=81 THEN _ZY81
     IF ZY=105 THEN _ZY105
     IF ZY=129 THEN _ZY129
     IF ZY=153 THEN _ZY153
     IF ZY=177 THEN _ZY177
//PRINT "ZY GLITCH AT ZCD" :: BREAK
_ZY33:
     ZLDET=10 :: ZRDET=11 :: ZHOL=3 :: GOTO _ZCOLDETS 
_ZY57:
     ZLDET=12 :: ZRDET=13 :: ZHOL=4 :: GOTO _ZCOLDETS 
_ZY81:
     ZLDET=14 :: ZRDET=15 :: ZHOL=5 :: GOTO _ZCOLDETS 
_ZY105:
     ZLDET=16 :: ZRDET=17 :: ZHOL=6 :: GOTO _ZCOLDETS 
_ZY129:
     ZLDET=18 :: ZRDET=19 :: ZHOL=7 :: GOTO _ZCOLDETS 
_ZY153:
     ZLDET=20 :: ZRDET=21 :: ZHOL=8 :: GOTO _ZCOLDETS 
_ZY177:
     ZLDET=22 :: ZRDET=23 :: ZHOL=2 :: GOTO _ZCOLDETS
_ZCOLDETS:
     IF HDC=1 THEN _GORET
     AHART=HART(1,1) :: AHARTY=HART(2,1)// :: AHARTX=HART(3,1)
     FOR ZHCOINC=1 TO 14 :: IF HARTZ<=0 THEN _ENDHCOZ
     AHART=HART(1,ZHCOINC) :: AHARTY=HART(2,ZHCOINC)// :: AHARTX=HART(3,ZHCOINC)
     IF AHART=0 THEN _ENDHCOZ
     IF AHART=-1 THEN _NXTHCOZ
     IF AHART<>ZLDET AND AHART<>ZRDET THEN _NXTHCOZ
     IF ZY<>(AHARTY+1) THEN _NXTHCOZ
// SET DEBUGGER HERE********************************************************************************************* 
     CALL COINC(#TZEDZ,#AHART,8,C) :: IF C=0 THEN _NXTHCOZ
     CALL DELSPRITE(#AHART) :: HART(1,ZHCOINC)=-1 ::  HARTZ=HARTZ-1
     IF AZED=-1 THEN _NXTHCOZ
     IF AZED=0 or TZEDZ=0 or ZS=0 or ZDR=0 or ZHOLX=0 THEN _ENDZHCZ
_ENDHCOZ:
     ZHCOINC=14
_NXTHCOZ:
     NEXT ZHCOINC
//ZOMBI TO HOLE COINC 
_HOLZEDCHKR:
     HDC=1 :: GOSUB _SKIPPLAYR :: HDC=0
     IF ZHOL=2 THEN _NXTZHCZ
     CALL COINC(#TZEDZ,#ZHOL,6,C) :: IF C=0 THEN _NXTZHCZ
_CHDZEDHOL:
     IF BOARD<=50 AND ZY<YP THEN _GSZFALL ELSE _CZGCC //CHECK FOR FALLING ZED ENABLE ELSE CONTINUE CHECK ZED HOLE COLLISION CHECKS
_GSZFALL:
     GOSUB _ZFALL
_CZGCC:
     IF ZDR=1 THEN _POSH ELSE _NEGH
_POSH:
     ZX=ZX-6 :: CALL PATTERN(#TZEDZ,96) :: ZEDZ(ZHCK,3)=-1 :: ZDR=-1 :: ZX=ZX-ZS :: CALL LOCATE(#TZEDZ,ZY,ZX) :: GOSUB _ZEDPATTERN
     ZS=INT((RND*ZSS)+1) :: ZEDZ(ZHCK,4)=ZS //SETS RANDOM ZED SPEED
     IF ZX<=1 THEN _JMPZED3 ELSE _ZEDZCONT1
_JMPZED3:
     ZX=249 
_ZEDZCONT1:
     GOTO _NXTZHCZ
_NEGH:
     ZX=ZX+6 :: CALL PATTERN(#TZEDZ,96) :: ZEDZ(ZHCK,3)=1 :: ZDR=1 :: ZX=ZX+ZS :: CALL LOCATE(#TZEDZ,ZY,ZX) :: GOSUB _ZEDPATTERN
     ZS=INT((RND*ZSS)+1) :: ZEDZ(ZHCK,4)=ZS //SETS RANDOM ZED SPEED
     IF ZX>=250 THEN _JMPZED4 ELSE _NXTZHCZ
_JMPZED4:
     ZX=2
     GOTO _NXTZHCZ
_ENDZHCZ:
//TRAP=14 :: GOSUB _DEBUGGER
     ZHCK=14
_NXTZHCZ:
     NEXT ZHCK
     RETURN
 
_ZFALL: 
     FOR ZFALLIN=12 TO 1 STEP -1 :: ZY=ZY+2 :: CALL SOUND(1,FALLIN*110,5) :: CALL SPRITE(#TZDEZ,96,6,ZY,ZX) :: NEXT ZFALLIN
     IF ZY=9 THEN _ZFY9
     IF ZY=33 THEN _ZFY33
     IF ZY=57 THEN _ZFY57
     IF ZY=81 THEN _ZFY81
     IF ZY=105 THEN _ZFY105
     IF ZY=129 THEN _ZFY129
     IF ZY=153 THEN _ZFY153
     IF ZY=177 THEN _ZFY177
_ZFY9:
     NZHOL=2 :: GOTO _NEWZHOLE 
_ZFY33:
     NZHOL=3 :: GOTO _NEWZHOLE 
_ZFY57:
     NZHOL=4 :: GOTO _NEWZHOLE 
_ZFY81:
     NZHOL=5 :: GOTO _NEWZHOLE 
_ZFY105:
     NZHOL=6 :: GOTO _NEWZHOLE 
_ZFY129:
     NZHOL=7 :: GOTO _NEWZHOLE 
_ZFY153:
     NZHOL=8 :: GOTO _NEWZHOLE 
_ZFY177:
     NZHOL=2 :: GOTO _NEWZHOLE
_NEWZHOLE:
     ZEDZ(ZHCK,2)=NZHOL :: RETURN
//_CRAWLERAI:
//CHASES AND DESTROYS HEARTS IF ANY, THEN GOES AFTER PLAYER. NEED CZHELTH DEFINED. MOVE CRAWLER LEVEL TO LEVEL LOOKING FOR HEARTS. LEVEL = PLAYER LEVEL THEN AGRO TO PLAYER
// RETURN
//_CRAWLERSPAWN:
//SPAWN ONE CRAWLER AT EACH 50< LEVEL - MAKE IT 2 AT LEVEL 25 AND 3 AT LEVEL 0
 
!MERGE DSK2.ZOMBITS3-M
!100 GOSUB 30000
!1040 GOSUB 30270
!SAVE DSK2.ZOMB50-X
!SAVE DSK2.ZOMB50-M,MERGE
!LIST "CLIP"
!RUN
// EDIT ABOVE 3 LINES BEFORE PASTING
END //OFFICIAL END OF MAIN PROGRAM ***************************************************************************************************************************************
 
//
//CHARECTER CODE RECORDS
//104=IDLE CG:2
//136=MAN MELEE ATTACK 
//137=MAN RANGED LEFT
//138=MAN RANGED RIGHT
//NUMBER 0-9 = 48-57 = 3,4
//105-110 RR = 6 PATTERNS
//120-122 SJR = 3 PAT
//123-125 JR = 3 PAT
//126-127 LR = 2 PAT
//104 = IDLE
//113-118 RL = 6 PAT
//128-130 SJL = 3 PAT 
//131-133 JL = 3 PAT
//134-135 LL = 2 PAT
 
//32,112,111,119,139-142: BLANK COLOR: N/A COLOR SETS: N/A
//33-47:W,G,Z,I,I,+,J,C,K,Q,U,L,F,H COLOR: 12* COLOR SETS: 1, 2
//48-57: NUMBERS 0-9 COLOR: 12* COLOR SETS: 3, 4
//58-74:M,V,A,Y,V,W,X,T,O,Q,G,B,P,R,E,S,N COLOR: 12* COLOR SETS: 4, 5, 6
//75-77: SCORE CHAR  COLOR: 12 COLOR SETS: 6
//78-79:LEVEL CHAR.  COLOR: 12 COLOR SETS: 6
//80-89:*, ~, MELEE ATTACK, BULLET, :, &, (, ), =, .CLR: 12*6 COLOR SETS: 7, 8
//90:HEART.  COLOR: 7 COLOR SETS: 8
//91:MELEE WEAPON.  COLOR: 8  COLOR SETS: 8
//92:RANGED WEAPON. COLOR: 8 COLOR SETS: 8
//93:BAD GIRDER.  COLOR: 15 COLOR SETS: 8
//94:GIRDER.  COLOR: 15* COLOR SETS: 8
//95:THE HOLE.  ASSIGNED VARIABLE HCLR COLOR: 15 COLOR SETS: 8
//96:ZOMBIE.  COLOR: 4 COLOR SETS: 9
//97-98: ZOMBIE RUN LEFT COLOR: 4 COLOR SETS: 9
//99-100: ZOMBIE RUN RIGHT COLOR: 4 COLOR SETS: 9
//101-102&103:ZOMBIE CRAWLER&ZCRAWLER IDLE COLOR: 13 COLOR SETS: 9
//104:PLAYER IDLE COLOR: 6 COLOR SETS: 10
//105-110:PLAYER RUN RIGHT COLOR: 6 COLOR SETS: 10
//113-118:PLAYER RUN LEFT COLOR: 6 COLOR SETS: 11
//120-127:PLAYER STOP,JUMP,LAND RIGHT COLOR: 6 COLOR SETS: 12
//128-135:PLAYER STOP,JUMP,LAND LEFT COLOR: 6 COLOR SETS: 13
//136: PLAYER MELEE ATTACK COLOR: 6 COLOR SETS: 14
//137-138:PLAYER RANGED ATTACK LEFT AND RIGHT. COLOR: 6 COLOR SETS: 14
//143:THE EXIT.  COLOR: 10* COLOR SETS: 14
//*USE CALL COLOR - THE REST ARE SPRITES AND GET ASSIGNED UPON CREATION.
 

 

 

 

And how V0.50 looks after TidBit translation and merged with the title screens.
don't attempt to run this, it won't work. The compressed data gets corrupted once copied/pasted.

 

 
100 GOSUB 30000
110 SCORE=5 :: HEALTH=5 :: BOARD=99 :: MELEE=5 :: RANGED=5 :: BULL=1 :: MAXHEALTH=10 :: MAXZHELTH=4
120 ZEDPERC=20 :: ZEDSTEPL=0 :: ZEDSETPR=0 :: JDELAY=8 :: MAXMELEE=10 :: MAXRANGED=10
130 ATDELAY=10 :: ZSS=3
140 RANDOMIZE
150 SLOT=10
160 OPTION BASE 1
170 DIM LO0T(2,14)
180 DIM HART(3,14)
190 DIM RANG(1,14)
200 DIM MELE(1,14)
210 DIM ZEDZ(14,6)
220 LTN=1 :: LAB=1 :: SHL=2 :: GRND=17 :: ZHELTH=4 :: YP=9 :: XP=8 :: PD=1 :: PS=2
230 JMP=0 :: ZOMBEZ=0 :: ZDR=1 :: HCLR=1 :: TYMER=BOARD*2
240 RLUT=1 :: MLUT=1 :: HLUT=1 :: HARTZ=0 :: RANGZ=0 :: MELEZ=0 :: PFALLIN=O
250 ZHOL=2
260 CALL COLOR(1,12,1,2,12,1,3,12,1,4,12,1,5,12,1,6,12,1,7,12,1,8,15,1,14,10,1):: CALL CLEAR :: CALL SCREEN(2)
270 GOSUB 830
280 HLE=INT((RND*15)+5):: FOR LVL=1 TO 8 :: IF LVL<>1 THEN 290 ELSE 300
290 GOSUB 440
300 CALL VCHAR(1,1,94,24):: CALL VCHAR(1,32,94,24):: CALL HCHAR(LVL*3,1,94,HLE-1)
310 IF LVL=8 THEN 350 ELSE 320
320 CALL SPRITE(#SHL,95,HCLR,GRND-7,(HLE*+1):: SHL=SHL+1
330 NHLE=INT((GRND+1)/8)
340 CALL HCHAR(NHLE+1,HLE+1,95)
350 LASTHLE=(HLE*+1 :: CALL HCHAR(LVL*3,HLE+3,94,32-(HLE+3))
360 IF LVL=8 THEN 410 ELSE 370
370 CALL HCHAR(LVL*3,HLE,93):: CALL HCHAR(LVL*3,HLE+2,93):: GRND=GRND+24
380 HOL=INT((RND*15)+5)
390 IF HOL=HLE THEN 380 ELSE 400
400 HLE=HOL
410 NEXT LVL
420 FOR EXTX=1 TO 31 STEP 30 :: FOR EXTY=2 TO 23 STEP 3 :: CALL HCHAR(EXTY,EXTX,143):: NEXT EXTY :: NEXT EXTX
430 CALL HCHAR(24,1,94,31):: GOTO 1130
440 SIDEZ=-40
450 FOR REPT=1 TO 2
460 IF LVL=8 AND ZOMBEZ=0 THEN 550
470 LDSN=INT(RND*100)+(1+ZEDPERC)
480 IF LDSN<BOARD THEN 720
490 LDSN=INT(RND*100)+(1+ZEDPERC)
500 IF LDSN>BOARD THEN 550
510 CALL SPRITE(#SLOT,90,7,GRND-9,((HLE+1)*+SIDEZ):: CALL POSITION(#SLOT,HY,HX):: HART(2,HLUT)=HY :: HART(3,HLUT)=HX
520 HART(1,HLUT)=SLOT :: SLOT=SLOT+1 :: HLUT=HLUT+1 :: HARTZ=HARTZ+1
530 LO0T(LAB,LTN)=90 :: LAB=LAB+1 :: LO0T(LAB,LTN)=SLOT-1 :: LAB=1 :: LTN=LTN+1
540 GOTO 800
550 IF BOARD>=51 THEN 560
560 CALL SPRITE(#SLOT,96,4,GRND-8,((HLE+1)*+SIDEZ)
570 ZHELTH=MAXZHELTH
580 ZOMBEZ=ZOMBEZ+1
590 ZEDZ(ZOMBEZ,1)=SLOT
600 ZHOLX=((HLE+1)*
610 ZEDZ(ZOMBEZ,2)=ZHOLX
620 ZEDZ(ZOMBEZ,3)=ZDR
630 ZS=INT((RND*ZSS)+1)
640 ZEDZ(ZOMBEZ,4)=ZS
650 ZEDZ(ZOMBEZ,5)=ZHELTH
660 ZEDZ(ZOMBEZ,6)=1
670 SLOT=SLOT+1
680 LO0T(LAB,LTN)=96 :: LAB=LAB+1 :: LO0T(LAB,LTN)=SLOT-1 :: LAB=1 :: LTN=LTN+1
690 IF BOARD>33 THEN 800
700 GOSUB 820
710 GOTO 800
720 LDSN=INT(RND*100)+1
730 LDSN=LDSN+ZEDPERC
740 IF LDSN<BOARD THEN 780
750 MELE(1,MLUT)=SLOT :: MLUT=MLUT+1 :: MELEZ=MELEZ+1
760 CALL SPRITE(#SLOT,91,8,GRND-9,((HLE+1)*+SIDEZ):: SLOT=SLOT+1 :: LO0T(LAB,LTN)=91 :: LAB=LAB+1 :: LO0T(LAB,LTN)=SLOT-1 :: LAB=1 :: LTN=LTN+1
770 GOTO 800
780 RANG(1,RLUT)=SLOT :: RLUT=RLUT+1 :: RANGZ=RANGZ+1
790 CALL SPRITE(#SLOT,92,14,GRND-9,((HLE+1)*+SIDEZ):: SLOT=SLOT+1 :: LO0T(LAB,LTN)=92 :: LAB=LAB+1 :: LO0T(LAB,LTN)=SLOT-1 :: LAB=1 :: LTN=LTN+1
800 SIDEZ=40 :: NEXT REPT
810 RETURN
820 RETURN
830 DISPLAY AT(1,3):SCORE :: DISPLAY AT(1,10):BOARD :: DISPLAY AT(1,15):HEALTH :: DISPLAY AT(1,21):MELEE :: DISPLAY AT(1,26):RANGED
840 CALL VCHAR(1,3,75):: CALL VCHAR(1,4,76):: CALL VCHAR(1,5,77):: CALL VCHAR(1,12,79):: CALL VCHAR(1,17,64):: CALL VCHAR(1,23,64)
850 CALL VCHAR(1,28,64):: CALL VCHAR(1,11,78):: CALL VCHAR(1,16,90):: CALL VCHAR(1,22,91):: CALL VCHAR(1,27,92):: RETURN
860 IF BOARD<=20 THEN 900
870 IF BOARD<=75 THEN 910
880 IF BOARD<=50 THEN 920
890 IF BOARD<=25 THEN 930 ELSE 940
900 ZEDPERC=0 :: GOTO 870
910 MAXHEALTH=20 :: GOTO 880
920 MAXRANGED=20 :: MAXZHELTH=6 :: GOTO 890
930 MAXMELEE=20
940 CALL DELSPRITE(ALL):: BOARD=BOARD-1 :: IF SCORE>HSCORE THEN 950 ELSE 960
950 HSCORE=SCORE
960 CALL SCREEN(2):: FOR CCLOR=0 TO 14 :: CALL COLOR(CCLOR,16,1):: NEXT CCLOR :: HCLR=2 :: CALL CLEAR
970 CALL VCHAR(11,12,47):: CALL VCHAR(11,13,36):: CALL VCHAR(11,14,34):: CALL VCHAR(11,15,47)
980 CALL VCHAR(11,16,73):: CALL VCHAR(11,17,40):: CALL VCHAR(11,18,66):: CALL VCHAR(11,19,71)
990 CALL VCHAR(11,20,72):: DISPLAY AT(12,13):HSCORE
1000 CALL LINK("DELAY",200)
1010 CALL KEY(1,K,S):: IF S=0 THEN 1010
1020 GOTO 140
1030 CALL SCREEN(10):: CALL CLEAR :: CALL DELSPRITE(ALL)
1040 GOSUB 30270
1050 FOR CCLOR=0 TO 14 :: CALL COLOR(CCLOR,16,10):: NEXT CCLOR
1060 DISPLAY AT(7,13):HSCORE :: DISPLAY AT(21,13):SCORE
1070 CALL SCREEN(2):: CALL LINK("DELAY",200)
1080 CALL KEY(1,K,S):: CALL JOYST(1,X,Y):: IF K<>-1 OR S<>0 OR X<>0 OR Y<>0 THEN 1100
1090 GOTO 1080
1100 CALL DELSPRITE(ALL):: GOTO 110
1110 CALL DELSPRITE(ALL):: GOTO 100
1120 CALL CLEAR :: END :: RETURN
1130 CALL SPRITE(#1,104,6,YP,XP)
1140 GOSUB 3080 :: GOSUB 3540 :: GOSUB 3860
1150 CALL JOYST(1,JX,JY):: CALL KEY(1,K,S):: IF K=0 AND S=-1 THEN 1120
1160 IF K=16 THEN 860
1170 IF K=6 THEN 1110
1180 IF K=18 OR K=74 OR K=106 THEN 1200
1190 IF JX<>0 OR JY<>0 THEN 1210 ELSE 1130
1200 JMP=1 :: GOSUB 1930 :: JMP=0 :: GOTO 1210
1210 IF JY=0 THEN 1230 ELSE 1220
1220 GOSUB 2250
1230 CALL KEY(1,K,S):: IF K=16 THEN 860
1240 IF K=18 OR K=74 OR K=106 THEN 1250 ELSE 1260
1250 JMP=1 :: GOSUB 1930 :: JMP=0
1260 IF JX<>0 THEN 1300
1270 IF JY<>0 THEN 1280 ELSE 1290
1280 GOSUB 2250
1290 GOTO 1130
1300 IF JX=-4 THEN 1310 ELSE 1320
1310 GOSUB 1660
1320 IF JX=4 THEN 1330 ELSE 1130
1330 GOSUB 1410
1340 CALL KEY(1,K,S):: IF K=16 THEN 860
1350 IF K=18 OR K=74 OR K=106 THEN 1360 ELSE 1370
1360 JMP=1 :: GOSUB 1930 :: JMP=0
1370 IF JX<>0 THEN 1300
1380 IF JY<>0 THEN 1390 ELSE 1400
1390 GOSUB 2250
1400 GOTO 1130
1410 IF XP>=250 THEN 1420 ELSE 1430
1420 XP=2
1430 PD=1 :: CALL SPRITE(#1,105,6,YP,XP)
1440 FOR PATR=105 TO 110 :: CALL PATTERN(#1,PATR):: CALL SOUND(1,-2,20):: XP=XP+PS
1450 IF XP>=250 THEN 1460 ELSE 1470
1460 XP=2
1470 CALL LOCATE(#1,YP,XP):: CALL KEY(1,K,S)
1480 IF K=18 THEN 1510
1490 IF K=74 THEN 1510
1500 IF K=106 THEN 1510 ELSE 1520
1510 JMP=1 :: PATR=110 :: GOTO 1580
1520 CALL JOYST(1,JX,JY):: IF JY=0 THEN 1540 ELSE 1530
1530 GOSUB 2250
1540 IF JX<>0 THEN 1560
1550 CALL SPRITE(#1,104,6,YP,XP):: RETURN
1560 IF JX=4 THEN 1580
1570 IF JX=-4 THEN 3530 ELSE 1580
1580 CALL COINC(ALL,C):: IF C=0 THEN 1600
1590 GOSUB 3080
1600 IF ZOMBEZ=0 THEN 1620
1610 GOSUB 3540 :: GOSUB 3860
1620 NEXT PATR
1630 IF JMP=1 THEN 1640 ELSE 1650
1640 GOSUB 1930 :: JMP=0
1650 IF JX=4 THEN 1410 ELSE 3530
1660 IF XP<=1 THEN 1670 ELSE 1680
1670 XP=249
1680 PD=-1 :: CALL SPRITE(#1,113,6,YP,XP)
1690 FOR PATL=113 TO 118 :: CALL PATTERN(#1,PATL):: CALL SOUND(1,-2,20):: XP=XP-PS
1700 IF XP<=1 THEN 1710 ELSE 1720
1710 XP=249
1720 CALL LOCATE(#1,YP,XP):: CALL KEY(1,K,S)
1730 IF K=18 THEN 1760
1740 IF K=74 THEN 1760
1750 IF K=106 THEN 1760 ELSE 1770
1760 JMP=1 :: PATL=118 :: GOTO 1830
1770 CALL JOYST(1,JX,JY):: IF JY=0 THEN 1790 ELSE 1780
1780 GOSUB 2250
1790 IF JX<>0 THEN 1810
1800 CALL SPRITE(#1,44,6,YP,XP):: RETURN
1810 IF JX=-4 THEN 1830
1820 IF JX=4 THEN 3530 ELSE 1830
1830 CALL COINC(ALL,C):: IF C=0 THEN 1850
1840 GOSUB 3080
1850 IF ZOMBEZ=0 THEN 1870
1860 GOSUB 3540 :: GOSUB 3860
1870 NEXT PATL
1880 IF JMP=1 THEN 1890 ELSE 1920
1890 GOSUB 1930 :: JMP=0 :: GOSUB 3080
1900 IF ZOMBEZ=0 THEN 1920
1910 GOSUB 3540 :: GOSUB 3860
1920 IF JX=-4 THEN 1660 ELSE 3530
1930 JMP=0
1940 IF PD<>-1 THEN 1970
1950 S1=128 :: J1=131 :: L1=134 :: JSND=18 :: S2=130 :: J2=133 :: L2=135 :: JMPDIS=-1
1960 GOTO 1990
1970 IF PD<>1 THEN 3530
1980 S1=120 :: J1=123 :: L1=126 :: JSND=10 :: S2=122 :: J2=125 :: L2=127 :: JMPDIS=1
1990 CALL LOCATE(#1,YP,XP)
2000 FOR PTS=S1 TO S2 :: CALL SOUND(1,(PTS-JSND),5):: CALL PATTERN(#1,PTS):: NEXT PTS
2010 FOR UDELAY=1 TO JDELAY :: IF ZOMBEZ=0 THEN 2030
2020 GOSUB 3540 :: GOSUB 3860
2030 NEXT UDELAY
2040 YP=YP-3 :: CALL LOCATE(#1,YP,XP)
2050 JMP=1
2060 FOR PTJ=J1 TO J2
2070 FOR PTJP=1 TO 7
2080 XP=XP+JMPDIS
2090 IF XP<=1 THEN 2100 ELSE 2110
2100 XP=248 :: GOTO 2130
2110 IF XP>=249 THEN 2120 ELSE 2130
2120 XP=2
2130 CALL PATTERN(#1,PTJ):: CALL SOUND(1,(PTJ-JSND),5):: CALL LOCATE(#1,YP,XP)
2140 NEXT PTJP
2150 NEXT PTJ
2160 YP=YP+3 :: CALL LOCATE(#1,YP,XP)
2170 FOR PTL=L1 TO L2
2180 IF PTL=L1 THEN 2210
2190 IF ZOMBEZ=0 THEN 2210
2200 GOSUB 3540 :: GOSUB 3860
2210 CALL PATTERN(#1,PTL):: CALL SOUND(1,(PTL-JSND),5):: NEXT PTL
2220 CALL COINC(ALL,C):: IF C<>0 THEN 2230 ELSE 2240
2230 RETURN
2240 ATDELAY=10 :: RETURN
2250 IF JY=4 AND MELEE>=1 THEN 2290 :: IF JY=4 AND MELEE<=0 THEN 2280
2260 IF JY=-4 THEN 2270 ELSE 3530
2270 GOSUB 2700 :: RETURN
2280 CALL SOUND(100,-3,0):: RETURN
2290 MELEE=MELEE-1 :: GOSUB 830
2300 GOSUB 2340 :: RETURN
2310 IF JY=-4 THEN 2330 ELSE 2320
2320 CALL SOUND(100,-6,0):: RETURN
2330 GOSUB 2700 :: RETURN
2340 CALL PATTERN(#1,136)
2350 IF XP+8>=250 THEN 2370
2360 CALL SPRITE(#24,82,12,YP,XP+:: GOTO 2380
2370 CALL SPRITE(#24,82,12,YP,XP)
2380 CALL SOUND(125,-5,0)
2390 GOSUB 2480
2400 IF XP+8>=250 THEN 2430
2410 CALL DELSPRITE(#24):: IF XP-8<=1 THEN 2430
2420 CALL SPRITE(#25,82,12,YP,XP-:: GOTO 2440
2430 CALL SPRITE(#25,82,12,YP,XP)
2440 CALL SOUND(125,-6,0)
2450 GOSUB 2500
2460 CALL DELSPRITE(#25):: CALL PATTERN(#1,136)
2470 RETURN
2480 FOR DET=10 TO 23 :: CALL COINC(#24,#DET,7,C):: IF C<>0 THEN 2520
2490 NEXT DET :: RETURN
2500 FOR DET=10 TO 23 :: CALL COINC(#25,#DET,7,C):: IF C<>0 THEN 2520
2510 NEXT DET :: RETURN
2520 TLOOP1=DET-9
2530 IF LO0T(1,TLOOP1)<>96 THEN 2630
2540 CALL COLOR(#DET,7):: LSPRN=LO0T(2,TLOOP1)
2550 FOR ZCHEK=1 TO 14
2560 ZPRN=ZEDZ(ZCHEK,1)
2570 IF LSPRN<>ZPRN THEN 2610
2580 ZHELTH=ZEDZ(ZCHEK,5):: ZHELTH=ZHELTH-1 :: ZEDZ(ZCHEK,5)=ZHELTH
2590 IF ZHELTH>=1 THEN 3530
2600 SCORE=SCORE+15 :: ZEDZ(ZCHEK,6)=-1 :: CALL DELSPRITE(#LSPRN):: ZOMBEZ=ZOMBEZ-1 :: RETURN
2610 NEXT ZCHEK
2620 RETURN
2630 IF LO0T(1,TLOOP1)<>90 THEN 2640 ELSE 2660
2640 IF LO0T(1,TLOOP1)<>91 THEN 2650 ELSE 2660
2650 IF LO0T(1,TLOOP1)<>92 THEN 3530
2660 FOR LCHEK=1 TO 14 :: IF DET=LO0T(LCHEK,2)THEN 2670 ELSE 2680
2670 LCHEK=14
2680 NEXT LCHEK :: CALL DELSPRITE(#DET)
2690 RETURN
2700 IF RANGED<=0 THEN 2710 ELSE 2720
2710 CALL SOUND(100,-3,0):: RETURN
2720 RANGED=RANGED-1 :: CALL SOUND(100,-6,0):: GOSUB 830
2730 YB=YP
2740 IF PD<>1 THEN 2790
2750 CALL PATTERN(#1,138)
2760 BULL=1
2770 XB=XP+32
2780 GOTO 2830
2790 IF PD<>-1 THEN 3530
2800 CALL PATTERN(#1,137)
2810 BULL=-1
2820 XB=XP-32
2830 CALL SPRITE(#26,83,6,YB,XB)
2840 FOR BHCK=2 TO 8
2850 CALL COINC(#26,#BHCK,8,C):: IF C=0 THEN 2870
2860 XB=XB+BULL :: CALL LOCATE(#26,YB,XB):: IF XB<=2 OR XB>=249 THEN 3050 ELSE 2850
2870 NEXT BHCK
2880 CALL COINC(ALL,C):: IF C<>0 THEN 2900
2890 XB=XB+BULL :: IF XB<=2 OR XB>=249 THEN 3050 ELSE 2830
2900 CALL LOCATE(#26,YB,XB):: FOR LCHECK=1 TO 14 :: LSPRN=LO0T(2,LCHECK):: LCHKB=LO0T(1,LCHECK)
2910 IF LSPRN<=9 OR LSPRN>=24 THEN 2920 ELSE 2930
2920 XB=XB+BULL :: CALL LOCATE(#26,YB,XB):: CALL COINC(#26,#LSPRN,8,C):: IF C<>0 THEN 2910
2930 CALL COINC(#26,#LSPRN,8,C)
2940 IF C=0 THEN 3040
2950 IF LCHKB=96 THEN 2960 ELSE 3020
2960 CALL COLOR(#LSPRN,7)
2970 FOR ZCHEK=1 TO 14 :: AZED=ZEDZ(ZCHEK,6):: IF AZED=-1 THEN 3030
2980 ZPRN=ZEDZ(ZCHEK,1):: IF LSPRN<>ZPRN THEN 3030
2990 ZHELTH=ZEDZ(ZCHEK,5):: ZHELTH=ZHELTH-2 :: ZEDZ(ZCHEK,5)=ZHELTH
3000 IF ZHELTH>=1 THEN 3050
3010 SCORE=SCORE+15 :: ZEDZ(ZCHEK,6)=-1 :: CALL DELSPRITE(#LSPRN):: ZOMBEZ=ZOMBEZ-1 :: GOTO 3050
3020 CALL COLOR(#LSPRN,7):: CALL DELSPRITE(#LSPRN):: LO0T(2,LCHECK)=1 :: GOTO 3050
3030 NEXT ZCHEK :: GOTO 3050
3040 NEXT LCHECK :: GOTO 2890
3050 CALL DELSPRITE(#26):: GOSUB 830 :: CALL JOYST(1,JX,JY):: IF JY=0 THEN 3530
3060 IF JY-4 THEN 3070 ELSE 3530
3070 GOSUB 2700 :: RETURN
3080 IF JMP=1 THEN 3530
3090 IF HARTZ<=0 THEN 3220
3100 FOR HCOINC=1 TO 14
3110 AHART=HART(1,HCOINC)
3120 IF AHART=-1 THEN 3210
3130 IF AHART=0 THEN 3200
3140 CALL COINC(#1,#AHART,8,C)
3150 IF C=0 THEN 3210
3160 SCORE=SCORE+10 :: CALL SOUND(1,500,5):: CALL SOUND(1,600,2)
3170 IF HEALTH<MAXHEALTH THEN 3180 ELSE 3190
3180 HEALTH=HEALTH+1
3190 GOSUB 830 :: CALL DELSPRITE(#AHART):: HART(1,HCOINC)=-1 :: HARTZ=HARTZ-1 :: GOTO 3210
3200 HCOINC=14
3210 NEXT HCOINC
3220 IF MELEZ=0 THEN 3340
3230 FOR MCOINC=1 TO 14
3240 AMELE=MELE(1,MCOINC)
3250 IF AMELE=-1 THEN 3330
3260 IF AMELE=0 THEN 3320
3270 CALL COINC(#1,#AMELE,8,C)
3280 IF C=0 THEN 3330
3290 SCORE=SCORE+3 :: IF MELEE<MAXMELEE THEN 3300 ELSE 3310
3300 MELEE=MELEE+1
3310 CALL SOUND(1,1500,5):: CALL SOUND(1,1600,2):: GOSUB 830 :: CALL DELSPRITE(#AMELE):: MELE(1,MCOINC)=-1 :: MELEZ=MELEZ-1
3320 MCOINC=14
3330 NEXT MCOINC
3340 IF RANGZ=0 THEN 3460
3350 FOR RCOINC=1 TO 14
3360 ARANG=RANG(1,RCOINC)
3370 IF ARANG=-1 THEN 3450
3380 IF ARANG=0 THEN 3440
3390 CALL COINC(#1,#ARANG,8,C)
3400 IF C=0 THEN 3450
3410 SCORE=SCORE+5 :: IF RANGED<MAXRANGED THEN 3420 ELSE 3430
3420 RANGED=RANGED+1
3430 CALL SOUND(1,1000,5):: CALL SOUND(1,1200,2):: GOSUB 830 :: CALL DELSPRITE(#ARANG):: RANG(1,RCOINC)=-1 :: RANGZ=RANGZ-1
3440 RCOINC=14
3450 NEXT RCOINC
3460 FOR HOLDET=2 TO 8
3470 CALL COINC(#1,#HOLDET,10,C)
3480 IF C=0 THEN 3500
3490 FOR FALLIN=12 TO 1 STEP -1 :: YP=YP+2 :: CALL SOUND(1,FALLIN*110,5):: CALL SPRITE(#1,104,6,YP,XP):: PFALLIN=1 :: GOSUB 3540 :: NEXT FALLIN :: PFALLIN=0
3500 NEXT HOLDET
3510 CALL POSITION(#1,YP,XP):: IF YP=177 AND XP>=235 THEN 860
3520 IF YP=177 AND XP<=8 THEN 860
3530 RETURN
3540 IF ZOMBEZ=0 THEN 3530
3550 TZEDZ=ZEDZ(1,1):: ZHOLX=ZEDZ(1,2):: ZDR=ZEDZ(1,3):: ZS=ZEDZ(1,4):: AZED=ZEDZ(1,6)
3560 FOR ZCK=1 TO 14
3570 TZEDZ=ZEDZ(ZCK,1):: ZHOLX=ZEDZ(ZCK,2):: ZDR=ZEDZ(ZCK,3):: ZS=ZEDZ(ZCK,4):: AZED=ZEDZ(ZCK,6)
3580 IF AZED=-1 THEN 3840
3590 IF TZEDZ=0 THEN 3600 ELSE 3610
3600 ZCK=14 :: GOTO 3840
3610 CALL POSITION(#TZEDZ,ZY,ZX)
3620 CALL POSITION(#1,YP,XP)
3630 IF BOARD>66 THEN 3680
3640 IF YP<>ZY AND BOARD>33 THEN 3680
3650 IF ZX<XP THEN 3670
3660 ZDR=-1 :: ZEDZ(ZCK,3)=-1 :: GOTO 3680
3670 ZDR=1 :: ZEDZ(ZCK,3)=1
3680 GOSUB 3690 :: GOTO 3760
3690 IF ZDR=1 THEN 3700 ELSE 3730
3700 IF ZEDSTEPR=0 THEN 3710 ELSE 3720
3710 CALL SPRITE(#TZEDZ,100,4,ZY,ZX):: ZEDSTEPR=1 :: RETURN
3720 CALL SPRITE(#TZEDZ,99,4,ZY,ZX):: ZEDSTEPR=0 :: RETURN
3730 IF ZEDSTEPL=0 THEN 3740 ELSE 3750
3740 CALL SPRITE(#TZEDZ,98,4,ZY,ZX):: ZEDSTEPL=1 :: RETURN
3750 CALL SPRITE(#TZEDZ,97,4,ZY,ZX):: ZEDSTEPL=0 :: RETURN
3760 IF ZDR=1 THEN 3770 ELSE 3790
3770 ZX=ZX+ZS :: IF ZX>=250 THEN 3780 ELSE 3810
3780 ZX=2 :: GOTO 3810
3790 ZX=ZX-ZS :: IF ZX<=1 THEN 3800 ELSE 3810
3800 ZX=249
3810 CALL LOCATE(#TZEDZ,ZY,ZX)
3820 CALL CHARPAT(97,ZPL1$):: CALL CHARPAT(98,ZPL2$)
3830 CALL CHARPAT(99,ZPR1$):: CALL CHARPAT(100,ZPR2$)
3840 NEXT ZCK
3850 RETURN
3860 IF ZOMBEZ<=0 THEN 3530
3870 TZEDZ=ZEDZ(1,1):: ZHOLX=ZEDZ(1,2):: ZDR=ZEDZ(1,3):: ZS=ZEDZ(1,4):: AZED=ZEDZ(1,6)
3880 FOR ZHCK=1 TO 14
3890 TZEDZ=ZEDZ(ZHCK,1):: ZHOLX=ZEDZ(ZHCK,2):: ZDR=ZEDZ(ZHCK,3):: ZS=ZEDZ(ZHCK,4):: AZED=ZEDZ(ZHCK,6)
3900 IF AZED=-1 THEN 4370
3910 IF AZED=0 OR TZEDZ=0 OR ZS=0 OR ZDR=0 OR ZHOLX=0 THEN 4540
3920 IF PFALLIN<>0 OR JMP=1 THEN 4080
3930 CALL POSITION(#1,YP,XP):: CALL POSITION(#TZEDZ,ZY,ZX)
3940 IF YP<>ZY THEN 4080
3950 CALL COINC(#TZEDZ,#1,8,C):: IF C<>0 THEN 3960 ELSE 4070
3960 CALL KEY(1,K,S):: IF S=0 THEN 4020 :: IF K=0 AND S=-1 THEN 1120
3970 IF K=16 THEN 860
3980 IF K=6 THEN 1110
3990 IF K=18 OR K=74 OR K=106 THEN 4010
4000 GOTO 4020
4010 JMP=1 :: GOSUB 1930 :: JMP=0 :: GOTO 4080
4020 IF ATDELAY=10 THEN 4050
4030 ATDELAY=ATDELAY-1 :: IF ATDELAY>=1 THEN 4080
4040 ATDELAY=10
4050 ATDELAY=ATDELAY-1 :: CALL SOUND(100,-4,0,110,0,1000,0):: HEALTH=HEALTH-1 :: IF HEALTH<=0 THEN 1030 :: GOSUB 830
4060 GOTO 4080
4070 ATDELAY=10
4080 IF ZHOL<>0 THEN 4100
4090 TZEDZ=ZEDZ(ZHCK,1):: IF TZEDZ=0 THEN 4540 :: CALL POSITION(#TZEDZ,ZY,ZX)
4100 IF ZY=33 THEN 4170
4110 IF ZY=57 THEN 4180
4120 IF ZY=81 THEN 4190
4130 IF ZY=105 THEN 4200
4140 IF ZY=129 THEN 4210
4150 IF ZY=153 THEN 4220
4160 IF ZY=177 THEN 4230
4170 ZLDET=10 :: ZRDET=11 :: ZHOL=3 :: GOTO 4240
4180 ZLDET=12 :: ZRDET=13 :: ZHOL=4 :: GOTO 4240
4190 ZLDET=14 :: ZRDET=15 :: ZHOL=5 :: GOTO 4240
4200 ZLDET=16 :: ZRDET=17 :: ZHOL=6 :: GOTO 4240
4210 ZLDET=18 :: ZRDET=19 :: ZHOL=7 :: GOTO 4240
4220 ZLDET=20 :: ZRDET=21 :: ZHOL=8 :: GOTO 4240
4230 ZLDET=22 :: ZRDET=23 :: ZHOL=2 :: GOTO 4240
4240 IF HDC=1 THEN 3530
4250 AHART=HART(1,1):: AHARTY=HART(2,1)
4260 FOR ZHCOINC=1 TO 14 :: IF HARTZ<=0 THEN 4360
4270 AHART=HART(1,ZHCOINC):: AHARTY=HART(2,ZHCOINC)
4280 IF AHART=0 THEN 4360
4290 IF AHART=-1 THEN 4370
4300 IF AHART<>ZLDET AND AHART<>ZRDET THEN 4370
4310 IF ZY<>(AHARTY+1)THEN 4370
4320 CALL COINC(#TZEDZ,#AHART,8,C):: IF C=0 THEN 4370
4330 CALL DELSPRITE(#AHART):: HART(1,ZHCOINC)=-1 :: HARTZ=HARTZ-1
4340 IF AZED=-1 THEN 4370
4350 IF AZED=0 OR TZEDZ=0 OR ZS=0 OR ZDR=0 OR ZHOLX=0 THEN 4540
4360 ZHCOINC=14
4370 NEXT ZHCOINC
4380 HDC=1 :: GOSUB 4080 :: HDC=0
4390 IF ZHOL=2 THEN 4550
4400 CALL COINC(#TZEDZ,#ZHOL,6,C):: IF C=0 THEN 4550
4410 IF BOARD<=50 AND ZY<YP THEN 4420 ELSE 4430
4420 GOSUB 4570
4430 IF ZDR=1 THEN 4440 ELSE 4490
4440 ZX=ZX-6 :: CALL PATTERN(#TZEDZ,96):: ZEDZ(ZHCK,3)=-1 :: ZDR=-1 :: ZX=ZX-ZS :: CALL LOCATE(#TZEDZ,ZY,ZX):: GOSUB 3690
4450 ZS=INT((RND*ZSS)+1):: ZEDZ(ZHCK,4)=ZS
4460 IF ZX<=1 THEN 4470 ELSE 4480
4470 ZX=249
4480 GOTO 4550
4490 ZX=ZX+6 :: CALL PATTERN(#TZEDZ,96):: ZEDZ(ZHCK,3)=1 :: ZDR=1 :: ZX=ZX+ZS :: CALL LOCATE(#TZEDZ,ZY,ZX):: GOSUB 3690
4500 ZS=INT((RND*ZSS)+1):: ZEDZ(ZHCK,4)=ZS
4510 IF ZX>=250 THEN 4520 ELSE 4550
4520 ZX=2
4530 GOTO 4550
4540 ZHCK=14
4550 NEXT ZHCK
4560 RETURN
4570 FOR ZFALLIN=12 TO 1 STEP -1 :: ZY=ZY+2 :: CALL SOUND(1,FALLIN*110,5):: CALL SPRITE(#TZDEZ,96,6,ZY,ZX):: NEXT ZFALLIN
4580 IF ZY=9 THEN 4660
4590 IF ZY=33 THEN 4670
4600 IF ZY=57 THEN 4680
4610 IF ZY=81 THEN 4690
4620 IF ZY=105 THEN 4700
4630 IF ZY=129 THEN 4710
4640 IF ZY=153 THEN 4720
4650 IF ZY=177 THEN 4730
4660 NZHOL=2 :: GOTO 4740
4670 NZHOL=3 :: GOTO 4740
4680 NZHOL=4 :: GOTO 4740
4690 NZHOL=5 :: GOTO 4740
4700 NZHOL=6 :: GOTO 4740
4710 NZHOL=7 :: GOTO 4740
4720 NZHOL=8 :: GOTO 4740
4730 NZHOL=2 :: GOTO 4740
4740 ZEDZ(ZHCK,2)=NZHOL :: RETURN
30000 CALL CLEAR :: CALL SCREEN(13)
30010 RESTORE 30360 !// SPRITESHEETS
30020 READ A$
30030 IF A$="" THEN 30060
30040 CALL LINK("CWRITE",A$)
30050 GOTO 30020
30060 RESTORE 30450 !//TITLE SCREEN
30070 READ B$
30080 IF B$="" THEN 30110
30090 CALL LINK("CWRITE",B$)
30100 GOTO 30070
30110 CALL CHAR(93,"D58027A282F72A21FFAAFFAAAAFFAAFFD25B810180000000"):: CALL LINK("DELAY",200)
30120 CALL KEY(0,K,S):: CALL JOYST(1,X,Y)
30130 IF K=-1 AND S=0 AND X=0 AND Y=0 THEN 30120
30140 CALL SCREEN(3)
30150 RESTORE 30560 !//INSTRUCTION SCREEN
30160 READ C$
30170 IF C$="" THEN 30200
30180 CALL LINK("CWRITE",C$)
30190 GOTO 30160
30200 CALL CHAR(93,"D58027A282F72A21FFAAFFAAAAFFAAFFD25B810180000000"):: CALL LINK("DELAY",200)
30210 CALL KEY(0,K,S):: CALL JOYST(1,X,Y)
30220 IF K=-1 AND S=0 AND X=0 AND Y=0 THEN 30210
30260 RETURN
30270 RESTORE 30700 !//YOU ARE DEAD SCREEN
30280 READ D$
30290 IF D$="" THEN 30320
30300 CALL CHAR(93,"D58027A282F72A21FFAAFFAAAAFFAAFFD25B810180000000"):: CALL LINK("CWRITE",D$)
30310 GOTO 30280
30320 CALL LINK("DELAY",200)
30330 CALL KEY(0,K,S):: CALL JOYST(1,X,Y)
30340 IF K=-1 AND S=0 AND X=0 AND Y=0 THEN 30330
30350 RETURN
30360 DATA "
30370 DATA "
30380 DATA "
30390 DATA "² @xDD8
30400 DATA "S dTLLDp€€cƒã„
30410 DATA "ýƒ
30420 DATA "š<zX̘~8N‚
30430 DATA "9
<<ÿ~<<üL<(l00 ?2<6 
30440 DATA ""
30450 DATA "
30460 DATA "
30470 DATA "  ²†€¦§¨©©€¨ª¡¨§€¡¢€¥¨¤„ª®€‡¢©¡„ˆ‰€§¨£‹„§¨Œ¯€¨Ž¡€µ€§„‚¡€š¢›¨ª€‹¦€¸€š¨¨¨€°€Œ¢ª€¸€§œª¤¨Œ¨€¥‹¡¡¢ª€¡¢€‡‹š¦€µ€Œ¢Œ‚¨¥€"
30480 DATA "
30490 DATA "
30500 DATA "² @xDD8
30510 DATA "S dTLLDp€€cƒã„
30520 DATA "ýƒ
30530 DATA "š<zX̘~8N‚
30540 DATA "9
<<ÿ~<<üL<(l00 ?2<6 
30550 DATA ""
30560 DATA "
30570 DATA ">¤€¼ƒ¹ †‘€§œª¤¨Œ‡¹•€¦¢„ª¡©¤€»ƒ¹†‘€š¨¨¨ˆ¹“€¦¢„ª¡©¤€š¨¨¨€Œ„©¡œªˆ¨€¸€‘€©¦œˆ¨€²è²„€§œª¤¨Œ€Œ„©¡œªˆ¨©€¸€•†€©¦œˆ¨©¢€‹³„€éê„€‹³¢€ €¸€Š‹„¡‰€§€¸€§¨©¡œ§¡©€"
30580 DATA "Ǧ§¨©©€¨ª¡¨§€¡¢€¦œ¦€"
30590 DATA "
30600 DATA ""
30610 DATA "
30620 DATA "
30630 DATA "
30640 DATA "°
 
30650 DATA "QDddTLLDp€€cƒã„
30660 DATA "ü€ƒ
30670 DATA "˜X<zX̘~8N‚
30680 DATA "7!
30690 DATA ""
30700 DATA "
30710 DATA "
30720 DATA "
30730 DATA "°
 
30740 DATA "QDddTLLDp€€cƒã„
30750 DATA "ü€ƒ
30760 DATA "˜X<zX̘~8N‚
30770 DATA "7!
30780 DATA ""
 

 

 

 

 

In case you felt like having a look/see.

Edited by Sinphaltimus
Link to comment
Share on other sites

Much better. :thumbsup:

 

Zombies sometimes get stuck over a hole (going back and forth).

 

1 zombie down to level 94. 3 zombies at level 93 through 88, and everything runs slow (feels like an uncompiled XB game - sorry). Especially the jump starts out with a long freeze frame (like he's taking time on the loo), and that's a problem when I try to avoid contact with the zombies (in which case I sometimes loose health).

 

Zombies often disappear upon contact without me loosing health (mostly walking as in not standing still).

 

Generally I did not concentrate on picking up anything. I stopped going further at level 86 (3 zombies again after level 87 with 2 zombies).

 

;)

 

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...