From a8c9d868be1f4130a41fc2b7152fb3832923df0a Mon Sep 17 00:00:00 2001 From: Raktbastr Date: Mon, 28 Apr 2025 12:19:02 -0500 Subject: [PATCH] My comments. --- files/combat.js | 151 ++++++++++++++++++++++++--------------------- files/functions.js | 31 +++++++--- files/inventory.js | 10 ++- files/main.js | 15 ++++- files/shops.js | 15 +++++ files/variables.js | 9 ++- 6 files changed, 147 insertions(+), 84 deletions(-) diff --git a/files/combat.js b/files/combat.js index a3ccc76..fb5aab4 100644 --- a/files/combat.js +++ b/files/combat.js @@ -2,6 +2,8 @@ import './variables.js'; import { randomNumber, userInput } from './functions.js'; import { inventoryMenuM } from './inventory.js'; +// InitCombat function (currently not used in final game) +// First sets the proper level of the enemy, then sets the stats of the enemy and runs combat() with it as a parameter. function initCombat(enemy) { if (enemy.minLevel > level) { var enemyLevelFinal = enemy.minLevel; @@ -14,92 +16,101 @@ function initCombat(enemy) { if (enemy.armor.value > 85 && enemy.armor.unit == "dr") { var enemyArmor = 85; } else { - var enemyArmor = enemy.armor.value + var enemyArmor = enemy.armor.value; } var enemyStats = {level: enemyLevelFinal, health: enemy.health+enemyLevelFinal, weapon: enemy.weapon, armor: enemyArmor, armorUnit: enemy.armor.unit}; var playerStats = {level: level, health: health, weapon: equippedWeapon, armor: equippedArmor, armorUnit: equippedArmor.unit, chem: "placeholder"}; + combat(enemyStats); } +// Combat function (currently not used in final game) +// Gives a menu to attack the enemy, open inventoryM(), or view player stats. Menu will repeat until enemy.health is not > 0 function combat(enemy) { console.clear(); console.log("You enter combat with "+enemy.name+"..."); let combatInput; - while (true) { - console.log("What would you like to do?"); - console.log("-----------------------"); - console.log("1) Attack"); - console.log("2) Check your Inventory"); - console.log("3) View Stats"); - combatInput = userInput("Enter: "); - - if (combatInput != "1" && combatInput != "2" && combatInput != "3") { - console.log("Invalid input. Please enter 1, 2, or 3."); - } else { - break; + while (enemy.health > 0) { + while (true) { + console.log("What would you like to do?"); + console.log("-----------------------"); + console.log("1) Attack"); + console.log("2) Check your Inventory"); + console.log("3) View Stats"); + combatInput = userInput("Enter: "); + + // Input validation + if (combatInput != "1" && combatInput != "2" && combatInput != "3") { + console.log("Invalid input. Please enter 1, 2, or 3."); + } else { + break; + } } - } - - switch(combatInput) { - case "1": - console.log("You attack "+enemy.name+" with your "+equippedWeapon.name+"!"); - sleep(2); - let attackRoll = randomNumber(1,100); - if (attackRoll <= 10) { - console.log("You critically hit "+enemy.name+" dealing "+damageCalc(player, true)+" damage!"); + + switch(combatInput) { + case "1": + console.log("You attack "+enemy.name+" with your "+equippedWeapon.name+"!"); sleep(2); - } else if (attackRoll <= 50) { - console.log("You hit "+enemy.name+" dealing "+damageCalc(player, false)+" damage!"); + let attackRoll = randomNumber(1,100); + if (attackRoll <= 10) { + console.log("You critically hit "+enemy.name+" dealing "+damageCalc(player, true)+" damage!"); + sleep(2); + } else if (attackRoll <= 50) { + console.log("You hit "+enemy.name+" dealing "+damageCalc(player, false)+" damage!"); + sleep(2); + } else if (attackRoll <= 90) { + console.log("You miss "+enemy.name+"!"); + sleep(2); + } else { + console.log("You critically miss "+enemy.name+", dealing 3 damage to yourself!"); + health-3; + sleep(2); + } + + console.log(enemy.name+" Attacks you with thier "+enemyStats.weapon.name+"!"); sleep(2); - } else if (attackRoll <= 90) { - console.log("You miss "+enemy.name+"!"); - sleep(2); - } else { - console.log("You critically miss "+enemy.name+", dealing 3 damage to yourself!"); - health-3; - sleep(2); - } - - console.log(enemy.name+" Attacks you with thier "+enemyStats.weapon.name+"!"); - sleep(2); - let enemyRoll = randomNumber(1,100); - if (attackRoll <= 10) { - console.log(enemy.name+" critically hit you dealing "+damageCalc(enemy, true)+" damage!"); - sleep(2); - } else if (attackRoll <= 50) { - console.log(enemy.name+" hit you dealing "+damageCalc(player, false)+" damage!"); - sleep(2); - } else if (attackRoll <= 90) { - console.log(enemy.name+" misses you!"); - sleep(2); - } else { - console.log(enemy.name+" critically misses, dealing 3 damage to themself!"); - enemyStats.health-3; - sleep(2); - } - case "2": - inventoryMenuM(); - break; - case "3": - console.clear(); - console.log("Player Stats"); - console.log("-------------"); - console.log("Name: "+name); - console.log("Level: "+level); - console.log("Current Health: "+health+"/"+healthCap); - console.log("Radiation Points: "+radPoints); - console.log("Radiation Severity: "+radSeverity); - console.log("Walk Rate: "+walkRate); - console.log("Food Amt: "+food); - console.log("Food Rate: "+foodRate); - console.log("Distance to next POI: " + pois[poiCounter].location-location); - console.log("Current Path: "+path); - userInput("\n[Press Enter to return]"); - break; + let enemyRoll = randomNumber(1,100); + if (attackRoll <= 10) { + console.log(enemy.name+" critically hit you dealing "+damageCalc(enemy, true)+" damage!"); + sleep(2); + } else if (attackRoll <= 50) { + console.log(enemy.name+" hit you dealing "+damageCalc(player, false)+" damage!"); + sleep(2); + } else if (attackRoll <= 90) { + console.log(enemy.name+" misses you!"); + sleep(2); + } else { + console.log(enemy.name+" critically misses, dealing 3 damage to themself!"); + enemyStats.health-3; + sleep(2); + } + case "2": + inventoryMenuM(); + break; + case "3": + console.clear(); + console.log("Player Stats"); + console.log("-------------"); + console.log("Name: "+name); + console.log("Level: "+level); + console.log("Current Health: "+health+"/"+healthCap); + console.log("Radiation Points: "+radPoints); + console.log("Radiation Severity: "+radSeverity); + console.log("Walk Rate: "+walkRate); + console.log("Food Amt: "+food); + console.log("Food Rate: "+foodRate); + console.log("Distance to next POI: " + pois[poiCounter].location-location); + console.log("Current Path: "+path); + userInput("\n[Press Enter to return]"); + break; + } } } - +// damageCalc() function (currently not used in final game) +// If the attacker parameter = the player it runs the respective menus, checking for damage dealt and returns it. +// Vice versa if attacker = enemy +// If crit = true 3 extra damage is applied regardless of armor calculations. function damageCalc(attacker, crit) { if (attacker = player) { if (playerStats.chem == "psycho") { diff --git a/files/functions.js b/files/functions.js index 3764756..adb4242 100755 --- a/files/functions.js +++ b/files/functions.js @@ -11,6 +11,7 @@ import { checkPOI } from './poiscreens.js'; import './poiscreens.js'; import os from 'os'; import { exit } from 'process'; +import { naturalEncounter } from './encounters.js'; global.isRawModeEnabled = false; // Track whether raw mode is enabled @@ -68,8 +69,7 @@ export function checkLose() { // Checks to see if any lose conditions have been death("Test Death"); } } - - +// Checks to see what path the player is on and adds the respective amount to the respective location variable export function calcLocation() { if (walkRate == 1) { if (path == 0) { @@ -106,6 +106,10 @@ export function calcLocation() { } } +// sleep() function +// First detects what os the user is on and assigns it to osPlat +// if osPlat == 'win32' the program runs the shell command 'sleep' with powershell and the desired time parameter +// if it is not equal to 'win32' the program just runs 'sleep' with the desired time parameter var osPlat = os.platform(); export async function sleep(time) { if (osPlat === 'win32') { @@ -123,6 +127,7 @@ export async function sleep(time) { } } +// Calculates a random number to see which death screen you recieve if called and imputs the death cause as a parameter. function death(deathCause) { let random = randomNumber(1,100); if (random >= 1 && random <= 33) { death1(deathCause); } @@ -131,6 +136,7 @@ function death(deathCause) { if (random == 100) { death4(deathCause); } } +// death1, death2, and death3 all display a death message, similar to those in Fallout 1, along with the cause given as a parameter function death1(dc) { console.clear(); sleep(2); @@ -203,6 +209,7 @@ function timeDeath() { // The death screen for passing the time limit var travelFrame = 0; +// Shows the 'frames' of the travel screen, and shows some player stats. export function travelScreen() { if (travelFrame < 0 || travelFrame > 3) { travelFrame = 0; @@ -305,6 +312,9 @@ export function travelScreen() { } } +// This function is run everytime the player 'moves' in the world. It first enables raw mode to detect for the pause button +// If paused it displays pauseScreen(); +// If not it runs calcLocation(), radPointsCalc(), healthCapCalc(), checkLose(), travelScreen(), checkPOI(), naturalEncounter(), eatFood(), adds to the day counter, and then re runs the function. export async function walkPathMain() { enableRawMode(); if (paused) { @@ -318,22 +328,23 @@ export async function walkPathMain() { checkLose(); travelScreen(); checkPOI(); + naturalEncounter(location); eatFood(); day++ await sleep(0.5); walkPathMain(); } +// This checks to see if the spacebar is pressed while raw menu is enabled. +// If so it sets paused to true. process.stdin.resume(); process.stdin.on('data', (key) => { if (key.toString() === ' ') { paused = true; // Pause the game - } else if (key.toString() === '\u0003') { // Handle Ctrl+C (ASCII code for Ctrl+C) - console.log("\nExiting game..."); - process.exit(); // Exit the program - } + } }); +// Turns raw mode on, runs the above function when called and sets the variable isRawModeEnabled to true export function enableRawMode() { if (!isRawModeEnabled) { process.stdin.setRawMode(true); @@ -342,6 +353,7 @@ export function enableRawMode() { } } +// Turns raw mode off and sets the variable isRawModeEnabled to true export function disableRawMode() { if (isRawModeEnabled) { process.stdin.setRawMode(false); @@ -350,6 +362,7 @@ export function disableRawMode() { } } +// Gives player a menu to resume the game, view inventory, distances, stats, scavenge, and change the speed/food rate var paused = false; export function pauseScreen() { let pauseInput @@ -365,6 +378,7 @@ export function pauseScreen() { console.log ("6) Change Speed/Food Rate"); pauseInput = userInput("Enter: "); + // Input validation if (pauseInput != "1" && pauseInput != "2" && pauseInput != "3" && pauseInput != "4" && pauseInput != "5" && pauseInput != "6") { console.log("Invalid input. Please enter 1, 2, or 3."); } else { @@ -372,6 +386,7 @@ export function pauseScreen() { } } switch(pauseInput) { + // Shows all pois on the main path, and the chosen path if the player choses one. case "1": paused = false; break; @@ -421,6 +436,7 @@ export function pauseScreen() { userInput("\n[Press Enter to return]"); break; case "4": + // Displays many player stat variables. console.clear(); console.log("Player Stats"); console.log("-------------"); @@ -437,9 +453,10 @@ export function pauseScreen() { userInput("\n[Press Enter to return]"); break; case "5": - scavenge(); + scavenge(); // Scavenge is curently not used in game break; case "6": + // Gives the player a menu to change the walkRate and foodRate variables. console.clear(); console.log("Current Walk Rate: "+walkRate); console.log("Current Food Rate: "+foodRate); diff --git a/files/inventory.js b/files/inventory.js index 21ceccd..7c9e684 100644 --- a/files/inventory.js +++ b/files/inventory.js @@ -1,7 +1,12 @@ import { userInput } from "./functions.js"; import "./variables.js"; -//Builds the main menu inventory +// inventoryMenuM() +// When the user asks to see thier inventory, this is called. +// Shows a list of options from which the player can choose +// If they choose to view, viewInventory() is called +// If they want to equip an armor or weapon, they are shown a list of all items with the specified type (weapon or armor) +// from there they can select the item and it replaces the item currently in the respective variable. export function inventoryMenuM(){ console.clear(); console.log("INVENTORY"); @@ -63,7 +68,8 @@ export function inventoryMenuM(){ } } -//Builds the supply inventory +// viewInventory() +// Lists all items in the inventory array. function viewInventory(){ console.clear(); console.log("Inventory"); diff --git a/files/main.js b/files/main.js index e3540ea..850abbf 100755 --- a/files/main.js +++ b/files/main.js @@ -1,8 +1,13 @@ // Program is started from here, runs functions from other files. + +// In order to use variables and functions from other files we must import them as shown below + +// To import functions we use the syntax below import { userInput, sleep, disableRawMode, walkPathMain, randomNumber } from './functions.js'; -import { forcedEncounter, naturalEncounter } from './encounters.js'; import { ravenRockStore } from './shops.js'; +// To import variables from a file you must mark them as global (done in file) and import the file they are in like shown below. +import './variables.js'; disableRawMode(); console.clear(); @@ -14,6 +19,7 @@ console.log(" / / ) / / / ) / / / o / / ) / ) console.log("_/________(___(_/___/___(___/_(___(__(_ __o_____/____/_(___/_/___/_(___ _(__)_(___/_/_/__/_(___ _____/_____|__(___/_(___(_(___/___\n\n"); await sleep(1); +// Collects player input for menus var mainMenuInput; while (true) { console.log("What would you like to do?"); @@ -24,6 +30,7 @@ while (true) { console.log("4) Credits\n"); mainMenuInput = userInput("Enter: "); + // Input validation if (mainMenuInput != "1" && mainMenuInput != "2" && mainMenuInput != "3" && mainMenuInput != "4") { console.log("Invalid input. Please enter 1, 2, or 3."); } else { @@ -49,7 +56,11 @@ switch(mainMenuInput) { break; } -function startGame() { // So far what I have is filler and testing, feel free to change. + +// startGame() function +// Walks player through character creation, story, and sets starting stats. Then opens up ravenRockStore() before +// runing the walkPath() function loop. +function startGame() { console.clear(); name = userInput("What is your name? "); console.log(name+" Is now your name...") diff --git a/files/shops.js b/files/shops.js index e0052e1..ccf26cb 100644 --- a/files/shops.js +++ b/files/shops.js @@ -131,6 +131,17 @@ var lostHillsInv = [ {item: equipmentList[12], name: equipmentList[12].name, price: equipmentList[12].cost, amount: 10}, ]; +// Store functions +// Each store gets its own inventory and function, and work exactly the same for the most part. +// It opens by giving a welcome screen and listing the items in stock, player is given choice to leave or buy items. +// If they chose to buy, player enters the item number, amount they want, and it is then pushed to thier inventory array +// If the item is food, the item is added to the food variable, not the inventory. + +// Exceptions to how this works: + +// ravenRockStore() and eurekaStore() both use Pre-War Money, multiplying the +// prices by 10 and using the players PWM to purchase the item, not caps. + export function ravenRockStore() { while (true) { console.clear(); @@ -151,19 +162,23 @@ export function ravenRockStore() { console.log("What would you like to buy?"); var itemNum = userInput("Enter item number: "); var itemAmt = userInput("Enter amount: "); + // Making sure the item has enough in stock if (itemAmt > rrInv[itemNum].amount) { console.log("Not enough stock."); userInput("[Enter]"); break; + // Making sure the items requested are not too expensive } else if (itemAmt * rrInv[itemNum].price*10 > preWarMoney) { console.log("Not enough money."); userInput("[Enter]"); break; + // If the choice is vaild, add the item to inventory and remove stock/money } else { preWarMoney -= itemAmt * rrInv[itemNum].price*10; rrInv[itemNum].amount -= itemAmt; console.log("You bought " + itemAmt + " " + rrInv[itemNum].name + "(s)."); console.log("You have " + preWarMoney + " pre-war money left."); + // Check if the item is food, if so add to food variable if (rrInv[itemNum].name == "Food") { food =+ itemAmt; } else { diff --git a/files/variables.js b/files/variables.js index 08d963c..f324667 100644 --- a/files/variables.js +++ b/files/variables.js @@ -1,6 +1,8 @@ // Now holds only variables -// Items +// To allow a variable to be read/wrote from across files you must begin them with "global.variablename" + +// Items and related stats global.supplyList = [ // Supplies: chems, aid {name: "Food", description: "Misc foods", cost: 1, weight: 0}, {name: "Stimpak", description: "A Stimpak syringe, heals 25 HP", cost: 5, weight: 0.5}, @@ -39,6 +41,7 @@ global.equipmentList = [ // Equipment: weapons, armor, tools {name: "Fists (Unarmed)", description: "Unarmed combat, does 5 bash damage", type: "weapon", value: "5", unit: "bash", cost: 5, weight: 1}, ]; +// List of possible achievements you can gain (Currently not used in game) global.achievements = [ // POI/Faction Destroy {name: "Dishonorable Discharge", description: "Deactivate MODUS at the Whitespring", unlocked: false}, @@ -96,8 +99,8 @@ global.inventory = [ // Inventory of player, holds all items equipmentList[27], equipmentList[25], ] -global.equippedWeapon = equipmentList[27]; -global.equippedArmor = equipmentList[25]; +global.equippedWeapon = equipmentList[27]; // Players currently equipped weapon +global.equippedArmor = equipmentList[25]; // PLayers currently equipped armor // Game Mechanics global.walkRate = 0; // Units the player walks per day, affects foodRateCalc and radPointsCalc