diff --git a/.gitignore b/.gitignore index 87dc21f..97de679 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ build/ slangin.hex +.ccls-cache/ diff --git a/slangin.ino b/slangin.ino index 088b9bf..5c82766 100644 --- a/slangin.ino +++ b/slangin.ino @@ -26,13 +26,16 @@ enum GameState { STATE_BUY_GUN_DIALOG, STATE_BUY_COAT_DIALOG, STATE_DO_WEED_DIALOG, + STATE_DID_WEED_DIALOG_1, + STATE_DID_WEED_DIALOG_2, STATE_HEAL_DIALOG, STATE_BUY_QTY_INPUT, STATE_SELL_QTY_INPUT, STATE_PAY_LOAN_INPUT, STATE_BORROW_INPUT, STATE_DEPOSIT_INPUT, - STATE_WITHDRAW_INPUT + STATE_WITHDRAW_INPUT, + STATE_GAME_OVER }; enum GameLocation { @@ -128,7 +131,7 @@ void loop() { case STATE_TITLE: arduboy.setCursor(25, 10); arduboy.print(F("Slangin' v0.9")); - menu[0] = F("New Game"); + menu[0] = F("Hit the Streets"); menuLength = 1; menuSmall = false; menuCols = false; @@ -158,7 +161,7 @@ void loop() { case STATE_INVENTORY: drawStatusBar(); - drawTitle("Trenchcoat"); + drawTitle(F("Trenchcoat")); buildDrugMenu(pInventory); drawMenu(menuSmall, menuCols, menuLength, menu); break; @@ -166,8 +169,8 @@ void loop() { case STATE_BUY_MENU: case STATE_SELL_MENU: drawStatusBar(); - if (sGameState == STATE_BUY_MENU) drawTitle("Buy Drugs"); - else drawTitle("Sell Drugs"); + if (sGameState == STATE_BUY_MENU) drawTitle(F("Buy Drugs")); + else drawTitle(F("Sell Drugs")); buildDrugMenu(sDrugPrices); drawMenu(menuSmall, menuCols, menuLength, menu); drawMenuIndicator(menuSelected, menuSmall, menuCols, menuLength, menu, false); @@ -192,7 +195,7 @@ void loop() { case STATE_SHARK_MENU: drawStatusBar(); - drawTitle("Loan Shark"); + drawTitle(F("Loan Shark")); menu[0] = F("Repay Loan"); menu[1] = F("Borrow Money"); menuLength = 2; @@ -204,7 +207,7 @@ void loop() { case STATE_BANK_MENU: drawStatusBar(); - drawTitle("Bank"); + drawTitle(F("Bank")); menu[0] = F("Deposit Money"); menu[1] = F("Withdraw Money"); menuLength = 2; @@ -215,7 +218,37 @@ void loop() { break; case STATE_INFO_DIALOG: + case STATE_BUY_GUN_DIALOG: + case STATE_BUY_COAT_DIALOG: + case STATE_DO_WEED_DIALOG: + case STATE_HEAL_DIALOG: drawDialog(); + if (sGameState != STATE_INFO_DIALOG) drawYesNoPrompt(); + break; + + case STATE_DID_WEED_DIALOG_1: + dialog[0] = "You hallucinate on the"; + dialog[1] = "wildest trip of your"; + dialog[2] = "life stumble onto the"; + dialog[3] = "subway tracks and get"; + dialog[4] = "creamed by a train."; + dialogLength = 5; + dialogSmall = true; + drawDialog(); + // draw a comma manually since the font doesn't have one + arduboy.drawRect(32, 34, 1, 1, WHITE); + arduboy.drawRect(31, 35, 1, 1, WHITE); + sPreviousGameState = STATE_DID_WEED_DIALOG_2; + break; + + case STATE_DID_WEED_DIALOG_2: + dialog[0] = ""; + dialog[1] = " Just say no"; + dialog[2] = " to drugs."; + dialogLength = 3; + dialogSmall = false; + drawDialog(); + sPreviousGameState = STATE_GAME_OVER; break; case STATE_BUY_QTY_INPUT: @@ -263,6 +296,21 @@ void loop() { drawMoney(55, 46, pMoney); drawQtySelector(F("Amt")); break; + + case STATE_GAME_OVER: { + int score = floor(sqrt((pSavingsAmount + pMoney - pLoanAmount) / 31.5)); + if (score > 100) score = 100; + dialog[0] = ""; + dialog[1] = " Game over!"; + dialog[2] = " Your score: "; + dialog[2] += String(score); + dialog[3] = " out of 100."; + dialogSmall = false; + dialogLength = 4; + sPreviousGameState = STATE_TITLE; + drawDialog(); + break; + } } screenInitialized = true; } @@ -337,8 +385,47 @@ void loop() { } case STATE_INVENTORY: case STATE_INFO_DIALOG: + case STATE_DID_WEED_DIALOG_1: + case STATE_DID_WEED_DIALOG_2: + case STATE_GAME_OVER: checkBackedOut(true); break; + + case STATE_BUY_GUN_DIALOG: + case STATE_BUY_COAT_DIALOG: + case STATE_DO_WEED_DIALOG: + case STATE_HEAL_DIALOG: + if (!checkBackedOut(false)) { // backed out = no + if (arduboy.justPressed(A_BUTTON)) { // yes + screenInitialized = false; + switch (sGameState) { + case STATE_BUY_GUN_DIALOG: + pGuns++; + pMoney -= 400; + pCapacity -= 5; + sGameState = STATE_TURN_MENU; + break; + + case STATE_BUY_COAT_DIALOG: + pCapacity += 10; + pMoney -= 200; + sGameState = STATE_TURN_MENU; + break; + + case STATE_DO_WEED_DIALOG: + sGameState = STATE_DID_WEED_DIALOG_1; + break; + + case STATE_HEAL_DIALOG: + pMoney -= 1000; + pHealth = 50; + sGameState = STATE_TURN_MENU; + break; + } + } + } + break; + case STATE_SELL_QTY_INPUT: case STATE_BUY_QTY_INPUT: case STATE_PAY_LOAN_INPUT: @@ -424,23 +511,23 @@ void drawStatusBar() { const int chars = numberChars(remaining); const int x = 128 - ((chars + 9) * 4); font3x5.setCursor(1, 0); - font3x5.print("Guns "); + font3x5.print(F("Guns ")); font3x5.print(pGuns); font3x5.setCursor(x, 0); - font3x5.print("Capacity "); + font3x5.print(F("Capacity ")); font3x5.print(remaining); } else { const int chars = numberChars(pMoney); const int x = 128 - (chars * 4); if (sGameState == STATE_SHARK_MENU || sGameState == STATE_BANK_MENU) { font3x5.setCursor(1, 0); - font3x5.print(sGameState == STATE_SHARK_MENU ? "Loan" : "Acct"); + font3x5.print(sGameState == STATE_SHARK_MENU ? F("Loan") : F("Acct")); Sprites::drawOverwrite(19, 1, spriteDollar, 0); font3x5.setCursor(25, 0); font3x5.print(sGameState == STATE_SHARK_MENU ? pLoanAmount : pSavingsAmount); } else { font3x5.setCursor(1, 0); - font3x5.print("Day"); + font3x5.print(F("Day")); font3x5.setCursor(14, 0); font3x5.print(sCurrentDay); } @@ -528,3 +615,10 @@ void drawQtyInputTotal() { } drawQtySelectorAmount(); } + +void drawYesNoPrompt() { + font3x5.setCursor(74, 55); + font3x5.print(F("A Yes B No")); + arduboy.drawCircle(75, 58, 5, WHITE); + arduboy.drawCircle(103, 58, 5, WHITE); +} diff --git a/states.ino b/states.ino index 052930b..a529e32 100644 --- a/states.ino +++ b/states.ino @@ -20,13 +20,11 @@ void initializeNewGame() { } sCurrentDay = 0; - incrementDay(); // start on day 1 + incrementDay(false); // start on day 1 } -void incrementDay() { +void incrementDay(const bool withInterest) { sCurrentDay++; - - // TODO: check for game over sAlreadyBorrowed = false; // generate new drug prices @@ -36,59 +34,65 @@ void incrementDay() { sDrugPrices[DRUG_WEED] = (random(43) + 33) * 10; sDrugPrices[DRUG_SPEED] = (random(16) + 7) * 10; sDrugPrices[DRUG_LUDES] = (random(5) + 1) * 10; + + // loan and savings interest + if (withInterest) { + pLoanAmount = floor(pLoanAmount * 1.1); + pSavingsAmount = floor(pSavingsAmount * 1.06); + } } void newDayRandomEvent() { - const int eventId = random(20); + const int eventId = 14; //random(20); sPreviousGameState = STATE_TURN_MENU; dialogSmall = false; switch (eventId) { case 1: - dialog[0] = "Rival dealers are"; - dialog[1] = "selling cheap"; - dialog[2] = "ludes!!!"; + dialog[0] = F("Rival dealers are"); + dialog[1] = F("selling cheap"); + dialog[2] = F("ludes!!!"); dialogLength = 3; sDrugPrices[DRUG_LUDES] = 2; sGameState = STATE_INFO_DIALOG; break; case 2: - dialog[0] = "Weed prices have"; - dialog[1] = "bottomed out!!!"; + dialog[0] = F("Weed prices have"); + dialog[1] = F("bottomed out!!!"); dialogLength = 2; sDrugPrices[DRUG_WEED] = 122; sGameState = STATE_INFO_DIALOG; break; case 3: - dialog[0] = "Pigs are selling"; - dialog[1] = "cheap heroine"; - dialog[2] = "from last week's"; - dialog[3] = "raid!!!!"; + dialog[0] = F("Pigs are selling"); + dialog[1] = F("cheap heroine"); + dialog[2] = F("from last week's"); + dialog[3] = F("raid!!!!"); dialogLength = 4; sDrugPrices[DRUG_HEROINE] = random(1150) + 850; sGameState = STATE_INFO_DIALOG; break; case 4: case 5: - dialog[0] = "Addicts are"; - dialog[1] = "buying heroine"; - dialog[2] = "at outrageous"; - dialog[3] = "prices!!!"; + dialog[0] = F("Addicts are"); + dialog[1] = F("buying heroine"); + dialog[2] = F("at outrageous"); + dialog[3] = F("prices!!!"); dialogLength = 4; sDrugPrices[DRUG_HEROINE] = random(25001) + 18000; sGameState = STATE_INFO_DIALOG; break; case 6: case 7: - dialog[0] = "Pigs made a big"; - dialog[1] = "coke bust! Prices"; - dialog[2] = "are outrageous!!!!"; + dialog[0] = F("Pigs made a big"); + dialog[1] = F("coke bust! Prices"); + dialog[2] = F("are outrageous!!!!"); dialogLength = 3; sDrugPrices[DRUG_COCAINE] = random(60001) + 80000; sGameState = STATE_INFO_DIALOG; break; case 8: - dialog[0] = "You were mugged"; - dialog[1] = "in the subway!"; + dialog[0] = F("You were mugged"); + dialog[1] = F("in the subway!"); dialogLength = 2; pMoney = round(pMoney / 3.0) * 2; sGameState = STATE_INFO_DIALOG; @@ -98,10 +102,10 @@ void newDayRandomEvent() { case 11: { if (playerDrugInventoryCount() >= 50) { const int pigs = eventId == 9 ? 1 : eventId == 10 ? 3 : 4; - dialog[0] = "Officer Hardass and"; + dialog[0] = F("Officer Hardass and"); dialog[1] = String(pigs); dialog[1] += F(" of his deputies"); - dialog[2] = "are after you!"; + dialog[2] = F("are after you!"); dialogLength = 3; sPreviousGameState = STATE_FIGHT_MENU; sGameState = STATE_INFO_DIALOG; @@ -114,15 +118,15 @@ void newDayRandomEvent() { case 13: { if (pMoney >= 500 && playerCapacityRemaining() >= 5) { const int x = random(3); - dialog[0] = "Will you buy a"; + dialog[0] = F("Will you buy a"); if (x == 0 || x == 1) { - dialog[1] = x == 0 ? "baretta for" : ".44 magnum for"; - dialog[2] = "400 dollars?"; + dialog[1] = x == 0 ? F("baretta for") : F(".44 magnum for"); + dialog[2] = F("400 dollars?"); dialogLength = 3; } else { - dialog[1] = "saturday night"; - dialog[2] = "special for 400"; - dialog[3] = "dollars?"; + dialog[1] = F("saturday night"); + dialog[2] = F("special for 400"); + dialog[3] = F("dollars?"); dialogLength = 4; } sGameState = STATE_BUY_GUN_DIALOG; @@ -132,19 +136,19 @@ void newDayRandomEvent() { break; } case 14: - dialog[0] = "There's some weed"; - dialog[1] = "here that smells"; - dialog[2] = "like good stuff!!"; - dialog[3] = "Will you smoke it?"; + dialog[0] = F("There's some weed"); + dialog[1] = F("here that smells"); + dialog[2] = F("like good stuff!!"); + dialog[3] = F("Will you smoke it?"); dialogLength = 4; sGameState = STATE_DO_WEED_DIALOG; break; case 15: if (pMoney >= 300) { - dialog[0] = "Will you buy a new"; - dialog[1] = "trenchcoat with"; - dialog[2] = "more pockets for"; - dialog[3] = "200 bucks?"; + dialog[0] = F("Will you buy a new"); + dialog[1] = F("trenchcoat with"); + dialog[2] = F("more pockets for"); + dialog[3] = F("200 bucks?"); dialogLength = 4; sGameState = STATE_BUY_COAT_DIALOG; } else { @@ -221,7 +225,7 @@ void handleMenuAction() { break; case STATE_JET_MENU: - incrementDay(); + incrementDay(true); pLocation = menuSelected < pLocation ? menuSelected : menuSelected + 1; newDayRandomEvent(); break;