' *************** ' * T R A D E R * ' * v1.0 * ' *************** ' ' Copyright 1997 Brennen Bearnes ' This is an attempted clone of an old Apple II game called Taipan, in which ' you sailed around, traded in stuff, and battled pirates. Copy and ' distribute as you like, provided you distribute the original unmodified ' archive (trader.zip). ' NOTES: ' I started this for the last Retro Compo on comp.lang.basic.misc (which got ' something like 3 entries), and it's been sitting there unfinished for ' months. There's quite a bit of stuff I'd like to add, but I figured I ' ought to release what I have. Below is a list of things I'd like to ' complete for version 2.0. ' Stuff that needs done: ' - A story (sort of have one worked out) ' - More enemies ' - Cannon and armor upgrades, etc. ' - More locations within cities ' - More/better graphics ' - End game animations ' The graphics (such as they are), were done with Lior Zur's excellent QBdraw. ' It can be found at: ' http://www.geocities.com/SiliconValley/Heights/9246/ ' Comments/ideas/suggestions are, as always, welcome. ' -- ' Brennen Bearnes | bbearnes@hardlink.com ' http://www.hardlink.com/~bbearnes/ ' ******** ' * SUBs * ' ******** DECLARE SUB AddCargo (d%, Item$, AddToPlace%) DECLARE SUB BankMenu () DECLARE SUB BlockPrint (StartY%, StartX%, EndY%, EndX%, ReplaceChar$) DECLARE SUB Events (d%) DECLARE SUB FLoad (FileOffset&, DataLength&, Pic1%()) DECLARE SUB FireCannon (startShotX!, startShotY!, shotSpeed!, shotAngle!, FireType, sX, psX) DECLARE SUB GameOver (OverType%) DECLARE SUB IconLoad (LoadIcon%, LIType%) DECLARE SUB IconPut (IconPutX%, IconPutY%, IconPut$) DECLARE SUB MainMenu () DECLARE SUB MarketMenu () DECLARE SUB PalLoad (PalFile$) DECLARE SUB Pause (delay!) DECLARE SUB ReadIcon () DECLARE SUB SeaBattle (PType%, PGuns%) DECLARE SUB SetPrices (d%) DECLARE SUB ShipMenu () DECLARE SUB WarehouseMenu () ' ************* ' * FUNCTIONs * ' ************* DECLARE FUNCTION BuyPrice% (Item$) DECLARE FUNCTION GetKey$ () DECLARE FUNCTION OpenMix1! (FileName$) DECLARE FUNCTION SellPrice% (Item$) DECLARE FUNCTION ShipFree% () DECLARE FUNCTION WareFree% () ' ********* ' * TYPEs * ' ********* TYPE World paidPirates AS INTEGER gameDate AS INTEGER END TYPE TYPE Storage capacity AS INTEGER cannon AS INTEGER wheat AS INTEGER ore AS INTEGER luxuries AS INTEGER contraband AS INTEGER equipment AS INTEGER damage AS INTEGER END TYPE TYPE CityType CName AS STRING * 11 CType AS STRING * 3 Hidden AS INTEGER END TYPE TYPE PalType r AS INTEGER g AS INTEGER B AS INTEGER END TYPE ' ************* ' * Variables * ' ************* 'The default text color. DIM SHARED TextCol% TextCol% = 4 'World data. Basically, all the misc. stuff that's going on in the game. DIM SHARED GameState AS World 'Holds data for the cities you can travel to. DIM SHARED Ports(8) AS CityType 'Storage variables. DIM SHARED WareHouse AS Storage DIM SHARED Ship AS Storage DIM SHARED CurrentPrices AS Storage 'Misc. stuff. DIM SHARED Credits!, City%, Bank! DIM SHARED PName$ 'QBdraw MIX loader variables. CONST MaxMIX = 30 'Max files in a MIX file. DIM SHARED DimSize AS INTEGER DIM SHARED pall(256) AS PalType DIM SHARED pal(768) DIM SHARED FileSizer AS INTEGER 'The file's number of bytes counter. DIM SHARED FilesNumber AS INTEGER 'number of picture files in the MIX DIM SHARED ArraySize(MaxMIX) AS INTEGER 'array size of each file DIM SHARED StartRead(MaxMIX) AS INTEGER 'start reading place 'For the cannon ball drawing code. CONST PI = 3.141592654# SCREEN 13 PalLoad "draw" 'load palette CLOSE N = OpenMix1("icon") 'open the MIX file and get variables. IF N = 0 THEN 'if no errors DIM SHARED ShipIcon%(ArraySize(1)) DIM SHARED PirateIcon%(ArraySize(2)) DIM SHARED cannon%(ArraySize(3)) DIM SHARED IndIcon%(ArraySize(4)) DIM SHARED AgrIcon%(ArraySize(5)) DIM SHARED MinIcon%(ArraySize(6)) DIM SHARED FunIcon%(ArraySize(7)) DIM SHARED Splash%(ArraySize(8)) DIM SHARED Cancel%(ArraySize(9)) DIM SHARED TavernSign%(ArraySize(10)) DIM SHARED WareHouseIcon%(ArraySize(11)) DIM SHARED BankSign%(ArraySize(12)) FOR LoadIcon% = 1 TO 12 IconLoad LoadIcon%, 1 NEXT LoadIcon% END IF CLOSE 'Load larger graphics. (just 4, so far.) N = OpenMix1("bigpics") 'open the MIX file and get variables. IF N = 0 THEN 'if no errors DIM SHARED BigShipPic%(ArraySize(1)) DIM SHARED PirateShipPic%(ArraySize(2)) DIM SHARED StormPic%(ArraySize(3)) DIM SHARED PatrolShipPic%(ArraySize(4)) FOR LoadIcon% = 1 TO 4 IconLoad LoadIcon%, 2 NEXT LoadIcon% END IF CLOSE 'The main game menu. MainMenu 'Starting stuff. How much your warehouse/ship can hold, what stuff you start 'out with, what things cost at the beginning. WareHouse.capacity = 1000 Ship.damage = 100 Ship.capacity = 100 Ship.cannon = 3 Ship.ore = 5 Credits! = 50 CurrentPrices.wheat = 4 CurrentPrices.ore = 45 CurrentPrices.luxuries = 30 CurrentPrices.contraband = 150 CurrentPrices.equipment = 1000 'Set the date to -1 so that you start out in January. GameState.gameDate = -1 'Read the cities. First is always "home base". FOR LoadCity% = 1 TO 8 READ Ports(LoadCity%).CName READ Ports(LoadCity%).CType NEXT LoadCity% City% = 1 CLS ' ******************* ' * Main game loop. * ' ******************* CityMenu: CLS 'PUT the city icon IconPut 10, 10, Ports(City%).CType LINE (5, 5)-(315, 195), 5, B LOCATE 4, 6: PRINT "You are in the city of "; Ports(City%).CName LOCATE 7, 3: PRINT "Where do you want to go?" IconPut 20, 68, Ports(City%).CType LOCATE 11, 7: PRINT "1. The Marketplace" IconPut 20, 92, "ship" LOCATE 14, 7: PRINT "2. Your Ship" IF City% = 1 THEN IconPut 20, 116, "warehouse" LOCATE 17, 7: PRINT "3. Your Warehouse" IconPut 20, 140, "banksign" LOCATE 20, 7: PRINT "4. The Bank" END IF SELECT CASE UCASE$(GetKey$) CASE "1" MarketMenu CASE "2" ShipMenu CASE "3" IF City% = 1 THEN WarehouseMenu ELSE GOSUB CityMenu END IF CASE "4" IF City% = 1 THEN BankMenu ELSE GOSUB CityMenu END IF CASE CHR$(27) LOCATE 22, 4: PRINT "Do you want to quit?" SELECT CASE UCASE$(GetKey$) CASE "Y" LOCATE 22, 25: PRINT "Y" Pause 1 END CASE ELSE GOSUB CityMenu END SELECT END SELECT GOSUB CityMenu ' ******** ' * DATA * ' ******** 'city data 'Format: Name, type 'Agr is Agricultural 'Min is Mining 'Ind is industrial, or manufacturing. 'Fun is a pleasure city or resort. DATA "Smogville", "Ind" DATA "Cowstown", "Agr" DATA "Millwater", "Ind" DATA "Rockton", "Min" DATA "Grainville", "Agr" DATA "Silvercreek", "Min" DATA "Coalburgh", "Ind" DATA "Utopia", "Fun" SUB AddCargo (d%, Item$, AddToPlace%) SELECT CASE AddToPlace% CASE 1 SELECT CASE Item$ CASE "cannon" Ship.cannon = Ship.cannon + d% CASE "wheat" Ship.wheat = Ship.wheat + d% CASE "ore" Ship.ore = Ship.ore + d% CASE "luxuries" Ship.luxuries = Ship.luxuries + d% CASE "contraband" Ship.contraband = Ship.contraband + d% CASE "equipment" Ship.equipment = Ship.equipment + d% END SELECT CASE 2 SELECT CASE Item$ CASE "cannon" WareHouse.cannon = WareHouse.cannon + d% CASE "wheat" WareHouse.wheat = WareHouse.wheat + d% CASE "ore" WareHouse.ore = WareHouse.ore + d% CASE "luxuries" WareHouse.luxuries = WareHouse.luxuries + d% CASE "contraband" WareHouse.contraband = WareHouse.contraband + d% CASE "equipment" WareHouse.equipment = WareHouse.equipment + d% END SELECT END SELECT END SUB SUB BankMenu MainBank: CLS LINE (5, 5)-(315, 195), 5, B IconPut 10, 10, "banksign" LOCATE 4, 6: PRINT "The Bank in " + Ports(City%).CName LOCATE 7, 3: PRINT "Your account contains"; FIX(Bank!); "Credits." LOCATE 8, 3: PRINT "You have "; FIX(Credits!); " Credits in Cash." LOCATE 10, 4: PRINT "1. Withdraw Cash" LOCATE 11, 4: PRINT "2. Deposit Cash" LOCATE 12, 4: PRINT "3. Back to Main Menu" SELECT CASE VAL(GetKey$) CASE 1 LOCATE 14, 5: INPUT "Enter amount to withdraw: ", Transaction! IF Transaction! > Bank! THEN LOCATE 16, 7: PRINT "Your account isn't that big." WHILE INKEY$ = "": WEND ELSEIF Transaction! <= Bank! THEN Bank! = Bank! - Transaction! Credits! = Credits! + Transaction! LOCATE 16, 7: PRINT "Thanks for your business." WHILE INKEY$ = "": WEND END IF GOSUB MainBank CASE 2 LOCATE 14, 5: INPUT "Enter amount to deposit: ", Transaction! IF Transaction! > Credits! THEN LOCATE 16, 7: PRINT "You don't have that many credits." WHILE INKEY$ = "": WEND ELSEIF Transaction! <= Credits! THEN Bank! = Bank! + Transaction! Credits! = Credits! - Transaction! LOCATE 16, 7: PRINT "Thanks for your business." WHILE INKEY$ = "": WEND END IF GOSUB MainBank CASE 3 EXIT SUB CASE ELSE GOSUB MainBank END SELECT END SUB SUB BlockPrint (StartY%, StartX%, EndY%, EndX%, ReplaceChar$) 'This little sub just prints a block of the specified character at the 'given coordinates. I use it for clearing a section of the screen, such as 'a menu. FOR PrintLine% = StartY% TO EndY% LOCATE PrintLine%, StartX%: PRINT STRING$((EndX% - StartX%), ReplaceChar$) NEXT PrintLine% END SUB FUNCTION BuyPrice% (Item$) 'Returns the cost to buy cargo. SELECT CASE Ports(City%).CType CASE "Agr" SELECT CASE Item$ CASE "cannon" Price% = 0 CASE "wheat" Price% = CurrentPrices.wheat CASE "ore" Price% = 0 CASE "luxuries" Price% = 0 CASE "contraband" Price% = 0 CASE "equipment" Price% = 0 END SELECT CASE "Ind" SELECT CASE Item$ CASE "cannon" Price% = 0 CASE "wheat" Price% = 0 CASE "ore" Price% = 0 CASE "luxuries" Price% = CurrentPrices.luxuries CASE "contraband" Price% = 0 CASE "equipment" Price% = CurrentPrices.equipment END SELECT CASE "Min" SELECT CASE Item$ CASE "cannon" Price% = 0 CASE "wheat" Price% = 0 CASE "ore" Price% = CurrentPrices.ore CASE "luxuries" Price% = 0 CASE "contraband" Price% = 0 CASE "equipment" Price% = 0 END SELECT CASE "Fun" SELECT CASE Item$ CASE "cannon" Price% = 0 CASE "wheat" Price% = 0 CASE "ore" Price% = 0 CASE "luxuries" Price% = 0 CASE "contraband" Price% = CurrentPrices.contraband CASE "equipment" Price% = 0 END SELECT END SELECT BuyPrice% = Price% END FUNCTION SUB Events (d%) 'This sub does all the stuff after you complete a voyage. Interest at the 'bank, the date, calls SetPrices, etc. 'Increase the date. Each voyage takes one month. 'Yeah, I know it's unrealistic. GameState.gameDate = GameState.gameDate + 1 Year = FIX((GameState.gameDate / 12)) + 1850 Month = GameState.gameDate - ((Year - 1850) * 12) SELECT CASE Month CASE 0 Month$ = "January" CASE 1 Month$ = "February" CASE 2 Month$ = "March" CASE 3 Month$ = "April" CASE 4 Month$ = "May" CASE 5 Month$ = "June" CASE 6 Month$ = "July" CASE 7 Month$ = "August" CASE 8 Month$ = "September" CASE 9 Month$ = "October" CASE 10 Month$ = "November" CASE 11 Month$ = "December" END SELECT 'Calculate interest at the bank. Bank! = FIX(Bank! + (Bank! * .05)) 'This SUB sets the prices at the marketplace. SetPrices d% CLS LINE (5, 5)-(315, 195), 5, B IconPut 10, 10, Ports(d%).CType LOCATE 4, 6: PRINT "Arriving at " + Ports(d%).CName LOCATE 7, 3: PRINT Month$; Year SELECT CASE Month$ CASE "January" 'Every January, the pirate's guild demands tribute. If you pay, you won't 'be attacked by pirates. Much. GameState.paidPirates = 0 IF Credits! > 100 AND GameState.paidPirates = 1 THEN Tribute% = INT(Credits! * .25) ELSEIF Credits! > 100 AND GameState.paidPirates = 0 THEN Tribute% = INT(Credits! * .5) ELSEIF Credits! < 100 THEN Tribute% = 50 END IF LOCATE 9, 3: PRINT "The pirate's guild demands "; Tribute%; "in" LOCATE 10, 3: PRINT "tribute. Will you pay?" SELECT CASE UCASE$(GetKey$) CASE "Y" IF Credits! >= Tribute% THEN LOCATE 10, 27: PRINT "Y" Credits! = Credits! - Tribute% GameState.paidPirates = 1 ELSE LOCATE 11, 3: PRINT "You can't afford to pay." END IF CASE "N" LOCATE 10, 27: PRINT "N" END SELECT CASE "July" 'The wheat harvest is in or around july, which means that wheat prices 'fall. They don't pick back up again for several months, which should 'be an easy way to turn a good profit. (Exercise left to reader.) LOCATE 9, 3: PRINT "The wheat harvest has been completed." LOCATE 10, 3: PRINT "Wheat prices are down." CASE "October" 'Wheat prices rise again. LOCATE 9, 3: PRINT "Wheat prices have risen somewhat." END SELECT WHILE INKEY$ = "": WEND END SUB SUB FireCannon (startShotX, startShotY, shotSpeed, shotAngle, FireType, sX, psX) 'FireType is what kind of shot it is. '1 = Your ship, hit '2 = Your ship, miss '3 = Pirate ship, hit '4 = Pirate ship, miss shotAngle = shotAngle / 180 * PI startShotXvel = COS(shotAngle) * shotSpeed startShotYvel = SIN(shotAngle) * shotSpeed t = 0 EndShot% = 0 DO FOR paws = 1 TO 900: NEXT paws CIRCLE (shotX, shotY), 1, 0 t = t + .1 shotX = startShotX + (startShotXvel * t) shotY = startShotY + ((-1 * (startShotYvel * t)) + (4.9 * t ^ 2)) * (200 / 350) CIRCLE (shotX, shotY), 1, 24 IF FireType = 1 AND shotX >= psX THEN CIRCLE (shotX, shotY), 1, 0 EndShot% = 1 ELSEIF FireType = 2 AND shotY >= 94 THEN CIRCLE (shotX, shotY), 1, 0 PUT (shotX, shotY), Splash% EndShot% = 1 paws = TIMER: WHILE TIMER <= paws + .5: WEND PUT (shotX, shotY), Splash% ELSEIF FireType = 3 AND shotX <= sX + 50 THEN CIRCLE (shotX, shotY), 1, 0 EndShot% = 1 ELSEIF FireType = 4 AND shotY >= 94 THEN CIRCLE (shotX, shotY), 1, 0 PUT (shotX - 5, shotY), Splash% EndShot% = 1 paws = TIMER: WHILE TIMER <= paws + .5: WEND PUT (shotX - 5, shotY), Splash% END IF LOOP UNTIL EndShot% = 1 END SUB SUB FLoad (FileOffset&, DataLength&, DestArray() AS INTEGER) ' ' FLoad -- Quickly loads a file's contents into specified integer array. ' ' --Parameters-- ' FileName$ = The file name to load ' FileOffset& = The offset of the file to start loading ' DataLength& = The amount, in bytes, of data to load. ' DestArray() = The array to load all the data into. IF FileOffset& = 0 THEN FileOffset& = 1 RemBytes& = DataLength& BufferSize% = 32766 ' The buffer size to use. If you get out of string ' space errors, lower it. (result : it's slower) BufStart% = LBOUND(DestArray) ' Lowest element number of buffer DEF SEG = VARSEG(DestArray(BufStart%)) ' The segment of the song buffer Ptr& = VARPTR(DestArray(BufStart%)) ' Pointer to the song buffer LeftBytes& = RemBytes& MOD BufferSize% ' The amount of left over bytes SEEK #1, FileOffset& IF (LeftBytes& < RemBytes&) THEN FOR QuickLoad% = 1 TO (DataLength& - LeftBytes&) / BufferSize% Buffer$ = SPACE$(BufferSize%) GET #1, , Buffer$ FOR x% = 1 TO BufferSize% POKE Ptr&, ASC(MID$(Buffer$, x%, 1)) Ptr& = Ptr& + 1 NEXT Buffer$ = "" RemBytes& = RemBytes& - BufferSize% NEXT END IF IF (LeftBytes& > 0) THEN Buffer$ = SPACE$(LeftBytes&) GET #1, , Buffer$ FOR x% = 1 TO LeftBytes& POKE Ptr&, ASC(MID$(Buffer$, x%, 1)) Ptr& = Ptr& + 1 NEXT Buffer$ = "" END IF DEF SEG END SUB SUB GameOver (OverType%) ' 1 - Sunk by a pirate ' 2 - Sunk in a storm ' more to come SELECT CASE OverType% CASE 1 CLS LINE (5, 5)-(315, 195), 5, B LOCATE 19, 3: PRINT "Your ship has been sunk in a" LOCATE 20, 3: PRINT "fierce battle with pirates." Pause 1 FOR MovingShip% = 50 TO 75 WAIT &H3DA, 8 PUT (120, (MovingShip% - 1)), BigShipPic% PUT (120, MovingShip%), BigShipPic%, PSET Pause .3 NEXT MovingShip% LOCATE 22, 3: PRINT "Press a key to continue." SLEEP CASE 2 PRINT "Your ship has been sunk in a storm." PRINT TAB(6); "Press a key to continue." SLEEP END SELECT 'This may be clumsy, but all this does is re-run the program, bringing you 'back to the main menu, which lets you start a new game, restore, etc. RUN "trader" END SUB FUNCTION GetKey$ 'This just returns a keypress value. Used for all those menus. I think it 'makes things a little more efficient, anyway. k$ = "" WHILE k$ = "": k$ = INKEY$: WEND GetKey$ = k$ END FUNCTION SUB IconLoad (LoadIcon%, LIType%) DatLen& = ArraySize(LoadIcon%) * 2 'just temporary variables StrRed& = StartRead(LoadIcon%) 'because of Fload. IF LIType% = 1 THEN SELECT CASE LoadIcon% CASE 1 FLoad StrRed&, DatLen&, ShipIcon%() CASE 2 FLoad StrRed&, DatLen&, PirateIcon%() CASE 3 FLoad StrRed&, DatLen&, cannon%() CASE 4 FLoad StrRed&, DatLen&, IndIcon%() CASE 5 FLoad StrRed&, DatLen&, AgrIcon%() CASE 6 FLoad StrRed&, DatLen&, MinIcon%() CASE 7 FLoad StrRed&, DatLen&, FunIcon%() CASE 8 FLoad StrRed&, DatLen&, Splash%() CASE 9 FLoad StrRed&, DatLen&, Cancel%() CASE 10 FLoad StrRed&, DatLen&, TavernSign%() CASE 11 FLoad StrRed&, DatLen&, WareHouseIcon%() CASE 12 FLoad StrRed&, DatLen&, BankSign%() END SELECT ELSEIF LIType% = 2 THEN SELECT CASE LoadIcon% CASE 1 FLoad StrRed&, DatLen&, BigShipPic%() CASE 2 FLoad StrRed&, DatLen&, PirateShipPic%() CASE 3 FLoad StrRed&, DatLen&, StormPic%() END SELECT END IF END SUB SUB IconPut (IconPutX%, IconPutY%, IconPutName$) SELECT CASE IconPutName$ CASE "Ind" PUT (IconPutX%, IconPutY%), IndIcon% CASE "Min" PUT (IconPutX%, IconPutY%), MinIcon% CASE "Agr" PUT (IconPutX%, IconPutY%), AgrIcon% CASE "Fun" PUT (IconPutX%, IconPutY%), FunIcon% CASE "warehouse" PUT (IconPutX%, IconPutY%), WareHouseIcon% CASE "banksign" PUT (IconPutX%, IconPutY%), BankSign% CASE "tavernsign" PUT (IconPutX%, IconPutY%), TavernSign% CASE "ship" PUT (IconPutX%, IconPutY%), ShipIcon% CASE "cancel" PUT (IconPutX%, IconPutY%), Cancel% END SELECT END SUB SUB MainMenu Start: CLS COLOR TextCol% PRINT PRINT TAB(13); "T R A D E R" PRINT IconPut 20, 44, "ship" LOCATE 8, 7: PRINT "1. New Game" IconPut 20, 68, "cancel" LOCATE 11, 7: PRINT "2. Quit" SELECT CASE VAL(GetKey$) CASE 1 GOSUB StartGame CASE 2 END CASE ELSE GOSUB Start END SELECT StartGame: CLS PRINT PRINT TAB(6); "What is your name, Trader?" LOCATE 4, 10: INPUT "]", PName$ 'Get the player's name. CLS END SUB SUB MarketMenu 'Buy and sell stuff, etc. MainMarket: CLS LINE (5, 5)-(315, 195), 5, B 'Draw the city icon thingy. IconPut 10, 10, Ports(City%).CType LOCATE 4, 6: PRINT "The market in " + Ports(City%).CName LOCATE 7, 3: PRINT "Cargo Free" IF ShipFree% >= 0 THEN LOCATE 8, 3: PRINT USING "#### ####"; (Ship.capacity - ShipFree%); ShipFree% ELSEIF ShipFree% < 0 THEN LOCATE 8, 3: PRINT USING "#### Overloaded"; (Ship.capacity - ShipFree%) END IF LOCATE 10, 3: PRINT FIX(Credits!); "Credits" LOCATE 12, 3: PRINT "What do you want to do?" LOCATE 13, 4: PRINT "1. Sell Items" LOCATE 14, 4: PRINT "2. Buy Items" LOCATE 15, 4: PRINT "3. Back to Main Menu" SELECT CASE VAL(GetKey$) CASE 1 GOSUB SellMenu CASE 2 GOSUB BuyMenu CASE 3 EXIT SUB CASE ELSE GOSUB MainMarket END SELECT SellMenu: CLS LINE (5, 5)-(315, 195), 5, B LOCATE 5, 3: PRINT "What do you want to sell?" 'Put the city icon thingy. IconPut 10, 10, Ports(City%).CType LOCATE 7, 4: PRINT "Item No." IF Ship.cannon > 0 THEN LOCATE 9, 4: PRINT USING "(C)annon ####"; Ship.cannon IF Ship.wheat > 0 THEN LOCATE 10, 4: PRINT USING "(W)heat ####"; Ship.wheat IF Ship.ore > 0 THEN LOCATE 11, 4: PRINT USING "(O)re ####"; Ship.ore IF Ship.luxuries > 0 THEN LOCATE 12, 4: PRINT USING "(L)uxury Goods ####"; Ship.luxuries IF Ship.contraband > 0 THEN LOCATE 13, 4: PRINT USING "Con(t)raband ####"; Ship.contraband IF Ship.equipment > 0 THEN LOCATE 14, 4: PRINT USING "(E)quipment ####"; Ship.equipment LOCATE 16, 4: PRINT "(D)one" 'There has *got* to be a better way to do this... SELECT CASE UCASE$(GetKey$) CASE "C" NumItems% = Ship.cannon: Item$ = "cannon" CASE "W" NumItems% = Ship.wheat: Item$ = "wheat" CASE "O" NumItems% = Ship.ore: Item$ = "ore" CASE "L" NumItems% = Ship.luxuries: Item$ = "luxuries" CASE "T" NumItems% = Ship.contraband: Item$ = "contraband" CASE "E" NumItems% = Ship.equipment: Item$ = "equipment" CASE "D" GOSUB MainMarket CASE ELSE GOSUB SellMenu END SELECT CalcSale: SPrice% = SellPrice%(Item$) LOCATE 18, 3: PRINT "You have "; NumItems%; " Units of " + Item$ LOCATE 19, 3: PRINT Item$ + " is/are selling for "; SPrice% LOCATE 20, 3: INPUT "Number to Sell: ", d% IF d% <= NumItems% THEN AddCargo -d%, Item$, 1 Credits! = Credits! + (SPrice% * d%) LOCATE 20, 3: PRINT TAB(6); "Items Sold: "; d%; Item$ ELSEIF d% > NumItems% THEN LOCATE 20, 3: PRINT "You don't have that many " + Item$ + "." END IF WHILE INKEY$ = "": WEND GOSUB SellMenu 'This is the menu where one buys stuff. BuyMenu: CLS LINE (5, 5)-(315, 195), 5, B LOCATE 5, 3: PRINT USING "Free space: ####"; ShipFree% LOCATE 6, 3: PRINT USING "Credits: ##########"; FIX(Credits!) LOCATE 7, 3: PRINT "What do you want to buy?" 'Icon thingy again. IconPut 10, 10, Ports(City%).CType SELECT CASE Ports(City%).CType CASE "Agr" LOCATE 9, 4: PRINT "(W)heat" CASE "Ind" LOCATE 9, 4: PRINT "(L)uxury Goods" LOCATE 10, 4: PRINT "(E)quipment" CASE "Min" LOCATE 9, 4: PRINT "(O)re" CASE "Fun" LOCATE 9, 4: PRINT "Con(t)raband" END SELECT LOCATE 16, 4: PRINT "(D)one" SELECT CASE UCASE$(GetKey$) CASE "W" Item$ = "wheat" CASE "L" Item$ = "luxuries" CASE "E" Item$ = "equipment" CASE "O" Item$ = "ore" CASE "T" Item$ = "contraband" CASE "D" GOSUB MainMarket CASE ELSE GOSUB BuyMenu END SELECT CalcPurchase: BPrice% = BuyPrice%(Item$) IF BPrice% > 0 THEN LOCATE 18, 4: PRINT Item$ + " costs "; BPrice%; " per Unit." LOCATE 19, 4: PRINT "You can afford " + STR$(FIX(Credits! / BPrice%)) LOCATE 20, 4: INPUT "Number to buy: ", d% IF (d% * BPrice%) <= Credits! THEN Credits! = Credits! - (d% * BPrice%) AddCargo d%, Item$, 1 LOCATE 20, 4: PRINT "Number bought: "; d% IF ShipFree% < 0 THEN LOCATE 21, 4: PRINT "Your ship is overloaded." END IF ELSEIF (d% * BPrice%) > Credits! AND ShipFree% >= d% THEN LOCATE 20, 4: PRINT "You can't afford that many." END IF ELSEIF BPrice% = 0 THEN GOSUB BuyMenu END IF WHILE INKEY$ = "": WEND GOSUB BuyMenu END SUB FUNCTION OpenMix1 (FileName$) DIM lbyte AS STRING * 1 '(5) 5 char file id -+ ' + | '(4) 2 integer file version + num files |= calculate '==== | file header ' 9 _| FileSizer = 10 'this is the header size + 1 (1 = starting location) DIM Dummy AS INTEGER 'just for info inside file that we don't need. mk = FREEFILE OPEN FileName$ + ".MIX" FOR BINARY AS mk IF LOF(mk) <= 0 THEN 'file doesn't exist! CLOSE KILL FileName$ + "MIX" ' kill file! (opening file that doesn't ' exist creates an empty file) OpenMix1 = -1 EXIT FUNCTION END IF id$ = "" 'get file id, to check if it's MIX FOR I = 1 TO 5 'file... GET #mk, , lbyte id$ = id$ + lbyte NEXT I IF id$ <> "QBMIX" THEN 'if it's not, EXIT!!!! OpenMix1 = -2 EXIT FUNCTION END IF DIM vers AS INTEGER GET #mk, , vers 'get version IF vers <> 1 THEN 'we know how to open only version 1 OpenMix1 = -3 EXIT FUNCTION END IF GET #mk, , FilesNumber 'number of pictures inside MIX IF FilesNumber > MaxMIX OR FilesNumber <= 0 THEN OpenMix1 = -4 'if it's too big or too small, exit! EXIT FUNCTION END IF 'until now file header FOR I = 1 TO FilesNumber 'file name (8 bytes) FOR d = 1 TO 8 'read file name. It's not useful here, so GET #mk, , lbyte 'we just use a dummy. FileSizer = FileSizer + 1 'we read one byte at a time. NEXT d GET #mk, , ArraySize(I) 'read array size GET #mk, , Dummy 'read x size GET #mk, , Dummy 'read y size (we use a dummy) FileSizer = FileSizer + 6 'we read 3 integers that are 2 bytes NEXT I 'each. 'now we have to calculate the place of each picture 'inside the file FOR I = 1 TO FilesNumber StartRead(I) = FileSizer 'array place in bytes FileSizer = FileSizer + (ArraySize(I) * 2) 'because integer = 2 NEXT I 'bytes END FUNCTION SUB PalLoad (PalFile$) CLOSE OPEN PalFile$ + ".PAL" FOR BINARY AS #1 IF LOF(1) = 0 THEN CLOSE #1 KILL PalFile$ + ".PAL" EXIT SUB END IF CLOSE #1 OPEN PalFile$ + ".PAL" FOR INPUT AS #1 FOR I = 1 TO 768 INPUT #1, pal(I) NEXT I CLOSE #1 num = 1 an = 1 DO pall(an).r = pal(num) num = num + 1 pall(an).g = pal(num) num = num + 1 pall(an).B = pal(num) num = num + 1 an = an + 1 LOOP UNTIL num > 768 OUT &H3C7, 0: OUT &H3C8, 0 FOR a% = 1 TO 256 * 3: OUT &H3C9, pal(a%) NEXT a% END SUB SUB Pause (delay!) 'This sub just delays for the specified amount of time. Found it in an ABC 'packet. Seems like a good method. t! = INT(TIMER) IF delay! >= 1 THEN DO IF t! <> INT(TIMER) THEN t! = INT(TIMER) count = count + 1 END IF LOOP UNTIL count = delay! ELSEIF delay! < 1 THEN DO IF t! <> TIMER THEN t! = TIMER count = count + .1 END IF LOOP UNTIL count = delay! END IF END SUB SUB SeaBattle (PType%, PGuns%) CLS LINE (5, 5)-(315, 195), 5, B SELECT CASE PType% CASE 1 'Pirates EnemyHealth = 40 PDistance = 3 END SELECT DO CLS LINE (5, 5)-(315, 195), 5, B LINE (5, 110)-(315, 110), 5 'PUT the cannons FOR PutIcon% = 1 TO Ship.cannon PUT (3 + (16 * PutIcon%), 3), cannon% NEXT PutIcon% 'PUT the ships. SELECT CASE PDistance CASE 3 sX = 25: psX = 215 CASE 2 sX = 45: psX = 185 CASE 1 sX = 70: psX = 150 END SELECT PUT (sX, 40), BigShipPic% SELECT CASE PType% CASE 1 PUT (psX, 40), PirateShipPic% END SELECT 'Damage bar IF Ship.damage > 50 THEN COLOR 32 ELSE COLOR 40 END IF DamagePercent = (Ship.damage / 100) * 100 LOCATE 15, 2: PRINT STRING$((Ship.damage / 4), 219) + " -" + STR$(DamagePercent) + "%" COLOR TextCol% 'Here's where the pirates fire at you. Hits = 0 LOCATE 17, 2: PRINT "They're firing!" + STRING$(10, " ") FOR Shoot = 1 TO PGuns% 'The chance they'll actually have a hit. RANDOMIZE TIMER: HitChance = (RND * 100) IF PDistance = 1 THEN IF HitChance >= 15 THEN 'The most damage, and it's pretty hard to miss. Of course, at this 'range, it becomes a simple pounding match. Ship.damage = Ship.damage - 9 Hits = Hits + 1 END IF ELSEIF PDistance = 2 THEN IF HitChance >= 35 THEN Hits = Hits + 1 'Quite a bit better chance of a hit, and more damage. Ship.damage = Ship.damage - 7 END IF ELSEIF PDistance = 3 THEN IF HitChance >= 72 THEN Hits = Hits + 1 'Further away, they have less chance of a hit, and do less damage. Ship.damage = Ship.damage - 5 END IF END IF NEXT Shoot IF Hits >= 1 THEN SELECT CASE PDistance CASE 3 FireCannon psX, 70, 40, 120, 3, sX, psX CASE 2 FireCannon psX, 70, 35, 140, 3, sX, psX CASE 1 FireCannon psX, 70, 30, 120, 3, sX, psX END SELECT ELSE RANDOMIZE TIMER: shotSpeedRnd = (RND * 10) SELECT CASE PDistance CASE 3 FireCannon psX, 70, 20 + shotSpeedRnd, 125, 4, sX, psX CASE 2 FireCannon psX, 70, 13 + shotSpeedRnd, 137, 4, sX, psX CASE 1 FireCannon psX, 70, 2, 90, 4, sX, psX END SELECT END IF LOCATE 19, 3: PRINT Hits; "of"; PGuns%; "shots hit us." Pause 2 'Combat menus. 'Do the damage bar again, test for death. IF Ship.damage <= 0 THEN 'You've been sunk. EndBattle% = 1: GOSUB EndBattleLoop ELSEIF Ship.damage > 50 THEN COLOR 32 ELSE COLOR 40 END IF BlockPrint 15, 2, 21, 40, " " DamagePercent = (Ship.damage / 100) * 100 LOCATE 15, 2: PRINT STRING$((Ship.damage / 4), 219) + " -" + STR$(DamagePercent) + "%" COLOR TextCol% LOCATE 17, 2: PRINT "What do you want to do?" 'If you've got cannons, show the menu option to fire them. IF Ship.cannon > 0 THEN LOCATE 19, 2: PRINT "(F)ire Cannon" IF Ship.cannon > 1 THEN LOCATE 19, 15: PRINT "s" END IF 'Move away from the enemy ship. If you're far enough away, this attempts 'to escape. IF PDistance = 3 THEN LOCATE 20, 2: PRINT "Run (A)way" ELSE LOCATE 20, 2: PRINT "Move (A)way" END IF 'Move towards the pirate ship. IF PDistance > 1 THEN LOCATE 21, 2: PRINT "Move (C)loser" 'If you're close enough to the enemy ship, then you can ram them, or 'attempt to board. 'ELSEIF PDistance = 1 THEN ' LOCATE 21, 2: PRINT "(R)am" ' LOCATE 22, 2: PRINT "(B)oard" END IF SeaBattleInput: SELECT CASE UCASE$(GetKey$) CASE "F" 'Fire your cannon IF Ship.cannon > 0 THEN 'Clear the menu. BlockPrint 17, 2, 22, 32, " " Hits = 0 FOR Shoot = 1 TO Ship.cannon BlockPrint 17, 2, 19, 32, " " LOCATE 17, 2: PRINT "We're firing..." + STRING$(10, " ") 'The chance you'll actually have a hit. RANDOMIZE TIMER: HitChance = (RND * 100) IF PDistance = 1 THEN IF HitChance >= 15 THEN Hits = Hits + 1 EnemyHealth = EnemyHealth - 9 END IF ELSEIF PDistance = 2 THEN IF HitChance >= 35 THEN Hits = Hits + 1 EnemyHealth = EnemyHealth - 7 END IF ELSEIF PDistance = 3 THEN IF HitChance >= 72 THEN Hits = Hits + 1 EnemyHealth = EnemyHealth - 5 END IF END IF NEXT Shoot IF Hits >= 1 THEN OldEnemyHealth = EnemyHealth SELECT CASE PDistance CASE 3 FireCannon 80, 70, 40, 30, 1, sX, psX CASE 2 FireCannon 100, 70, 40, 30, 1, sX, psX CASE 1 FireCannon 135, 70, 15, 10, 1, sX, psX END SELECT ELSE RANDOMIZE TIMER: shotSpeedRnd = (RND * 10) SELECT CASE PDistance CASE 3 FireCannon 80, 70, 20 + shotSpeedRnd, 35, 2, sX, psX CASE 2 FireCannon 100, 70, 13 + shotSpeedRnd, 47, 2, sX, psX CASE 1 FireCannon 135, 70, 2, 90, 2, sX, psX END SELECT END IF LOCATE 19, 3: PRINT Hits; "of"; Ship.cannon; "hit them." Pause 1 ELSE GOSUB SeaBattleInput END IF CASE "C" 'Move closer to the enemy ship IF PDistance > 1 THEN PDistance = PDistance - 1 ELSE GOSUB SeaBattleInput END IF CASE "A" 'Move away from the enemy ship, if you're far enough, attempt to escape 'completely. IF PDistance < 3 THEN PDistance = PDistance + 1 ELSEIF PDistance = 3 THEN 'The "run away" code goes here RANDOMIZE TIMER: EscapeChance% = INT(RND * 100) IF ShipFree% = Ship.capacity AND EscapeChance% >= 30 THEN EndBattle% = 3 GOSUB EndBattleLoop ELSEIF ShipFree% < (Ship.capacity / 2) AND EscapeChance% >= 50 THEN EndBattle% = 3 GOSUB EndBattleLoop ELSEIF ShipFree% < (Ship.capacity / 4) AND EscapeChance% >= 70 THEN EndBattle% = 3 GOSUB EndBattleLoop END IF END IF CASE ELSE GOSUB SeaBattleInput END SELECT 'Decide whether or not to end the battle, and if so how much money you 'make from it, etc. IF Ship.damage <= 0 THEN EndBattle% = 1 GOSUB EndBattleLoop END IF IF EnemyHealth <= 0 THEN EndBattle% = 2 GOSUB EndBattleLoop END IF EndBattleLoop: LOOP UNTIL EndBattle% > 0 SELECT CASE EndBattle% CASE 1 'You sink GameOver 1 CASE 2 'They sink SELECT CASE PType% CASE 1 RANDOMIZE TIMER: GainedCredits = INT(RND * 400) RANDOMIZE TIMER: CargoToAdd = INT(RND * 3) + 1 RANDOMIZE TIMER: d% = INT(RND * ShipFree%) SELECT CASE CargoToAdd CASE 1 Item$ = "contraband" CASE 2 Item$ = "luxuries" CASE 3 Item$ = "ore" END SELECT BlockPrint 17, 2, 22, 32, " " LOCATE 17, 2: PRINT "We sank them!" LOCATE 19, 2: PRINT "We've captured"; GainedCredits; "in cash." LOCATE 20, 2: PRINT "We've captured"; d%; "units of " + Item$ LOCATE 22, 2: PRINT "Do you want to keep it? (y/n)" IF UCASE$(GetKey$) = "Y" THEN AddCargo d%, Item$, 1 CASE 2 END SELECT CASE 3 'You run BlockPrint 17, 2, 22, 32, " " LOCATE 17, 2: PRINT "We've escaped!" END SELECT END SUB FUNCTION SellPrice% (Item$) 'Returns a value for how much you can sell something for. SELECT CASE Item$ CASE "cannon" Price% = 100 CASE "wheat" Price% = CurrentPrices.wheat CASE "ore" Price% = CurrentPrices.ore CASE "luxuries" Price% = CurrentPrices.luxuries CASE "contraband" Price% = CurrentPrices.contraband CASE "equipment" Price% = CurrentPrices.equipment END SELECT SellPrice% = Price% END FUNCTION SUB SetPrices (d%) 'This sets the prices for all of the items at the marketplace. 'For now it just takes into account the type of city and time of year, 'but I plan on adding other economic factors. Year = FIX((GameState.gameDate / 12)) + 1850 Month = GameState.gameDate - ((Year - 1850) * 12) SELECT CASE Month CASE 0 TO 5 WheatModifier = 3 CASE 6 TO 8 WheatModifier = 1 CASE 9 TO 11 WheatModifier = 2 END SELECT SELECT CASE Ports(d%).CType CASE "Agr" RANDOMIZE TIMER: CurrentPrices.wheat = 1 + (INT(RND * 10) * WheatModifier) RANDOMIZE TIMER: CurrentPrices.ore = 1 + INT(RND * 3) RANDOMIZE TIMER: CurrentPrices.luxuries = 1 + INT(RND * 3) RANDOMIZE TIMER: CurrentPrices.equipment = 500 + INT(RND * 2000) CASE "Ind" RANDOMIZE TIMER: CurrentPrices.wheat = 1 + INT(RND * 5) RANDOMIZE TIMER: CurrentPrices.ore = 10 + INT(RND * 60) RANDOMIZE TIMER: CurrentPrices.luxuries = 20 + INT(RND * 30) RANDOMIZE TIMER: CurrentPrices.equipment = 500 + INT(RND * 800) CASE "Min" RANDOMIZE TIMER: CurrentPrices.wheat = 5 + (INT(RND * 20) * WheatModifier) RANDOMIZE TIMER: CurrentPrices.ore = 2 + INT(RND * 25) RANDOMIZE TIMER: CurrentPrices.luxuries = 1 + INT(RND * 16) RANDOMIZE TIMER: CurrentPrices.equipment = 500 + INT(RND * 1000) CASE "Fun" RANDOMIZE TIMER: CurrentPrices.wheat = 1 + INT(RND * 6) RANDOMIZE TIMER: CurrentPrices.ore = 1 + INT(RND * 3) RANDOMIZE TIMER: CurrentPrices.luxuries = 5 + INT(RND * 50) RANDOMIZE TIMER: CurrentPrices.equipment = 400 END SELECT RANDOMIZE TIMER: CurrentPrices.contraband = 10 + INT(RND * 100) END SUB FUNCTION ShipFree% 'Returns the amount of free space left in the ship. Space = 0 Space% = Space% + Ship.cannon * 10 Space% = Space% + Ship.wheat + Ship.ore + Ship.luxuries + Ship.contraband + Ship.equipment ShipFree% = Ship.capacity - Space% END FUNCTION SUB ShipMenu MainShip: CLS LINE (5, 5)-(315, 195), 5, B PUT (10, 10), ShipIcon% 'Draw the cannons. FOR PutIcon% = 1 TO Ship.cannon PUT (30 + (16 * PutIcon%), 10), cannon% NEXT PutIcon% LOCATE 6, 3: PRINT "At ship in " + Ports(City%).CName LOCATE 8, 3: PRINT "What do you want to do?" LOCATE 10, 4: PRINT "1. Sail for Another Port" LOCATE 11, 4: PRINT "2. Upgrade or Repair Ship" LOCATE 12, 4: PRINT "3. Back to Main Menu" SELECT CASE VAL(GetKey$) CASE 1 GOSUB SailAway CASE 2 GOSUB ShipYard CASE 3 EXIT SUB CASE ELSE GOSUB MainShip END SELECT 'This menu lets you upgrade/repair your ship. 'You can repair, buy cannons or a lifeboat, upgrade stuff, etc. ShipYard: CLS LINE (5, 5)-(315, 195), 5, B PUT (10, 10), ShipIcon% 'Draw the cannons. FOR PutIcon% = 1 TO Ship.cannon PUT (30 + (16 * PutIcon%), 10), cannon% NEXT PutIcon% LOCATE 7, 3: PRINT "You have "; Ship.cannon; " Cannons." LOCATE 8, 3: PRINT "Ship condition: " + STR$(Ship.damage) + "%" LOCATE 9, 3: PRINT "You have "; Credits!; " Credits in cash." LOCATE 11, 4: PRINT "1. Repair Damage - 30 Credits" LOCATE 12, 4: PRINT "2. Buy a Cannon - 250 Credits" LOCATE 14, 4: PRINT "3. Done" SELECT CASE VAL(GetKey$) CASE 1 'Repair the ship. IF Ship.damage >= 100 THEN LOCATE 16, 3: PRINT "Your ship is already repaired." ELSEIF Ship.damage < 100 AND Credits! >= 30 THEN Credits! = Credits! - 30 Ship.damage = Ship.damage + 10 IF Ship.damage > 100 THEN Ship.damage = 100 LOCATE 16, 3: PRINT "Repairs done." END IF WHILE INKEY$ = "": WEND GOSUB ShipYard CASE 2 'Buy a cannon IF Credits! >= 250 AND ShipFree% >= 10 THEN Credits! = Credits! - 250 AddCargo 1, "cannon", 1 LOCATE 16, 3: PRINT "Cannon Purchased" ELSEIF (Credits! < 250) OR (ShipFree% < 10) THEN LOCATE 16, 5: PRINT "You can't afford a new cannon." END IF WHILE INKEY$ = "": WEND GOSUB ShipYard CASE 3 GOSUB MainShip CASE ELSE GOSUB ShipYard END SELECT SailAway: 'The menu of other ports to sail to. I'm sure there's a better way to do 'this, but I have no idea what it is. CLS LINE (5, 5)-(315, 195), 5, B PUT (10, 10), ShipIcon% LOCATE 4, 6: PRINT "Where do you want to sail?" IconPut 20, 44, Ports(1).CType IconPut 20, 68, Ports(2).CType IconPut 20, 92, Ports(3).CType IconPut 20, 116, Ports(4).CType IconPut 20, 140, Ports(5).CType LOCATE 8, 7: PRINT "1. " + Ports(1).CName LOCATE 11, 7: PRINT "2. " + Ports(2).CName LOCATE 14, 7: PRINT "3. " + Ports(3).CName LOCATE 17, 7: PRINT "4. " + Ports(4).CName LOCATE 20, 7: PRINT "5. " + Ports(5).CName IconPut 165, 44, Ports(6).CType IconPut 165, 68, Ports(7).CType IconPut 165, 92, Ports(8).CType IconPut 165, 116, "cancel" LOCATE 8, 25: PRINT "6. " + Ports(6).CName LOCATE 11, 25: PRINT "7. " + Ports(7).CName LOCATE 14, 25: PRINT "8. " + Ports(8).CName LOCATE 17, 25: PRINT "9. Cancel" d% = INT(VAL(GetKey$)) IF d% <= 9 AND d% >= 1 THEN IF d% = City% THEN LOCATE 23, 5: PRINT "You're already there!" paws = TIMER: WHILE TIMER <= paws + 2: WEND GOSUB SailAway ELSEIF (d% <> City%) AND (ShipFree% < 0) THEN LOCATE 22, 5: PRINT "Your ship is overloaded!" LOCATE 23, 5: PRINT "Sell or move some cargo." paws = TIMER: WHILE TIMER <= paws + 1: WEND EXIT SUB ELSEIF d% = 9 THEN GOSUB MainShip ELSE GOSUB MovingShip END IF ELSE GOSUB SailAway END IF 'Sail to whatever your port of choice is. MovingShip: CLS LINE (5, 5)-(315, 195), 5, B PUT (10, 10), ShipIcon% 'Show the cannons. FOR PutIcon% = 1 TO Ship.cannon PUT (30 + (16 * PutIcon%), 10), cannon% NEXT PutIcon% LOCATE 5, 3: PRINT "Sailing to "; Ports(d%).CName FOR MovingShip% = 5 TO 200 STEP 5 WAIT &H3DA, 8 PUT (25 + (MovingShip% - 5), 50), BigShipPic% PUT (25 + MovingShip%, 50), BigShipPic%, PSET Pause .3 IF MovingShip% = 85 THEN SELECT CASE ShipFree% CASE 0 TO (Ship.capacity / 4) Chance = Chance + .4 CASE ((Ship.capacity / 4) + 1) TO (Ship.capacity / 2) Chance = Chance + .3 CASE ((Ship.capacity / 2) + 1) TO ((Ship.capacity / 4) * 3) Chance = Chance + .2 END SELECT IF Ship.cannon >= 3 THEN Chance = Chance - (.1 * (INT(Ship.cannon / 3))) RANDOMIZE TIMER: Attack = RND + Chance IF GameState.paidPirates = 0 THEN SELECT CASE Attack CASE .85 TO .94 'Start a battle PAttacked% = 1 SeaBattle 1, 2 CASE .95 'Start a battle PAttacked% = 1 SeaBattle 1, 3 END SELECT ELSEIF GameState.paidPirates = 1 THEN IF Attack >= .99 THEN 'Start a battle PAttacked% = 1 SeaBattle 1, 2 END IF END IF IF PAttacked% = 1 THEN CLS LINE (5, 5)-(315, 195), 5, B PUT (10, 10), ShipIcon% 'Show the cannons. FOR PutIcon% = 1 TO Ship.cannon PUT (30 + (16 * PutIcon%), 10), cannon% NEXT PutIcon% LOCATE 5, 3: PRINT "Sailing to "; Ports(d%).CName PUT (25 + MovingShip%, 50), BigShipPic%, PSET END IF END IF NEXT MovingShip% RANDOMIZE TIMER: Storm = RND IF Storm >= .8 THEN StormCity% = 0 StormRnd = 0 CLS LINE (5, 5)-(315, 195), 5, B PUT (130, 30), StormPic% LOCATE 19, 3: PRINT "Storm!" Pause 1 'Calculate the effects of a storm. RANDOMIZE TIMER: StormRnd = RND * 10 Ship.damage = Ship.damage - INT(StormRnd) LOCATE 21, 3: PRINT "The ship has taken " + STR$(INT(StormRnd)) + " Damage." IF Ship.damage <= 0 THEN 'You're sunk. GameOver 2 END IF RANDOMIZE TIMER: StormRnd = RND IF StormRnd >= .6 THEN StormCity% = d% + 1 IF StormCity% > 8 THEN StormCity% = d% - 1 d% = StormCity% LOCATE 23, 3: PRINT "We've been blown to " + Ports(d%).CName END IF WHILE INKEY$ = "": WEND END IF 'Finished sailing, arrived without being killed, etc... 'This sub calculates interest at the bank, advances the date, triggers events, 'etc. Events d% City% = d%: EXIT SUB END SUB FUNCTION WareFree% 'Returns the amount of free space left in the warehouse. Space = 0 Space% = Space% + WareHouse.cannon * 10 Space% = Space% + WareHouse.wheat + WareHouse.ore + WareHouse.luxuries + WareHouse.contraband + WareHouse.equipment WareFree% = WareHouse.capacity - Space% END FUNCTION SUB WarehouseMenu MainWarehouse: CLS LINE (5, 5)-(315, 195), 5, B 'Draw the city icon thingy. IconPut 10, 10, Ports(City%).CType LOCATE 5, 3: PRINT "You are at your warehouse." LOCATE 7, 3: PRINT " Cargo Free" LOCATE 8, 3: PRINT USING "Ship: #### ####"; (Ship.capacity - ShipFree%); ShipFree% LOCATE 9, 3: PRINT USING "Warehouse: ##### #####"; (WareHouse.capacity - WareFree%); WareFree% LOCATE 11, 3: PRINT "What do you want to do?" LOCATE 13, 4: PRINT "1. Transfer to ship" LOCATE 14, 4: PRINT "2. Transfer from ship" LOCATE 15, 4: PRINT "3. Back to Main Menu" SELECT CASE VAL(GetKey$) CASE 1 GOSUB MoveToShip CASE 2 GOSUB MoveFromShip CASE 3 EXIT SUB CASE ELSE END SELECT MoveToShip: CLS LINE (5, 5)-(315, 195), 5, B LOCATE 5, 3: PRINT "What do you want to transfer?" LOCATE 7, 4: PRINT "Item No." IF WareHouse.cannon > 0 THEN LOCATE 9, 4: PRINT USING "(C)annon ####"; WareHouse.cannon IF WareHouse.wheat > 0 THEN LOCATE 10, 4: PRINT USING "(W)heat ####"; WareHouse.wheat IF WareHouse.ore > 0 THEN LOCATE 11, 4: PRINT USING "(O)re ####"; WareHouse.ore IF WareHouse.luxuries > 0 THEN LOCATE 12, 4: PRINT USING "(L)uxury Goods ####"; WareHouse.luxuries IF WareHouse.contraband > 0 THEN LOCATE 13, 4: PRINT USING "Con(t)raband ####"; WareHouse.contraband IF WareHouse.equipment > 0 THEN LOCATE 14, 4: PRINT USING "(E)quipment ####"; WareHouse.equipment LOCATE 16, 4: PRINT "(D)one" 'There has *got* to be a better way to do this... SELECT CASE UCASE$(GetKey$) CASE "C" NumItems% = WareHouse.cannon: Item$ = "cannon" CASE "W" NumItems% = WareHouse.wheat: Item$ = "wheat" CASE "O" NumItems% = WareHouse.ore: Item$ = "ore" CASE "L" NumItems% = WareHouse.luxuries: Item$ = "luxuries" CASE "T" NumItems% = WareHouse.contraband: Item$ = "contraband" CASE "E" NumItems% = WareHouse.equipment: Item$ = "equipment" CASE "D" GOSUB MainWarehouse CASE ELSE GOSUB MoveToShip END SELECT LOCATE 18, 3: PRINT "You have "; NumItems%; " Units of " + Item$ LOCATE 19, 3: INPUT "Number to move aboard ship: ", d% IF d% <= NumItems% AND d% <= ShipFree% THEN AddCargo d%, Item$, 1 AddCargo -d%, Item$, 2 LOCATE 20, 3: PRINT TAB(6); "Items Moved: "; d%; Item$ ELSEIF d% > NumItems% THEN LOCATE 20, 3: PRINT "You don't have that many " + Item$ + "." END IF WHILE INKEY$ = "": WEND GOSUB MainWarehouse 'Move stuff from the ship into the warehouse. MoveFromShip: CLS LINE (5, 5)-(315, 195), 5, B LOCATE 5, 3: PRINT "What do you want to transfer?" LOCATE 7, 4: PRINT "Item No." IF Ship.cannon > 0 THEN LOCATE 9, 4: PRINT USING "(C)annon ####"; Ship.cannon IF Ship.wheat > 0 THEN LOCATE 10, 4: PRINT USING "(W)heat ####"; Ship.wheat IF Ship.ore > 0 THEN LOCATE 11, 4: PRINT USING "(O)re ####"; Ship.ore IF Ship.luxuries > 0 THEN LOCATE 12, 4: PRINT USING "(L)uxury Goods ####"; Ship.luxuries IF Ship.contraband > 0 THEN LOCATE 13, 4: PRINT USING "Con(t)raband ####"; Ship.contraband IF Ship.equipment > 0 THEN LOCATE 14, 4: PRINT USING "(E)quipment ####"; Ship.equipment SELECT CASE UCASE$(GetKey$) CASE "C" NumItems% = Ship.cannon: Item$ = "cannon" CASE "W" NumItems% = Ship.wheat: Item$ = "wheat" CASE "O" NumItems% = Ship.ore: Item$ = "ore" CASE "L" NumItems% = Ship.luxuries: Item$ = "luxuries" CASE "T" NumItems% = Ship.contraband: Item$ = "contraband" CASE "E" NumItems% = Ship.equipment: Item$ = "equipment" CASE "D" CASE ELSE END SELECT LOCATE 18, 3: PRINT "You have "; NumItems%; " Units of " + Item$ LOCATE 19, 3: INPUT "Number to move to warehouse: ", d% IF d% <= NumItems% AND d% <= WareFree% THEN AddCargo -d%, Item$, 1 AddCargo d%, Item$, 2 LOCATE 20, 3: PRINT TAB(6); "Items Moved: "; d%; Item$ ELSEIF d% > NumItems% THEN LOCATE 20, 3: PRINT "You don't have that many " + Item$ + "." END IF WHILE INKEY$ = "": WEND GOSUB MainWarehouse END SUB