slangin/states.ino

456 lines
12 KiB
C++

/*
Slangin'
State Management
Author: Rudis Muiznieks
License: WTFPL
*/
void initializeNewGame(int days) {
sGameState = STATE_TURN_MENU;
pMoney = 2000;
pLoanAmount = 5000;
pSavingsAmount = 0;
pLocation = LOC_BRONX;
pGuns = 0;
pCapacity = 100;
pHealth = 50;
for (int i = 0; i < 6; i++) {
pInventory[i] = 0;
}
sMaxDays = days + 1;
sCurrentDay = 0;
incrementDay(false); // start on day 1
}
void incrementDay(const bool withInterest) {
sCurrentDay++;
sAlreadyBorrowed = false;
// generate new drug prices
sDrugPrices[DRUG_COCAINE] = random(12001) + 16000;
sDrugPrices[DRUG_HEROINE] = random(7001) + 5000;
sDrugPrices[DRUG_ACID] = (random(35) + 10) * 100;
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);
}
screenInitialized = false;
}
void newDayRandomEvent() {
const int eventId = random(20);
sPreviousGameState = STATE_TURN_MENU;
dialogSmall = false;
switch (eventId) {
case 1:
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] = F("Weed prices have");
dialog[1] = F("bottomed out!!!");
dialogLength = 2;
sDrugPrices[DRUG_WEED] = 122;
sGameState = STATE_INFO_DIALOG;
break;
case 3:
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] = 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] = 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] = F("You were mugged");
dialog[1] = F("in the subway!");
dialogLength = 2;
pMoney = round(pMoney / 3.0) * 2;
sGameState = STATE_INFO_DIALOG;
break;
case 9:
case 10:
case 11: {
if (playerDrugInventoryCount() >= 50) {
sPigs = eventId == 9 ? 2 : eventId == 10 ? 4 : 5;
dialog[0] = F("Officer Hardass");
dialog[1] = F("and ");
dialog[1] += String(sPigs - 1);
dialog[1] += F(" of his");
dialog[2] = F("deputies are");
dialog[3] = F("after you!");
dialogLength = 4;
sPreviousGameState = STATE_FIGHT_MENU;
sGameState = STATE_INFO_DIALOG;
} else {
sGameState = STATE_TURN_MENU;
}
break;
}
case 12:
case 13: {
if (pMoney >= 500 && playerCapacityRemaining() >= 5) {
const int x = random(3);
dialog[0] = F("Will you buy a");
if (x == 0 || x == 1) {
dialog[1] = x == 0 ? F("baretta for") : F(".44 magnum for");
dialog[2] = F("400 dollars?");
dialogLength = 3;
} else {
dialog[1] = F("saturday night");
dialog[2] = F("special for 400");
dialog[3] = F("dollars?");
dialogLength = 4;
}
sGameState = STATE_BUY_GUN_DIALOG;
} else {
sGameState = STATE_TURN_MENU;
}
break;
}
case 14:
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] = 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 {
sGameState = STATE_TURN_MENU;
}
break;
case 16: {
if (playerCapacityRemaining() >= 8) {
const int amount = random(7) + 1;
const int drug = random(6);
pInventory[drug] += amount;
dialog[0] = F("You found ");
dialog[0] += String(amount);
dialog[1] = F("units of: ");
dialog[1] += lookupDrug(drug);
dialog[2] = "on a dead dude in";
dialog[3] = "the subway!!!";
dialogLength = 4;
sGameState = STATE_INFO_DIALOG;
} else {
sGameState = STATE_TURN_MENU;
}
break;
}
case 17:
dialog[0] = "The market has";
dialog[1] = "been flooded with";
dialog[2] = "cheap homemade";
dialog[3] = "acid!!!!";
dialogLength = 4;
sDrugPrices[DRUG_ACID] = random(551) + 250;
sGameState = STATE_INFO_DIALOG;
break;
default:
sGameState = STATE_TURN_MENU;
break;
}
}
void handleMenuAction() {
screenInitialized = false;
switch (sGameState) {
case STATE_TITLE:
switch (menuSelected) {
case 0: // new game
initializeNewGame(30);
break;
case 1: // extended game
initializeNewGame(60);
break;
case 2: // high scores
dialog[0] = F("Normal Game:");
dialog[1] = F("");
dialog[2] = F("Extended Game:");
dialogSmall = false;
dialogLength = 3;
sGameState = STATE_HIGH_SCORES;
break;
}
break;
case STATE_TURN_MENU:
sPreviousGameState = STATE_TURN_MENU;
switch (menuSelected) {
case 0: // buy drugs
sGameState = STATE_BUY_MENU;
break;
case 1: // sell drugs
sGameState = STATE_SELL_MENU;
break;
case 2: // trenchcoat
sGameState = STATE_INVENTORY;
break;
case 3: // jet
sGameState = STATE_JET_MENU;
break;
case 4: // loan shark
sGameState = STATE_SHARK_MENU;
break;
case 5: // bank
sGameState = STATE_BANK_MENU;
break;
}
break;
case STATE_JET_MENU:
pLocation = menuSelected < pLocation ? menuSelected : menuSelected + 1;
incrementDay(true);
newDayRandomEvent();
break;
case STATE_BUY_MENU: {
int remaining = playerCapacityRemaining();
sPreviousGameState = STATE_BUY_MENU;
sCurrentDrug = menuSelected;
if (remaining <= 0) {
dialog[0] = F("Oops!");
dialog[1] = F("");
dialog[2] = F("You can't carry");
dialog[3] = F("more ");
dialog[3] += lookupDrug(sCurrentDrug);
dialog[3] += F("!");
dialogLength = 4;
dialogSmall = false;
sPreviousGameState = sGameState;
sGameState = STATE_INFO_DIALOG;
} else if (pMoney < sDrugPrices[sCurrentDrug]) {
dialog[0] = F("Oops!");
dialog[1] = F("");
dialog[2] = F("You can't afford");
dialog[3] = lookupDrug(sCurrentDrug);
dialog[3] += F("!");
dialogLength = 4;
dialogSmall = false;
sPreviousGameState = sGameState;
sGameState = STATE_INFO_DIALOG;
} else {
sGameState = STATE_BUY_QTY_INPUT;
sCurrentQty = 0;
sQtyMax = floor(pMoney / (float)sDrugPrices[sCurrentDrug]);
if (remaining < sQtyMax) sQtyMax = remaining;
}
break;
}
case STATE_SELL_MENU:
sPreviousGameState = STATE_SELL_MENU;
sCurrentDrug = menuSelected;
if (pInventory[sCurrentDrug] > 0) {
sGameState = STATE_SELL_QTY_INPUT;
sCurrentQty = 0;
sQtyMax = pInventory[sCurrentDrug];
} else {
dialog[0] = F("Oops!");
dialog[1] = F("");
dialog[2] = F("You don't have any");
dialog[3] = lookupDrug(sCurrentDrug);
dialog[3] += F("!");
dialogLength = 4;
dialogSmall = false;
sPreviousGameState = sGameState;
sGameState = STATE_INFO_DIALOG;
}
break;
case STATE_SHARK_MENU:
sPreviousGameState = STATE_SHARK_MENU;
sCurrentQty = 0;
switch (menuSelected) {
case 0: // repay loan
sGameState = STATE_PAY_LOAN_INPUT;
sQtyMax = pLoanAmount > pMoney ? pMoney : pLoanAmount;
break;
case 1: // borrow money
if (sAlreadyBorrowed) {
dialog[0] = F("You already");
dialog[1] = F("borrowed money");
dialog[2] = F("today!");
dialogLength = 3;
dialogSmall = false;
sGameState = STATE_INFO_DIALOG;
} else {
sGameState = STATE_BORROW_INPUT;
sQtyMax = 5000;
}
break;
}
break;
case STATE_BANK_MENU:
sPreviousGameState = STATE_BANK_MENU;
sCurrentQty = 0;
switch (menuSelected) {
case 0: // deposit money
sGameState = STATE_DEPOSIT_INPUT;
sQtyMax = pMoney;
break;
case 1: // withdraw money
sGameState = STATE_WITHDRAW_INPUT;
sQtyMax = pSavingsAmount;
break;
}
break;
}
}
void handleFightMenuInput() {
if (arduboy.justPressed(B_BUTTON)) { // run
screenInitialized = false;
if (random(2) == 0) {
dialog[0] = F("You lost them in");
dialog[1] = F("an alley!!");
dialogLength = 2;
dialogSmall = false;
sPreviousGameState = STATE_TURN_MENU;
sGameState = STATE_INFO_DIALOG;
} else {
dialog[0] = F("You can't shake");
dialog[1] = F("them!");
dialogLength = 2;
dialogSmall = false;
sPreviousGameState = STATE_FIGHT_DAMAGE;
sGameState = STATE_INFO_DIALOG;
}
} else if (arduboy.justPressed(A_BUTTON)) { // fight
screenInitialized = false;
if (pGuns == 0) {
dialog[0] = F("You don't have");
dialog[1] = F("any guns! You");
dialog[2] = F("have to run!");
dialogLength = 3;
dialogSmall = false;
sPreviousGameState = STATE_FIGHT_MENU;
sGameState = STATE_INFO_DIALOG;
} else {
if (random(2) == 0) {
dialog[0] = F("");
dialog[1] = F(" You missed!!!");
dialogLength = 2;
dialogSmall = false;
sPreviousGameState = STATE_FIGHT_DAMAGE;
sGameState = STATE_INFO_DIALOG;
} else {
sPigs--;
if (sPigs > 0) {
dialog[0] = F("");
dialog[1] = F("You killed one!!");
dialogLength = 2;
dialogSmall = false;
sPreviousGameState = STATE_FIGHT_DAMAGE;
sGameState = STATE_INFO_DIALOG;
} else {
const int found = random(1251) + 750;
dialog[0] = F("You killed all of");
dialog[1] = F("them! You found ");
dialog[1] += String(found);
dialog[2] = F("dollars on Officer");
dialog[3] = F("Hardass' carcass!!");
dialogLength = 4;
dialogSmall = true;
pMoney += found;
sPreviousGameState = pMoney >= 1200
? STATE_HEAL_DIALOG : STATE_TURN_MENU;
sGameState = STATE_INFO_DIALOG;
// TODO: draw apostrophe :(
}
}
}
}
}
void handleFightDamage() {
const int x = random(2);
dialog[0] = F("They're firing at");
dialog[1] = F("you!! ");
sPreviousGameState = STATE_FIGHT_MENU;
dialogLength = 3;
dialogSmall = false;
if (x == 0) { // missed
dialog[1] += F("They");
dialog[2] = F("missed!!");
} else { // hit
dialog[1] += F("You've");
dialog[2] = F("been hit!");
pHealth -= 3;
if (pHealth <= 0) { // dead
dialog[3] = F("You're dead!!");
dialogLength = 4;
sPreviousGameState = STATE_GAME_OVER;
}
}
}
bool checkBackedOut(const bool eitherButton) {
if (arduboy.justPressed(B_BUTTON) ||
(eitherButton && arduboy.justPressed(A_BUTTON))) {
screenInitialized = false;
menuBackOut = getMenuBackOut();
sGameState = sPreviousGameState;
return true;
}
return false;
}
int playerCapacityRemaining() {
int qty = 0;
for (int i = 0; i < 6; i++) {
qty += pInventory[i];
}
//qty += pGuns * 5; // already accounted for
return pCapacity - qty;
}
int playerDrugInventoryCount() {
int count = 0;
for (int i = 0; i < 6; i++) {
count += pInventory[i];
}
return count;
}