-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathlevels.cp
More file actions
2420 lines (2261 loc) · 91.7 KB
/
Copy pathlevels.cp
File metadata and controls
2420 lines (2261 loc) · 91.7 KB
1
/****************************************************************************************//* LEVELS.CP *//****************************************************************************************//* (c) 1995 by Magnet Interactive Studios, inc. All rights reserved. *//****************************************************************************************//* Revision History: *//* v5.6 5/5/95 Icebreaker Golden Master version. By Andrew Looney. *//* v6.1 8/21/95 Began making changes for Icebreaker Two. By Andrew Looney. *//****************************************************************************************//***************************** WHAT THIS SOFTWARE DOES ********************************** This file contains all of the code that deals with loading in the level specificparameters for each level. Most of these functions are top level functions and could justas well be in the application level file (ICEBREAKER.CP); instead, however, they are gathered together into this file because it is easier to integrate a new level if all ofthe level definition stuff is in one place. By this same token, the functionInitializeSeekers (from the seeker class) is located in this file (rather than inSEEKER.CP where it really belongs).*****************************************************************************************//***** includes (make sure CPlusSwiHack.h is the last one) *****/#include "graphics.h"#include "stdio.h"#include "stdlib.h"#include "mem.h"#include "types.h"#include "hardware.h"#include "event.h"#include "strings.h"#include "access.h"#include "UMemory.h"#include "Form3DO.h"#include "Init3DO.h"#include "Parse3DO.h"#include "Utils3DO.h"#include "audio.h"#include "music.h"/***** Magnet includes *****/#include "icebreaker.h"#include "levels.h"#include "animation.h"#include "landscape.h"#include "solids.h"#include "seeker.h"#include "PlayMusic.h"/***** special c++ include (this must be last) *****/#include "CPlusSwiHack.h"/***** global variables *****/extern int32 g_total_pyramids;extern int32 level_lookup_table [ROWS_IN_LANDSCAPE] [COLUMNS_IN_LANDSCAPE];extern int32 g_file_buffer[MAX_FILE_BYTES/4];extern bool g_art_usage[TOTAL_ART_ELEMENTS];extern char g_level_filename[80];extern random_level *random_level_spec;extern landscape pavement;extern solids population;extern seeker enemies;/********************************* FetchLevelName ************************************* This function is used whenever the name of a level is to be displayed. It takes thelevel number as input and returns the name of the level as a string. It also copies thename of the corresponding level spec file into the global variable g_level_filename; thiskills the proverbial two birds with one stone and saves us the trouble of having to maintain two separate, gigantic, level-specific case statements.*****************************************************************************************/void FetchLevelName (char *msg, int32 level){ sprintf (msg, "This is not a valid level."); strcpy(g_level_filename,"$boot/IceFiles/Newlevels/impossible"); switch(level) { case ITS_TOTALLY_RANDOM: sprintf (msg, "%cIt's Totally Random!%c",34,34); strcpy(g_level_filename,"ITS_TOTALLY_RANDOM"); break; case LESSON_1_BLUE: sprintf (msg, "Lesson One: %cBlue Guys%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/levels/lesson_1"); break; case LESSON_2_RED: sprintf (msg, "Lesson Two: %cRed Guys%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/levels/lesson_2"); break; case LESSON_3_GREEN: sprintf (msg, "Lesson Three: %cGreen Guys%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/levels/lesson_3"); break; case LESSON_4_RANDOM_CHANGES: sprintf (msg, "Lesson Four: %cRandom Changes%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/levels/lesson_4"); break; case 1: sprintf (msg, "%cThe Yellow Assembly%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/The Yellow Assembly"); break; case 2: // Ken Megill sprintf (msg, "%cProduction & decay of strange 'mids%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/padosp.lev"); break; case 3: // Ken Megill sprintf (msg, "%cGreen Pyramids and Ham%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/greenham.lev"); break; case 4: // Ken Megill sprintf (msg, "%cLord of the Pits%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/lord_of.lev"); break; case 5: // Andrew Looney sprintf (msg, "%cSlimy Pyramids, Dude!%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/slimy_pyramids"); break; case 6: // Andrew Looney sprintf (msg, "%cRedcoats and Bummers%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/redcoats_and_bummers"); break; case 7: // Andrew Looney sprintf (msg, "%cIntroducing Mirrors!%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/mirrors"); break; case 8: // Andrew Looney sprintf (msg, "%cBehold, Psychos!%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/behold_psychos"); break; case 9: // Andrew Looney sprintf (msg, "%cWe have a problem%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/We have a problem"); break; case 10: // Andrew Looney sprintf (msg, "%cBehold, Juggernauts!%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/behold_juggernauts"); break; case 11: // Andrew Looney sprintf (msg, "%cNow Fortified with Iron!%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/fortified"); break; case 12: // Andrew Looney sprintf (msg, "%cCrush Me%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/crush_me"); break; case 13: // Andrew Looney sprintf (msg, "%cSwampy Canals%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/swampy canals"); break; case 14: // Keith Baker sprintf (msg, "%cRiver of Lava%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/River of Lava"); break; case 15: // Mike Young sprintf (msg, "%cRock and a Hard Place%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/ROCK_AND_A_HARD_PLACE"); break; case 16: // Mike Young sprintf (msg, "%cSouth Pole%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/SOUTH_POLE"); break; case 17: // Mike Young sprintf (msg, "%cThe Pit Wall%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/THE_PIT_WALL"); break; case 18: // Mike Young sprintf (msg, "%cTrapped Like a Rat%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/TRAPPED_LIKE_A_RAT"); break; case 19: // Andrew Looney sprintf (msg, "%cOperation Zombie Drop%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Operation Zombie Drop"); break; case 20: // Ken Megill sprintf (msg, "%cBibble%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Bibble"); break; case 21: // Mike Young sprintf (msg, "%cSlowly I Lurk%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Slowly I Lurk"); break; case 22: // Andrew Looney sprintf (msg, "%cLava Tubes%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/lava tubes"); break; case 23: // Andrew Looney sprintf (msg, "%cVolcano Season%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Volcano Season"); break; case 24: // Ken Megill sprintf (msg, "%cFriends in the Limey Barrio%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Friends in the Limey Barrio"); break; case 25: // Mike Young sprintf (msg, "%cAll Good Pyramids go to Heaven%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/ALL_GOOD_PYRAMIDS_GO_TO_HEAVEN"); break; case 26: // Mike Young sprintf (msg, "%cGraveyard Shift%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/GRAVEYARD_SHIFT"); break; case 27: // Mike Young sprintf (msg, "%cMaelstrom%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/MAELSTROM"); break; case 28: // Mike Young sprintf (msg, "%cLittle Dutch Boy%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/LITTLE_DUTCH_BOY"); break; case 29: // Mike Young sprintf (msg, "%cMidnight at the Oasis%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/MIDNIGHT_AT_THE_OASIS"); break; case 30: // Ken Megill sprintf (msg, "%cRequiem Mass%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Requiem Mass"); break; case 31: // Ken Megill sprintf (msg, "%cZombie Jamboree%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Zombie Jamboree"); break; case 32: // Ken Megill sprintf (msg, "%cUnder Siege%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Under Siege"); break; case 33: // Ken Megill sprintf (msg, "%cNight of the Long Knives%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Night of the Long Knives"); break; case 34: // Ken Megill sprintf (msg, "%cThe Limeys of August%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/The Limeys of August"); break; case 35: // Ken Megill sprintf (msg, "%cMids, Mr. Rico!%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Mids, Mr. Rico!"); break; case 36: // Ken Megill sprintf (msg, "%cThe Road to Heck%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/The Road to Heck"); break; case 37: // Ken Megill sprintf (msg, "%cChokepoint%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Chokepoint"); break; case 38: // Paul Murphy sprintf (msg, "%cPachinko%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Pachinko"); break; case 39: // Kristin Looney sprintf (msg, "%c4 Traps for 4 Chameleons%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/4_traps_for_4_chams"); break; case 40: // Ken Megill sprintf (msg, "%cPeekaboo%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Peekaboo"); break; case 41: // Keith Baker sprintf (msg, "%cPit Crossing%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Pit Crossing"); break; case 42: // Ken Megill sprintf (msg, "%cRaymond's Green & Evil Level%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Raymond's Green & Evil Level"); break; case 43: // Mike Young sprintf (msg, "%cHalf the Battle%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/HALF_THE_BATTLE"); break; case 44: // Mike Young sprintf (msg, "%cOle Slime Religion%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/OLE_SLIME_RELIGION"); break; case 45: // Mike Young sprintf (msg, "%cThe Corral%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/THE_CORRAL"); break; case 46: // Mike Young sprintf (msg, "%cIt's Totally Random%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/TOTALLY_RANDOM"); break; case 47: // Mike Young sprintf (msg, "%cDon't Break the Ice%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/DONT_BREAK_THE_ICE"); break; case 48: // Mike Young sprintf (msg, "%cPsycho Somatic%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/PSYCHO_SOMATIC"); break; case 49: // Mike Young sprintf (msg, "%c5 Little Juggernauts%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/5_JUGGERNAUTS"); break; case 50: // Andrew Looney sprintf (msg, "%cPlanet X%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Planet X"); break; case 51: // Keith Baker sprintf (msg, "%cThis Level Sucks!%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/sucks"); break; case 52: // Keith Baker sprintf (msg, "%cYou're Soaking In It%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/You're Soaking In It"); break; case 53: // Mike Young sprintf (msg, "%cMy Roommate is Slimy%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/MY_ROOMMATE_IS_SLIMEY"); break; case 54: // Mike Young sprintf (msg, "%cMerry Chase%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/MERRY_CHASE"); break; case 55: // Mike Young sprintf (msg, "%cI Lava Zombies%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/I LAVA ZOMBIES"); break; case 56: // Andrew Looney sprintf (msg, "%cThe Dead Pyramid Society%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/The Dead Pyramid Society"); break; case 57: // Mike Young sprintf (msg, "%cHere They Come!%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Here They Come!"); break; case 58: // Mike Young sprintf (msg, "%cRelease The Hounds%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Release The Hounds"); break; case 59: // Zeb Cook sprintf (msg, "%cTime Bomb%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Time bomb"); break; case 60: // Paul Murphy sprintf (msg, "%cA Fistful of Bummers%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/A Fistful of Bummers"); break; case 61: // Keith Baker sprintf (msg, "%c4 Juggernauts & A Funeral%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/4 Juggernauts & A Funeral"); break; case 62: // Andrew Looney sprintf (msg, "%cSpa Fon!%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Spa Fon!"); break; case 63: // Mike Young sprintf (msg, "%cMirror, Mirror%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Mirror_Mirror"); break; case 64: // Mike Young sprintf (msg, "%cOne Way%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/ONE_WAY"); break; case 65: // Mike Young sprintf (msg, "%cRing Around the Rosie%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/RING AROUND THE ROSIE"); break; case 66: // Ken Megill/Keith Baker sprintf (msg, "%cA Green And Unpleasant Level%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/green_and_unpleasant"); break; case 67: // Ken Megill sprintf (msg, "%cA Blue and Cheerful Level%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/A Blue and Cheerful Level"); break; case 68: // Ken Megill sprintf (msg, "%cFrozen Heck%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Frozen Heck"); break; case 69: // Keith Baker sprintf (msg, "%cA Red And Jolly Level%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/A Red And Jolly Level"); break; case 70: // Paul Murphy sprintf (msg, "%cZombie Stew%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Zombie_Stew"); break; case 71: // Mike Young sprintf (msg, "%cSlimex%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/SLIMEX"); break; case 72: // Mike Young sprintf (msg, "%cBetter Dead Than Red%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/BETTER_DEAD_THAN_RED"); break; case 73: // Mike Young sprintf (msg, "%cClose The Door!%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/CLOSE_THE_DOOR!"); break; case 74: // Mike Young sprintf (msg, "%cCave Dwellers%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Cave Dwellers"); break; case 75: // Paul Murphy sprintf (msg, "%cStrange Reflections%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Strange Reflections"); break; case 76: // Paul Murphy sprintf (msg, "%cThe Pyrminator%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/The_Pyrminator"); break; case 77: // Mike Young sprintf (msg, "%cYour Alien Masters%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Your_Alien_Masters"); break; case 78: // Mike Young sprintf (msg, "%cPsychotic Episode%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Psychotic Episode"); break; case 79: // Paul Murphy sprintf (msg, "%cSoup is Good Food%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Soup_is_Good_Food"); break; case 80: // Paul Murphy sprintf (msg, "%cPyrminator II%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Pyrminator_II"); break; case 81: // Paul Murphy sprintf (msg, "%cA Green and Bilious Level%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/A_Green_and_Bilious_Level"); break; case 82: // Paul Murphy sprintf (msg, "%cPulp Friction%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Pulp_Friction"); break; case 83: // Paul Murphy sprintf (msg, "%cThe Mountains of Madness%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/The_Mountains_of_Madness"); break; case 84: // Keith Baker sprintf (msg, "%cDesert Rats%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Desert Rats"); break; case 85: // Keith Baker sprintf (msg, "%cCrossroads%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Crossroads"); break; case 86: // Andrew Looney sprintf (msg, "%cPyramid Fondue%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Pyramid Fondue"); break; case 87: // Zeb Cook sprintf (msg, "%cHole In One%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Hole in one"); break; case 88: // Andrew Looney sprintf (msg, "%cThe Pyramid Has Landed%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/The Pyramid Has Landed"); break; case 89: // Andrew Looney sprintf (msg, "%cPyramid-o-rama%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/pyramid-o-rama"); break; case 90: // Mike Young sprintf (msg, "%cCoral Entities%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Coral Entities"); break; case 91: // Mike Young sprintf (msg, "%cYellow Fever%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Yellow Fever"); break; case 92: // Mike Young sprintf (msg, "%cDon't Cry For Me%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Don't Cry For Me"); break; case 93: // Dave Bondi sprintf (msg, "%cClamjam%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/clamjam"); break; case 94: // Paul Murphy sprintf (msg, "%cPyramid Scheme%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Pyramid Scheme"); break; case 95: // Keith Baker sprintf (msg, "%cThe Hills are Alive%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/The Hills are Alive"); break; case 96: // Keith Baker sprintf (msg, "%cFragments%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Fragments"); break; case 97: // Mike Young sprintf (msg, "%c20 Quatloos on the Dudemeyer%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/20 Qaatlunes on the Dudemeyer"); break; case 98: // Mike Young sprintf (msg, "%cYou Can Run%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/You Can Run"); break; case 99: // Andrew Looney sprintf (msg, "%cCream of Pyramid Soup%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Cream of Pyramid Soup"); break; case 100: // Graeme Davis sprintf (msg, "%cPhilosopher's Isle%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Philosopher's Isle"); break; case 101: // Andrew Looney sprintf (msg, "%cIon Zones and Evil Drones%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/zones_and_drones"); break; case 102: // Andrew Looney sprintf (msg, "%cNew Features Showroom%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/showroom"); break; case 103: // Keith Baker sprintf (msg, "%cLanding Zone%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Landing Zone"); break; case 104: // Andrew Looney sprintf (msg, "%cThe Ouija Lounge%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/The Ouija Lounge"); break; case 105: // Keith Baker sprintf (msg, "%cStalag Gulag%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Stalag Gulag"); break; case 106: // Andrew Looney sprintf (msg, "%cEight Traps for Bunches of Blues%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/eight easy traps"); break; case 107: // Andrew Looney sprintf (msg, "%cApollo 19%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Apollo 19"); break; case 108: // Andrew Looney (with apologizes to Murphy) sprintf (msg, "%cBaptism By Fire%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/baptism by fire"); break; case 109: // Kristin Looney (with help from Andy) sprintf (msg, "%cOrange County Prison%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/orange county prison"); break; case 149: sprintf (msg, "%cPlace Your Bets%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Place_yer_bets"); break; case 150: sprintf (msg, "%cAndy's Workshop #2 (Keep Out!)%c",34,34); strcpy(g_level_filename,"$boot/IceFiles/newlevels/Andy'S 2ND WORKSHOP"); break; }}/***************************** FetchMusicTrackFromFile ******************************** Included in the level spec file is a text string that identifies the musical track tobe played during the level. This function opens the level spec file, reads in the musicspecification string, translates it into the corresponding code, and returns the code.****************************************************************************************/int32 FetchMusicTrackFromFile() { int32 i; int32 bytes_read; char *input_index; int32 music_track; if (strcmp(g_level_filename,"ITS_TOTALLY_RANDOM") == 0) { switch (RandomNumber (0, TOTAL_TRACKS - 1)) { default: return (QUACK); case 0: return (QUACK); case 1: return (CHECK_THIS_OUT_TALK); case 2: return (MADONNA); case 3: return (SPACE_AGE); case 4: return (SOUND_OF_TALK); case 5: return (LOTS_OF_PERC); case 6: return (DRUNK_TRUMPET); case 7: return (MONKEY); case 8: return (THE_LONGER_ONE); case 9: return (MORE_QUACK); case 10: return (SEVENTIES2); case 11: return (SHAFT); case 12: return (HIT_ME); case 13: return (WATER_WORKS); case 14: return (FAST_HUNT); case 15: return (G_BOUNCE); case 16: return (SCHICK); case 17: return (BALI); } } bytes_read = ReadFile(g_level_filename,MAX_FILE_BYTES,g_file_buffer,0); if (bytes_read == -1) { printf("Bummer dude! Failure in attempt to open level parms file!!!!!\n"); return(QUACK); } input_index = (char *) &g_file_buffer[0]; for (i = 0; i < 33; i++) { while (*(input_index) != 13) input_index++; input_index++; } music_track = QUACK; if (strncmp(input_index,"CHECK_THIS_OUT_TALK",strlen("CHECK_THIS_OUT_TALK")) == 0) music_track = CHECK_THIS_OUT_TALK; if (strncmp(input_index,"SPACE_AGE",strlen("SPACE_AGE")) == 0) music_track = SPACE_AGE; if (strncmp(input_index,"SOUND_OF_TALK",strlen("SOUND_OF_TALK")) == 0) music_track = SOUND_OF_TALK; if (strncmp(input_index,"LOTS_OF_PERC",strlen("LOTS_OF_PERC")) == 0) music_track = LOTS_OF_PERC; if (strncmp(input_index,"DRUNK_TRUMPET",strlen("DRUNK_TRUMPET")) == 0) music_track = DRUNK_TRUMPET; if (strncmp(input_index,"MONKEY",strlen("MONKEY")) == 0) music_track = MONKEY; if (strncmp(input_index,"THE_LONGER_ONE",strlen("THE_LONGER_ONE")) == 0) music_track = THE_LONGER_ONE; if (strncmp(input_index,"MORE_QUACK",strlen("MORE_QUACK")) == 0) music_track = MORE_QUACK; if (strncmp(input_index,"SEVENTIES2",strlen("SEVENTIES2")) == 0) music_track = SEVENTIES2; if (strncmp(input_index,"MADONNA",strlen("MADONNA")) == 0) music_track = MADONNA; if (strncmp(input_index,"SHAFT",strlen("SHAFT")) == 0) music_track = SHAFT; if (strncmp(input_index,"HIT_ME",strlen("HIT_ME")) == 0) music_track = HIT_ME; if (strncmp(input_index,"WATER_WORKS",strlen("WATER_WORKS")) == 0) music_track = WATER_WORKS; if (strncmp(input_index,"FAST_HUNT",strlen("FAST_HUNT")) == 0) music_track = FAST_HUNT; if (strncmp(input_index,"G_BOUNCE",strlen("G_BOUNCE")) == 0) music_track = G_BOUNCE; if (strncmp(input_index,"SCHICK",strlen("SCHICK")) == 0) music_track = SCHICK; if (strncmp(input_index,"BALI",strlen("BALI")) == 0) music_track = BALI; if (strncmp(input_index,"QUACK",strlen("QUACK")) == 0) music_track = QUACK; else if (music_track == QUACK) printf("Warning: using default music track.\n"); return(music_track);}/******************************* ExtractSeekerData *********************************** Given a pointer to a string that contains seeker specification information, thisfunction parses that string and returns the type and home base information for thatseeker.****************************************************************************************/char* ExtractSeekerData(char *input_index, int32 &seeker_type, int32 &row, int32 &column, int32 &direction){ /***** First, extract the seeker type from the line. *****/ seeker_type = NOTHING; if (strncmp(input_index,"LTBLUE_SEEKER",13) == 0) seeker_type = LTBLUE_SEEKER; if (strncmp(input_index,"YELLOW_SEEKER",13) == 0) seeker_type = YELLOW_SEEKER; if (strncmp(input_index,"PINK_SEEKER",11) == 0) seeker_type = PINK_SEEKER; if (strncmp(input_index,"CHAMELEON",strlen("CHAMELEON")) == 0) seeker_type = DORMANT_CHAMELEON; if (strncmp(input_index,"BUMMER",strlen("BUMMER")) == 0) seeker_type = DORMANT_BUMMER; if (strncmp(input_index,"REDCOAT",strlen("REDCOAT")) == 0) seeker_type = DORMANT_REDCOAT; if (strncmp(input_index,"LIME_SEEKER",11) == 0) seeker_type = LIME_SEEKER; if (strncmp(input_index,"ZOMBIE",strlen("ZOMBIE")) == 0) seeker_type = ZOMBIE; if (strncmp(input_index,"LURKER",strlen("LURKER")) == 0) seeker_type = LURKER; if (strncmp(input_index,"MEANY",strlen("MEANY")) == 0) seeker_type = MEANY; if (strncmp(input_index,"JUGGERNAUT",strlen("JUGGERNAUT")) == 0) seeker_type = JUGGERNAUT; if (strncmp(input_index,"PSYCHO",strlen("PSYCHO")) == 0) seeker_type = PSYCHO; if (seeker_type == NOTHING) { printf("Error: Unknown seeker type ('"); while (*(input_index) != ',') { printf("%c",*(input_index)); input_index++; } printf("').\n"); exit(0); } /***** Second, extract the home tile row from the line. *****/ while (*(input_index) != ',') input_index++; while ((*(input_index) == ',') || (*(input_index) == ' ') || (*(input_index) == TAB)) input_index++; row = atoi(input_index); /***** Third, extract the home tile column from the line. *****/ while (*(input_index) != ',') input_index++; while ((*(input_index) == ',') || (*(input_index) == ' ') || (*(input_index) == TAB)) input_index++; column = atoi(input_index); /***** Fourth, extract the offset direction from the line. *****/ while ((*(input_index) >= '0') && (*(input_index) <= '9')) input_index++; while ((*(input_index) == ',') || (*(input_index) == ' ') || (*(input_index) == TAB)) input_index++; direction = NO_DIRECTION; if (strncmp(input_index,"NORTH",5) == 0) direction = NORTH; if (strncmp(input_index,"SOUTH",5) == 0) direction = SOUTH; if (strncmp(input_index,"WEST",4) == 0) direction = WEST; if (strncmp(input_index,"EAST",4) == 0) direction = EAST; if (strncmp(input_index,"NONE",4) == 0) direction = NO_DIRECTION; if (strncmp(input_index,"RANDOM",6) == 0) direction = RANDOM; if ((direction == RANDOM) && (seeker_type != ZOMBIE)) { printf("Error: Only Zombies can have random placement.\n"); exit(0); }// if ((direction == NO_DIRECTION) && (seeker_type != DORMANT_CHAMELEON)// && (seeker_type != DORMANT_BUMMER) && (seeker_type != DORMANT_REDCOAT)// && (seeker_type != ZOMBIE)) // {// printf("Error: Invalid Offset Direction ('");// while (*(input_index) != 13)// {// printf("%c",*(input_index));// input_index++;// }// printf("').\n");// exit(0);// } /***** Lastly, skip to the end of the line *****/ while (*(input_index) != 13) input_index++; input_index++; return(input_index);}/******************************** TranslateTileCode ************************************ Given a 16 bit number (i.e. the value of 2 ascii characters) this function translatesthis code into the symbol for the corresponding tile. If no known symbol matches the code,the value AMBIGUOUS is returned.*****************************************************************************************/int32 TranslateTileCode (int16 tile_code){ int32 tile; bool obsolete,warning; obsolete = FALSE; warning = FALSE; switch (tile_code) { case 0x4731: /* G1 */ tile = GA_TILE; obsolete = TRUE; break; case 0x4732: /* G2 */ tile = GB_TILE; obsolete = TRUE; break; case 0x4733: /* G3 */ tile = HE_TILE; obsolete = TRUE; break; case 0x5731: /* W1 */ tile = DA_TILE; obsolete = TRUE; break; case 0x5732: /* W2 */ tile = DA_TILE; obsolete = TRUE; break; case 0x5733: /* W3 */ tile = DA_TILE; obsolete = TRUE; break; case 0x5734: /* W4 */ tile = DA_TILE; obsolete = TRUE; break; case 0x5735: /* W5 */ tile = DA_TILE; obsolete = TRUE; break; case 0x5032: /* P2 */ tile = PB_TILE; obsolete = TRUE; break; case 0x4931: /* I1 */ tile = IA_TILE; obsolete = TRUE; break; case 0x5332: /* S2 */ tile = SA_TILE; obsolete = TRUE; break; case 0x5641: /* VA */ tile = FA_TILE; obsolete = TRUE; break; case 0x5642: /* VB */ tile = FB_TILE; obsolete = TRUE; break; case 0x5031: /* P1 */ tile = P1_TILE; break; case 0x4741: /* GA */ tile = GA_TILE; break; case 0x4742: /* GB */ tile = GB_TILE; break; case 0x4743: /* GC */ tile = GC_TILE; break; case 0x4744: /* GD */ tile = GD_TILE; break; case 0x4745: /* GE */ tile = GE_TILE; break; case 0x4746: /* GF */ tile = GF_TILE; break; case 0x4845: /* HE */ tile = HE_TILE; break; case 0x4441: /* DA */ tile = DA_TILE; break; case 0x4442: /* DB */ tile = DB_TILE; break; case 0x4443: /* DC */ tile = DC_TILE; break; case 0x4444: /* DD */ tile = DD_TILE; break; case 0x4445: /* DE */ tile = DE_TILE; break; case 0x5741: /* WA */ tile = WA_TILE; break; case 0x4841: /* HA */ tile = HA_TILE; break; case 0x4842: /* HB */ tile = HB_TILE; break; case 0x4843: /* HC */ tile = HC_TILE; break; case 0x4844: /* HD */ tile = HD_TILE; break; case 0x5041: /* PA */ tile = PA_TILE; break; case 0x5042: /* PB */ tile = PB_TILE; break; case 0x4941: /* IA */ tile = IA_TILE; break; case 0x5331: /* S1 */ tile = S1_TILE; break; case 0x5341: /* SA */ tile = SA_TILE; break; case 0x4C31: /* L1 */ tile = L1_TILE; break; case 0x4C41: /* LA */ tile = LA_TILE; break; case 0x4C42: /* LB */ tile = LB_TILE; break; case 0x5342: /* SB */ tile = SB_TILE; break; case 0x4942: /* IB */ tile = IB_TILE; break; case 0x5043: /* PC */ tile = PC_TILE; break; case 0x5047: /* PA */ tile = PG_TILE; break; case 0x5742: /* WB */ tile = WB_TILE; break; case 0x5743: /* WC */ tile = WC_TILE; break; case 0x5744: /* WD */ tile = WD_TILE; break; case 0x4943: /* IC */ tile = IC_TILE; break; case 0x4944: /* ID */ tile = ID_TILE; break; case 0x5044: /* PD */ tile = PD_TILE; break; case 0x5045: /* PE */ tile = PE_TILE; break; case 0x5046: /* PF */ tile = PF_TILE; break; case 0x5048: /* PH */ tile = PH_TILE; break; case 0x5049: /* PI */ tile = PI_TILE; break; case 0x504A: /* PJ */ tile = PJ_TILE; break; case 0x504C: /* PL */ tile = PL_TILE; break; case 0x504D: /* PM */ tile = PM_TILE; break; case 0x5541: /* UA */ tile = UA_TILE; break; case 0x5542: /* UB */ tile = UB_TILE; break; case 0x5543: /* UC */ tile = UC_TILE; break; case 0x5544: /* UD */ tile = UD_TILE; break; case 0x5545: /* UE */ tile = UE_TILE; break; case 0x4641: /* FA */ tile = FA_TILE; break; case 0x4642: /* FB */ tile = FB_TILE; break; default: tile = AMBIGUOUS; break; } if ((obsolete) && (warning)) printf("Warning: Obsolete tile code (%c%c).\n",(char) (tile_code >> 8), (char) (tile_code & 0xFF)); return(tile); }/************************************ LoadLevel *************************************** This function is dedicated to performing as much of the level-specific initializationas possible. Specifically, it parses the level parameters file and uses the data thereinto construct the population of solid objects and the layout of tiles. A global datastructure called level_lookup_table is used for initialization of both of these gameassets. The specification of the solid objects (which appears first in the parametersfile) is stored in the level_lookup_table and then is used by the solids class to createthe initial population, after which the table is no longer needed. This function thenreuses the level_lookup_table. The tile layout specification (which appears in secondin the parameters file) is parsed and stored in the same data structure, which isthen handed off for use by the landscape class. Unlike the solids class, the landscapeclass uses the level_lookup_table throughout execution of the game. After this,the wasteland descriptor is read in. This routine also fills out the global art usage table, which is used to determineif a given piece of artwork will be used during the level. If it won't be, but is alreadyin memory from a previous level, it can be recognized as unneeded and discarded.****************************************************************************************/void LoadLevel (int32 level) { int32 i,j; int32 bytes_read; char *input_index; int16 *short_pointer; int32 seeker_type, row, column, direction; for (i = 0; i < MAX_FILE_BYTES/4; i++) g_file_buffer[i] = 0xFFFFFFFF; for (i = 0; i < TOTAL_ART_ELEMENTS; i++) g_art_usage[i] = FALSE; g_art_usage[BLUE_PYRAMID] = TRUE; g_art_usage[RED_PYRAMID] = TRUE; g_art_usage[GREEN_PYRAMID] = TRUE; /**********************************************************************************/ // Deal with special case levels first, then exit: /**********************************************************************************/ if (level == ITS_TOTALLY_RANDOM) { g_total_pyramids = 0; for (i = 0; i < ROWS_IN_LANDSCAPE; i++) { for (j = 0; j < COLUMNS_IN_LANDSCAPE; j++) { level_lookup_table[i][j] = random_level_spec->pyramids[i][j]; g_art_usage[level_lookup_table[i][j]] = TRUE; if ((level_lookup_table[i][j] != NOTHING) && (level_lookup_table[i][j] < FIRST_BOULDER)) g_total_pyramids++; } } population.InitializeSolids(); pavement.wasteland_descriptor = random_level_spec->wasteland; g_art_usage[pavement.wasteland_descriptor] = TRUE; for (i = 0; i < ROWS_IN_LANDSCAPE; i++) { for (j = 0; j < COLUMNS_IN_LANDSCAPE; j++) { level_lookup_table[i][j] = random_level_spec->tiles[i][j]; g_art_usage[level_lookup_table[i][j]] = TRUE; } } return; } /**********************************************************************************/ // Open the file and discard the title line: /**********************************************************************************/ bytes_read = ReadFile(g_level_filename,MAX_FILE_BYTES,g_file_buffer,0); if (bytes_read == -1) { printf("Bummer dude! Failure in attempt to open level parms file!!!!!\n"); return; } input_index = (char *) &g_file_buffer[0]; while (*(input_index) != 13) input_index++; /**********************************************************************************/ // Translate the solids table: /**********************************************************************************/ for (i = 0; i < ROWS_IN_LANDSCAPE; i++) { for (j = 0; j < COLUMNS_IN_LANDSCAPE; j++) { /* skip over white space (or asterisks): */ while ((*(input_index) == 13) || (*(input_index) == 32) || (*(input_index)==42)) input_index++; /* translate the character into the correct type of dude: */ switch (*(input_index)) { case 'A': level_lookup_table[i][j] = BOULDERA; break; case 'B': level_lookup_table[i][j] = BLUE_PYRAMID; break; case 'C': level_lookup_table[i][j] = CONCRETE_PYRAMID; break; case 'D': level_lookup_table[i][j] = BOULDERD; break; case 'G': level_lookup_table[i][j] = GREEN_PYRAMID; break; case 'H': level_lookup_table[i][j] = STEEL_PYRAMID; break; case 'M': level_lookup_table[i][j] = MIRROR_PYRAMID; break; case 'N': level_lookup_table[i][j] = NOTHING; break; case 'O': level_lookup_table[i][j] = BOULDER0; break; case 'P': level_lookup_table[i][j] = PURPLE_PYRAMID; break; case 'R': level_lookup_table[i][j] = RED_PYRAMID; break; case 'S': level_lookup_table[i][j] = SLIMY_PYRAMID; break; case 'T': level_lookup_table[i][j] = RAINBOW_PYRAMID; g_art_usage[PURPLE_PYRAMID] = TRUE; break; case '0': level_lookup_table[i][j] = BOULDER0; break; case '1': level_lookup_table[i][j] = BOULDER1; break; case '2': level_lookup_table[i][j] = BOULDER2; break; case '3': level_lookup_table[i][j] = BOULDER3; break; case '4': level_lookup_table[i][j] = BOULDER4; break; case '5': level_lookup_table[i][j] = BOULDER5; break; case '6': level_lookup_table[i][j] = BOULDER6; break; case '7': level_lookup_table[i][j] = BOULDER7; break; case '8': level_lookup_table[i][j] = BOULDER8; break; case '9': level_lookup_table[i][j] = BOULDER9; break; default: printf("invalid object descriptor (%c).\n",*(input_index)); level_lookup_table[i][j] = NOTHING; break; } g_art_usage[(level_lookup_table[i][j])] = TRUE; /* now move on to the next element: */ input_index++; } } /**********************************************************************************/ // Calculate the number of pyramids: /**********************************************************************************/ g_total_pyramids = 0; for (i = 0; i < ROWS_IN_LANDSCAPE; i++) for (j = 0; j < COLUMNS_IN_LANDSCAPE; j++) if ((level_lookup_table[i][j] != NOTHING) && (level_lookup_table[i][j] < FIRST_BOULDER)) g_total_pyramids++; /**********************************************************************************/ // Pass level_lookup_table (with solids info) to solids class for initialization: /**********************************************************************************/ population.InitializeSolids(); /**********************************************************************************/ // Translate the landscape table: /**********************************************************************************/ for (i = 0; i < ROWS_IN_LANDSCAPE; i++) { for (j = 0; j < COLUMNS_IN_LANDSCAPE; j++) { /* skip over white space (or asterisks): */ while ((*(input_index) == 13) || (*(input_index) == 32) || (*(input_index) == 42)) input_index++; /* translate the 2 character code into the correct type of tile: */ short_pointer = (int16 *) input_index; level_lookup_table[i][j] = TranslateTileCode (*(short_pointer)); if (level_lookup_table[i][j] == AMBIGUOUS) { printf("Warning: invalid tile (%c%c).\n",*(input_index),*(input_index+1)); level_lookup_table[i][j] = GA_TILE; } /* then indicate in the usage table that this tile is being used: */ g_art_usage[(level_lookup_table[i][j])] = TRUE; if ((level_lookup_table[i][j] == FA_TILE) || (level_lookup_table[i][j] == FB_TILE)) g_art_usage[SEEKER_MATERIALIZATION] = TRUE; /* and then move on to the next element. */ input_index += 2; } } /**********************************************************************************/ // Fetch the wasteland identifier: /**********************************************************************************/ pavement.wasteland_descriptor = DA_TILE; while ((*(input_index) == 13) || (*(input_index) == 32) || (*(input_index) == 42)) input_index++; short_pointer = (int16 *) input_index; pavement.wasteland_descriptor = TranslateTileCode (*(short_pointer)); if (pavement.wasteland_descriptor == AMBIGUOUS) { printf("invalid wasteland descriptor.\n"); pavement.wasteland_descriptor = DA_TILE; } g_art_usage[pavement.wasteland_descriptor] = TRUE; /**********************************************************************************/ // Skip over the music track identifier: /**********************************************************************************/ input_index += 2; while ((*(input_index) == 13) || (*(input_index) == 32) || (*(input_index) == 42)) input_index++; for (i = 0; i < 2; i++) { while (*(input_index) != 13) input_index++; input_index++; } /**********************************************************************************/ // Examine seeker specs and fill out art usage table accordingly: /**********************************************************************************/ while (*(input_index) != 0xFF) { if ((*(input_index) == 13) || (*(input_index) == 32) || (*(input_index) == 42)) input_index++; else { input_index = ExtractSeekerData(input_index,seeker_type,row,column,direction); g_art_usage[seeker_type] = TRUE; } }}/**************************** seeker::InitializeSeekers ******************************* This function handles all setup and initialization of variables that are used by this class. It is intended to be used repeatedly, at the start of each round of the game. Note that this function is part of the seeker class, but it is in this file ratherthan SEEKER.CP because of its intense level specific orientation.****************************************************************************************/void seeker::InitializeSeekers (int32 level, int16 skill_level) { int32 seeker_type, row, column, direction; int32 i,j,k; int32 bytes_read; char *input_index; int16 difficulty; bool this_mode_has_seekers,warning; warning = FALSE; seeker_list = (dude *) NULL; grumpy_death_toll = 0; ShutdownUnusedArtwork(); if (level == ITS_TOTALLY_RANDOM) { k = 0; for (i = 0; i < random_level_spec->total_flavors; i++) { for (j = 0; j < random_level_spec->insane_seeker_count[i]; j++) { this_mode_has_seekers = FALSE; switch (skill_level) { case EASY: if (j < random_level_spec->easy_seeker_count[i]) this_mode_has_seekers = TRUE; break; case MEDIUM: if (j < random_level_spec->medium_seeker_count[i]) this_mode_has_seekers = TRUE; break; case HARD: if (j < random_level_spec->hard_seeker_count[i]) this_mode_has_seekers = TRUE; break; case INSANE: this_mode_has_seekers = TRUE; break; } if (this_mode_has_seekers) { CreateSeeker(random_level_spec->seeker_type[k], random_level_spec->row[k], random_level_spec->column[k], random_level_spec->direction[k],TRUE); g_art_usage[random_level_spec->seeker_type[k]] = TRUE; } k++; } } return; } bytes_read = ReadFile(g_level_filename,MAX_FILE_BYTES,g_file_buffer,0); if (bytes_read == -1) { printf("Bummer dude! Failure in attempt to open level parms file!!!!!\n"); return; } /* skip over the specs that don't relate to the seekers: */ input_index = (char *) &g_file_buffer[0]; for (i = 0; i < 35; i++) { while (*(input_index) != 13) input_index++; input_index++; } difficulty = 0; this_mode_has_seekers = FALSE; while (*(input_index) != 0xFF) { if (*(input_index) == '*') { while (*(input_index) != 13) input_index++; input_index++; if ((this_mode_has_seekers == FALSE) && (warning)) { switch (difficulty) { case 0: printf("\nNo seekers for EASY mode. "); break; case 1: printf("\nNo seekers for MEDIUM mode. "); break; case 2: printf("\nNo seekers for HARD mode. "); break; case 3: printf("\nNo seekers for INSANE mode. "); break; } } this_mode_has_seekers = FALSE; difficulty++; if (difficulty > skill_level) break; } if (*(input_index) != '*') { input_index = ExtractSeekerData(input_index,seeker_type,row,column,direction); this_mode_has_seekers = TRUE; if (seeker_type == DORMANT_CHAMELEON) population.ConcealChameleons(RandomNumber(row,column),GREEN_PYRAMID); else if (seeker_type == DORMANT_REDCOAT) population.ConcealChameleons(RandomNumber(row,column),RED_PYRAMID); else if (seeker_type == DORMANT_BUMMER) population.ConcealChameleons(RandomNumber(row,column),BLUE_PYRAMID); else CreateSeeker(seeker_type, row, column, direction, TRUE); } }}/****************************** PlaceHazardsRandomly ********************************** Given a type of hazard (or otherwise interesting) tile, a count of how many to use,and a pointer to a level specification structure, this function will randomly distributethe supply of hazard tiles within that structure.****************************************************************************************/void PlaceHazardsRandomly (int32 total, int32 type, int32 base){ int32 i, row, column; for (i = 0; i < total; i++) { do { row = RandomNumber(0,13); column = RandomNumber(0,13); } while (random_level_spec->tiles[row][column] != (char) base); random_level_spec->tiles[row][column] = (char) type; }}/******************************* PlaceHazardsInLines ********************************** Given a type of hazard (or otherwise interesting) tile, a count of how many to use,and a pointer to a level specification structure, this function will distribute the supply of hazard tiles within that structure, in one or more diagonal lines.****************************************************************************************/void PlaceHazardsInLines (int32 total, int32 type, int32 base){ int32 direction, row, column, line_length, new_row, new_column; direction = SOUTHWEST; while (total) { do { row = RandomNumber(0,13); column = RandomNumber(0,13); } while (random_level_spec->tiles[row][column] != (char) base); random_level_spec->tiles[row][column] = (char) type; total--; switch (RandomNumber(0,3)) { case 0: direction = SOUTHWEST; break; case 1: direction = SOUTHEAST; break; case 2: direction = NORTHWEST; break; case 3: direction = NORTHEAST; break; } line_length = RandomNumber (0,total); while(line_length) { pavement.DetermineAdjacentTile (row, column, direction, new_row, new_column); if (new_row == -1) break; if (random_level_spec->tiles[new_row][new_column] != (char) base) break; random_level_spec->tiles[new_row][new_column] = (char) type; line_length--; total--; row = new_row; column = new_column; } }}/****************************** PlaceHazardsInBunches ********************************* Given a type of hazard (or otherwise interesting) tile, a count of how many to use,and a pointer to a level specification structure, this function will distribute the supply of hazard tiles within that structure, in one or small clusters.****************************************************************************************/void PlaceHazardsInBunches (int32 total, int32 type, int32 base){ int32 direction, row, column, cluster_size, new_row, new_column, i; bool directions_attempted[8]; while (total) { for (i = 0; i < 8; i++) directions_attempted[i] = FALSE; do { row = RandomNumber(0,13); column = RandomNumber(0,13); } while (random_level_spec->tiles[row][column] != (char) base); random_level_spec->tiles[row][column] = (char) type; total--; if (total > 8) cluster_size = RandomNumber (0,8); else cluster_size = RandomNumber (0,total); while (cluster_size) { direction = RandomNumber (0,7); if (directions_attempted[direction] == FALSE) { directions_attempted[direction] = TRUE; cluster_size--; pavement.DetermineAdjacentTile (row, column, direction, new_row, new_column); if ((new_row != -1) && (random_level_spec->tiles[new_row][new_column] == (char) base)) { random_level_spec->tiles[new_row][new_column] = (char) type; total--; } } } }}/******************************** ThisTileIsHazardous ********************************* This is a simple function that returns TRUE if the specified tile value is deadly,and FALSE if it isn't. This function is intended for use by the RandomLevelGenerator,and as such considers SLIME deadly (even though it isn't for seekers) and rocks deadly(even though they aren't, simply because you can't go through them).****************************************************************************************/bool ThisTileIsHazardous (int32 tile_type){ if ((tile_type >= FIRST_SLIME_TILE) && (tile_type <= LAST_SLIME_TILE)) return(TRUE); if ((tile_type >= FIRST_LAVA_TILE) && (tile_type <= LAST_LAVA_TILE)) return(TRUE); if ((tile_type >= FIRST_PIT_TILE) && (tile_type <= LAST_PIT_TILE)) return(TRUE); if ((tile_type >= FIRST_BOULDER) && (tile_type <= LAST_BOULDER)) return(TRUE); return(FALSE);}/****************************** CheckForAndRemoveImpossibilites ********************************** Given the existence of a randomly generated landscape chart, this function examinesthe chart to make sure that no illegal situations exist, i.e. the starting square doesn'tcontain a hazard, and that there are no locations in the level that cannot be reachedby the player.****************************************************************************************/void CheckForAndRemoveImpossibilites (int32 base_tile){ int32 i,j,k,m,n; int32 pass; int32 still_unreachable; bool wasteland_safe_and_reachable; int32 row_to_change,column_to_change; wasteland_safe_and_reachable = FALSE; row_to_change = 0; column_to_change = 0; /* Make sure the home tile is ok. */ if (ThisTileIsHazardous(random_level_spec->tiles[6][5])) random_level_spec->tiles[6][5] = (char) base_tile; /* Initially set the chart up with all obstacles set to impassable and all tiles */ /* except the home tile set to unreachable. */ for (i = 0; i < ROWS_IN_LANDSCAPE; i++) { for (j = 0; j < COLUMNS_IN_LANDSCAPE; j++) { if (ThisTileIsHazardous(random_level_spec->tiles[i][j])) random_level_spec->pyramids[i][j] = IMPASSABLE; else random_level_spec->pyramids[i][j] = UNREACHABLE; } } random_level_spec->pyramids[6][5] = REACHABLE; /* we will stay in this loop until all tiles can be reached. */ while (FOREVER) { pass = 0; while (pass++ < 20) { /* count the number of unreachable tiles. */ still_unreachable = 0; for (i = 0; i < ROWS_IN_LANDSCAPE; i++) for (j = 0; j < COLUMNS_IN_LANDSCAPE; j++) if (random_level_spec->pyramids[i][j] == UNREACHABLE) still_unreachable++; if (still_unreachable == 0) return; /* now flag any tile that's adjacent to a reachable tile on at least one side.*/ for (i = 0; i < ROWS_IN_LANDSCAPE; i++) { for (j = 0; j < COLUMNS_IN_LANDSCAPE; j++) { if (random_level_spec->pyramids[i][j] == UNREACHABLE) { for (k = 0; k < 8; k++) { pavement.DetermineAdjacentTile(i,j,k,m,n); if (m == -1) { if (wasteland_safe_and_reachable) { random_level_spec->pyramids[i][j] = REACHABLE; break; } } else { if (random_level_spec->pyramids[m][n] == REACHABLE) { random_level_spec->pyramids[i][j] = REACHABLE; break; } } } } /* if we've reached a non-deadly wasteland from the center, set a flag. */ else { if ((random_level_spec->pyramids[i][j] == REACHABLE) && (random_level_spec->wasteland != SA_TILE) && (random_level_spec->wasteland != SB_TILE) && (wasteland_safe_and_reachable == FALSE)) { for (k = 0; k < 8; k++) { pavement.DetermineAdjacentTile(i,j,k,m,n); if (m == -1) wasteland_safe_and_reachable = TRUE; } } } } } } /* if we get to here, then the level can't currently be completely. Change it. */ for (i = 0; i < ROWS_IN_LANDSCAPE; i++) for (j = 0; j < COLUMNS_IN_LANDSCAPE; j++) if (random_level_spec->pyramids[i][j] == UNREACHABLE) for (k = 0; k < 8; k++) { pavement.DetermineAdjacentTile(i,j,k,m,n); if ((m != -1) && (random_level_spec->pyramids[m][n] == IMPASSABLE)) { row_to_change = m; column_to_change = n; break; } } random_level_spec->pyramids[row_to_change][column_to_change] = UNREACHABLE; random_level_spec->tiles[row_to_change][column_to_change] = (char) base_tile; printf("Randomly generated level is currently impossible. "); printf("Removing obstruction at %ld,%ld.\n",row_to_change, column_to_change); }}/******************************* GenerateRandomLevel ********************************** As the name suggests, this function creates a level specification at random. Thedetails of the random level are stored in the data structure pointed to by the globalpointer called random_level_spec. The random level can then be replayed again and againas long as the level specification structure remains intact.****************************************************************************************/void GenerateRandomLevel (void){ int32 base_tile; int32 base_tile_type; int32 wasteland_type; int32 number_of_special_tile_types; int32 total_number_of_special_tiles; int32 featured_special_tiles[4]; int32 number_of_featured_special_tiles[4]; int32 chosen_random_number; int32 i,j,k; int32 type_of_environment; int32 swamp_status; int32 types_of_normal_pyramids; int32 featured_normal_pyramids[3]; int32 types_of_special_pyramids; int32 total_special_pyramids; int32 featured_special_pyramids[3]; i = 0; j = 0; k = 0; wasteland_type = DA_TILE; number_of_special_tile_types = 2; /************************************************************************************/ /***** Step 1: Select the base tile. ************************************************/ /************************************************************************************/ switch (RandomNumber(0,9)) { case 0: base_tile_type = FROZEN; base_tile = RandomNumber(FIRST_ICE_TILE,LAST_ICE_TILE); break; case 1: base_tile_type = MARSH; base_tile = RandomNumber(FIRST_SWAMP_TILE,LAST_SWAMP_TILE); break; default: base_tile_type = PLAINS; base_tile = RandomNumber(FIRST_PLAIN_TILE,LAST_PLAIN_TILE); break; } /************************************************************************************/ /***** Step 2: Select the wasteland tile. *******************************************/ /************************************************************************************/ chosen_random_number = RandomNumber(0,99); switch (base_tile_type) { case FROZEN: if (chosen_random_number < 10) wasteland_type = TOXIC; else if (chosen_random_number < 20) wasteland_type = MARSH; else if (chosen_random_number < 60) wasteland_type = FROZEN; else wasteland_type = PLAINS; break; case PLAINS: if (chosen_random_number < 30) wasteland_type = TOXIC; else if (chosen_random_number < 35) wasteland_type = MARSH; else if (chosen_random_number < 45) wasteland_type = FROZEN; else wasteland_type = PLAINS; break; case MARSH: if (chosen_random_number < 20) wasteland_type = TOXIC; else if (chosen_random_number < 60) wasteland_type = MARSH; else if (chosen_random_number < 70) wasteland_type = FROZEN; else wasteland_type = PLAINS; break; } switch (wasteland_type) { case TOXIC: random_level_spec->wasteland = RandomNumber(SA_TILE,SB_TILE); break; case FROZEN: random_level_spec->wasteland = RandomNumber(FIRST_ICE_TILE,LAST_ICE_TILE); break; case PLAINS: random_level_spec->wasteland = RandomNumber(FIRST_PLAIN_TILE,LAST_PLAIN_TILE); break; case MARSH: random_level_spec->wasteland = RandomNumber(FIRST_SWAMP_TILE,LAST_SWAMP_TILE); break; } /************************************************************************************/ /***** Step 3: Decide how many different kinds of special tiles the level will have.*/ /************************************************************************************/ chosen_random_number = RandomNumber(0,99); switch (base_tile_type) { case PLAINS: case FROZEN: if (chosen_random_number < 25) number_of_special_tile_types = 0; else if (chosen_random_number < 60) number_of_special_tile_types = 1; else if (chosen_random_number < 80) number_of_special_tile_types = 2; else if (chosen_random_number < 95) number_of_special_tile_types = 3; else number_of_special_tile_types = 4; break; case MARSH: if (chosen_random_number < 10) number_of_special_tile_types = 0; else if (chosen_random_number < 45) number_of_special_tile_types = 1; else if (chosen_random_number < 70) number_of_special_tile_types = 2; else if (chosen_random_number < 95) number_of_special_tile_types = 3; else number_of_special_tile_types = 4; break; } /************************************************************************************/ /***** Step 4: Now decide what the special tiles will be. ***************************/ /************************************************************************************/ for (i = 0; i < 4; i++) featured_special_tiles[i] = base_tile; for (i = 0; i < number_of_special_tile_types; i++) { do { chosen_random_number = RandomNumber(0,99); switch (base_tile_type) { case FROZEN: if (chosen_random_number < 10) j = MARSH; else if (chosen_random_number < 30) j = PLAINS; else if (chosen_random_number < 45) j = CHASM; else if (chosen_random_number < 60) j = MOLTEN; else if (chosen_random_number < 70) j = TOXIC; else j = ROCKY; break; case MARSH: if (chosen_random_number < 10) j = FROZEN; else if (chosen_random_number < 30) j = PLAINS; else if (chosen_random_number < 45) j = CHASM; else if (chosen_random_number < 60) j = MOLTEN; else if (chosen_random_number < 80) j = TOXIC; else j = ROCKY; break; case PLAINS: if (chosen_random_number < 10) j = MARSH; else if (chosen_random_number < 20) j = FROZEN; else if (chosen_random_number < 35) j = CHASM; else if (chosen_random_number < 50) j = MOLTEN; else if (chosen_random_number < 70) j = TOXIC; else j = ROCKY; break; } switch (j) { case PLAINS: k = RandomNumber(FIRST_PLAIN_TILE, LAST_PLAIN_TILE); break; case FROZEN: k = RandomNumber(FIRST_ICE_TILE, LAST_ICE_TILE); break; case MARSH: k = RandomNumber(FIRST_SWAMP_TILE, LAST_SWAMP_TILE); break; case TOXIC: k = RandomNumber(FIRST_SLIME_TILE, LAST_SLIME_TILE); break; case MOLTEN: k = RandomNumber(FIRST_LAVA_TILE, LAST_LAVA_TILE); break; case CHASM: k = RandomNumber(FIRST_PIT_TILE, LAST_PIT_TILE); break; case ROCKY: k = RandomNumber(BOULDER0,BOULDERD); break; } } while ((featured_special_tiles[0] == k) || (featured_special_tiles[1] == k) || (featured_special_tiles[2] == k) || (featured_special_tiles[3] == k)); featured_special_tiles[i] = k; } /************************************************************************************/ /***** Step 5: Decide on how many special tiles there will be. **********************/ /************************************************************************************/ total_number_of_special_tiles = (number_of_special_tile_types * 5) + RandomNumber(0,15) + RandomNumber(0,15); i = RandomNumber(1,6); if (i == 1) total_number_of_special_tiles += 50; if (i == 2) total_number_of_special_tiles += 20; /************************************************************************************/ /***** Step 6: Decide on how many of each type of special tile there will be. *******/ /************************************************************************************/ if (number_of_special_tile_types > 0) { for (i = 0; i < number_of_special_tile_types; i++) total_number_of_special_tiles -= 5; for (i = 0; i < (number_of_special_tile_types - 1); i++) { j = RandomNumber(0,total_number_of_special_tiles); total_number_of_special_tiles -= j; number_of_featured_special_tiles[i] = 5 + j; } i = number_of_special_tile_types - 1; number_of_featured_special_tiles[i] = 5 + total_number_of_special_tiles; } /************************************************************************************/ /***** Step 7: Load the tile chart up with the basic tile. **************************/ /************************************************************************************/ for (i = 0; i < ROWS_IN_LANDSCAPE; i++) for (j = 0; j < COLUMNS_IN_LANDSCAPE; j++) random_level_spec->tiles[i][j] = (char) base_tile; /************************************************************************************/ /***** Step 8: Distribute the special tiles within the landscape. *******************/ /************************************************************************************/ switch(RandomNumber(0,2)) { case 0: for (i = 0; i < number_of_special_tile_types; i++) PlaceHazardsRandomly (number_of_featured_special_tiles[i], featured_special_tiles[i],base_tile); break; case 1: for (i = 0; i < number_of_special_tile_types; i++) PlaceHazardsInLines (number_of_featured_special_tiles[i], featured_special_tiles[i],base_tile); break; case 2: for (i = 0; i < number_of_special_tile_types; i++) PlaceHazardsInBunches (number_of_featured_special_tiles[i], featured_special_tiles[i],base_tile); break; } /************************************************************************************/ /***** Step 9: Check the landscape for unacceptible situations and remove any found.*/ /************************************************************************************/ CheckForAndRemoveImpossibilites (base_tile); /************************************************************************************/ /***** Step 10: Initialize the solids layout. **************************************/ /************************************************************************************/ for (i = 0; i < ROWS_IN_LANDSCAPE; i++) for (j = 0; j < COLUMNS_IN_LANDSCAPE; j++) random_level_spec->pyramids[i][j] = NOTHING; /************************************************************************************/ /***** Step 11: Convert the rock tiles into rock objects. **************************/ /************************************************************************************/ for (i = 0; i < ROWS_IN_LANDSCAPE; i++) { for (j = 0; j < COLUMNS_IN_LANDSCAPE; j++) { if ((random_level_spec->tiles[i][j] >= BOULDER0) && (random_level_spec->tiles[i][j] <= LAST_BOULDER)) { random_level_spec->pyramids[i][j] = random_level_spec->tiles[i][j]; random_level_spec->tiles[i][j] = (char) base_tile; } } } /************************************************************************************/ /***** Step 12: Decide how many special pyramids to include. ***********************/ /************************************************************************************/ chosen_random_number = RandomNumber(0,99); if (chosen_random_number < 10) types_of_special_pyramids = 3; else if (chosen_random_number < 20) types_of_special_pyramids = 2; else if (chosen_random_number < 30) types_of_special_pyramids = 1; else types_of_special_pyramids = 0; total_special_pyramids = (types_of_special_pyramids * 5) + RandomNumber (0,30); featured_special_pyramids[0] = RandomNumber(PURPLE_PYRAMID,CONCRETE_PYRAMID); if (types_of_special_pyramids == 2) { do featured_special_pyramids[1] = RandomNumber(PURPLE_PYRAMID,CONCRETE_PYRAMID); while (featured_special_pyramids[1] == featured_special_pyramids[0]); } if (types_of_special_pyramids == 3) { featured_special_pyramids[0] = PURPLE_PYRAMID; featured_special_pyramids[1] = RAINBOW_PYRAMID; featured_special_pyramids[2] = CONCRETE_PYRAMID; } /************************************************************************************/ /***** Step 13: Populate the universe with special pyramids (if any). ***************/ /************************************************************************************/ if (types_of_special_pyramids != 0) { while (total_special_pyramids) { do { i = RandomNumber(0,13); j = RandomNumber(0,13); } while ((ThisTileIsHazardous(random_level_spec->tiles[i][j])) || (random_level_spec->pyramids[i][j] != NOTHING)); k = RandomNumber(0,(types_of_special_pyramids - 1)); random_level_spec->pyramids[i][j] = (char) featured_special_pyramids[k]; total_special_pyramids--; } } /************************************************************************************/ /***** Step 14: Decide how many types of normal pyramids to use. *******************/ /************************************************************************************/ chosen_random_number = RandomNumber(0,99); types_of_normal_pyramids = 3; if (chosen_random_number >= 75) types_of_normal_pyramids = 2; if (chosen_random_number < 15) types_of_normal_pyramids = 1; featured_normal_pyramids[0] = RandomNumber (BLUE_PYRAMID,GREEN_PYRAMID); if (types_of_normal_pyramids == 2) { do featured_normal_pyramids[1] = RandomNumber (BLUE_PYRAMID,GREEN_PYRAMID); while (featured_normal_pyramids[1] == featured_normal_pyramids[0]); } if (types_of_normal_pyramids == 3) { featured_normal_pyramids[0] = BLUE_PYRAMID; featured_normal_pyramids[1] = GREEN_PYRAMID; featured_normal_pyramids[2] = RED_PYRAMID; } /************************************************************************************/ /***** Step 15: Populate the open spaces with normal pyramids. *********************/ /************************************************************************************/ for (i = 0; i < ROWS_IN_LANDSCAPE; i++) { for (j = 0; j < COLUMNS_IN_LANDSCAPE; j++) { if ((!(ThisTileIsHazardous(random_level_spec->tiles[i][j]))) && (random_level_spec->pyramids[i][j] == NOTHING)) { k = RandomNumber(0,(types_of_normal_pyramids - 1)); random_level_spec->pyramids[i][j] = (char) featured_normal_pyramids[k]; } } } /************************************************************************************/ /***** Step 16: Determine the type of environment (from the seeker's point of view).*/ /************************************************************************************/ type_of_environment = HAZARDLESS; swamp_status = SWAMPLESS; if (base_tile_type == MARSH) swamp_status = SWAMPY_BASE; for (i = 0; i < number_of_special_tile_types; i++) { if (((featured_special_tiles[i] >= FIRST_LAVA_TILE) && (featured_special_tiles[i] <= LAST_LAVA_TILE)) || ((featured_special_tiles[i] >= FIRST_PIT_TILE) && (featured_special_tiles[i] <= LAST_PIT_TILE))) { if (type_of_environment == HAZARDLESS) type_of_environment = PITS_ONLY; if (type_of_environment == ROCKS_ONLY) type_of_environment = ROCKS_AND_PITS; } if ((featured_special_tiles[i] >= BOULDER0) && (featured_special_tiles[i] <= BOULDERD)) { if (type_of_environment == HAZARDLESS) type_of_environment = ROCKS_ONLY; if (type_of_environment == PITS_ONLY) type_of_environment = ROCKS_AND_PITS; } if ((featured_special_tiles[i] >= FIRST_SWAMP_TILE) && (featured_special_tiles[i] <= LAST_SWAMP_TILE)) { switch (base_tile_type) { case MARSH: swamp_status = SWAMPY_WITH_SWAMPS; break; case FROZEN: swamp_status = ICY_WITH_SWAMPS; break; case PLAINS: swamp_status = PLAIN_WITH_SWAMPS; break; } } } /************************************************************************************/ /***** Step 17: Decide how many different types of seekers this level will have. ***/ /************************************************************************************/ random_level_spec->total_flavors = 1; i = RandomNumber(0,9); if (i <= 3) random_level_spec->total_flavors = 2; if (i >= 8) random_level_spec->total_flavors = 3; /************************************************************************************/ /***** Step 18: Will there be zombies? *********************************************/ /************************************************************************************/ chosen_random_number = RandomNumber(0,99); random_level_spec->featured_flavors[0] = NOTHING; if (wasteland_type == MARSH) { switch (swamp_status) { case SWAMPLESS: if (chosen_random_number < 35) random_level_spec->featured_flavors[0] = ZOMBIE; break; case SWAMPY_BASE: if (chosen_random_number < 95) random_level_spec->featured_flavors[0] = ZOMBIE; break; case PLAIN_WITH_SWAMPS: if (chosen_random_number < 65) random_level_spec->featured_flavors[0] = ZOMBIE; break; case ICY_WITH_SWAMPS: if (chosen_random_number < 45) random_level_spec->featured_flavors[0] = ZOMBIE; break; case SWAMPY_WITH_SWAMPS: if (chosen_random_number < 95) random_level_spec->featured_flavors[0] = ZOMBIE; break; } } else { switch (swamp_status) { case SWAMPLESS: break; case SWAMPY_BASE: if (chosen_random_number < 85) random_level_spec->featured_flavors[0] = ZOMBIE; break; case PLAIN_WITH_SWAMPS: if (chosen_random_number < 30) random_level_spec->featured_flavors[0] = ZOMBIE; break; case ICY_WITH_SWAMPS: if (chosen_random_number < 15) random_level_spec->featured_flavors[0] = ZOMBIE; break; case SWAMPY_WITH_SWAMPS: if (chosen_random_number < 85) random_level_spec->featured_flavors[0] = ZOMBIE; break; } } /************************************************************************************/ /***** Step 19: Decide what other seeker flavors will be featured. *****************/ /************************************************************************************/ k = 0; if (random_level_spec->featured_flavors[0] == ZOMBIE) { k = 1; if (random_level_spec->total_flavors == 3) random_level_spec->total_flavors = 2; } for (i = k; i < random_level_spec->total_flavors; i++) { chosen_random_number = RandomNumber(0,99); if (base_tile_type != FROZEN) { switch (type_of_environment) { case HAZARDLESS: do { if (chosen_random_number < 20) j = YELLOW_SEEKER; else if (chosen_random_number < 50) j = LTBLUE_SEEKER; else if (chosen_random_number < 65) j = PINK_SEEKER; else if (chosen_random_number < 80) j = LIME_SEEKER; else if (chosen_random_number < 95) j = LURKER; else j = MEANY; chosen_random_number = RandomNumber(0,99); } while ((random_level_spec->total_flavors == 1) && (j == YELLOW_SEEKER)); break; case ROCKS_ONLY: if (chosen_random_number < 15) j = YELLOW_SEEKER; else if (chosen_random_number < 50) j = LTBLUE_SEEKER; else if (chosen_random_number < 60) j = PINK_SEEKER; else if (chosen_random_number < 80) j = LIME_SEEKER; else if (chosen_random_number < 95) j = LURKER; else j = MEANY; break; case PITS_ONLY: if (chosen_random_number < 15) j = YELLOW_SEEKER; else if (chosen_random_number < 30) j = LTBLUE_SEEKER; else if (chosen_random_number < 50) j = PINK_SEEKER; else if (chosen_random_number < 70) j = LIME_SEEKER; else if (chosen_random_number < 85) j = LURKER; else j = MEANY; break; case ROCKS_AND_PITS: if (chosen_random_number < 15) j = YELLOW_SEEKER; else if (chosen_random_number < 30) j = LTBLUE_SEEKER; else if (chosen_random_number < 45) j = PINK_SEEKER; else if (chosen_random_number < 70) j = LIME_SEEKER; else if (chosen_random_number < 85) j = LURKER; else j = MEANY; break; } } else { switch (type_of_environment) { case HAZARDLESS: do { if (chosen_random_number < 50) j = YELLOW_SEEKER; else if (chosen_random_number < 70) j = LTBLUE_SEEKER; else if (chosen_random_number < 85) j = PINK_SEEKER; else if (chosen_random_number < 90) j = LIME_SEEKER; else if (chosen_random_number < 99) j = LURKER; else j = MEANY; chosen_random_number = RandomNumber(0,99); } while ((random_level_spec->total_flavors == 1) && (j == YELLOW_SEEKER)); break; case ROCKS_ONLY: if (chosen_random_number < 35) j = YELLOW_SEEKER; else if (chosen_random_number < 60) j = LTBLUE_SEEKER; else if (chosen_random_number < 75) j = PINK_SEEKER; else if (chosen_random_number < 90) j = LIME_SEEKER; else if (chosen_random_number < 99) j = LURKER; else j = MEANY; break; case PITS_ONLY: if (chosen_random_number < 20) j = YELLOW_SEEKER; else if (chosen_random_number < 40) j = LTBLUE_SEEKER; else if (chosen_random_number < 65) j = PINK_SEEKER; else if (chosen_random_number < 85) j = LIME_SEEKER; else if (chosen_random_number < 95) j = LURKER; else j = MEANY; break; case ROCKS_AND_PITS: if (chosen_random_number < 20) j = YELLOW_SEEKER; else if (chosen_random_number < 40) j = LTBLUE_SEEKER; else if (chosen_random_number < 60) j = PINK_SEEKER; else if (chosen_random_number < 80) j = LIME_SEEKER; else if (chosen_random_number < 90) j = LURKER; else j = MEANY; break; } } random_level_spec->featured_flavors[i] = j; } /************************************************************************************/ /***** Step 20: Decide how many of each type of seeker (in each mode) there will be.*/ /************************************************************************************/ for (i = 0; i < random_level_spec->total_flavors; i++) { switch (random_level_spec->total_flavors) { case 1: switch(random_level_spec->featured_flavors[i]) { case YELLOW_SEEKER: random_level_spec->easy_seeker_count[i] = RandomNumber(3,6); random_level_spec->medium_seeker_count[i] = RandomNumber(7,10); random_level_spec->hard_seeker_count[i] = RandomNumber(11,15); random_level_spec->insane_seeker_count[i] = RandomNumber(16,50); break; case PINK_SEEKER: random_level_spec->easy_seeker_count[i] = RandomNumber(2,5); random_level_spec->medium_seeker_count[i] = RandomNumber(6,9); random_level_spec->hard_seeker_count[i] = RandomNumber(10,12); random_level_spec->insane_seeker_count[i] = RandomNumber(13,20); break; case LTBLUE_SEEKER: random_level_spec->easy_seeker_count[i] = RandomNumber(2,4); random_level_spec->medium_seeker_count[i] = RandomNumber(5,6); random_level_spec->hard_seeker_count[i] = RandomNumber(7,8); random_level_spec->insane_seeker_count[i] = RandomNumber(9,10); break; case LIME_SEEKER: random_level_spec->easy_seeker_count[i] = RandomNumber(2,3); random_level_spec->medium_seeker_count[i] = RandomNumber(4,5); random_level_spec->hard_seeker_count[i] = RandomNumber(6,7); random_level_spec->insane_seeker_count[i] = RandomNumber(8,12); break; case ZOMBIE: random_level_spec->easy_seeker_count[i] = RandomNumber(2,3); random_level_spec->medium_seeker_count[i] = RandomNumber(4,5); random_level_spec->hard_seeker_count[i] = RandomNumber(6,7); random_level_spec->insane_seeker_count[i] = RandomNumber(8,10); break; case LURKER: random_level_spec->easy_seeker_count[i] = 1; random_level_spec->medium_seeker_count[i] = RandomNumber(2,3); random_level_spec->hard_seeker_count[i] = RandomNumber(4,5); random_level_spec->insane_seeker_count[i] = RandomNumber(6,10); break; case MEANY: random_level_spec->easy_seeker_count[i] = 1; random_level_spec->medium_seeker_count[i] = 2; random_level_spec->hard_seeker_count[i] = RandomNumber(3,4); random_level_spec->insane_seeker_count[i] = RandomNumber(5,7); break; } break; case 2: switch(random_level_spec->featured_flavors[i]) { case YELLOW_SEEKER: random_level_spec->easy_seeker_count[i] = RandomNumber(2,3); random_level_spec->medium_seeker_count[i] = RandomNumber(4,5); random_level_spec->hard_seeker_count[i] = RandomNumber(6,7); random_level_spec->insane_seeker_count[i] = RandomNumber(8,25); break; case PINK_SEEKER: random_level_spec->easy_seeker_count[i] = RandomNumber(1,2); random_level_spec->medium_seeker_count[i] = RandomNumber(3,4); random_level_spec->hard_seeker_count[i] = RandomNumber(5,6); random_level_spec->insane_seeker_count[i] = RandomNumber(7,10); break; case LTBLUE_SEEKER: random_level_spec->easy_seeker_count[i] = RandomNumber(1,2); random_level_spec->medium_seeker_count[i] = RandomNumber(3,4); random_level_spec->hard_seeker_count[i] = RandomNumber(5,6); random_level_spec->insane_seeker_count[i] = RandomNumber(7,10); break; case LIME_SEEKER: random_level_spec->easy_seeker_count[i] = 1; random_level_spec->medium_seeker_count[i] = RandomNumber(2,3); random_level_spec->hard_seeker_count[i] = RandomNumber(4,5); random_level_spec->insane_seeker_count[i] = RandomNumber(6,7); break; case ZOMBIE: random_level_spec->easy_seeker_count[i] = 1; random_level_spec->medium_seeker_count[i] = 2; random_level_spec->hard_seeker_count[i] = RandomNumber(3,4); random_level_spec->insane_seeker_count[i] = RandomNumber(5,6); break; case LURKER: random_level_spec->easy_seeker_count[i] = 1; random_level_spec->medium_seeker_count[i] = 2; random_level_spec->hard_seeker_count[i] = 3; random_level_spec->insane_seeker_count[i] = RandomNumber(4,5); break; case MEANY: random_level_spec->easy_seeker_count[i] = 1; random_level_spec->medium_seeker_count[i] = 2; random_level_spec->hard_seeker_count[i] = 3; random_level_spec->insane_seeker_count[i] = 4; break; } break; case 3: switch(random_level_spec->featured_flavors[i]) { case YELLOW_SEEKER: random_level_spec->easy_seeker_count[i] = RandomNumber(1,2); random_level_spec->medium_seeker_count[i] = RandomNumber(2,3); random_level_spec->hard_seeker_count[i] = RandomNumber(3,4); random_level_spec->insane_seeker_count[i] = RandomNumber(5,10); break; case PINK_SEEKER: random_level_spec->easy_seeker_count[i] = RandomNumber(1,2); random_level_spec->medium_seeker_count[i] = RandomNumber(2,3); random_level_spec->hard_seeker_count[i] = RandomNumber(3,4); random_level_spec->insane_seeker_count[i] = RandomNumber(4,5); break; case LTBLUE_SEEKER: random_level_spec->easy_seeker_count[i] = RandomNumber(1,2); random_level_spec->medium_seeker_count[i] = RandomNumber(2,3); random_level_spec->hard_seeker_count[i] = RandomNumber(3,4); random_level_spec->insane_seeker_count[i] = RandomNumber(4,5); break; case LIME_SEEKER: random_level_spec->easy_seeker_count[i] = 1; random_level_spec->medium_seeker_count[i] = 2; random_level_spec->hard_seeker_count[i] = 3; random_level_spec->insane_seeker_count[i] = 4; break; case ZOMBIE: random_level_spec->easy_seeker_count[i] = 1; random_level_spec->medium_seeker_count[i] = 2; random_level_spec->hard_seeker_count[i] = 2; random_level_spec->insane_seeker_count[i] = 3; break; case LURKER: random_level_spec->easy_seeker_count[i] = 1; random_level_spec->medium_seeker_count[i] = 1; random_level_spec->hard_seeker_count[i] = 2; random_level_spec->insane_seeker_count[i] = 3; break; case MEANY: random_level_spec->easy_seeker_count[i] = 1; random_level_spec->medium_seeker_count[i] = 1; random_level_spec->hard_seeker_count[i] = 2; random_level_spec->insane_seeker_count[i] = 2; break; } break; } } /************************************************************************************/ /***** Step 21: Now assign homes at random for all these guys. **********************/ /************************************************************************************/ k = 0; for (i = 0; i < random_level_spec->total_flavors; i++) { for (j = 0; j < random_level_spec->insane_seeker_count[i]; j++) { random_level_spec->seeker_type[k] = random_level_spec->featured_flavors[i]; switch (RandomNumber(0,3)) { case 0: random_level_spec->direction[k] = NORTH; break; case 1: random_level_spec->direction[k] = SOUTH; break; case 2: random_level_spec->direction[k] = EAST; break; case 3: random_level_spec->direction[k] = WEST; break; } switch (random_level_spec->direction[k]) { case NORTH: random_level_spec->row[k] = 0; random_level_spec->column[k] = RandomNumber(0,13); break; case SOUTH: random_level_spec->row[k] = 13; random_level_spec->column[k] = RandomNumber(0,13); break; case WEST: random_level_spec->row[k] = RandomNumber(0,13); random_level_spec->column[k] = 0; break; case EAST: random_level_spec->row[k] = RandomNumber(0,13); random_level_spec->column[k] = 13; break; } if ((random_level_spec->seeker_type[k] == ZOMBIE) && (swamp_status != SWAMPLESS)) { random_level_spec->direction[k] = RANDOM; random_level_spec->row[k] = 0; random_level_spec->column[k] = 0; } k++; } }}/******************************** PrintObjectCode ************************************** This function is used by DumpRandomlyGeneratedLevel to output the ASCII sybmol forthe given solid object.*****************************************************************************************/void PrintObjectCode(int32 object_id){ switch(object_id) { case NOTHING: printf("N "); break; case BLUE_PYRAMID: printf("B "); break; case RED_PYRAMID: printf("R "); break; case GREEN_PYRAMID: printf("G "); break; case PURPLE_PYRAMID: printf("P "); break; case RAINBOW_PYRAMID: printf("T "); break; case CONCRETE_PYRAMID: printf("C "); break; case BOULDER0: printf("0 "); break; case BOULDER1: printf("1 "); break; case BOULDER2: printf("2 "); break; case BOULDER3: printf("3 "); break; case BOULDER4: printf("4 "); break; case BOULDER5: printf("5 "); break; case BOULDER6: printf("6 "); break; case BOULDER7: printf("7 "); break; case BOULDER8: printf("8 "); break; case BOULDER9: printf("9 "); break; case BOULDERA: printf("A "); break; case BOULDERD: printf("D "); break; default: printf("%ld ",object_id); break; }}/********************************* PrintTileCode *************************************** This function is used by DumpRandomlyGeneratedLevel to output the ASCII sybmol forthe given tile.*****************************************************************************************/void PrintTileCode(int32 tile_id){ switch(tile_id) { case UA_TILE: printf("UA"); break; case UB_TILE: printf("UB"); break; case UC_TILE: printf("UC"); break; case UD_TILE: printf("UD"); break; case UE_TILE: printf("UE"); break; case DA_TILE: printf("DA"); break; case DB_TILE: printf("DB"); break; case DC_TILE: printf("DC"); break; case DD_TILE: printf("DD"); break; case GA_TILE: printf("GA"); break; case GB_TILE: printf("GB"); break; case GC_TILE: printf("GC"); break; case GD_TILE: printf("GD"); break; case GE_TILE: printf("GE"); break; case GF_TILE: printf("GF"); break; case HA_TILE: printf("HA"); break; case HB_TILE: printf("HB"); break; case HC_TILE: printf("HC"); break; case HD_TILE: printf("HD"); break; case HE_TILE: printf("HE"); break; case IA_TILE: printf("IA"); break; case IB_TILE: printf("IB"); break; case IC_TILE: printf("IC"); break; case ID_TILE: printf("ID"); break; case WA_TILE: printf("WA"); break; case WB_TILE: printf("WB"); break; case S1_TILE: printf("S1"); break; case SA_TILE: printf("SA"); break; case L1_TILE: printf("L1"); break; case LA_TILE: printf("LA"); break; case LB_TILE: printf("LB"); break; case PA_TILE: printf("PA"); break; case PB_TILE: printf("PB"); break; case PC_TILE: printf("PC"); break; case PD_TILE: printf("PD"); break; case PE_TILE: printf("PE"); break; case PF_TILE: printf("PF"); break; case PG_TILE: printf("PG"); break; case PH_TILE: printf("PH"); break; case PI_TILE: printf("PI"); break; case PJ_TILE: printf("PJ"); break; case P1_TILE: printf("P1"); break; case SB_TILE: printf("SB"); break; case DE_TILE: printf("DE"); break; case WC_TILE: printf("WC"); break; case WD_TILE: printf("WD"); break; case PL_TILE: printf("PL"); break; case PM_TILE: printf("PM"); break; default: printf("%ld ",tile_id); break; }}/************************ PrintRandomSeekersForGivenSetting *************************** This function is used by DumpRandomlyGeneratedLevel to output the seeker settings fora particular difficulty's contingent of seekers.*****************************************************************************************/void PrintRandomSeekersForGivenSetting(int32 setting){ int32 i,j,k; bool print_this_seeker; k = 0; for (i = 0; i < random_level_spec->total_flavors; i++) { for (j = 0; j < random_level_spec->insane_seeker_count[i]; j++) { print_this_seeker = FALSE; switch (setting) { case EASY: if (j < random_level_spec->easy_seeker_count[i]) print_this_seeker = TRUE; break; case MEDIUM: if ((j >= random_level_spec->easy_seeker_count[i]) && (j < random_level_spec->medium_seeker_count[i])) print_this_seeker = TRUE; break; case HARD: if ((j >= random_level_spec->medium_seeker_count[i]) && (j < random_level_spec->hard_seeker_count[i])) print_this_seeker = TRUE; break; case INSANE: if (j >= random_level_spec->hard_seeker_count[i]) print_this_seeker = TRUE; break; } if (print_this_seeker) { switch(random_level_spec->seeker_type[k]) { case YELLOW_SEEKER: printf("YELLOW_SEEKER, "); break; case LTBLUE_SEEKER: printf("LTBLUE_SEEKER, "); break; case PINK_SEEKER: printf("PINK_SEEKER, "); break; case LIME_SEEKER: printf("LIME_SEEKER, "); break; case LURKER: printf("LURKER, "); break; case ZOMBIE: printf("ZOMBIE, "); break; case MEANY: printf("MEANY, "); break; } printf("%ld, %ld, ", random_level_spec->row[k], random_level_spec->column[k]); switch(random_level_spec->direction[k]) { case NORTH: printf("NORTH"); break; case SOUTH: printf("SOUTH"); break; case EAST: printf("EAST"); break; case WEST: printf("WEST"); break; case RANDOM: printf("RANDOM"); break; case NO_DIRECTION: printf("NONE"); break; } printf("\n"); } k++; } }}/**************************** DumpRandomlyGeneratedLevel ******************************* This function prints the particulars of a randomly generated level in the usuallevel specification format. It is meant for use in cases in which a randomly generatedlevel is particularly successful and we want to save it for use as an actual level. *****************************************************************************************/void DumpRandomlyGeneratedLevel(){ int32 i,j; printf("*** Randomly Generated Level Specification ***\n"); for (i = 0; i < ROWS_IN_LANDSCAPE; i++) { for (j = 0; j < COLUMNS_IN_LANDSCAPE; j++) PrintObjectCode(random_level_spec->pyramids[i][j]); printf("\n"); } printf("*****************************************\n"); for (i = 0; i < ROWS_IN_LANDSCAPE; i++) { for (j = 0; j < COLUMNS_IN_LANDSCAPE; j++) { PrintTileCode(random_level_spec->tiles[i][j]); printf(" "); } printf("\n"); } printf("*****************************************\n"); PrintTileCode(random_level_spec->wasteland); printf("\n"); printf("*****************************************\n"); switch (RandomNumber (0, TOTAL_TRACKS - 1)) { default: printf ("QUACK\n"); break; case 0: printf ("QUACK\n"); break; case 1: printf ("CHECK_THIS_OUT_TALK\n"); break; case 2: printf ("MADONNA\n"); break; case 3: printf ("SPACE_AGE\n"); break; case 4: printf ("SOUND_OF_TALK\n"); break; case 5: printf ("LOTS_OF_PERC\n"); break; case 6: printf ("DRUNK_TRUMPET\n"); break; case 7: printf ("MONKEY\n"); break; case 8: printf ("THE_LONGER_ONE\n"); break; case 9: printf ("MORE_QUACK\n"); break; case 10: printf ("SEVENTIES2\n"); break; case 11: printf ("SHAFT\n"); break; case 12: printf ("HIT_ME\n"); break; case 13: printf ("WATER_WORKS\n"); break; case 14: printf ("FAST_HUNT\n"); break; case 15: printf ("G_BOUNCE\n"); break; case 16: printf ("SCHICK\n"); break; case 17: printf ("BALI\n"); break; } printf("*****************************************\n"); PrintRandomSeekersForGivenSetting(EASY); printf("*****************************************\n"); PrintRandomSeekersForGivenSetting(MEDIUM); printf("*****************************************\n"); PrintRandomSeekersForGivenSetting(HARD); printf("*****************************************\n"); PrintRandomSeekersForGivenSetting(INSANE); printf("*****************************************\n");} /***************************************** EOF ******************************************/