From 3178ef479bde30a28b029bce084f75466c5b995d Mon Sep 17 00:00:00 2001 From: Raktbastr Date: Wed, 26 Feb 2025 09:51:09 -0600 Subject: [PATCH 01/27] Add game,js and modify calcLocation. Added variable exports to every file. --- files/deathscreens.js | 3 +- files/game.js | 90 +++++++++++++++++++++++++++++++++++++++++ files/huntinggame.js | 3 +- files/main.js | 6 ++- files/map.js | 3 +- files/poiscreens.js | 3 +- files/rivercrossing.js | 3 +- files/shops.js | 2 +- files/stoptravelmenu.js | 3 +- files/variables.js | 78 +---------------------------------- 10 files changed, 109 insertions(+), 85 deletions(-) create mode 100644 files/game.js diff --git a/files/deathscreens.js b/files/deathscreens.js index 15729f3..e53de46 100644 --- a/files/deathscreens.js +++ b/files/deathscreens.js @@ -1,4 +1,5 @@ // Deathscreens, they should be the fallout 1 screens +const variables = require("./variables.js"); module.exports = { deathScreen, @@ -6,7 +7,7 @@ module.exports = { }; function deathScreen() { - let random = Math.random(1,3); + let random = variables.randomNumber(1,3); if (random = 1) { death1(); } if (random = 2) { death2(); } if (random = 3) { death3(); } diff --git a/files/game.js b/files/game.js new file mode 100644 index 0000000..c793cf3 --- /dev/null +++ b/files/game.js @@ -0,0 +1,90 @@ +// Holds functions needed to play the game +const variables = require("./variables.js"); +const death = require("./deathscreens.js"); + +module.exports = { + eatFood, + calcSickPoints, + scavenge, + checkLose, + calcLocation, +} + +function eatfood() { + if (variables.food == 0) { + variables.health - 3*variables.travelSpeed + } else if (variables.isSick == true) { + variables.food = variables.food-((variables.travelSpeed*variables.foodAmt)+variables.sickSeverity); + } else { + variables.food = variables.food-(variables.travelSpeed*variables.foodAmt); + } + variables.health = variables.health+(5*variables.foodAmt); +} + +function calcSickPoints() { + if (variables.isSick = true) { + variables.sickPoints = variables.sickPoints+((variables.sickSeverity-(0.5*variables.foodAmt))+(0.5*(variables.travelSpeed+variables.radSeverity))); + } +} + +function scavenge() { // Rolls a random number between 1 and 100 to see which loot table you get, then picks a random item from it. ADD COOLDOWN! + if (variables.daysSinceScav < 20 ) { + console.log("You must wait "+(20-variables.daysSinceScav)+" days until you can scavenge again") + } else { + let luck = variables.randomNumber(1,100); + if (luck <= 20) { + let group = 0; + let random = variables.randomNumber(variables.lootTables[group][0], variables.lootTables[group][3]); + inventory.push(random); + } else if (luck <= 40) { + let group = 1; + let random = variables.randomNumber(variables.lootTables[group][0], variables.lootTables[group][3]); + inventory.push(random); + } else if (luck <= 60) { + let group = 2; + let random = variables.randomNumber(variables.lootTables[group][0], variables.lootTables[group][3]); + inventory.push(random); + } else if (luck <= 80) { + let group = 3; + let random = variables.randomNumber(variables.lootTables[group][0], variables.lootTables[group][3]); + inventory.push(random); + } else if (luck <= 100) { + let group = 4; + let random = variables.randomNumber(variables.lootTables[group][0], variables.lootTables[group][3]); + inventory.push(random); + } + } +} + +function checkLose() { // Checks to see if any lose conditions have been met + if (variables.health <= 0 || variables.sickPoints >= 50) { + death.deathScreen(); + } + if (variables.day >= 365) { + death.timeDeath(); + } +} + +function calcLocation() { // Calculates your location in the world using location points, You move your move speed per day, but 3/4 of it if you are sick + if (variables.travelSpeed == 1) { + if (variables.isSick == true) { + variables.location = variables.location+0.75; + } else { + variables.location++; + } + } + if (variables.travelSpeed == 2) { + if (variables.isSick == true) { + variables.location = variables.location+1.5; + } else { + variables.location = variables.location+2; + } + } + if (variables.travelSpeed == 3) { + if (variables.isSick == true) { + variables.location = variables.location+2.25; + } else { + variables.location = variables.location+3; + } + } +} diff --git a/files/huntinggame.js b/files/huntinggame.js index 446270c..e7bc4ac 100644 --- a/files/huntinggame.js +++ b/files/huntinggame.js @@ -1 +1,2 @@ -// Hunting Game, if we even decide to do it. \ No newline at end of file +// Hunting Game, if we even decide to do it. +const variables = require("./variables.js"); diff --git a/files/main.js b/files/main.js index ba4954b..8d43160 100644 --- a/files/main.js +++ b/files/main.js @@ -1,5 +1,6 @@ // Program is started from here, runs functions from other files. const variables = require("./variables.js"); +const game = require("./game.js"); const shops = require("./shops"); const readline = require('node:readline'); @@ -26,7 +27,8 @@ switch(mainMenuInput) { startGame(); break; case "2": - while (true) { console.log(variables.randomNumber(10,15)); } + console.log("Follow the link below for a game manual.") + console.log("[ENTER LINK HERE]") break; case "3": console.log("Quitting Game..."); @@ -48,5 +50,5 @@ function startGame() { // So far what I have is filler and testing, feel free to console.clear(); variables.prewarmoney = 500; - shops.trader(); + shops.ravenRock(); } \ No newline at end of file diff --git a/files/map.js b/files/map.js index 1a03627..4bbb499 100644 --- a/files/map.js +++ b/files/map.js @@ -1 +1,2 @@ -// Map Screen \ No newline at end of file +// Map Screen +const variables = require("./variables.js"); diff --git a/files/poiscreens.js b/files/poiscreens.js index 18515d5..5f3ccdf 100644 --- a/files/poiscreens.js +++ b/files/poiscreens.js @@ -1 +1,2 @@ -// Holds the screens for every POI including thier menus. \ No newline at end of file +// Holds the screens for every POI including thier menus. +const variables = require("./variables.js"); diff --git a/files/rivercrossing.js b/files/rivercrossing.js index 8c13059..974e563 100644 --- a/files/rivercrossing.js +++ b/files/rivercrossing.js @@ -1 +1,2 @@ -// River crossing screens and options. \ No newline at end of file +// River crossing screens and options. +const variables = require("./variables.js"); diff --git a/files/shops.js b/files/shops.js index 656b08f..fd7f663 100644 --- a/files/shops.js +++ b/files/shops.js @@ -1,5 +1,5 @@ const readline = require('readline-sync'); -const variables = require("./variables"); +const variables = require("./variables.js"); module.exports = { ravenRock, diff --git a/files/stoptravelmenu.js b/files/stoptravelmenu.js index 8412d50..665bf0a 100644 --- a/files/stoptravelmenu.js +++ b/files/stoptravelmenu.js @@ -1 +1,2 @@ -// Halt travel screen and menu. \ No newline at end of file +// Halt travel screen and menu. +const variables = require("./variables.js"); \ No newline at end of file diff --git a/files/variables.js b/files/variables.js index 48544c8..501a8b3 100644 --- a/files/variables.js +++ b/files/variables.js @@ -1,4 +1,4 @@ -// Holds the global variables, functions, and math operations such as the day counter and food eaten.. +// Holds the global variables and useful functions such as userInput const readline = require('readline-sync'); module.exports = { // Lets variables and functions be used in other files @@ -17,12 +17,7 @@ module.exports = { // Lets variables and functions be used in other files name, prewarmoney, caps, - eatfood, - calcLocation, - calcSickPoints, - scavenge, sleep, - checkLose, userInput, randomNumber }; @@ -59,81 +54,12 @@ var inventory = []; // Max of 5 items var lootTables = [[],[],[],[],[]] // Only small things like food and ammo, 5 Loot tables per scavenge score, 3 items in each, first is best -function eatfood() { - if (food == 0) { health - 20 } - if (isSick == true) { food = food-((travelSpeed*foodAmt)+sickSeverity); } - else { food = food-(travelSpeed*foodAmt); } - health = health+(5*foodAmt); -} - -function calcSickPoints() { - if (isSick = true) { - sickPoints = sickPoints+((sickSeverity-(0.5*foodAmt))+(0.5*(travelSpeed+radSeverity))); - } -} - -function scavenge() { // Rolls a random number between 1 and 100 to see which loot table you get, then picks a random item from it. ADD COOLDOWN! - let luck = Math.random(1,100); - if (luck <= 20) { - let group = 0; - let random = Math.random(lootTables[group][0], lootTables[group][3]); - inventory.push(random); - } else if (luck <= 40) { - let group = 1; - let random = Math.random(lootTables[group][0], lootTables[group][3]); - inventory.push(random); - } else if (luck <= 60) { - let group = 2; - let random = Math.random(lootTables[group][0], lootTables[group][3]); - inventory.push(random); - } else if (luck <= 80) { - let group = 3; - let random = Math.random(lootTables[group][0], lootTables[group][3]); - inventory.push(random); - } else if (luck <= 100) { - let group = 4; - let random = Math.random(lootTables[group][0], lootTables[group][3]); - inventory.push(random); - } -} +var daysSinceScav = 0; // Days since your last scavenge, you must wait 15 days before scavenging again. function sleep(time) { // Waits the inputed amt of miliseconds before proceeding setTimeout(() => {}, time); } -function checkLose() { // Checks to see if any lose conditions have been met - if (health <= 0 || sickPoints >= 50) { - deathScreen(); - } - if (day >= 365) { - timeDeath(); - } -} - -function calcLocation() { // Calculates your location in the world using location points, You move your move speed per day, but 3/4 of it if you are sick - if (travelSpeed == 1) { - if (isSick == true) { - location = location+0.75; - } else { - location++; - } - } - if (travelSpeed == 2) { - if (isSick == true) { - location = location+1.5; - } else { - location = location+2; - } - } - if (travelSpeed == 3) { - if (isSick == true) { - location = location+2.25; - } else { - location = location+3; - } - } -} - function userInput(question) { // Basic user input functions, takes in the question to be asked. let answer = readline.question(question); return(answer); From 6e476dcf149f9c1daa85973e0a60350dc8403175 Mon Sep 17 00:00:00 2001 From: Raktbastr Date: Wed, 26 Feb 2025 10:22:58 -0600 Subject: [PATCH 02/27] Edit TODO. --- TODO.md | 89 +++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 74 insertions(+), 15 deletions(-) diff --git a/TODO.md b/TODO.md index 409dd3b..e030168 100644 --- a/TODO.md +++ b/TODO.md @@ -1,19 +1,78 @@ -## Basic -* See if we can split things across multiple files for readability -* Graphics -* Dialogue, make in function -* __Story__ - ## Game Mechanics -* Scavenging (random num 1-100, items based on that) -* POI Menu (talk with people, trade, map, etc) -* Stop Menu (scavenge, change settings) -* River crossing menu -* Random Encounters -* Trading -* Movement/Time (day counter that multiplies stats by certain amt) -* POI Chosing based on location in world (NCR bases in Cali, Legion in CO, BOS in Midwest) -* Hunting minigame (only if we can make the terminal blankout and not just add lines) +- POI's and Factions + - Art for locations + - Raven Rock + - Whitespring + - Brotherhood Bunkers + - Tibbets + - Flagstaff + - New Vegas + - NCR Cities + - Lost Hills + - Sierra Madre + - Divide + - Eureka + - Navarro + - Logic for faction armor + - Logic for calling locations at right location point (incl. different paths) + - Use the Google Earth Project for location points + - Logic for path split + - Trade menus for locations + - Raven Rock + - Whitespring + - Brotherhood Bunkers + - Tibbets + - Flagstaff + - New Vegas + - NCR Cities + - Sierra Madre + - Divide + - Eureka + - Navarro + - Dialogue for locations + - Raven Rock + - Whitespring + - Brotherhood Bunkers + - Tibbets + - Flagstaff + - New Vegas + - NCR Cities + - Lost Hills + - Sierra Madre + - Divide + - Eureka + - Navarro + - Combat for locations (Can be negated with faction armor unless stated) + - Brotherhood Bunker Delta - Easy Radiers(No faction armor) + - Tibbets - Medium Raiders(No faction armor) + - Flagstaff - Medium Legion + - NCR Cities - Hard NCR + - Shady Sands - Hard NCR (no faction armor) + - New Reno and Redding (no combat) + - Lost Hills - Hard BOS (no faction armor) + - Sierra Madre - Hard Abominations + - Divide - Hard Abominations + - Navarro - Difficult NCR + +- Random Encounters + - Very Rare Wild Wasteland encounter chance + - Rare trader encounters + - 5 Areas + - The Forest + - Tutorial Encounters + - The Midwest + - Easy Encounters + - The Rockies + - Medium Encounters + - Legion Territory + - Medium Faction Encounters, can be negated with faction armor + - Lower NCR + - Hard Faction Encounters, difficult but can be negated with faction armor (not Lost Hills) + - Upper NCR + - Hard Encounters + +- Gameplay Mechanics + ## Misc * Credit Bethesda if needed From 0dfc20e470404e7598147009ff9e03f4c30baecc Mon Sep 17 00:00:00 2001 From: Caroline Foy Date: Wed, 26 Feb 2025 15:38:51 -0600 Subject: [PATCH 03/27] Hi --- files/game.js | 2 +- files/main.js | 4 +++ files/poiscreens.js | 73 ++++++++++++++++++++++++++++++++++++++++++++- files/shops.js | 2 +- 4 files changed, 78 insertions(+), 3 deletions(-) diff --git a/files/game.js b/files/game.js index c793cf3..355bcca 100644 --- a/files/game.js +++ b/files/game.js @@ -10,7 +10,7 @@ module.exports = { calcLocation, } -function eatfood() { +function eatFood() { if (variables.food == 0) { variables.health - 3*variables.travelSpeed } else if (variables.isSick == true) { diff --git a/files/main.js b/files/main.js index 8d43160..44f73cb 100644 --- a/files/main.js +++ b/files/main.js @@ -3,6 +3,7 @@ const variables = require("./variables.js"); const game = require("./game.js"); const shops = require("./shops"); const readline = require('node:readline'); +const encounterMenus = require("./poiscreens.js"); console.clear(); console.log("__________________________________________________________________________________________________________________________________"); @@ -27,6 +28,9 @@ switch(mainMenuInput) { startGame(); break; case "2": + var array = [1, 2, 3, 4, 5]; + console.log(array); + console.log(encounterMenus.filterFaction(encounterDiffOne, "abomination")); console.log("Follow the link below for a game manual.") console.log("[ENTER LINK HERE]") break; diff --git a/files/poiscreens.js b/files/poiscreens.js index 5f3ccdf..b6d07f7 100644 --- a/files/poiscreens.js +++ b/files/poiscreens.js @@ -1,2 +1,73 @@ -// Holds the screens for every POI including thier menus. +module.exports = { + masterDiffArray, + encounterMenuMaker, + poiMenuMaker, + filterFaction, + encounterDiffOne, +} + const variables = require("./variables.js"); + +//Assign every possible encounter type to a difficulty 1-5 +var encounterDiffOne = [ + {name: "radroach", faction: "abomination", minHealth: 1, maxHealth: 10, lootTable: "food", numEnemies: 1}, + {name: "weak ghoul", faction: "abomination", minHealth: 10, maxHealth: 15, lootTable: "junk", numEnemies: 1}, + {name: "raider aspirant", faction: "raider", minHealth: 30, maxHealth: 50, lootTable: "teir1A&W", numEnemies: 1}, + {name: "bloatfly swarm", faction: "abomination", minHealth: 1, maxHealth: 5, lootTable: "food", numEnemies: 5}, + {name: "drunk", faction: "settler", minHealth: 15, maxHealth: 25, lootTable: "junk", numEnemies: 1}, +]; +var encounterDiffTwo = [ + +]; +var encounterDiffThree = [ + +]; +var encounterDiffFour = [ + +]; +var encounterDiffFive = [ + {name: "deathclaw", faction: "abomination", minHealth: 750, maxHealth: 1000, lootTable: "food", numEnemies: 1}, + +]; +var masterDiffArray = [encounterDiffOne, encounterDiffTwo, encounterDiffThree, encounterDiffFour, encounterDiffFive]; + +function poiMenuMaker(){ + +} + +function filterFaction(diff, factionLook) { + var THEFACTION = []; + for (var i = 0; i < diff.length; i++) { + if (diff[0].faction == factionLook) { + THEFACTION.push(diff[0]); + } + } + THEFACTION.push(diff[1]); + return THEFACTION; +} + + +//Creates the menu for an encounter. "faction" represents the faction for the encounter, "diffWeighting" changes the odds for +//an encounter's difficulty (1-5) +function encounterMenuMaker(reqFaction, diffWeighting){ + let encounterDifficulty = diffWeighting*(variables.randomNumber(1, 20)); + switch(encounterDifficulty){ + case(encounterDifficulty <= 20): + //var encounterDiffActual = 1; + const encountered = []; + filterFaction(encounterDiffOne, reqFaction); + break; + case(21 <= encounterDifficulty <= 40): + var encounterDiffActual = 2; + break; + case(41 <= encounterDifficulty <= 60): + var encounterDiffActual = 3; + break; + case(61 <= encounterDifficulty <= 80): + var encounterDiffActual = 4; + break; + case(81 <= encounterDifficulty): + var encounterDiffActual = 5; + break; + } +} \ No newline at end of file diff --git a/files/shops.js b/files/shops.js index fd7f663..98c7559 100644 --- a/files/shops.js +++ b/files/shops.js @@ -32,7 +32,7 @@ function eureka() { // purchasing code } -function trader() { // One of the 3 trader inventories, chosen randomly +function trader() { // Picks a selection of items from a global trader inventory var tempTraderInv = []; for (var a = 0; a <= 2; a++) { let randomPick = Math.m From 93c65c362772d4252ef9dff77723ef6b2af572fd Mon Sep 17 00:00:00 2001 From: Raktbastr Date: Wed, 26 Feb 2025 15:56:21 -0600 Subject: [PATCH 04/27] Todo and Story --- TODO.md | 137 ++++++++++++++++++++++++++++++++++++++++----- files/variables.js | 2 +- 2 files changed, 124 insertions(+), 15 deletions(-) diff --git a/TODO.md b/TODO.md index e030168..8b9e940 100644 --- a/TODO.md +++ b/TODO.md @@ -71,21 +71,130 @@ - Upper NCR - Hard Encounters -- Gameplay Mechanics +- Achievements + - Wastland Pacifier + - Clear out all Raider compounds and defeat every Raider encounter + + - Dishonourable Discharge + - Deactivate Modus + + - Force of habit + - Destroy the Midwest Brotherhood + + - 7 Karat Run + - Find the Platnium Chip + + - Profligate + - Destroy Flagstaff + + - Rigged From the Start + - Accidentally Kill Benny at the Tops Casino + + - What in the Goddamn? + - Start and fight in the First Battle of Hoover Dam + + - Rocket's Red Glare + - Launch the nuke at Hopeville/Ashton + + - Long Time Coming + - Destroy the main NCR cities or Shady Sands + + - You and what army? + - Raid Navarro with the help of Eureka + -## Misc -* Credit Bethesda if needed -## Locations (Please Read) -* Raven Rock to Whitespring, tutorial ghoul encounters -* Whitespring to Delta, Easy raider encounters, Missisippi crossing -* Delta to Vault 0, Medium raider encounters, rare chance of enclave base -* Vault 0 to New Vegas, medium Legion encounters, garunteed location encounter -* Lower Path, medium NCR encounters, garunteed location encounters -* Upper Path, bad NCR+encounter, garunteed location encounters, disguise doesnt work in shady sands +- Achievements + - Wasteland Pacifier + - Clear out all raider compounds and defeat every raider encounter + - Force of Habit + - Destory the Midwest Brotherhood + - Dishonorable Discharge + - Deactivate MODUS and/or Destory Eureka + - Long Time Coming + - Destory all NCR Cities or Shady Sands (path dependent) + - Profligate + - Destroy Flagstaff + - Pit Stop + - Destory the Lost Hills bunker + - Double Agent + - Reach max NCR rep + - Uneasy Alliance + - Reach max Midwest BOS rep + - Frumentari + - Reach max Legion rep + - Low Tech Stealth Boy + - Successfully sneak through a faction POI with a faction disguise + - High Roller + - Win 100 Caps by gambling in New Vegas or New Reno + - Retcon + - Launch Hopville and Ashton's nukes at Shady Sands + - + - Destory Hopeville and Ashton with its nukes + - 7 Karat Run + - Find the platnium chip + - What in the goddamn? + - Reach New Vegas + - Rigged from the start + - Shoot and kill Benny at the Tops Casino + - 510 Years old + - Find and wear a suit of APA Mk2 -### Other Location notes -* MODUS at the Whitespring directs you to the Midwest Brotherhood -* Bunker gamma directs you to Delta but it is overrun with raiders, hence the medium encounter -* The legion inst directly hostile with you, however you can still have bad encounters \ No newline at end of file +## Story + +### Intro +You are an Enclave soldier tasked with making your way to Navarro to retrieve a GECK needed for Project Purity. You requisition materials from the armory and head out, first stop being the Whitespring Bunker, a side trip to check in on it. + +### Whitespring +After fighting your way through easy enimies you arrive at the Whitespring Bunker where a robotic voice greets you, that being MODUS. He informs you that many factions have setup in the years since Navarro, first being the Midwest Brotherhood. He calculates that they should be friendly to you, however you are a member of the Enclave and it is your duty to destory them. You head to the first MWBOS bunker, fighting radiers along the way. + +### Brotherhood Bunkers +The soldiers at Bunker Gamma welcome you with open arms, explaining that they are not like the other chapters. You explain that you need to get across the country for a classified mission, and they give you the locations of a few of thier bunkers, leading up to Vault 0. + +The next bunker, Delta, is overrun with raiders. You defeat them and gain some rep from doing so. + +Once you arrive at Vault 0 they inform you that your next stop would be Tibbets Prison then Flagstaff, lest you cross through Utah and its 80's raider gang. + +### Tibbets Prison +The prison is overrun with raiders and the remnants of a failed plan of major proportions. You, being a saint of the wastes, clear out the raiders. In the wreckage you find a mysterious shiny metal disc. It looks intresting enough. While traveling to your next destination, you start encountering Caesars Legion, but they are not hostile to you. + +### Flagstaff +Once at Flagstaff you discover the full extent of the legion, a horrible organization. It is up to you to decide what to do with them, but you overhear talks about New Vegas and start heading there, encountering more legion scouting parties along the way. + +### New Vegas +You cross the Hoover Dam and make your way into the city. You are mesmorised by the city and decide to walk into one of its establishments, the Tops. You spend some caps on Black Jack and unfortunately lose. + +#### Shoot Benny +Filled with rage you point your hidden sidearm at the dealer and fire, however it misses and strikes an important looking man in a checkered suit. Realizing your crime you dash out of the casino, meeting robots on the other side who take you into the Lucky 38. While there Mr. House introduces himself and reveals what the mysterious disc you picked up earlier was. It was a platnium chip, and he tasks you with going around the area, recruiting factions for the upcoming battle. You run through the events of Fallout New Vegas + the first hoover dam battle, except the NCR definitivley wins the fight. Along the way you find the Enclave Remnants who decide to help you on your mission. Unfortunately they cannot travel with you, but this will not be the last we see of them. + +#### Crossroads +After your Mojave adventure you are presented with two choices, travel through the heart of the NCR including Lost Hills, or avoid the NCR as much as possible, detouring through the Sierra madre, Hopeville/Ashton and Shady Sands. + +#### Travel Through the NCR +Either through a desperate attempt to save time, a desire to wipe out Lost Hills, or somthing else, you decide to travel through the lower NCR. This includes the Mojave Outpost, Necropolis, The Hub, Lost Hills, Mariposa MB, and San Francisco. + +Lost Hills, an unavoidable landmark in your journey, rears its ugly head as the base starts immediately firing on you. Somehow you are able to survive and possibly destroy the base. + +At Mariposa MB you encounter remnants of a failed army. The NCR soldiers posted at the area are gone, and in its place you discover abominations only seen back home in Enclave Lands. Luckily you survie and continue on to San Francisco. + +When you arrive at SF the stories of Control Station Enclave fill your head, and you must make a decision to either make them pay for allowing the atrocity to be commited, or to let them be. Either way, you move on to Navarro your final destination. + +#### Travel Around the NCR +You make your way through the Canyon Wreckage to Hopeville and Ashton, a city plaged with Legion and NCR warfare. You also come across the missle silos located in the area. Using your credentials you pass under the main conflict area to a lesser war torn area. While in the silo you are also given the choice to launch warheads at Shady Sands, weather you do this is up to you. + +Your next stop is Sierra Madre, a hellish abomination-filled resort. You go scorched earth through it, destorying all ghost people. + +Shady Sands is your next marker, either a place you must fight your way through, or marrily pass through (rep dependent). + +Your next location is New Reno, a relatively neutral area. They direct you to Redding next. + +Redding is much of the same, however you learn of Eureka, an Enclave Stronghold. You decide you must go there next\ + +Eureka is your home away from home. Stories of your conquest across the country has made its way there, inspiring many of the veterans there to rise up with you and reclaim Navarro from the NCR. + +### Navarro, alone ending +You and your intentions are finally made clear to the NCR. Fear is instilled in the soldiers as they realize who they must fight now. You decimate the NCR crowd, regardless of your standing with them. Youve come this far and you are taking this for yourself or for your country (enclave rep dependent). During the battle the Enclave Remnants in thier vertibird, if enlisted, see the battle below and turn back, knowing thier potential fate. Once the NCR is relieved of thier position, you retrieve the GECK, and on your way out of the facility you now realize the path you have carved yourself, one that you will not survive, one that the enclave sent you on, knowing how it would end, is not one that you are able to continue on alone. You radio Raven Rock for support and they oblige, however you must wait 3 days for it to arrive. You prepare defences for the invetable NCR retalliation and look over the horizon. + +### Navarro, with Eureka Ending +You and your squad of Enclave veterans march on Navarro, easily defeating the NCR troops there. The Enclave Remnants, if enlisted, jump down from thier vertibird and join the fight while providing air support. Once the battle is over you grab the GECK and make contact with Raven Rock. They are quite suprised you made it, but congragulate your effort. President Eden gets on the line and he orders you and your troops to make a Enclave presence on the coast. Ending by explaining that "A new dawn has just begun for the enclave, and your leading it General". \ No newline at end of file diff --git a/files/variables.js b/files/variables.js index 501a8b3..cef1b5b 100644 --- a/files/variables.js +++ b/files/variables.js @@ -19,7 +19,7 @@ module.exports = { // Lets variables and functions be used in other files caps, sleep, userInput, - randomNumber + randomNumber, }; var name = ''; From 0c36b89ff68bd0e46e12f807ad333391a70e0a56 Mon Sep 17 00:00:00 2001 From: Caroline Foy Date: Thu, 27 Feb 2025 13:44:22 -0600 Subject: [PATCH 05/27] Mess around with the POI menu stuff --- files/main.js | 7 +-- files/poiscreens.js | 112 ++++++++++++++++++++++++++++---------------- 2 files changed, 76 insertions(+), 43 deletions(-) diff --git a/files/main.js b/files/main.js index 44f73cb..9af4a95 100644 --- a/files/main.js +++ b/files/main.js @@ -1,3 +1,6 @@ +//For testing purposes +const moreTestingShite = require("./poiscreens.js"); + // Program is started from here, runs functions from other files. const variables = require("./variables.js"); const game = require("./game.js"); @@ -28,9 +31,7 @@ switch(mainMenuInput) { startGame(); break; case "2": - var array = [1, 2, 3, 4, 5]; - console.log(array); - console.log(encounterMenus.filterFaction(encounterDiffOne, "abomination")); + moreTestingShite.beginTesting(); console.log("Follow the link below for a game manual.") console.log("[ENTER LINK HERE]") break; diff --git a/files/poiscreens.js b/files/poiscreens.js index b6d07f7..64d53e3 100644 --- a/files/poiscreens.js +++ b/files/poiscreens.js @@ -1,73 +1,105 @@ +const testingShite = require("./main.js"); + module.exports = { - masterDiffArray, encounterMenuMaker, - poiMenuMaker, - filterFaction, - encounterDiffOne, + beginTesting, +} + +function beginTesting(){ + console.log(encounterMenuMaker("abomination", 1)); } const variables = require("./variables.js"); -//Assign every possible encounter type to a difficulty 1-5 -var encounterDiffOne = [ - {name: "radroach", faction: "abomination", minHealth: 1, maxHealth: 10, lootTable: "food", numEnemies: 1}, - {name: "weak ghoul", faction: "abomination", minHealth: 10, maxHealth: 15, lootTable: "junk", numEnemies: 1}, - {name: "raider aspirant", faction: "raider", minHealth: 30, maxHealth: 50, lootTable: "teir1A&W", numEnemies: 1}, - {name: "bloatfly swarm", faction: "abomination", minHealth: 1, maxHealth: 5, lootTable: "food", numEnemies: 5}, +//abomination, raider, settler, BOS, NCR, Legion + +//Declare all faction arrays and difficulties +const legion1 = []; +const BOS1 = []; +const settler1 = [ {name: "drunk", faction: "settler", minHealth: 15, maxHealth: 25, lootTable: "junk", numEnemies: 1}, ]; -var encounterDiffTwo = [ - +const NCR1 = []; +const raider1 = [ + {name: "raider aspirant", faction: "raider", minHealth: 30, maxHealth: 50, lootTable: "teir1A&W", numEnemies: 1}, ]; -var encounterDiffThree = [ - +const abomination1 = [ + {name: "radroach", faction: "abomination", minHealth: 1, maxHealth: 10, lootTable: "food", numEnemies: 1}, + {name: "weak ghoul", faction: "abomination", minHealth: 10, maxHealth: 15, lootTable: "junk", numEnemies: 1}, + {name: "bloatfly swarm", faction: "abomination", minHealth: 1, maxHealth: 5, lootTable: "food", numEnemies: 5}, ]; -var encounterDiffFour = [ -]; -var encounterDiffFive = [ - {name: "deathclaw", faction: "abomination", minHealth: 750, maxHealth: 1000, lootTable: "food", numEnemies: 1}, +const legion2 = []; +const BOS2 = []; +const settler2 = []; +const NCR2 = []; +const raider2 = []; +const abomination2 = []; -]; -var masterDiffArray = [encounterDiffOne, encounterDiffTwo, encounterDiffThree, encounterDiffFour, encounterDiffFive]; +const legion3 = []; +const BOS3 = []; +const settler3 = []; +const NCR3 = []; +const raider3 = []; +const abomination3 = []; -function poiMenuMaker(){ - -} +const legion4 = []; +const BOS4 = []; +const settler4 = []; +const NCR4 = []; +const raider4 = []; +const abomination4 = []; -function filterFaction(diff, factionLook) { - var THEFACTION = []; - for (var i = 0; i < diff.length; i++) { - if (diff[0].faction == factionLook) { - THEFACTION.push(diff[0]); - } - } - THEFACTION.push(diff[1]); - return THEFACTION; -} +const legion5 = []; +const BOS5 = []; +const settler5 = []; +const NCR5 = []; +const raider5 = []; +const abomination5 = []; +//RIP the filterFactionFunction :( //Creates the menu for an encounter. "faction" represents the faction for the encounter, "diffWeighting" changes the odds for //an encounter's difficulty (1-5) +//IGNORE THE VARIABLE COMMENTS IN THE NESTED SWITCH STATEMENT, they're placeholders for me function encounterMenuMaker(reqFaction, diffWeighting){ - let encounterDifficulty = diffWeighting*(variables.randomNumber(1, 20)); + var encounterDifficulty = diffWeighting*(variables.randomNumber(1, 20)); switch(encounterDifficulty){ case(encounterDifficulty <= 20): //var encounterDiffActual = 1; - const encountered = []; - filterFaction(encounterDiffOne, reqFaction); + switch(reqFaction){ + case "legion": + var encountered = legion1[variables.randomNumber(0, legion1.length)]; + break; + case "BOS": + var encountered = BOS1[variables.randomNumber(0, BOS1.length)]; + break; + case "NCR": + var encountered = NCR1[variables.randomNumber(0, NCR1.length)]; + break; + case "raider": + var encountered = raider1[variables.randomNumber(0, raider1.length)]; + break; + case "settler": + var encountered = settler1[variables.randomNumber(0, settler1.length)]; + break; + case "abomination": + var encountered = abomination1[variables.randomNumber(0, abomination1.length)]; + break; + } break; case(21 <= encounterDifficulty <= 40): - var encounterDiffActual = 2; + //var encounterDiffActual = 2; break; case(41 <= encounterDifficulty <= 60): - var encounterDiffActual = 3; + //var encounterDiffActual = 3; break; case(61 <= encounterDifficulty <= 80): - var encounterDiffActual = 4; + //var encounterDiffActual = 4; break; case(81 <= encounterDifficulty): - var encounterDiffActual = 5; + //var encounterDiffActual = 5; break; } + return encountered; } \ No newline at end of file From e4b96a8537c974bdfd13503cfa79483e28cd7cb6 Mon Sep 17 00:00:00 2001 From: Raktbastr Date: Thu, 27 Feb 2025 14:56:49 -0600 Subject: [PATCH 06/27] Finish Achievement to-do section. --- TODO.md | 73 +++++++++++++++++++------------------------ files/deathscreens.js | 4 +-- 2 files changed, 35 insertions(+), 42 deletions(-) diff --git a/TODO.md b/TODO.md index 8b9e940..5b6d04f 100644 --- a/TODO.md +++ b/TODO.md @@ -1,3 +1,8 @@ +### POIs, Enemy Selection, Random Encounters: Car +### Combat, Achievements, People: Finn + + + ## Game Mechanics - POI's and Factions - Art for locations @@ -87,59 +92,47 @@ - Profligate - Destroy Flagstaff - - Rigged From the Start + - What in the Goddamn? - Accidentally Kill Benny at the Tops Casino - - What in the Goddamn? - - Start and fight in the First Battle of Hoover Dam + - Just a chore, like any other + - Fight in the First Battle of Hoover Dam and defeat the Malpais Legate + + - Yes, man + - Kill Mr. House and the 2 other families, dooming New Vegas - Rocket's Red Glare - Launch the nuke at Hopeville/Ashton + - Begin Again + - Kill Father Elijah + - Long Time Coming - Destroy the main NCR cities or Shady Sands - - You and what army? - - Raid Navarro with the help of Eureka + - A New Dawn For America + - Reactivate Camp Navarro with the help of Eureka - + - Against All odds + - Retrieve the Geck from Navarro with or without the help of the Remnants. + - Finish What Was Started + - Destroy all main factions and cities + + - 510 Years + - Find and wear a suit of APA mk2 -- Achievements - - Wasteland Pacifier - - Clear out all raider compounds and defeat every raider encounter - - Force of Habit - - Destory the Midwest Brotherhood - - Dishonorable Discharge - - Deactivate MODUS and/or Destory Eureka - - Long Time Coming - - Destory all NCR Cities or Shady Sands (path dependent) - - Profligate - - Destroy Flagstaff - - Pit Stop - - Destory the Lost Hills bunker - - Double Agent - - Reach max NCR rep - - Uneasy Alliance - - Reach max Midwest BOS rep - - Frumentari - - Reach max Legion rep - - Low Tech Stealth Boy - - Successfully sneak through a faction POI with a faction disguise - High Roller - - Win 100 Caps by gambling in New Vegas or New Reno - - Retcon - - Launch Hopville and Ashton's nukes at Shady Sands - - - - Destory Hopeville and Ashton with its nukes - - 7 Karat Run - - Find the platnium chip - - What in the goddamn? - - Reach New Vegas - - Rigged from the start - - Shoot and kill Benny at the Tops Casino - - 510 Years old - - Find and wear a suit of APA Mk2 + - Win 200 caps from gambling + + - Veteran Ranger + - Reach max rep with the NCR + + - Frumentari + - Reach max rep with the Legion + + - Knight Errant + - Reach max rep with the BOS ## Story diff --git a/files/deathscreens.js b/files/deathscreens.js index e53de46..1fc4ea5 100644 --- a/files/deathscreens.js +++ b/files/deathscreens.js @@ -14,7 +14,7 @@ function deathScreen() { } function death1() { - + console.log("") } function death2() { @@ -26,5 +26,5 @@ function death3() { } function timeDeath() { // The death screen for passing the time limit - + console.log("") } \ No newline at end of file From f732586c24180d03804ed54f846f80213a2af618 Mon Sep 17 00:00:00 2001 From: Caroline Foy Date: Tue, 4 Mar 2025 17:55:42 -0600 Subject: [PATCH 07/27] Finally got the encounter menu function working --- files/poiscreens.js | 200 ++++++++++++++++++++++++++------------------ 1 file changed, 118 insertions(+), 82 deletions(-) diff --git a/files/poiscreens.js b/files/poiscreens.js index 64d53e3..6d6c74b 100644 --- a/files/poiscreens.js +++ b/files/poiscreens.js @@ -1,4 +1,5 @@ const testingShite = require("./main.js"); +const variables = require("./variables.js"); module.exports = { encounterMenuMaker, @@ -9,97 +10,132 @@ function beginTesting(){ console.log(encounterMenuMaker("abomination", 1)); } -const variables = require("./variables.js"); - -//abomination, raider, settler, BOS, NCR, Legion - -//Declare all faction arrays and difficulties -const legion1 = []; -const BOS1 = []; -const settler1 = [ - {name: "drunk", faction: "settler", minHealth: 15, maxHealth: 25, lootTable: "junk", numEnemies: 1}, +//Editor's note: abomination, raider, settler, BOS, NCR, Legion +var encounterDiffOne = [ + //NCR + [], + //Legion + [], + //Raider + [ + {name: "raider aspirant", minHealth: 30, maxHealth: 50, lootTable: "teir1A&W", numEnemies: 1}, + ], + //Settler + [ + {name: "drunk", minHealth: 15, maxHealth: 25, lootTable: "junk", numEnemies: 1}, + ], + //BOS + [], + //Abomination + [ + {name: "radroach", minHealth: 1, maxHealth: 10, lootTable: "food", numEnemies: 1}, + {name: "weak ghoul", minHealth: 10, maxHealth: 15, lootTable: "junk", numEnemies: 1}, + {name: "bloatfly swarm", minHealth: 1, maxHealth: 5, lootTable: "food", numEnemies: 5}, + ] ]; -const NCR1 = []; -const raider1 = [ - {name: "raider aspirant", faction: "raider", minHealth: 30, maxHealth: 50, lootTable: "teir1A&W", numEnemies: 1}, +var encounterDiffTwo = [ + //NCR + [], + //Legion + [], + //Raider + [], + //Settler + [], + //BOS + [], + //Abomination + [] ]; -const abomination1 = [ - {name: "radroach", faction: "abomination", minHealth: 1, maxHealth: 10, lootTable: "food", numEnemies: 1}, - {name: "weak ghoul", faction: "abomination", minHealth: 10, maxHealth: 15, lootTable: "junk", numEnemies: 1}, - {name: "bloatfly swarm", faction: "abomination", minHealth: 1, maxHealth: 5, lootTable: "food", numEnemies: 5}, +var encounterDiffThree = [ + //NCR + [], + //Legion + [], + //Raider + [], + //Settler + [], + //BOS + [], + //Abomination + [] +]; +var encounterDiffFour = [ + //NCR + [], + //Legion + [], + //Raider + [], + //Settler + [], + //BOS + [], + //Abomination + [] +]; +var encounterDiffFive = [ + //NCR + [], + //Legion + [], + //Raider + [], + //Settler + [], + //BOS + [], + //Abomination + [] ]; - -const legion2 = []; -const BOS2 = []; -const settler2 = []; -const NCR2 = []; -const raider2 = []; -const abomination2 = []; - -const legion3 = []; -const BOS3 = []; -const settler3 = []; -const NCR3 = []; -const raider3 = []; -const abomination3 = []; - -const legion4 = []; -const BOS4 = []; -const settler4 = []; -const NCR4 = []; -const raider4 = []; -const abomination4 = []; - -const legion5 = []; -const BOS5 = []; -const settler5 = []; -const NCR5 = []; -const raider5 = []; -const abomination5 = []; //RIP the filterFactionFunction :( +//Declaring some stuff to make them global variables +var encountered = []; +var faction = 0; + //Creates the menu for an encounter. "faction" represents the faction for the encounter, "diffWeighting" changes the odds for //an encounter's difficulty (1-5) //IGNORE THE VARIABLE COMMENTS IN THE NESTED SWITCH STATEMENT, they're placeholders for me function encounterMenuMaker(reqFaction, diffWeighting){ - var encounterDifficulty = diffWeighting*(variables.randomNumber(1, 20)); - switch(encounterDifficulty){ - case(encounterDifficulty <= 20): - //var encounterDiffActual = 1; - switch(reqFaction){ - case "legion": - var encountered = legion1[variables.randomNumber(0, legion1.length)]; - break; - case "BOS": - var encountered = BOS1[variables.randomNumber(0, BOS1.length)]; - break; - case "NCR": - var encountered = NCR1[variables.randomNumber(0, NCR1.length)]; - break; - case "raider": - var encountered = raider1[variables.randomNumber(0, raider1.length)]; - break; - case "settler": - var encountered = settler1[variables.randomNumber(0, settler1.length)]; - break; - case "abomination": - var encountered = abomination1[variables.randomNumber(0, abomination1.length)]; - break; - } - break; - case(21 <= encounterDifficulty <= 40): - //var encounterDiffActual = 2; - break; - case(41 <= encounterDifficulty <= 60): - //var encounterDiffActual = 3; - break; - case(61 <= encounterDifficulty <= 80): - //var encounterDiffActual = 4; - break; - case(81 <= encounterDifficulty): - //var encounterDiffActual = 5; - break; + var encounterDifficulty = (diffWeighting * variables.randomNumber(1, 20)); + if((reqFaction != "NCR") && (reqFaction != "BOS")){ + factionFailsafe = reqFaction.toLowerCase(); + } else { + factionFailsafe = reqFaction; } - return encountered; + switch(factionFailsafe){ + case "NCR": + faction = 0; + break; + case "legion": + faction = 1; + break; + case "raider": + faction = 2; + break; + case "settler": + faction = 3; + break; + case "BOS": + faction = 4; + break; + case "abomination": + faction = 5; + break; + } + if(encounterDifficulty <= 20){ + encountered.push(encounterDiffOne[faction][variables.randomNumber(0, encounterDiffOne[faction].length - 1)]); + } else if(21 <= encounterDifficulty <= 40){ + encountered.push(encounterDiffTwo[faction][variables.randomNumber(0, encounterDiffTwo[faction].length - 1)]); + } else if(41 <= encounterDifficulty <= 60){ + encountered.push(encounterDiffThree[faction][variables.randomNumber(0, encounterDiffThree[faction].length - 1)]); + } else if(61 <= encounterDifficulty <= 80){ + encountered.push(encounterDiffFour[faction][variables.randomNumber(0, encounterDiffFour[faction].length - 1)]); + } else { + encountered.push(encounterDiffFive[faction][variables.randomNumber(0, encounterDiffFive[faction].length - 1)]); + } + return encountered[0]; } \ No newline at end of file From 6ca88b7c6f79df4f7b3d26d766aaf85df2503222 Mon Sep 17 00:00:00 2001 From: Caroline Foy Date: Mon, 10 Mar 2025 12:05:17 -0500 Subject: [PATCH 08/27] More changes to menuing, added a basic inventory system --- files/inventory.js | 53 +++++++++++++++++++++++++++++++++++++++++++++ files/main.js | 13 ++++++----- files/poiscreens.js | 26 +++++++++++++++++----- files/variables.js | 10 ++++++++- 4 files changed, 90 insertions(+), 12 deletions(-) create mode 100644 files/inventory.js diff --git a/files/inventory.js b/files/inventory.js new file mode 100644 index 0000000..970e930 --- /dev/null +++ b/files/inventory.js @@ -0,0 +1,53 @@ +const variables = require("./variables"); +const main = require("./main"); + +module.exports = { + inventoryMenuM, +}; + +//Builds the main menu inventory +function inventoryMenuM(){ + console.clear(); + console.log("INVENTORY"); + console.log("---------"); + console.log("1) Supplies"); + console.log("2) Equipment"); + console.log("[spacebar to exit]"); + var userInput = variables.userInput("Enter: "); + switch(userInput){ + case "1": + supplyInventory(); + break; + case "2": + equipmentInventory(); + break; + } +} + +//Builds the supply inventory +function supplyInventory(){ + console.clear(); + console.log("SUPPLIES"); + console.log("---------"); + for(var a = 0; a < variables.inventory[0].length;){ + console.log((a + 1) + ") " + variables.inventory[0][a].name); + a++; + } + variables.userInput("[Enter to return]"); + console.clear(); + inventoryMenuM(); +} + +//Builds the equipment inventory +function equipmentInventory(){ + console.clear(); + console.log("EQUIPMENT"); + console.log("---------"); + for(var a = 0; a < variables.inventory[1].length;){ + console.log((a + 1) + ") " + variables.inventory[1][a].name); + a++; + } + variables.userInput("[Enter to return]"); + console.clear(); + inventoryMenuM(); +} \ No newline at end of file diff --git a/files/main.js b/files/main.js index 9af4a95..acc27db 100644 --- a/files/main.js +++ b/files/main.js @@ -1,12 +1,10 @@ -//For testing purposes -const moreTestingShite = require("./poiscreens.js"); - // Program is started from here, runs functions from other files. const variables = require("./variables.js"); const game = require("./game.js"); const shops = require("./shops"); const readline = require('node:readline'); const encounterMenus = require("./poiscreens.js"); +const inventoryStuff = require("./inventory.js"); console.clear(); console.log("__________________________________________________________________________________________________________________________________"); @@ -23,6 +21,7 @@ console.log("--------------------------"); console.log("1) Start new game"); console.log("2) Learn How to play"); console.log("3) Quit Game"); +console.log("4) Dev stuff for testing"); var mainMenuInput = variables.userInput("Enter: ") @@ -31,7 +30,6 @@ switch(mainMenuInput) { startGame(); break; case "2": - moreTestingShite.beginTesting(); console.log("Follow the link below for a game manual.") console.log("[ENTER LINK HERE]") break; @@ -39,6 +37,9 @@ switch(mainMenuInput) { console.log("Quitting Game..."); variables.sleep(1000); break; + case "4": + inventoryStuff.inventoryMenuM(); + break; } function startGame() { // So far what I have is filler and testing, feel free to change. @@ -49,9 +50,9 @@ function startGame() { // So far what I have is filler and testing, feel free to variables.sleep(2000); console.clear(); console.log("Intro:"); - console.log("You are an ordinary loyal Enclave Soldier working at Raven Rock. \nYou are typing away at your terminal, entering reports of recovered materials when a message flashes on it.\n\nDear "+variables.name+" ,\n\n This is a direct order from the Enclave High Command. \nIgnore all previous directives. Proceed to Camp Navarro immediately. \nSeek safe passage through the Brotherhood and NCR territories. \nDo not disclose your mission to anyone but Enclave Personel with \nsecurity clearance 5 or higher. Reqisition supplies before departure. \n\n Signed, President John Henry Eden\n\n"); + console.log("You are an ordinary loyal Enclave Soldier working at Raven Rock. \nYou are typing away at your terminal, entering reports of recovered materials when a message flashes on it.\n\nDear "+variables.name+",\n\n This is a direct order from the Enclave High Command. \nIgnore all previous directives. Proceed to Camp Navarro immediately. \nSeek safe passage through the Brotherhood and NCR territories. \nDo not disclose your mission to anyone but Enclave Personel with \nsecurity clearance 5 or higher. Reqisition supplies before departure. \n\n Signed, President John Henry Eden\n\n"); - variables.userInput("[Enter to open shop]") + variables.userInput("[Enter to open shop]"); console.clear(); variables.prewarmoney = 500; diff --git a/files/poiscreens.js b/files/poiscreens.js index 6d6c74b..becc8ae 100644 --- a/files/poiscreens.js +++ b/files/poiscreens.js @@ -1,16 +1,31 @@ -const testingShite = require("./main.js"); const variables = require("./variables.js"); module.exports = { encounterMenuMaker, - beginTesting, + initializeEncounter, } -function beginTesting(){ - console.log(encounterMenuMaker("abomination", 1)); +function initializeEncounter(reqFaction, diffWeighting, fight, flee){ + var encounter = encounterMenuMaker(reqFaction, diffWeighting); + console.clear(); + console.log("You come across a " + encounter.name); + var encounterHealth = variables.randomNumber(encounter.minHealth, encounter.maxHealth); + console.log("Health: " + encounterHealth); + console.log("What would you like to do?"); + console.log("--------------------------"); + var playerOptions = 1; + if(fight == true){ + console.log(playerOptions + ") Fight"); + playerOptions++; + } + if(flee == true){ + console.log(playerOptions + ") Flee"); + playerOptions++; + } + console.log(playerOptions + ") Inventory"); } -//Editor's note: abomination, raider, settler, BOS, NCR, Legion +//Add any new encounter ideas to their required faction and difficulty var encounterDiffOne = [ //NCR [], @@ -31,6 +46,7 @@ var encounterDiffOne = [ {name: "radroach", minHealth: 1, maxHealth: 10, lootTable: "food", numEnemies: 1}, {name: "weak ghoul", minHealth: 10, maxHealth: 15, lootTable: "junk", numEnemies: 1}, {name: "bloatfly swarm", minHealth: 1, maxHealth: 5, lootTable: "food", numEnemies: 5}, + {name: "wolf", minHealth: 5, maxHealth: 10, lootTable: "food", numEnemies: 1}, ] ]; var encounterDiffTwo = [ diff --git a/files/variables.js b/files/variables.js index 501a8b3..5112ac7 100644 --- a/files/variables.js +++ b/files/variables.js @@ -50,7 +50,15 @@ var isSick = false; var sickPoints = 0; // If you accumulate 50 sick points you lose var sickSeverity = 0; // 3 levls, starting at 1 -var inventory = []; // Max of 5 items +//Player inventory +//Record all items in the player's inventory as objects with a name, item category, value, and boolean properties. Example below. +//{name: "example", category: "testItems", value: 300, use: true, eat: false, drop: true, equip: true} +var inventory = [ + //Supplies + [], + //Equipment + [] +]; var lootTables = [[],[],[],[],[]] // Only small things like food and ammo, 5 Loot tables per scavenge score, 3 items in each, first is best From 49f93574af8bfe2162bbcab42845813f8c531f1e Mon Sep 17 00:00:00 2001 From: Raktbastr Date: Thu, 20 Mar 2025 11:34:17 -0500 Subject: [PATCH 09/27] Begin work on rep system. Finished encounter generation for the most part. Needs testing. --- files/combat.js | 0 files/game.js | 54 +++++++++++++++++++++++ files/main.js | 45 +++++++++++-------- files/poiscreens.js | 103 +++++++++++++++++++++++++++++++++++--------- files/variables.js | 20 +++++++++ 5 files changed, 185 insertions(+), 37 deletions(-) create mode 100644 files/combat.js diff --git a/files/combat.js b/files/combat.js new file mode 100644 index 0000000..e69de29 diff --git a/files/game.js b/files/game.js index 355bcca..6fc803b 100644 --- a/files/game.js +++ b/files/game.js @@ -1,6 +1,7 @@ // Holds functions needed to play the game const variables = require("./variables.js"); const death = require("./deathscreens.js"); +const poi = require("./poiscreens.js"); module.exports = { eatFood, @@ -8,6 +9,7 @@ module.exports = { scavenge, checkLose, calcLocation, + calcEncounter, } function eatFood() { @@ -88,3 +90,55 @@ function calcLocation() { // Calculates your location in the world using locatio } } } + +// Rundown on how I did this: +/** + * calcEncounter() checks what faction territory you are in and pipes the respective faction into initilizeEncounter(). + * + * initEncounter() is pretty much the same however you can use forceFaction (set to true) to bypass the random raider/abomination chance. + * forceFaction will always be false unless under certian circumstances (eg. Lost Hills, Legion Territory, Malcom Holmes). + * Turns out the fight/flee variables work exactly how I want so I did not change them. + * + * encounterMenuMaker() was changed to account for forceFaction. If forceFaction is set to true, EMM's equivilant forceOpt will take its value. + * If true it runs the code you had before, no changes. If it is false it will roll a dice to see if you get the normal faction, given by your switch statement, + * or a radier/abomination. If it is a radier/abomination it will then roll a 50/50. The code for both is the same as the default faction code except that + * 'faction' will just be 'raider' or 'abomination' instead of the default. + * + * I also implemented auto difficulty scaling. Instead of piping in 'encounterDiffOne' you just input the interger of it. This is because you cant + * use a string as a variable name and or whatever. Just trust me, this is the only way it works. initEncounter() will figure it out on the otherside. + */ + +function calcEncounter() { + if (variables.randomNumber(1,100) <= 20) { + if (variables.location >= 255) { + if (variables.locationA > variables.locationB) { + if ((variables.locationA >= 5 && variables.locationA < 17) || (variables.locationA >= 23 && variables.locationA < 40)) { + poi.initializeEncounter(NCR,4,true,true,false); + } + if (variables.locationB >= 40) { + poi.initializeEncounter(NCR,5,true,true,false); + } + } else if (variables.locationA < variables.locationB) { + if ((variables.locationB >= 0 && variables.locationB < 30) || (variables.locationB >= 40 && variables.locationB < 80)) { + poi.initializeEncounter(abomination,3,true,true,false) + } + if ((variables.locationB >= 30 && variables.locationB < 40) || (variables.locationB >= 90)) { + poi.initializeEncounter(NCR,5,true,true,false) + } + if (variables.locationB >= 80 && variables.locationB < 90) { + poi.initializeEncounter(enclave,4,true,true,false) + } + } else { + if (variables.location >= 5 && variables.location < 50) { + poi.initializeEncounter(abomination,1,true,true,false) + } + if (variables.location >= 50 && variables.location < 200) { + poi.initializeEncounter(MWBOS,2,true,true,false) + } + if (variables.location >= 200 && variables.location < 255) { + poi.initializeEncounter(legion,3,true,true,false) + } + } + } + } +} \ No newline at end of file diff --git a/files/main.js b/files/main.js index acc27db..bb9a04a 100644 --- a/files/main.js +++ b/files/main.js @@ -23,25 +23,28 @@ console.log("2) Learn How to play"); console.log("3) Quit Game"); console.log("4) Dev stuff for testing"); -var mainMenuInput = variables.userInput("Enter: ") -switch(mainMenuInput) { - case "1": - startGame(); - break; - case "2": - console.log("Follow the link below for a game manual.") - console.log("[ENTER LINK HERE]") - break; - case "3": - console.log("Quitting Game..."); - variables.sleep(1000); - break; - case "4": - inventoryStuff.inventoryMenuM(); - break; + +while(true) { + let mainMenuInput = variables.userInput("Enter: ") + switch(mainMenuInput) { + case "1": + startGame(); + break; + case "2": + console.log("Follow the link below for a game manual.") + console.log("[ENTER LINK HERE]") + break; + case "3": + console.log("Quitting Game..."); + variables.sleep(1000); + break; + case "4": + let testarr = [1,2,3,4] + console.log(testarr[testarr.length - 1]); + break; + } } - function startGame() { // So far what I have is filler and testing, feel free to change. console.clear(); variables.sleep(1000); @@ -57,4 +60,12 @@ function startGame() { // So far what I have is filler and testing, feel free to variables.prewarmoney = 500; shops.ravenRock(); + + for (variables.location = 0; variables.location <= 255; variables.location++) { + game.calcLocation(); + game.calcEncounter(); + game.calcSickPoints(); + game.eatFood(); + game.checkLose(); + } } \ No newline at end of file diff --git a/files/poiscreens.js b/files/poiscreens.js index becc8ae..6c1867f 100644 --- a/files/poiscreens.js +++ b/files/poiscreens.js @@ -1,12 +1,13 @@ const variables = require("./variables.js"); +const combat = requre("./combat.js"); module.exports = { encounterMenuMaker, initializeEncounter, } -function initializeEncounter(reqFaction, diffWeighting, fight, flee){ - var encounter = encounterMenuMaker(reqFaction, diffWeighting); +function initializeEncounter(reqFaction, diffWeighting, fight, flee, forceFaction){ + var encounter = encounterMenuMaker(reqFaction, diffWeighting, forceFaction); console.clear(); console.log("You come across a " + encounter.name); var encounterHealth = variables.randomNumber(encounter.minHealth, encounter.maxHealth); @@ -14,6 +15,8 @@ function initializeEncounter(reqFaction, diffWeighting, fight, flee){ console.log("What would you like to do?"); console.log("--------------------------"); var playerOptions = 1; + console.log(playerOptions + ") Inventory"); + playerOptions++ if(fight == true){ console.log(playerOptions + ") Fight"); playerOptions++; @@ -22,7 +25,23 @@ function initializeEncounter(reqFaction, diffWeighting, fight, flee){ console.log(playerOptions + ") Flee"); playerOptions++; } - console.log(playerOptions + ") Inventory"); + while(true) { + let encounterInput = variables.userInput("Enter: ") + switch(mainMenuInput) { + case "1": + console.log(variables.inventory); + case "2": + combat.initCombat(encounter); + break; + case "3": + if (variables.reputation{reqFaction} < 4) { + if (variables.randomNumber(1,100) < 40){ + console.log("You tried to flee... but they noticed you."); + combat.initCombat(encounter); + } + } + } + } } //Add any new encounter ideas to their required faction and difficulty @@ -47,7 +66,9 @@ var encounterDiffOne = [ {name: "weak ghoul", minHealth: 10, maxHealth: 15, lootTable: "junk", numEnemies: 1}, {name: "bloatfly swarm", minHealth: 1, maxHealth: 5, lootTable: "food", numEnemies: 5}, {name: "wolf", minHealth: 5, maxHealth: 10, lootTable: "food", numEnemies: 1}, - ] + ], + //MWBOS + [] ]; var encounterDiffTwo = [ //NCR @@ -61,6 +82,8 @@ var encounterDiffTwo = [ //BOS [], //Abomination + [], + //MWBOS [] ]; var encounterDiffThree = [ @@ -75,6 +98,8 @@ var encounterDiffThree = [ //BOS [], //Abomination + [], + //MWBOS [] ]; var encounterDiffFour = [ @@ -89,6 +114,8 @@ var encounterDiffFour = [ //BOS [], //Abomination + [], + //MWBOS [] ]; var encounterDiffFive = [ @@ -103,25 +130,40 @@ var encounterDiffFive = [ //BOS [], //Abomination + [], + //MWBOS [] ]; //RIP the filterFactionFunction :( //Declaring some stuff to make them global variables -var encountered = []; var faction = 0; +let encountered = []; //Creates the menu for an encounter. "faction" represents the faction for the encounter, "diffWeighting" changes the odds for //an encounter's difficulty (1-5) //IGNORE THE VARIABLE COMMENTS IN THE NESTED SWITCH STATEMENT, they're placeholders for me -function encounterMenuMaker(reqFaction, diffWeighting){ - var encounterDifficulty = (diffWeighting * variables.randomNumber(1, 20)); - if((reqFaction != "NCR") && (reqFaction != "BOS")){ - factionFailsafe = reqFaction.toLowerCase(); - } else { - factionFailsafe = reqFaction; +function encounterMenuMaker(reqFactionEMM, diffWeightingEMM, forceOptEMM){ + switch(diffWeightingEMM){ + case 1: + reqFactionEMM = encounterDiffOne + break; + case 2: + reqFactionEMM = encounterDiffTwo + break; + case 3: + reqFactionEMM = encounterDiffThree + break; + case 4: + reqFactionEMM = encounterDiffFour + break; + case 5: + reqFactionEMM = encounterDiffFive + break; } + var encounterDifficulty = (diffWeightingEMM * variables.randomNumber(1, 20)); + factionFailsafe = reqFactionEMM.toLowerCase(); switch(factionFailsafe){ case "NCR": faction = 0; @@ -141,17 +183,38 @@ function encounterMenuMaker(reqFaction, diffWeighting){ case "abomination": faction = 5; break; + case "MWBOS": + faction = 6; + break; } - if(encounterDifficulty <= 20){ - encountered.push(encounterDiffOne[faction][variables.randomNumber(0, encounterDiffOne[faction].length - 1)]); - } else if(21 <= encounterDifficulty <= 40){ - encountered.push(encounterDiffTwo[faction][variables.randomNumber(0, encounterDiffTwo[faction].length - 1)]); - } else if(41 <= encounterDifficulty <= 60){ + if (forceOptEMM == true) { + if(encounterDifficulty <= 20){ + encountered.push(encounterDiffOne[faction][variables.randomNumber(0, encounterDiffOne[faction].length - 1)]); + } else if(21 <= encounterDifficulty <= 40){ + encountered.push(encounterDiffTwo[faction][variables.randomNumber(0, encounterDiffTwo[faction].length - 1)]); + } else if(41 <= encounterDifficulty <= 60){ encountered.push(encounterDiffThree[faction][variables.randomNumber(0, encounterDiffThree[faction].length - 1)]); - } else if(61 <= encounterDifficulty <= 80){ - encountered.push(encounterDiffFour[faction][variables.randomNumber(0, encounterDiffFour[faction].length - 1)]); + } else if(61 <= encounterDifficulty <= 80){ + encountered.push(encounterDiffFour[faction][variables.randomNumber(0, encounterDiffFour[faction].length - 1)]); + } else { + encountered.push(encounterDiffFive[faction][variables.randomNumber(0, encounterDiffFive[faction].length - 1)]); + } + return encountered[encountered.length - 1]; } else { - encountered.push(encounterDiffFive[faction][variables.randomNumber(0, encounterDiffFive[faction].length - 1)]); + let x = variables.randomNumber(0, 100) + if (x >= 75) { + if (x <=80) { + encountered.push(encounterDiffOne[raider][variables.randomNumber(0, encounterDiffOne[raider].length - 1)]) + } + if (x <=90) { + encountered.push(encounterDiffOne[settler][variables.randomNumber(0, encounterDiffOne[settler].length - 1)]) + } + if (x <=100) { + encountered.push(encounterDiffOne[abomination][variables.randomNumber(0, encounterDiffOne[abomination].length - 1)]) + } + } + if (x < 75) { + encountered.push(encounterDiffOne[faction][variables.randomNumber(0, encounterDiffOne[faction].length - 1)]) + } } - return encountered[0]; } \ No newline at end of file diff --git a/files/variables.js b/files/variables.js index 2ec353e..4239613 100644 --- a/files/variables.js +++ b/files/variables.js @@ -17,6 +17,8 @@ module.exports = { // Lets variables and functions be used in other files name, prewarmoney, caps, + locationA, + locationB, sleep, userInput, randomNumber, @@ -50,6 +52,24 @@ var isSick = false; var sickPoints = 0; // If you accumulate 50 sick points you lose var sickSeverity = 0; // 3 levls, starting at 1 +/* + 1 - Villified - Will attack you at all POIs and encounters + 2 - Hated - Will only attack you in major POIs + 3 - Disliked - Will not engage in combat and will not allow you to trade + 4 - Neutral - Can trade + 5 - Good - Will offer assistance and minor discounts when trading + 6 - Liked - Better discounts and assistance, faction bonus + 7 - Idolized - Gives faction bonus and severe discounts when trading, underarmor + + Faction bonuses + * MW BOS - X-01 PA + * Legion - The Mark of Caesar, show to frumentari in locations to recieve gear + * NCR - NCR Emergency 2-Way radio, recieve supply drop when in NCR territory. Useable 3 times + * BOS - X-01 upgrade to tesla + * Enclave - X-01 upgrade to APA +*/ +var reputation = {mwbos: 4, legion: 4, ncr: 2, bos: 1, enclave: 10, abomination: 0, raider: 0} //Number between 0(worst) and 10(best), 5 is neutral + //Player inventory //Record all items in the player's inventory as objects with a name, item category, value, and boolean properties. Example below. //{name: "example", category: "testItems", value: 300, use: true, eat: false, drop: true, equip: true} From 8871c644fbd1b43a822e5ff1502e2663d4f95e62 Mon Sep 17 00:00:00 2001 From: Raktbastr Date: Sun, 30 Mar 2025 18:52:44 -0500 Subject: [PATCH 10/27] Stashing changes for later --- files/game.js | 72 +++++++++++++++++++++++++++++++++++++++++ files/main.js | 22 ++++++------- files/poiscreens.js | 35 ++++++++++++++++++-- files/stoptravelmenu.js | 2 -- files/variables.js | 6 ++-- 5 files changed, 116 insertions(+), 21 deletions(-) delete mode 100644 files/stoptravelmenu.js diff --git a/files/game.js b/files/game.js index 6fc803b..f620b49 100644 --- a/files/game.js +++ b/files/game.js @@ -10,6 +10,8 @@ module.exports = { checkLose, calcLocation, calcEncounter, + travelScreen, + checkPOI, } function eatFood() { @@ -89,6 +91,9 @@ function calcLocation() { // Calculates your location in the world using locatio variables.location = variables.location+3; } } + if (variables.location > 300) { + variables.location = 300; + } } // Rundown on how I did this: @@ -141,4 +146,71 @@ function calcEncounter() { } } } +} + +function checkPOI() { + if (variables.location < 300) { + if (variables.location >= (poi.pois[poi.poiCounter].location)-3 && variables.location <= poi.pois[poi.poiCounter].location) + } + if (variables.locationA > 0) { + + } + if (variables.locationB > 0) { + + } +} + +var travelFrame = 0; +function travelScreen() { + if (travelFrame < 0 || travelFrame > 1) { + travelFrame = 0; + } else if (travelFrame == 0) { + console.clear(); + console.log("┌──────────────────────────────────────┐"); + console.log("│ │"); + console.log("│ │"); + console.log("│ │"); + console.log("│ │"); + console.log("│ ◜─◝ │"); + console.log("│ ◟_◞ │"); + console.log("│ /║\\ │"); + console.log("│ \\V/ │"); + console.log("│ / \\ │"); + console.log("│ ▁\\ ▔╹ │"); + console.log("│======================================│"); + console.log("│ . . - . . - . . . - │"); + console.log("│ - . . . . . . - . .│"); + console.log("└──────────────────────────────────────┘"); + console.log("Press [ENTER] to open Pip-Boy"); + console.log("Current Health: "+variables.health); + console.log("Food Amt: "+variables.food); + console.log("Distance to next POI: "); + travelFrame++ + } else { + console.clear(); + console.log("┌──────────────────────────────────────┐"); + console.log("│ │"); + console.log("│ │"); + console.log("│ │"); + console.log("│ │"); + console.log("│ ◜─◝ │"); + console.log("│ ◟_◞ │"); + console.log("│ /║\\ │"); + console.log("│ \\V/ │"); + console.log("│ \\ │"); + console.log("│ ▁│▔╹ │"); + console.log("│======================================│"); + console.log("│ - . - . . . - . - . │"); + console.log("│ - . . - . . . - .│"); + console.log("└──────────────────────────────────────┘"); + console.log("Press [ENTER] to open Pip-Boy"); + console.log("Current Health: "+variables.health); + console.log("Food Amt: "+variables.food); + console.log("Distance to next POI: "); + travelFrame-- + } +} + +function haltTravelScreen() { + } \ No newline at end of file diff --git a/files/main.js b/files/main.js index bb9a04a..051a5ba 100644 --- a/files/main.js +++ b/files/main.js @@ -13,19 +13,16 @@ console.log(" / ' / / / console.log("---/__-------__---/---/----__---------_/_---------/-------__----__----__---__----__---_--_----__-------/___ /----__----__----__-/-"); console.log(" / / ) / / / ) / / / o / / ) / ) /___) (_ ` / ) / / ) /___) / | / ) / ) / / "); console.log("_/________(___(_/___/___(___/_(___(__(_ __o_____/____/_(___/_/___/_(___ _(__)_(___/_/_/__/_(___ _____/_____|__(___/_(___(_(___/___"); -console.log("Credits: Bethesda Game Studio"); +console.log("Credits: Bethesda Game Studio\n") variables.sleep(1000); -console.log("What would you like to do?"); -console.log("--------------------------"); -console.log("1) Start new game"); -console.log("2) Learn How to play"); -console.log("3) Quit Game"); -console.log("4) Dev stuff for testing"); - - - while(true) { + console.log("What would you like to do?"); + console.log("--------------------------"); + console.log("1) Start new game"); + console.log("2) Learn How to play"); + console.log("3) Quit Game"); + console.log("4) Dev stuff for testing"); let mainMenuInput = variables.userInput("Enter: ") switch(mainMenuInput) { case "1": @@ -40,8 +37,7 @@ while(true) { variables.sleep(1000); break; case "4": - let testarr = [1,2,3,4] - console.log(testarr[testarr.length - 1]); + game.travelScreen(); break; } } @@ -64,8 +60,10 @@ function startGame() { // So far what I have is filler and testing, feel free to for (variables.location = 0; variables.location <= 255; variables.location++) { game.calcLocation(); game.calcEncounter(); + game.checkPOI(); game.calcSickPoints(); game.eatFood(); game.checkLose(); + game.travelScreen(); } } \ No newline at end of file diff --git a/files/poiscreens.js b/files/poiscreens.js index 6c1867f..6a01bc7 100644 --- a/files/poiscreens.js +++ b/files/poiscreens.js @@ -1,9 +1,11 @@ const variables = require("./variables.js"); -const combat = requre("./combat.js"); +const combat = require("./combat.js"); module.exports = { encounterMenuMaker, initializeEncounter, + poiCounter, + pois, } function initializeEncounter(reqFaction, diffWeighting, fight, flee, forceFaction){ @@ -34,7 +36,7 @@ function initializeEncounter(reqFaction, diffWeighting, fight, flee, forceFactio combat.initCombat(encounter); break; case "3": - if (variables.reputation{reqFaction} < 4) { + if (variables.reputation.reqFaction < 4) { if (variables.randomNumber(1,100) < 40){ console.log("You tried to flee... but they noticed you."); combat.initCombat(encounter); @@ -217,4 +219,31 @@ function encounterMenuMaker(reqFactionEMM, diffWeightingEMM, forceOptEMM){ encountered.push(encounterDiffOne[faction][variables.randomNumber(0, encounterDiffOne[faction].length - 1)]) } } -} \ No newline at end of file +} + +var poiCounter = 0; +var pois = [ + {name: "Whitespring Bunker", location: 25, path: 0}, + {name: "BOS Bunker Gamma", location: 100, path: 0}, + {name: "BOS Bunker Delta", location: 125, path: 0}, + {name: "BOS Bunker Epsilon", location: 175, path: 0}, + {name: "Vault 0", location: 200, path: 0}, + {name: "Tibbets Prison", location: 250, path: 0}, + {name: "Flagstaff", location: 275, path: 0}, + {name: "New Vegas", location: 300, path: 0}, + {name: "Mojave Outpost", location: 5, path: 1}, + {name: "Necropolis", location: 10, path: 1}, + {name: "The Hub", location: 15, path: 1}, + {name: "Lost Hills", location: 20, path: 1}, + {name: "Mariposa MB", location: 30, path: 1}, + {name: "San Franciso", location: 35, path: 1}, + {name: "Camp Navarro", location: 45, path: 1}, + {name: "Canyon Wreckage", location: 5, path: 2}, + {name: "Hopeville & Ashton", location: 15, path: 2}, + {name: "The Sierra Madre", location: 25, path: 2}, + {name: "Shady Sands", location: 35, path: 2}, + {name: "New Reno", location: 55, path: 2}, + {name: "Redding", location: 75, path: 2}, + {name: "Eureka", location: 85, path: 2}, + {name: "Camp Navarro", location: 100, path: 2}, +] \ No newline at end of file diff --git a/files/stoptravelmenu.js b/files/stoptravelmenu.js deleted file mode 100644 index 665bf0a..0000000 --- a/files/stoptravelmenu.js +++ /dev/null @@ -1,2 +0,0 @@ -// Halt travel screen and menu. -const variables = require("./variables.js"); \ No newline at end of file diff --git a/files/variables.js b/files/variables.js index 4239613..f8a1e5a 100644 --- a/files/variables.js +++ b/files/variables.js @@ -52,6 +52,8 @@ var isSick = false; var sickPoints = 0; // If you accumulate 50 sick points you lose var sickSeverity = 0; // 3 levls, starting at 1 +var sleepVar = 0; // Placeholder variable that allows sleep() to run a command without changing/printing somthing + /* 1 - Villified - Will attack you at all POIs and encounters 2 - Hated - Will only attack you in major POIs @@ -84,10 +86,6 @@ var lootTables = [[],[],[],[],[]] // Only small things like food and ammo, 5 Loo var daysSinceScav = 0; // Days since your last scavenge, you must wait 15 days before scavenging again. -function sleep(time) { // Waits the inputed amt of miliseconds before proceeding - setTimeout(() => {}, time); -} - function userInput(question) { // Basic user input functions, takes in the question to be asked. let answer = readline.question(question); return(answer); From e5fe71ce4649e85e682bb2e631c4231027b8c5bd Mon Sep 17 00:00:00 2001 From: Raktbastr Date: Thu, 3 Apr 2025 11:10:35 -0500 Subject: [PATCH 11/27] Rewrite --- .DS_Store | Bin 0 -> 6148 bytes examples.js | 15 +- files/.DS_Store | Bin 0 -> 6148 bytes files/encounters.js | 151 +++++++++ files/functions.js | 122 +++++++ files/game.js | 216 ------------- files/huntinggame.js | 2 - files/inventory.js | 22 +- files/main.js | 93 +++--- files/node_modules/.package-lock.json | 2 +- files/package-lock.json | 2 +- files/package.json | 3 +- files/poiscreens.js | 445 ++++++++++++-------------- files/rivercrossing.js | 2 - files/shops.js | 13 +- files/variables.js | 123 ++----- 16 files changed, 573 insertions(+), 638 deletions(-) create mode 100644 .DS_Store create mode 100644 files/.DS_Store create mode 100644 files/encounters.js create mode 100644 files/functions.js delete mode 100644 files/game.js delete mode 100644 files/huntinggame.js delete mode 100644 files/rivercrossing.js diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..b035c60ff653885ad9d50d3ec90740d1f6454e78 GIT binary patch literal 6148 zcmeHKL2KJE6n;w6#wHAM*r1n!VAqf}pCHp(=_at>BOM5DeQS{*Hlb*gOp-)D#h)8rNNt>uaL>`>6;-k33xSxH+DmJnK z6ncyyWi+6ITJ&{=?E?R!0=##1?AaAXbU};zSG>v8d7P;j4E{X!;jL?Js1dExCrZtJ z|Hb@yKQo>dLp$cLc$lTdczgS|sH|1jH)>wZt9xhR7c~vX(RfmHqtOR$ohX&XxAiD~ zmky@=#?u3pkE1jnjC4Yp3_v-3pXQ00cGVeHk!_y0!{&^z=IXAC!AM*@JMa|r+`!7u_?gk zgM>2%7E6Qr=s=;L0Kh83+EC}8Mb42H1B<0W^uUBk1)5Z0pBTcVBQ7m3uvi*2=_Ksq zL)e*xeW3_FJI0rqP9iYqN~eHRU|E4R(`@kle|Z1usuoB~dPN2P$M_QGBlOR{(C x%HsI0mGF;nHs+NE|D>RzuVQfdD&B-^LtJtN7+5R~A_8+i0$K)FI0gQx0ypkYd;9 {}, time); -} \ No newline at end of file +console.log(time.now) \ No newline at end of file diff --git a/files/.DS_Store b/files/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..8b6de9159c5997cb0ed6b1298a9cedccf20e75fe GIT binary patch literal 6148 zcmeHK%TB{E5FD2Z3bX=lT##}`q7r`)5F9x30nit1p)^$=NZfMgSCIHVPB6Q+P?9D> zTo6LLl6P!p$Low0I|ks+SN&69A3%deu)afAV)9(dn$<#2i|BNW4wh)+9*e8VTC{bT z0;a%UQ$W7mZS;`f5nW`y-=x=_Bwaq0t>KKN{h`Jhu!lYd8a={->^WNlOj!?Ke~$fD zV7D|@a<0f(vNf+}y5mgVChnBeBWp~4MMihT4JpqXGxkaIF3FqYxooEHy)e@)s?uSm zX<2k_Scu-#=vi5;D)^dvlPTvRD&CMKwG}38apzpqF3UT>j5F%tfquyN6S5L*tMaT* z^CO5B$d1q~j8MgUDezk4CDh{E^;Q+L85`t`$eoq1vg(+PZ*rwNT%$34*Q-*cX>OG{ zVY447z%yH{vFp*iDPRhi0$&Qq{t&SU#sO20x^>X$6@XZ0w;Jp6!yud}U>q>@$R{-C zsYFk8;fmoro&8aWivy+}JsmDwK3vG`!VSe~c8(uuI9%+}yeVJ`cy_}r25z8%$n8c+Xl|mPeW39+he8{54XOUEhalq6g Qdua9}pfZ><1%6e5Pd=>6(*OVf literal 0 HcmV?d00001 diff --git a/files/encounters.js b/files/encounters.js new file mode 100644 index 0000000..81e7a18 --- /dev/null +++ b/files/encounters.js @@ -0,0 +1,151 @@ +// Holds encounter code, seperate from poiscreens.js + +import { randomNumber } from "./functions.js"; + +export function calcEncounter() { + if (randomNumber(1,100) <= 20) { + if (location >= 255) { + if (locationA > locationB) { + if ((locationA >= 5 && locationA < 17) || (locationA >= 23 && locationA < 40)) { + initializeEncounter(NCR,4,true,true,false); + } + if (locationB >= 40) { + initializeEncounter(NCR,5,true,true,false); + } + } else if (locationA < locationB) { + if ((locationB >= 0 && locationB < 30) || (locationB >= 40 && locationB < 80)) { + initializeEncounter(abomination,3,true,true,false) + } + if ((locationB >= 30 && locationB < 40) || (locationB >= 90)) { + initializeEncounter(NCR,5,true,true,false) + } + if (locationB >= 80 && locationB < 90) { + initializeEncounter(enclave,4,true,true,false) + } + } else { + if (location >= 5 && location < 50) { + initializeEncounter(abomination,1,true,true,false) + } + if (location >= 50 && location < 200) { + initializeEncounter(MWBOS,2,true,true,false) + } + if (location >= 200 && location < 255) { + initializeEncounter(legion,3,true,true,false) + } + } + } + } +} + +export function encounterMenuMaker(reqFactionEMM, diffWeightingEMM, forceOptEMM){ + switch(diffWeightingEMM){ + case 1: + reqFactionEMM = encounterDiffOne + break; + case 2: + reqFactionEMM = encounterDiffTwo + break; + case 3: + reqFactionEMM = encounterDiffThree + break; + case 4: + reqFactionEMM = encounterDiffFour + break; + case 5: + reqFactionEMM = encounterDiffFive + break; + } + var encounterDifficulty = (diffWeightingEMM * randomNumber(1, 20)); + factionFailsafe = reqFactionEMM.toLowerCase(); + switch(factionFailsafe){ + case "NCR": + faction = 0; + break; + case "legion": + faction = 1; + break; + case "raider": + faction = 2; + break; + case "settler": + faction = 3; + break; + case "BOS": + faction = 4; + break; + case "abomination": + faction = 5; + break; + case "MWBOS": + faction = 6; + break; + } + if (forceOptEMM == true) { + if(encounterDifficulty <= 20){ + encountered.push(encounterDiffOne[faction][randomNumber(0, encounterDiffOne[faction].length - 1)]); + } else if(21 <= encounterDifficulty <= 40){ + encountered.push(encounterDiffTwo[faction][randomNumber(0, encounterDiffTwo[faction].length - 1)]); + } else if(41 <= encounterDifficulty <= 60){ + encountered.push(encounterDiffThree[faction][randomNumber(0, encounterDiffThree[faction].length - 1)]); + } else if(61 <= encounterDifficulty <= 80){ + encountered.push(encounterDiffFour[faction][randomNumber(0, encounterDiffFour[faction].length - 1)]); + } else { + encountered.push(encounterDiffFive[faction][randomNumber(0, encounterDiffFive[faction].length - 1)]); + } + return encountered[encountered.length - 1]; + } else { + let x = randomNumber(0, 100) + if (x >= 75) { + if (x <=80) { + encountered.push(encounterDiffOne[raider][randomNumber(0, encounterDiffOne[raider].length - 1)]) + } + if (x <=90) { + encountered.push(encounterDiffOne[settler][randomNumber(0, encounterDiffOne[settler].length - 1)]) + } + if (x <=100) { + encountered.push(encounterDiffOne[abomination][randomNumber(0, encounterDiffOne[abomination].length - 1)]) + } + } + if (x < 75) { + encountered.push(encounterDiffOne[faction][randomNumber(0, encounterDiffOne[faction].length - 1)]) + } + } +} + +export function initializeEncounter(reqFaction, diffWeighting, fight, flee, forceFaction){ + var encounter = encounterMenuMaker(reqFaction, diffWeighting, forceFaction); + console.clear(); + console.log("You come across a " + encounter.name); + var encounterHealth = randomNumber(encounter.minHealth, encounter.maxHealth); + console.log("Health: " + encounterHealth); + console.log("What would you like to do?"); + console.log("--------------------------"); + var playerOptions = 1; + console.log(playerOptions + ") Inventory"); + playerOptions++ + if(fight == true){ + console.log(playerOptions + ") Fight"); + playerOptions++; + } + if(flee == true){ + console.log(playerOptions + ") Flee"); + playerOptions++; + } + while(true) { + let encounterInput = userInput("Enter: ") + switch(encounterInput) { + case "1": + console.log(inventory); + case "2": + initCombat(encounter); + break; + case "3": + if (reputation.reqFaction < 4) { + if (randomNumber(1,100) < 40){ + console.log("You tried to flee... but they noticed you."); + initCombat(encounter); + } + } + } + } +} \ No newline at end of file diff --git a/files/functions.js b/files/functions.js new file mode 100644 index 0000000..c96da68 --- /dev/null +++ b/files/functions.js @@ -0,0 +1,122 @@ +// Holds all functions used in multiple files +import { createRequire } from 'module'; +const require = createRequire(import.meta.url); +var readlineSync = require('readline-sync'); + + +import { food, foodRate, health, healthCap, locationA, locationB, name, radPoints, radSeverity, walkRate } from "./variables.js"; + +// Used for basic functions, not game specific +export function userInput(question) { // Basic user input functions, takes in the question to be asked. + let answer = readlineSync.question(question); + return(answer); +} + +export function randomNumber(min, max) { // Takes in two parameters, min and max, and returns a random number between those boundries. + while (true) { + var randNum = Math.floor(Math.random() * (max+1)); + if (randNum >= min) { break; } + } + return randNum; +} + + +// Used for game +export function healthCapCalc() { // Calculates HP cap given current radPoints + healthCap = healthCap-radPoints; + if (health > healthCap) { health = healthCap; } +} + +export function radPointsCalc() { // Calculates radPoints given walk/foodrate + radPoints = radPoints + 0.5 * (radSeverity * 10 + 5 * (walkRate + foodRate)) +} + +export function eatFood() { // Calculates food amount after a day of eating + if (food == 0) { + health = health - 3*walkRate + } else { + food = food - walkRate * foodRate + } +} + +export function checkLose() { // Checks to see if any lose conditions have been met + if (health <= 0 || radPoints >= 100) { + death(); + } +} + + +export function calcLocation() { + if (walkRate == 1) { + if (path = 0) { + location++; + } + if (path = 1) { + locationA++; + } + if (path = 2) { + locationB++; + } + } + if (walkRate == 2) { + if (path = 0) { + location * 2; + } + if (path = 1) { + locationA * 2; + } + if (path = 2) { + locationB * 2; + } + } + if (walkRate == 3) { + if (path = 0) { + location * 3; + } + if (path = 1) { + locationA * 3; + } + if (path = 2) { + locationB * 3; + } + } +} + +function death() { + let random = variables.randomNumber(1,3); + if (random = 1) { deathScreen1(); } + if (random = 2) { deathScreen2(); } + if (random = 3) { deathScreen3(); } +} + +function death1() { + console.log("") +} + +function death2() { + +} + +function death3() { + +} + + + +function timeDeath() { // The death screen for passing the time limit + console.clear; + console.log("Your PIP-Boy starts ringing...\n\n") + console.log("BEEP...BEEP...BEEP"); + console.log("INCOMING MESAGE FROM: Raven_Rock_Comms-1\n\n"); + console.log("|||||||") + console.log("|| Enclave Intranet Messager"); + console.log("|||||||") + console.log("|| Message From: automessager"); + console.log("|||||||\n\n") + console.log("Dear, "+name+",\n\n"); + console.log("You have failed to faithfully execute the tasks laid before you in a timely manner."); + console.log("In consequence you have been dishonorably discharged from the Enclave Armed Forces"); + console.log("Please return to the nearest active Enclave Military Installation immeditely\n\n"); + console.log("Signed, Enclave Internal Messager"); + console.clear; +} \ No newline at end of file diff --git a/files/game.js b/files/game.js deleted file mode 100644 index f620b49..0000000 --- a/files/game.js +++ /dev/null @@ -1,216 +0,0 @@ -// Holds functions needed to play the game -const variables = require("./variables.js"); -const death = require("./deathscreens.js"); -const poi = require("./poiscreens.js"); - -module.exports = { - eatFood, - calcSickPoints, - scavenge, - checkLose, - calcLocation, - calcEncounter, - travelScreen, - checkPOI, -} - -function eatFood() { - if (variables.food == 0) { - variables.health - 3*variables.travelSpeed - } else if (variables.isSick == true) { - variables.food = variables.food-((variables.travelSpeed*variables.foodAmt)+variables.sickSeverity); - } else { - variables.food = variables.food-(variables.travelSpeed*variables.foodAmt); - } - variables.health = variables.health+(5*variables.foodAmt); -} - -function calcSickPoints() { - if (variables.isSick = true) { - variables.sickPoints = variables.sickPoints+((variables.sickSeverity-(0.5*variables.foodAmt))+(0.5*(variables.travelSpeed+variables.radSeverity))); - } -} - -function scavenge() { // Rolls a random number between 1 and 100 to see which loot table you get, then picks a random item from it. ADD COOLDOWN! - if (variables.daysSinceScav < 20 ) { - console.log("You must wait "+(20-variables.daysSinceScav)+" days until you can scavenge again") - } else { - let luck = variables.randomNumber(1,100); - if (luck <= 20) { - let group = 0; - let random = variables.randomNumber(variables.lootTables[group][0], variables.lootTables[group][3]); - inventory.push(random); - } else if (luck <= 40) { - let group = 1; - let random = variables.randomNumber(variables.lootTables[group][0], variables.lootTables[group][3]); - inventory.push(random); - } else if (luck <= 60) { - let group = 2; - let random = variables.randomNumber(variables.lootTables[group][0], variables.lootTables[group][3]); - inventory.push(random); - } else if (luck <= 80) { - let group = 3; - let random = variables.randomNumber(variables.lootTables[group][0], variables.lootTables[group][3]); - inventory.push(random); - } else if (luck <= 100) { - let group = 4; - let random = variables.randomNumber(variables.lootTables[group][0], variables.lootTables[group][3]); - inventory.push(random); - } - } -} - -function checkLose() { // Checks to see if any lose conditions have been met - if (variables.health <= 0 || variables.sickPoints >= 50) { - death.deathScreen(); - } - if (variables.day >= 365) { - death.timeDeath(); - } -} - -function calcLocation() { // Calculates your location in the world using location points, You move your move speed per day, but 3/4 of it if you are sick - if (variables.travelSpeed == 1) { - if (variables.isSick == true) { - variables.location = variables.location+0.75; - } else { - variables.location++; - } - } - if (variables.travelSpeed == 2) { - if (variables.isSick == true) { - variables.location = variables.location+1.5; - } else { - variables.location = variables.location+2; - } - } - if (variables.travelSpeed == 3) { - if (variables.isSick == true) { - variables.location = variables.location+2.25; - } else { - variables.location = variables.location+3; - } - } - if (variables.location > 300) { - variables.location = 300; - } -} - -// Rundown on how I did this: -/** - * calcEncounter() checks what faction territory you are in and pipes the respective faction into initilizeEncounter(). - * - * initEncounter() is pretty much the same however you can use forceFaction (set to true) to bypass the random raider/abomination chance. - * forceFaction will always be false unless under certian circumstances (eg. Lost Hills, Legion Territory, Malcom Holmes). - * Turns out the fight/flee variables work exactly how I want so I did not change them. - * - * encounterMenuMaker() was changed to account for forceFaction. If forceFaction is set to true, EMM's equivilant forceOpt will take its value. - * If true it runs the code you had before, no changes. If it is false it will roll a dice to see if you get the normal faction, given by your switch statement, - * or a radier/abomination. If it is a radier/abomination it will then roll a 50/50. The code for both is the same as the default faction code except that - * 'faction' will just be 'raider' or 'abomination' instead of the default. - * - * I also implemented auto difficulty scaling. Instead of piping in 'encounterDiffOne' you just input the interger of it. This is because you cant - * use a string as a variable name and or whatever. Just trust me, this is the only way it works. initEncounter() will figure it out on the otherside. - */ - -function calcEncounter() { - if (variables.randomNumber(1,100) <= 20) { - if (variables.location >= 255) { - if (variables.locationA > variables.locationB) { - if ((variables.locationA >= 5 && variables.locationA < 17) || (variables.locationA >= 23 && variables.locationA < 40)) { - poi.initializeEncounter(NCR,4,true,true,false); - } - if (variables.locationB >= 40) { - poi.initializeEncounter(NCR,5,true,true,false); - } - } else if (variables.locationA < variables.locationB) { - if ((variables.locationB >= 0 && variables.locationB < 30) || (variables.locationB >= 40 && variables.locationB < 80)) { - poi.initializeEncounter(abomination,3,true,true,false) - } - if ((variables.locationB >= 30 && variables.locationB < 40) || (variables.locationB >= 90)) { - poi.initializeEncounter(NCR,5,true,true,false) - } - if (variables.locationB >= 80 && variables.locationB < 90) { - poi.initializeEncounter(enclave,4,true,true,false) - } - } else { - if (variables.location >= 5 && variables.location < 50) { - poi.initializeEncounter(abomination,1,true,true,false) - } - if (variables.location >= 50 && variables.location < 200) { - poi.initializeEncounter(MWBOS,2,true,true,false) - } - if (variables.location >= 200 && variables.location < 255) { - poi.initializeEncounter(legion,3,true,true,false) - } - } - } - } -} - -function checkPOI() { - if (variables.location < 300) { - if (variables.location >= (poi.pois[poi.poiCounter].location)-3 && variables.location <= poi.pois[poi.poiCounter].location) - } - if (variables.locationA > 0) { - - } - if (variables.locationB > 0) { - - } -} - -var travelFrame = 0; -function travelScreen() { - if (travelFrame < 0 || travelFrame > 1) { - travelFrame = 0; - } else if (travelFrame == 0) { - console.clear(); - console.log("┌──────────────────────────────────────┐"); - console.log("│ │"); - console.log("│ │"); - console.log("│ │"); - console.log("│ │"); - console.log("│ ◜─◝ │"); - console.log("│ ◟_◞ │"); - console.log("│ /║\\ │"); - console.log("│ \\V/ │"); - console.log("│ / \\ │"); - console.log("│ ▁\\ ▔╹ │"); - console.log("│======================================│"); - console.log("│ . . - . . - . . . - │"); - console.log("│ - . . . . . . - . .│"); - console.log("└──────────────────────────────────────┘"); - console.log("Press [ENTER] to open Pip-Boy"); - console.log("Current Health: "+variables.health); - console.log("Food Amt: "+variables.food); - console.log("Distance to next POI: "); - travelFrame++ - } else { - console.clear(); - console.log("┌──────────────────────────────────────┐"); - console.log("│ │"); - console.log("│ │"); - console.log("│ │"); - console.log("│ │"); - console.log("│ ◜─◝ │"); - console.log("│ ◟_◞ │"); - console.log("│ /║\\ │"); - console.log("│ \\V/ │"); - console.log("│ \\ │"); - console.log("│ ▁│▔╹ │"); - console.log("│======================================│"); - console.log("│ - . - . . . - . - . │"); - console.log("│ - . . - . . . - .│"); - console.log("└──────────────────────────────────────┘"); - console.log("Press [ENTER] to open Pip-Boy"); - console.log("Current Health: "+variables.health); - console.log("Food Amt: "+variables.food); - console.log("Distance to next POI: "); - travelFrame-- - } -} - -function haltTravelScreen() { - -} \ No newline at end of file diff --git a/files/huntinggame.js b/files/huntinggame.js deleted file mode 100644 index e7bc4ac..0000000 --- a/files/huntinggame.js +++ /dev/null @@ -1,2 +0,0 @@ -// Hunting Game, if we even decide to do it. -const variables = require("./variables.js"); diff --git a/files/inventory.js b/files/inventory.js index 970e930..51bc179 100644 --- a/files/inventory.js +++ b/files/inventory.js @@ -1,9 +1,5 @@ -const variables = require("./variables"); -const main = require("./main"); - -module.exports = { - inventoryMenuM, -}; +import { userInput } from "./functions.js"; +import { inventory, userInput } from "./variables.js"; //Builds the main menu inventory function inventoryMenuM(){ @@ -13,7 +9,7 @@ function inventoryMenuM(){ console.log("1) Supplies"); console.log("2) Equipment"); console.log("[spacebar to exit]"); - var userInput = variables.userInput("Enter: "); + let invChoice = userInput("Enter: "); switch(userInput){ case "1": supplyInventory(); @@ -29,11 +25,11 @@ function supplyInventory(){ console.clear(); console.log("SUPPLIES"); console.log("---------"); - for(var a = 0; a < variables.inventory[0].length;){ - console.log((a + 1) + ") " + variables.inventory[0][a].name); + for(var a = 0; a < inventory[0].length;){ + console.log((a + 1) + ") " + inventory[0][a].name); a++; } - variables.userInput("[Enter to return]"); + userInput("[Enter to return]"); console.clear(); inventoryMenuM(); } @@ -43,11 +39,11 @@ function equipmentInventory(){ console.clear(); console.log("EQUIPMENT"); console.log("---------"); - for(var a = 0; a < variables.inventory[1].length;){ - console.log((a + 1) + ") " + variables.inventory[1][a].name); + for(var a = 0; a < inventory[1].length;){ + console.log((a + 1) + ") " + inventory[1][a].name); a++; } - variables.userInput("[Enter to return]"); + userInput("[Enter to return]"); console.clear(); inventoryMenuM(); } \ No newline at end of file diff --git a/files/main.js b/files/main.js index 051a5ba..0dd5252 100644 --- a/files/main.js +++ b/files/main.js @@ -1,10 +1,8 @@ // Program is started from here, runs functions from other files. -const variables = require("./variables.js"); -const game = require("./game.js"); -const shops = require("./shops"); -const readline = require('node:readline'); -const encounterMenus = require("./poiscreens.js"); -const inventoryStuff = require("./inventory.js"); +import { userInput, calcLocation, radPointsCalc, healthCapCalc, checkLose } from './functions.js'; +import { pois, poiCounter } from './poiscreens.js'; +import { name, prewarmoney } from './variables.js'; + console.clear(); console.log("__________________________________________________________________________________________________________________________________"); @@ -13,57 +11,56 @@ console.log(" / ' / / / console.log("---/__-------__---/---/----__---------_/_---------/-------__----__----__---__----__---_--_----__-------/___ /----__----__----__-/-"); console.log(" / / ) / / / ) / / / o / / ) / ) /___) (_ ` / ) / / ) /___) / | / ) / ) / / "); console.log("_/________(___(_/___/___(___/_(___(__(_ __o_____/____/_(___/_/___/_(___ _(__)_(___/_/_/__/_(___ _____/_____|__(___/_(___(_(___/___"); -console.log("Credits: Bethesda Game Studio\n") -variables.sleep(1000); +console.log("Credits: Bethesda Game Studio \n"); -while(true) { - console.log("What would you like to do?"); - console.log("--------------------------"); - console.log("1) Start new game"); - console.log("2) Learn How to play"); - console.log("3) Quit Game"); - console.log("4) Dev stuff for testing"); - let mainMenuInput = variables.userInput("Enter: ") - switch(mainMenuInput) { - case "1": - startGame(); - break; - case "2": - console.log("Follow the link below for a game manual.") - console.log("[ENTER LINK HERE]") - break; - case "3": - console.log("Quitting Game..."); - variables.sleep(1000); - break; - case "4": - game.travelScreen(); - break; +console.log("What would you like to do?"); +console.log("--------------------------"); +console.log("1) Start new game"); +console.log("2) Learn How to play"); +console.log("3) Quit Game"); +console.log("4) Dev stuff for testing"); + +var mainMenuInput = userInput("Enter: ") + +switch(mainMenuInput) { + case "1": + startGame(); + break; + case "2": + console.log("Follow the link below for a game manual.") + console.log("[ENTER LINK HERE]") + break; + case "3": + console.log("Quitting Game..."); + break; + case "4": + console.log(pois[poiCounter]); + break; } -} + function startGame() { // So far what I have is filler and testing, feel free to change. console.clear(); - variables.sleep(1000); - variables.name = variables.userInput("What is your name? "); - console.log(variables.name+" Is now your name...") - variables.sleep(2000); + name = userInput("What is your name? "); + console.log(name+" Is now your name...") console.clear(); console.log("Intro:"); - console.log("You are an ordinary loyal Enclave Soldier working at Raven Rock. \nYou are typing away at your terminal, entering reports of recovered materials when a message flashes on it.\n\nDear "+variables.name+",\n\n This is a direct order from the Enclave High Command. \nIgnore all previous directives. Proceed to Camp Navarro immediately. \nSeek safe passage through the Brotherhood and NCR territories. \nDo not disclose your mission to anyone but Enclave Personel with \nsecurity clearance 5 or higher. Reqisition supplies before departure. \n\n Signed, President John Henry Eden\n\n"); + console.log("You are an ordinary loyal Enclave Soldier working at Raven Rock. \nYou are typing away at your terminal, entering reports of recovered materials when a message flashes on it"); + console.log("|||||||") + console.log("|| Enclave Intranet Messager"); + console.log("") + console.log("|| Message From: potus"); + console.log("|||||||\n\n") + console.log("Dear "+name+",\n\n This is a direct order from the Enclave High Command. \nIgnore all previous directives. Proceed to Camp Navarro immediately. \nSeek safe passage through the Brotherhood and NCR territories. \nDo not disclose your mission to anyone but Enclave Personel with \nsecurity clearance 5 or higher. Reqisition supplies before departure. \nYou have been given 1 YEAR to complete this mission or face discharge.\n\n Signed, President John Henry Eden\n\n"); - variables.userInput("[Enter to open shop]"); + userInput("[Enter to open shop]"); console.clear(); - variables.prewarmoney = 500; - shops.ravenRock(); - + prewarmoney = 500; + ravenRockShop(); for (variables.location = 0; variables.location <= 255; variables.location++) { - game.calcLocation(); - game.calcEncounter(); - game.checkPOI(); - game.calcSickPoints(); - game.eatFood(); - game.checkLose(); - game.travelScreen(); + calcLocation(); + radPointsCalc(); + healthCapCalc + checkLose(); } } \ No newline at end of file diff --git a/files/node_modules/.package-lock.json b/files/node_modules/.package-lock.json index 3fb3820..46e4fa7 100644 --- a/files/node_modules/.package-lock.json +++ b/files/node_modules/.package-lock.json @@ -1,5 +1,5 @@ { - "name": "files", + "name": "CT Rewrite", "lockfileVersion": 3, "requires": true, "packages": { diff --git a/files/package-lock.json b/files/package-lock.json index 9401b7e..1d55cc7 100644 --- a/files/package-lock.json +++ b/files/package-lock.json @@ -1,5 +1,5 @@ { - "name": "files", + "name": "CT Rewrite", "lockfileVersion": 3, "requires": true, "packages": { diff --git a/files/package.json b/files/package.json index 65adf18..a749437 100644 --- a/files/package.json +++ b/files/package.json @@ -1,5 +1,6 @@ { "dependencies": { "readline-sync": "^1.4.10" - } + }, + "type": "module" } diff --git a/files/poiscreens.js b/files/poiscreens.js index 6a01bc7..6ebbd87 100644 --- a/files/poiscreens.js +++ b/files/poiscreens.js @@ -1,249 +1,218 @@ -const variables = require("./variables.js"); -const combat = require("./combat.js"); +// Holds poi code, seperate from encounters.js -module.exports = { - encounterMenuMaker, - initializeEncounter, - poiCounter, - pois, +import { userInput } from "./functions.js"; +import { location, locationA, locationB, path } from "./variables.js"; + +export function checkPOI() { + if (path == 0) { + if (location >= (pois[poiCounter].location)-3 && location <= pois[poiCounter].location && pois[poiCounter].visited == false) { + switch(pois[poiCounter].name) { + case "Whitespring Bunker": + whitespring(); + break; + case "BOS Bunker Gamma": + bosGamma(); + break; + case "BOS Bunker Delta": + bosDelta(); + break; + case "BOS Bunker Epsilon": + bosEpsilon(); + break; + case "Vault 0": + vault0(); + break; + case "Tibbets Prison": + tibbets(); + break; + case "Flagstaff": + flagstaff(); + break; + case "New Vegas": + newVegas(); + } + } + } + if (path == 1) { + if (locationA >= (pois[poiCounter].location)-3 && locationA <= pois[poiCounter].location && pois[poiCounter].visited == false) { + switch(pois[poiCounter].name) { + case "Mojave Outpost": + mojaveOutpost(); + break; + case "Necropolis": + necropolis(); + break; + case "The Hub": + hub(); + break; + case "Lost Hills": + lostHills(); + break; + case "Mariposa MB": + mariposa(); + break; + case "San Francisco": + sanFrancisco(); + break; + case "Camp Navarro": + navarro(); + break; + } + } + } + if (path == 2) { + if (locationB >= (pois[poiCounter].location)-3 && locationB <= pois[poiCounter].location && pois[poiCounter].visited == false) { + switch(pois[poiCounter].name) { + case "Canyon Wreckage": + canyonWreck(); + break; + case "Hopeville & Ashton": + hopeville(); + break; + case "The Sierra Madre": + sierraMadre(); + break; + case "Shady Sands": + shadySands(); + break; + case "New Reno": + newReno(); + break; + case "Redding": + redding(); + break; + case "Eureka": + eureka(); + break; + case "Camp Navarro": + navarro(); + } + } + } } -function initializeEncounter(reqFaction, diffWeighting, fight, flee, forceFaction){ - var encounter = encounterMenuMaker(reqFaction, diffWeighting, forceFaction); +export var poiCounter = 0; +export var pois = [ + {name: "Whitespring Bunker", location: 25, path: 0, visited: false}, + {name: "BOS Bunker Gamma", location: 100, path: 0, visited: false}, + {name: "BOS Bunker Delta", location: 125, path: 0, visited: false}, + {name: "BOS Bunker Epsilon", location: 175, path: 0, visited: false}, + {name: "Vault 0", location: 200, path: 0, visited: false}, + {name: "Tibbets Prison", location: 250, path: 0, visited: false}, + {name: "Flagstaff", location: 275, path: 0, visited: false}, + {name: "New Vegas", location: 300, path: 0, visited: false}, + {name: "Mojave Outpost", location: 5, path: 1, visited: false}, + {name: "Necropolis", location: 10, path: 1, visited: false}, + {name: "The Hub", location: 15, path: 1, visited: false}, + {name: "Lost Hills", location: 20, path: 1, visited: false}, + {name: "Mariposa MB", location: 30, path: 1, visited: false}, + {name: "San Franciso", location: 35, path: 1, visited: false}, + {name: "Camp Navarro", location: 45, path: 1, visited: false}, + {name: "Canyon Wreckage", location: 5, path: 2, visited: false}, + {name: "Hopeville & Ashton", location: 15, path: 2, visited: false}, + {name: "The Sierra Madre", location: 25, path: 2, visited: false}, + {name: "Shady Sands", location: 35, path: 2, visited: false}, + {name: "New Reno", location: 55, path: 2, visited: false}, + {name: "Redding", location: 75, path: 2, visited: false}, + {name: "Eureka", location: 85, path: 2, visited: false}, + {name: "Camp Navarro", location: 100, path: 2, visited: false}, +] + +function whitespring() { + +} + +function bosGamma() { + +} + +function bosDelta() { + +} + +function bosEpsilon() { + +} + +function vault0() { + +} + +function tibbets() { + +} + +function flagstaff() { + +} + +function newVegas() { + // The below is placeholder, once we add proper code delete this console.clear(); - console.log("You come across a " + encounter.name); - var encounterHealth = variables.randomNumber(encounter.minHealth, encounter.maxHealth); - console.log("Health: " + encounterHealth); - console.log("What would you like to do?"); - console.log("--------------------------"); - var playerOptions = 1; - console.log(playerOptions + ") Inventory"); - playerOptions++ - if(fight == true){ - console.log(playerOptions + ") Fight"); - playerOptions++; + console.log("Ahead lies 2 routes to Navarro."); + console.log("The northern route passes through the Divide before going north through the mountains.\nIt offers a longer path with fewer possible enimies, but those you face will not back down.") + console.log("The southern route goes through the heart of the NCR along I-15.\nIt is shorter and more pleasant, however without proper reputation your many stops may become worrisome.") + var pathChoice = userInput("Which path would you like to follow, Northern or Southern? "); + if (pathChoice.toLowerCase == "northern") { + path = 2; } - if(flee == true){ - console.log(playerOptions + ") Flee"); - playerOptions++; - } - while(true) { - let encounterInput = variables.userInput("Enter: ") - switch(mainMenuInput) { - case "1": - console.log(variables.inventory); - case "2": - combat.initCombat(encounter); - break; - case "3": - if (variables.reputation.reqFaction < 4) { - if (variables.randomNumber(1,100) < 40){ - console.log("You tried to flee... but they noticed you."); - combat.initCombat(encounter); - } - } - } + if (pathChoice.toLowerCase == "southern") { + path = 1; } } -//Add any new encounter ideas to their required faction and difficulty -var encounterDiffOne = [ - //NCR - [], - //Legion - [], - //Raider - [ - {name: "raider aspirant", minHealth: 30, maxHealth: 50, lootTable: "teir1A&W", numEnemies: 1}, - ], - //Settler - [ - {name: "drunk", minHealth: 15, maxHealth: 25, lootTable: "junk", numEnemies: 1}, - ], - //BOS - [], - //Abomination - [ - {name: "radroach", minHealth: 1, maxHealth: 10, lootTable: "food", numEnemies: 1}, - {name: "weak ghoul", minHealth: 10, maxHealth: 15, lootTable: "junk", numEnemies: 1}, - {name: "bloatfly swarm", minHealth: 1, maxHealth: 5, lootTable: "food", numEnemies: 5}, - {name: "wolf", minHealth: 5, maxHealth: 10, lootTable: "food", numEnemies: 1}, - ], - //MWBOS - [] -]; -var encounterDiffTwo = [ - //NCR - [], - //Legion - [], - //Raider - [], - //Settler - [], - //BOS - [], - //Abomination - [], - //MWBOS - [] -]; -var encounterDiffThree = [ - //NCR - [], - //Legion - [], - //Raider - [], - //Settler - [], - //BOS - [], - //Abomination - [], - //MWBOS - [] -]; -var encounterDiffFour = [ - //NCR - [], - //Legion - [], - //Raider - [], - //Settler - [], - //BOS - [], - //Abomination - [], - //MWBOS - [] -]; -var encounterDiffFive = [ - //NCR - [], - //Legion - [], - //Raider - [], - //Settler - [], - //BOS - [], - //Abomination - [], - //MWBOS - [] -]; +function mojaveOutpost() { -//RIP the filterFactionFunction :( - -//Declaring some stuff to make them global variables -var faction = 0; -let encountered = []; - -//Creates the menu for an encounter. "faction" represents the faction for the encounter, "diffWeighting" changes the odds for -//an encounter's difficulty (1-5) -//IGNORE THE VARIABLE COMMENTS IN THE NESTED SWITCH STATEMENT, they're placeholders for me -function encounterMenuMaker(reqFactionEMM, diffWeightingEMM, forceOptEMM){ - switch(diffWeightingEMM){ - case 1: - reqFactionEMM = encounterDiffOne - break; - case 2: - reqFactionEMM = encounterDiffTwo - break; - case 3: - reqFactionEMM = encounterDiffThree - break; - case 4: - reqFactionEMM = encounterDiffFour - break; - case 5: - reqFactionEMM = encounterDiffFive - break; - } - var encounterDifficulty = (diffWeightingEMM * variables.randomNumber(1, 20)); - factionFailsafe = reqFactionEMM.toLowerCase(); - switch(factionFailsafe){ - case "NCR": - faction = 0; - break; - case "legion": - faction = 1; - break; - case "raider": - faction = 2; - break; - case "settler": - faction = 3; - break; - case "BOS": - faction = 4; - break; - case "abomination": - faction = 5; - break; - case "MWBOS": - faction = 6; - break; - } - if (forceOptEMM == true) { - if(encounterDifficulty <= 20){ - encountered.push(encounterDiffOne[faction][variables.randomNumber(0, encounterDiffOne[faction].length - 1)]); - } else if(21 <= encounterDifficulty <= 40){ - encountered.push(encounterDiffTwo[faction][variables.randomNumber(0, encounterDiffTwo[faction].length - 1)]); - } else if(41 <= encounterDifficulty <= 60){ - encountered.push(encounterDiffThree[faction][variables.randomNumber(0, encounterDiffThree[faction].length - 1)]); - } else if(61 <= encounterDifficulty <= 80){ - encountered.push(encounterDiffFour[faction][variables.randomNumber(0, encounterDiffFour[faction].length - 1)]); - } else { - encountered.push(encounterDiffFive[faction][variables.randomNumber(0, encounterDiffFive[faction].length - 1)]); - } - return encountered[encountered.length - 1]; - } else { - let x = variables.randomNumber(0, 100) - if (x >= 75) { - if (x <=80) { - encountered.push(encounterDiffOne[raider][variables.randomNumber(0, encounterDiffOne[raider].length - 1)]) - } - if (x <=90) { - encountered.push(encounterDiffOne[settler][variables.randomNumber(0, encounterDiffOne[settler].length - 1)]) - } - if (x <=100) { - encountered.push(encounterDiffOne[abomination][variables.randomNumber(0, encounterDiffOne[abomination].length - 1)]) - } - } - if (x < 75) { - encountered.push(encounterDiffOne[faction][variables.randomNumber(0, encounterDiffOne[faction].length - 1)]) - } - } } -var poiCounter = 0; -var pois = [ - {name: "Whitespring Bunker", location: 25, path: 0}, - {name: "BOS Bunker Gamma", location: 100, path: 0}, - {name: "BOS Bunker Delta", location: 125, path: 0}, - {name: "BOS Bunker Epsilon", location: 175, path: 0}, - {name: "Vault 0", location: 200, path: 0}, - {name: "Tibbets Prison", location: 250, path: 0}, - {name: "Flagstaff", location: 275, path: 0}, - {name: "New Vegas", location: 300, path: 0}, - {name: "Mojave Outpost", location: 5, path: 1}, - {name: "Necropolis", location: 10, path: 1}, - {name: "The Hub", location: 15, path: 1}, - {name: "Lost Hills", location: 20, path: 1}, - {name: "Mariposa MB", location: 30, path: 1}, - {name: "San Franciso", location: 35, path: 1}, - {name: "Camp Navarro", location: 45, path: 1}, - {name: "Canyon Wreckage", location: 5, path: 2}, - {name: "Hopeville & Ashton", location: 15, path: 2}, - {name: "The Sierra Madre", location: 25, path: 2}, - {name: "Shady Sands", location: 35, path: 2}, - {name: "New Reno", location: 55, path: 2}, - {name: "Redding", location: 75, path: 2}, - {name: "Eureka", location: 85, path: 2}, - {name: "Camp Navarro", location: 100, path: 2}, -] \ No newline at end of file +function necropolis() { + +} + +function hub() { + +} + +function lostHills() { + +} + +function mariposa() { + +} + +function sanFrancisco() { + +} + +function canyonWreck() { + +} + +function hopeville() { + +} + +function sierraMadre() { + +} + +function shadySands() { + +} + +function newReno() { + +} + +function redding() { + +} + +function eureka() { + +} + +function navarro() { + +} \ No newline at end of file diff --git a/files/rivercrossing.js b/files/rivercrossing.js deleted file mode 100644 index 974e563..0000000 --- a/files/rivercrossing.js +++ /dev/null @@ -1,2 +0,0 @@ -// River crossing screens and options. -const variables = require("./variables.js"); diff --git a/files/shops.js b/files/shops.js index 98c7559..a76fb32 100644 --- a/files/shops.js +++ b/files/shops.js @@ -1,13 +1,6 @@ -const readline = require('readline-sync'); -const variables = require("./variables.js"); +import { randomNumber } from "./functions.js"; +import {} from "./variables.js"; -module.exports = { - ravenRock, - vaultZero, - newVegas, - eureka, - trader, -} // Inventories for the various shops var rrInv = []; @@ -35,7 +28,7 @@ function eureka() { function trader() { // Picks a selection of items from a global trader inventory var tempTraderInv = []; for (var a = 0; a <= 2; a++) { - let randomPick = Math.m + let randomPick = randomNumber() tempTraderInv.push(traderInv[1]); console.log(randomPick); } diff --git a/files/variables.js b/files/variables.js index f8a1e5a..bd226f7 100644 --- a/files/variables.js +++ b/files/variables.js @@ -1,100 +1,39 @@ -// Holds the global variables and useful functions such as userInput -const readline = require('readline-sync'); +// Now holds only variables -module.exports = { // Lets variables and functions be used in other files - day, - location, - ammo, - food, - foodAmt, - health, - travelSpeed, - isRadiated, - radSeverity, - isSick, - sickSeverity, - inventory, - name, - prewarmoney, - caps, - locationA, - locationB, - sleep, - userInput, - randomNumber, -}; +// Player Currency +export var prewarmoney = 0; // Used with enclave vendors +export var caps = 0; // Used with all other vendors -var name = ''; - -var prewarmoney = 0; // Used in Enclave Stores - -var caps = 0; // Used everywhere - -var day = 0; // Should we add a definite end? 365 Days? - -var location = 0; // Location in the world, 0 is Raven Rock, 255 is New Vegas -var locationA = 0; // Location on path A, -var locationB = 0; // Location on path B, 225 is Navarro - -var ammo = 0; // Used in encounters and hunting, No cap :) - -var food = 0; // Max: 200 -var foodAmt = 0; // Amt of food eaten per day, 3 levels, starting at 1 - -var health = 0; // Max: 100 - -var travelSpeed = 0; // Location points per day, 3 levels, starting at 1 - -var isRadiated = false; -var radSeverity = 0; // Modifies many things, 3 levels, starting at 1 - -var isSick = false; -var sickPoints = 0; // If you accumulate 50 sick points you lose -var sickSeverity = 0; // 3 levls, starting at 1 - -var sleepVar = 0; // Placeholder variable that allows sleep() to run a command without changing/printing somthing - -/* - 1 - Villified - Will attack you at all POIs and encounters - 2 - Hated - Will only attack you in major POIs - 3 - Disliked - Will not engage in combat and will not allow you to trade - 4 - Neutral - Can trade - 5 - Good - Will offer assistance and minor discounts when trading - 6 - Liked - Better discounts and assistance, faction bonus - 7 - Idolized - Gives faction bonus and severe discounts when trading, underarmor - - Faction bonuses - * MW BOS - X-01 PA - * Legion - The Mark of Caesar, show to frumentari in locations to recieve gear - * NCR - NCR Emergency 2-Way radio, recieve supply drop when in NCR territory. Useable 3 times - * BOS - X-01 upgrade to tesla - * Enclave - X-01 upgrade to APA -*/ -var reputation = {mwbos: 4, legion: 4, ncr: 2, bos: 1, enclave: 10, abomination: 0, raider: 0} //Number between 0(worst) and 10(best), 5 is neutral - -//Player inventory -//Record all items in the player's inventory as objects with a name, item category, value, and boolean properties. Example below. -//{name: "example", category: "testItems", value: 300, use: true, eat: false, drop: true, equip: true} -var inventory = [ - //Supplies +// Player Stats +export var healthCap = 0; // Maximum health, raises each level +export var health = 0; // Players current HP +export var food = 0; // Amount of food player has +export var isRadiated = false; +export var radSeverity = 0; // Modifies healthCapCalc. 3 Levels +export var radPoints = 0; // If the player reaches 100 rad points the game ends +export var xpPerLevel = 10; // Amount of XP needed per level. Raises 50% each level +export var level = 0; // Level of player. Modifies enemy scaling +export var inventory = [ // Inventory of player, holds all items + // Supplies: chems, aid [], - //Equipment + // Equipment: weapons, armor, tools [] -]; +] -var lootTables = [[],[],[],[],[]] // Only small things like food and ammo, 5 Loot tables per scavenge score, 3 items in each, first is best +// Game Mechanics +export var walkRate = 0; // Units the player walks per day, affects foodRateCalc and radPointsCalc +export var foodRate = 0; // Amount of food player eats per day, affects radPointsCalc -var daysSinceScav = 0; // Days since your last scavenge, you must wait 15 days before scavenging again. +export var path = 0; // Path player is currently on, 0 = Main, 1 = A, 2 = B +export var location = 0; // Location on main path, 0-255 = main, 500-1000 = A, 1500-2000 = B +export var locationA = 0; // Location on path A +export var locationB =0; // Location on path B + +export var reputation = {mwbos: 4, legion: 4, ncr: 2, bos: 1, enclave: 10, abomination: 0, raider: 0} + // Rep for each faction. Number between 0(worst) and 10(best), 5 is neutral + +export var daysSinceScav = 0; // Days since player last scavenged. Must be >= 15 to scavenge again. + +export var name = "placeholder"; // Player name, changed when the game starts -function userInput(question) { // Basic user input functions, takes in the question to be asked. - let answer = readline.question(question); - return(answer); -} -function randomNumber(min, max) { // Takes in two parameters, min and max, and returns a random number between those boundries. - while (true) { - var randNum = Math.floor(Math.random() * (max+1)) - if (randNum >= min) { break; } - } - return randNum; -} \ No newline at end of file From 7846f80f11a307629753dd4b280a4bab90504b84 Mon Sep 17 00:00:00 2001 From: Raktbastr Date: Thu, 3 Apr 2025 11:23:51 -0500 Subject: [PATCH 12/27] We can finally rest... --- files/functions.js | 9 ++++++--- files/main.js | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/files/functions.js b/files/functions.js index c96da68..e7632f9 100644 --- a/files/functions.js +++ b/files/functions.js @@ -2,7 +2,7 @@ import { createRequire } from 'module'; const require = createRequire(import.meta.url); var readlineSync = require('readline-sync'); - +const { exec } = require("child_process"); import { food, foodRate, health, healthCap, locationA, locationB, name, radPoints, radSeverity, walkRate } from "./variables.js"; @@ -82,6 +82,11 @@ export function calcLocation() { } } + +export function sleep(time) { + exec("sleep "+time); +} + function death() { let random = variables.randomNumber(1,3); if (random = 1) { deathScreen1(); } @@ -101,8 +106,6 @@ function death3() { } - - function timeDeath() { // The death screen for passing the time limit console.clear; console.log("Your PIP-Boy starts ringing...\n\n") diff --git a/files/main.js b/files/main.js index 0dd5252..79ebc19 100644 --- a/files/main.js +++ b/files/main.js @@ -1,5 +1,5 @@ // Program is started from here, runs functions from other files. -import { userInput, calcLocation, radPointsCalc, healthCapCalc, checkLose } from './functions.js'; +import { userInput, calcLocation, radPointsCalc, healthCapCalc, checkLose, sleep } from './functions.js'; import { pois, poiCounter } from './poiscreens.js'; import { name, prewarmoney } from './variables.js'; @@ -34,7 +34,7 @@ switch(mainMenuInput) { console.log("Quitting Game..."); break; case "4": - console.log(pois[poiCounter]); + sleep(5); break; } From 6714250079f79b8bc7e0ae859e8954a182cc45a5 Mon Sep 17 00:00:00 2001 From: Raktbastr Date: Thu, 3 Apr 2025 12:15:48 -0500 Subject: [PATCH 13/27] variablefilevariablechangefunction --- files/main.js | 7 ++++--- files/variables.js | 10 +++++++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/files/main.js b/files/main.js index 79ebc19..0665ef2 100644 --- a/files/main.js +++ b/files/main.js @@ -1,7 +1,7 @@ // Program is started from here, runs functions from other files. import { userInput, calcLocation, radPointsCalc, healthCapCalc, checkLose, sleep } from './functions.js'; import { pois, poiCounter } from './poiscreens.js'; -import { name, prewarmoney } from './variables.js'; +import { name, prewarmoney, variableChange } from './variables.js'; console.clear(); @@ -34,13 +34,14 @@ switch(mainMenuInput) { console.log("Quitting Game..."); break; case "4": - sleep(5); + variableChange("name","=","finn"); + console.log(name); break; } function startGame() { // So far what I have is filler and testing, feel free to change. console.clear(); - name = userInput("What is your name? "); + variableChange("name","=",userInput("What is your name? ")); console.log(name+" Is now your name...") console.clear(); console.log("Intro:"); diff --git a/files/variables.js b/files/variables.js index bd226f7..e709fbe 100644 --- a/files/variables.js +++ b/files/variables.js @@ -36,4 +36,12 @@ export var daysSinceScav = 0; // Days since player last scavenged. Must be >= 15 export var name = "placeholder"; // Player name, changed when the game starts - +export function variableChange(variable, operation, value) { + switch(operation) { + case "%": global[variable] = global[variable] % value + case "+": global[variable] = global[variable] + value + case "-": global[variable] = global[variable] - value + case "/": global[variable] = global[variable] / value + case "=": global[variable] = value + } +} From dbd27cfa7db3339ef4daba70cc9dd8d6e1cd0202 Mon Sep 17 00:00:00 2001 From: Caroline Foy Date: Sat, 12 Apr 2025 09:38:55 -0500 Subject: [PATCH 14/27] Added a working "forced encounter" function and a yet to be functional natural encounter function. --- files/encounters.js | 334 +++++++++++++++++++++++++------------------- files/main.js | 15 +- 2 files changed, 206 insertions(+), 143 deletions(-) diff --git a/files/encounters.js b/files/encounters.js index 81e7a18..35764d6 100644 --- a/files/encounters.js +++ b/files/encounters.js @@ -2,150 +2,204 @@ import { randomNumber } from "./functions.js"; -export function calcEncounter() { - if (randomNumber(1,100) <= 20) { - if (location >= 255) { - if (locationA > locationB) { - if ((locationA >= 5 && locationA < 17) || (locationA >= 23 && locationA < 40)) { - initializeEncounter(NCR,4,true,true,false); - } - if (locationB >= 40) { - initializeEncounter(NCR,5,true,true,false); - } - } else if (locationA < locationB) { - if ((locationB >= 0 && locationB < 30) || (locationB >= 40 && locationB < 80)) { - initializeEncounter(abomination,3,true,true,false) - } - if ((locationB >= 30 && locationB < 40) || (locationB >= 90)) { - initializeEncounter(NCR,5,true,true,false) - } - if (locationB >= 80 && locationB < 90) { - initializeEncounter(enclave,4,true,true,false) - } - } else { - if (location >= 5 && location < 50) { - initializeEncounter(abomination,1,true,true,false) - } - if (location >= 50 && location < 200) { - initializeEncounter(MWBOS,2,true,true,false) - } - if (location >= 200 && location < 255) { - initializeEncounter(legion,3,true,true,false) - } - } +//5-50 abominations, 51-200 MWBOS, 201-255 legion, a5-a40 NCR, b0-b30 abomination, b40-b80 abomination, b90+ NCR, b80-b90 enclave +//HLE = high level encounter, this is a filter that determines if the player can get, as the name implies, high level encounters +export function naturalEncounter(location){ + var HLE = false; + var encounter = false; + var encounterLuck = randomNumber(1, 100); + if(location > 250){ + HLE = true; + } + if(0 < location <= 5){ + encounter = false; + } else if(5 < location <= 50){ + if(1 <= encounterLuck <= 50){ + encounter = false; + } else if(51 <= encounterLuck <= 80){ + encounter = "abomination"; + } else if(81 <= encounterLuck <= 90){ + encounter = "settler"; + } else if(91 <= encounterLuck <= 100){ + encounter = "MWBOS"; + } + } else if(50 < location <= 200){ + if(1 <= encounterLuck <= 50){ + encounter = false; + } else if(51 <= encounterLuck <= 80){ + encounter = "MWBOS"; + } else if(81 <= encounterLuck <= 95){ + encounter = "settler"; + } else if(96 <= encounterLuck <= 100){ + encounter = "abominaton"; + } + } else if(200 < location <= 255){ + if(1 <= encounterLuck <= 40){ + encounter = false; + } else if(41 <= encounterLuck <= 75){ + encounter = "legion"; + } else if(76 <= encounterLuck <= 90){ + encounter = "abomination"; + } else if(91 <= encounterLuck <= 99){ + encounter = "raider"; + } else if(encounterLuck = 100){ + encounter = "settler"; } } -} -export function encounterMenuMaker(reqFactionEMM, diffWeightingEMM, forceOptEMM){ - switch(diffWeightingEMM){ - case 1: - reqFactionEMM = encounterDiffOne - break; - case 2: - reqFactionEMM = encounterDiffTwo - break; - case 3: - reqFactionEMM = encounterDiffThree - break; - case 4: - reqFactionEMM = encounterDiffFour - break; - case 5: - reqFactionEMM = encounterDiffFive - break; - } - var encounterDifficulty = (diffWeightingEMM * randomNumber(1, 20)); - factionFailsafe = reqFactionEMM.toLowerCase(); - switch(factionFailsafe){ - case "NCR": - faction = 0; - break; - case "legion": - faction = 1; - break; - case "raider": - faction = 2; - break; - case "settler": - faction = 3; - break; - case "BOS": - faction = 4; - break; - case "abomination": - faction = 5; - break; - case "MWBOS": - faction = 6; - break; - } - if (forceOptEMM == true) { - if(encounterDifficulty <= 20){ - encountered.push(encounterDiffOne[faction][randomNumber(0, encounterDiffOne[faction].length - 1)]); - } else if(21 <= encounterDifficulty <= 40){ - encountered.push(encounterDiffTwo[faction][randomNumber(0, encounterDiffTwo[faction].length - 1)]); - } else if(41 <= encounterDifficulty <= 60){ - encountered.push(encounterDiffThree[faction][randomNumber(0, encounterDiffThree[faction].length - 1)]); - } else if(61 <= encounterDifficulty <= 80){ - encountered.push(encounterDiffFour[faction][randomNumber(0, encounterDiffFour[faction].length - 1)]); - } else { - encountered.push(encounterDiffFive[faction][randomNumber(0, encounterDiffFive[faction].length - 1)]); - } - return encountered[encountered.length - 1]; - } else { - let x = randomNumber(0, 100) - if (x >= 75) { - if (x <=80) { - encountered.push(encounterDiffOne[raider][randomNumber(0, encounterDiffOne[raider].length - 1)]) - } - if (x <=90) { - encountered.push(encounterDiffOne[settler][randomNumber(0, encounterDiffOne[settler].length - 1)]) - } - if (x <=100) { - encountered.push(encounterDiffOne[abomination][randomNumber(0, encounterDiffOne[abomination].length - 1)]) - } - } - if (x < 75) { - encountered.push(encounterDiffOne[faction][randomNumber(0, encounterDiffOne[faction].length - 1)]) - } - } -} - -export function initializeEncounter(reqFaction, diffWeighting, fight, flee, forceFaction){ - var encounter = encounterMenuMaker(reqFaction, diffWeighting, forceFaction); - console.clear(); - console.log("You come across a " + encounter.name); - var encounterHealth = randomNumber(encounter.minHealth, encounter.maxHealth); - console.log("Health: " + encounterHealth); - console.log("What would you like to do?"); - console.log("--------------------------"); - var playerOptions = 1; - console.log(playerOptions + ") Inventory"); - playerOptions++ - if(fight == true){ - console.log(playerOptions + ") Fight"); - playerOptions++; - } - if(flee == true){ - console.log(playerOptions + ") Flee"); - playerOptions++; - } - while(true) { - let encounterInput = userInput("Enter: ") - switch(encounterInput) { - case "1": - console.log(inventory); - case "2": - initCombat(encounter); - break; - case "3": - if (reputation.reqFaction < 4) { - if (randomNumber(1,100) < 40){ - console.log("You tried to flee... but they noticed you."); - initCombat(encounter); + if(encounter != false){ + switch(encounter){ + case "abomination": + if(HLE == true){ + switch(randomNumber(1, 2)){ + case 1: + return abominationEncounters[randomNumber(0, abominationEncounters.length-1)]; + case 2: + return HLabominationEncounters[randomNumber(0, HLabominationEncounters.length-1)]; } + } else { + return abominationEncounters[randomNumber(0, abominationEncounters.length-1)]; + } + case "MWBOS": + if(HLE == true){ + switch(randomNumber(1, 2)){ + case 1: + return MWBOSEncounters[randomNumber(0, MWBOSEncounters.length-1)]; + case 2: + return HLMWBOSEncounters[randomNumber(0, HLMWBOSEncounters.length-1)]; + } + } else { + return MWBOSEncounters[randomNumber(0, MWBOSEncounters.length-1)]; + } + case "BOS": + if(HLE == true){ + switch(randomNumber(1, 2)){ + case 1: + return BOSEncounters[randomNumber(0, BOSEncounters.length-1)]; + case 2: + return HLBOSEncounters[randomNumber(0, HLBOSEncounters.length-1)]; + } + } else { + return BOSEncounters[randomNumber(0, BOSEncounters.length-1)]; + } + case "NCR": + if(HLE == true){ + switch(randomNumber(1, 2)){ + case 1: + return NCREncounters[randomNumber(0, NCREncounters.length-1)]; + case 2: + return HLNCREncounters[randomNumber(0, HLNCREncounters.length-1)]; + } + } else { + return NCREncounters[randomNumber(0, NCREncounters.length-1)]; + } + case "legion": + if(HLE == true){ + switch(randomNumber(1, 2)){ + case 1: + return legionEncounters[randomNumber(0, legionEncounters.length-1)]; + case 2: + return HLlegionEncounters[randomNumber(0, HLlegionEncounters.length-1)]; + } + } else { + return legionEncounters[randomNumber(0, legionEncounters.length-1)]; + } + case "settler": + if(HLE == true){ + switch(randomNumber(1, 2)){ + case 1: + return settlerEncounters[randomNumber(0, settlerEncounters.length-1)]; + case 2: + return HLsettlerEncounters[randomNumber(0, HLsettlerEncounters.length-1)]; + } + } else { + return settlerEncounters[randomNumber(0, settlerEncounters.length-1)]; + } + case "raider": + if(HLE == true){ + switch(randomNumber(1, 2)){ + case 1: + return raiderEncounters[randomNumber(0, raiderEncounters.length-1)]; + case 2: + return HLraiderEncounters[randomNumber(0, HLraiderEncounters.length-1)]; + } + } else { + return raiderEncounters[randomNumber(0, raiderEncounters.length-1)]; } } + } else { + return false; } -} \ No newline at end of file +}; + +export function forcedEncounter(HLE, faction, forcedHLE){ + var HLEDeterminant = randomNumber(1, 2) + if((HLE == true && HLEDeterminant == 1) || forcedHLE == true){ + switch (faction){ + case "raider": + return HLraiderEncounters[randomNumber(0, HLraiderEncounters.length-1)]; + case "MWBOS": + return HLMWBOSEncounters[randomNumber(0, HLMWBOSEncounters.length-1)]; + case "BOS": + return HLBOSEncounters[randomNumber(0, HLBOSEncounters.length-1)]; + case "settler": + return HLsettlerEncounters[randomNumber(0, HLsettlerEncounters.length-1)]; + case "abomination": + return HLabominationEncounters[randomNumber(0, HLabominationEncounters.length-1)]; + case "NCR": + return HLNCREncounters[randomNumber(0, HLNCREncounters.length-1)]; + case "legion": + return HLlegionEncounters[randomNumber(0, HLlegionEncounters.length-1)]; + } + } else { + switch (faction){ + case "raider": + return raiderEncounters[randomNumber(0, raiderEncounters.length-1)]; + case "MWBOS": + return MWBOSEncounters[randomNumber(0, MWBOSEncounters.length-1)]; + case "BOS": + return BOSEncounters[randomNumber(0, BOSEncounters.length-1)]; + case "settler": + return settlerEncounters[randomNumber(0, settlerEncounters.length-1)]; + case "abomination": + return abominationEncounters[randomNumber(0, abominationEncounters.length-1)]; + case "NCR": + return NCREncounters[randomNumber(0, NCREncounters.length-1)]; + case "legion": + return legionEncounters[randomNumber(0, legionEncounters.length-1)]; + } + } +} + +var raiderEncounters = [ + {name: "Raider Aspirant", faction: "raider", minLevel: 5, maxLevel: 15, damageClass: "B", minDamage: 5, maxDamage: 10} +]; +var HLraiderEncounters = [ +]; +var MWBOSEncounters = [ + {name: "MWBOS Paladin", faction: "MWBOS", minLevel: 40, maxLevel: 65, damageClass: "E", minDamage: 5, maxDamage: 40} +]; +var HLMWBOSEncounters = [ +]; +var abominationEncounters = [ + {name: "Deathclaw", faction: "abomination", minLevel: 50, maxLevel: 100, damageClass: "B", minDamage: 35, maxDamage: 75} +]; +var HLabominationEncounters = [ +]; +var NCREncounters = [ +]; +var HLNCREncounters = [ +]; +var BOSEncounters = [ +]; +var HLBOSEncounters = [ +]; +var settlerEncounters = [ + {name: "John Settler", faction: "settler", minLevel: 1, maxLevel: 2, damageClass: "B", minDamage: 1, maxDamage: 2} +]; +var HLsettlerEncounters = [ +]; +var legionEncounters = [ +]; +var HLlegionEncounters = [ +]; \ No newline at end of file diff --git a/files/main.js b/files/main.js index 0665ef2..0602886 100644 --- a/files/main.js +++ b/files/main.js @@ -1,7 +1,8 @@ // Program is started from here, runs functions from other files. -import { userInput, calcLocation, radPointsCalc, healthCapCalc, checkLose, sleep } from './functions.js'; +import { userInput, calcLocation, radPointsCalc, healthCapCalc, checkLose, sleep, randomNumber } from './functions.js'; import { pois, poiCounter } from './poiscreens.js'; import { name, prewarmoney, variableChange } from './variables.js'; +import { forcedEncounter, naturalEncounter } from './encounters.js'; console.clear(); @@ -13,6 +14,8 @@ console.log(" / / ) / / / ) / / / o / / ) / ) console.log("_/________(___(_/___/___(___/_(___(__(_ __o_____/____/_(___/_/___/_(___ _(__)_(___/_/_/__/_(___ _____/_____|__(___/_(___(_(___/___"); console.log("Credits: Bethesda Game Studio \n"); +sleep(5); + console.log("What would you like to do?"); console.log("--------------------------"); console.log("1) Start new game"); @@ -34,8 +37,14 @@ switch(mainMenuInput) { console.log("Quitting Game..."); break; case "4": - variableChange("name","=","finn"); - console.log(name); + for(var a = 0; a < 10; a++){ + var test = naturalEncounter(25); + if(test != false){ + console.log(test.name); + } else { + console.log("failed encounter"); + } + } break; } From fdd58af63ecc2882c0e002874f56909abada4215 Mon Sep 17 00:00:00 2001 From: Raktbastr Date: Sun, 6 Apr 2025 09:28:09 -0500 Subject: [PATCH 15/27] Fixed sleep function issue and writing to global variables. --- files/functions.js | 13 +++++++++---- files/main.js | 9 +++++---- files/poiscreens.js | 6 +++--- files/variables.js | 40 ++++++++++++++++++++-------------------- 4 files changed, 37 insertions(+), 31 deletions(-) diff --git a/files/functions.js b/files/functions.js index e7632f9..70fd95c 100644 --- a/files/functions.js +++ b/files/functions.js @@ -3,8 +3,10 @@ import { createRequire } from 'module'; const require = createRequire(import.meta.url); var readlineSync = require('readline-sync'); const { exec } = require("child_process"); +import { promisify } from "util"; +const execPromise = promisify(exec); + -import { food, foodRate, health, healthCap, locationA, locationB, name, radPoints, radSeverity, walkRate } from "./variables.js"; // Used for basic functions, not game specific export function userInput(question) { // Basic user input functions, takes in the question to be asked. @@ -82,9 +84,12 @@ export function calcLocation() { } } - -export function sleep(time) { - exec("sleep "+time); +export async function sleep(time) { + try { + await execPromise(`sleep ${time}`); + } catch (error) { + console.error("Error executing sleep command:", error); + } } function death() { diff --git a/files/main.js b/files/main.js index 0602886..fd53310 100644 --- a/files/main.js +++ b/files/main.js @@ -21,9 +21,9 @@ console.log("--------------------------"); console.log("1) Start new game"); console.log("2) Learn How to play"); console.log("3) Quit Game"); -console.log("4) Dev stuff for testing"); +console.log("4) Dev stuff for testing\n"); -var mainMenuInput = userInput("Enter: ") +var mainMenuInput = userInput("Enter: "); switch(mainMenuInput) { case "1": @@ -35,6 +35,7 @@ switch(mainMenuInput) { break; case "3": console.log("Quitting Game..."); + await sleep(1); break; case "4": for(var a = 0; a < 10; a++){ @@ -50,14 +51,14 @@ switch(mainMenuInput) { function startGame() { // So far what I have is filler and testing, feel free to change. console.clear(); - variableChange("name","=",userInput("What is your name? ")); + name = userInput("What is your name? "); console.log(name+" Is now your name...") console.clear(); console.log("Intro:"); console.log("You are an ordinary loyal Enclave Soldier working at Raven Rock. \nYou are typing away at your terminal, entering reports of recovered materials when a message flashes on it"); console.log("|||||||") console.log("|| Enclave Intranet Messager"); - console.log("") + console.log("|||||||") console.log("|| Message From: potus"); console.log("|||||||\n\n") console.log("Dear "+name+",\n\n This is a direct order from the Enclave High Command. \nIgnore all previous directives. Proceed to Camp Navarro immediately. \nSeek safe passage through the Brotherhood and NCR territories. \nDo not disclose your mission to anyone but Enclave Personel with \nsecurity clearance 5 or higher. Reqisition supplies before departure. \nYou have been given 1 YEAR to complete this mission or face discharge.\n\n Signed, President John Henry Eden\n\n"); diff --git a/files/poiscreens.js b/files/poiscreens.js index 6ebbd87..474cf45 100644 --- a/files/poiscreens.js +++ b/files/poiscreens.js @@ -1,7 +1,7 @@ // Holds poi code, seperate from encounters.js import { userInput } from "./functions.js"; -import { location, locationA, locationB, path } from "./variables.js"; +import './variables.js'; export function checkPOI() { if (path == 0) { @@ -91,8 +91,8 @@ export function checkPOI() { } } -export var poiCounter = 0; -export var pois = [ +global.poiCounter = 0; +global.pois = [ {name: "Whitespring Bunker", location: 25, path: 0, visited: false}, {name: "BOS Bunker Gamma", location: 100, path: 0, visited: false}, {name: "BOS Bunker Delta", location: 125, path: 0, visited: false}, diff --git a/files/variables.js b/files/variables.js index e709fbe..a439559 100644 --- a/files/variables.js +++ b/files/variables.js @@ -1,19 +1,19 @@ // Now holds only variables // Player Currency -export var prewarmoney = 0; // Used with enclave vendors -export var caps = 0; // Used with all other vendors +global.prewarmoney = 0; // Used with enclave vendors +global.caps = 0; // Used with all other vendors // Player Stats -export var healthCap = 0; // Maximum health, raises each level -export var health = 0; // Players current HP -export var food = 0; // Amount of food player has -export var isRadiated = false; -export var radSeverity = 0; // Modifies healthCapCalc. 3 Levels -export var radPoints = 0; // If the player reaches 100 rad points the game ends -export var xpPerLevel = 10; // Amount of XP needed per level. Raises 50% each level -export var level = 0; // Level of player. Modifies enemy scaling -export var inventory = [ // Inventory of player, holds all items +global.healthCap = 0; // Maximum health, raises each level +global.health = 0; // Players current HP +global.food = 0; // Amount of food player has +global.isRadiated = false; +global.radSeverity = 0; // Modifies healthCapCalc. 3 Levels +global.radPoints = 0; // If the player reaches 100 rad points the game ends +global.xpPerLevel = 10; // Amount of XP needed per level. Raises 50% each level +global.level = 0; // Level of player. Modifies enemy scaling +global.inventory = [ // Inventory of player, holds all items // Supplies: chems, aid [], // Equipment: weapons, armor, tools @@ -21,20 +21,20 @@ export var inventory = [ // Inventory of player, holds all items ] // Game Mechanics -export var walkRate = 0; // Units the player walks per day, affects foodRateCalc and radPointsCalc -export var foodRate = 0; // Amount of food player eats per day, affects radPointsCalc +global.walkRate = 0; // Units the player walks per day, affects foodRateCalc and radPointsCalc +global.foodRate = 0; // Amount of food player eats per day, affects radPointsCalc -export var path = 0; // Path player is currently on, 0 = Main, 1 = A, 2 = B -export var location = 0; // Location on main path, 0-255 = main, 500-1000 = A, 1500-2000 = B -export var locationA = 0; // Location on path A -export var locationB =0; // Location on path B +global.path = 0; // Path player is currently on, 0 = Main, 1 = A, 2 = B +global.location = 0; // Location on main path, 0-255 = main, 500-1000 = A, 1500-2000 = B +global.locationA = 0; // Location on path A +global.locationB =0; // Location on path B -export var reputation = {mwbos: 4, legion: 4, ncr: 2, bos: 1, enclave: 10, abomination: 0, raider: 0} +global.reputation = {mwbos: 4, legion: 4, ncr: 2, bos: 1, enclave: 10, abomination: 0, raider: 0} // Rep for each faction. Number between 0(worst) and 10(best), 5 is neutral -export var daysSinceScav = 0; // Days since player last scavenged. Must be >= 15 to scavenge again. +global.daysSinceScav = 0; // Days since player last scavenged. Must be >= 15 to scavenge again. -export var name = "placeholder"; // Player name, changed when the game starts +global.name = "placeholder"; // Player name, changed when the game starts export function variableChange(variable, operation, value) { switch(operation) { From 82565a2be9883868aab24f8f7ab21553f98e1d08 Mon Sep 17 00:00:00 2001 From: Raktbastr Date: Mon, 14 Apr 2025 11:37:22 -0500 Subject: [PATCH 16/27] A lot, i dont rembr --- files/functions.js | 249 ++++++++++++++++++++++++++++++++++++++++++-- files/inventory.js | 8 +- files/main.js | 26 +++-- files/poiscreens.js | 24 ++++- files/shops.js | 245 ++++++++++++++++++++++++++++++++++++++++--- files/variables.js | 40 +++++-- 6 files changed, 547 insertions(+), 45 deletions(-) diff --git a/files/functions.js b/files/functions.js index 70fd95c..9780f00 100644 --- a/files/functions.js +++ b/files/functions.js @@ -5,6 +5,11 @@ var readlineSync = require('readline-sync'); const { exec } = require("child_process"); import { promisify } from "util"; const execPromise = promisify(exec); +import './variables.js'; +import { inventoryMenuM } from './inventory.js'; +import { checkPOI } from './poiscreens.js'; + +global.isRawModeEnabled = false; // Track whether raw mode is enabled @@ -30,12 +35,14 @@ export function healthCapCalc() { // Calculates HP cap given current radPoints } export function radPointsCalc() { // Calculates radPoints given walk/foodrate - radPoints = radPoints + 0.5 * (radSeverity * 10 + 5 * (walkRate + foodRate)) + if (isRadiated == true) { + radPoints = radPoints + 0.5 * (radSeverity * 10 + 5 * (walkRate + foodRate)); + } } export function eatFood() { // Calculates food amount after a day of eating if (food == 0) { - health = health - 3*walkRate + health = health - 0.25*walkRate } else { food = food - walkRate * foodRate } @@ -93,10 +100,10 @@ export async function sleep(time) { } function death() { - let random = variables.randomNumber(1,3); - if (random = 1) { deathScreen1(); } - if (random = 2) { deathScreen2(); } - if (random = 3) { deathScreen3(); } + let random = randomNumber(1,3); + if (random = 1) { death1(); } + if (random = 2) { death2(); } + if (random = 3) { death3(); } } function death1() { @@ -127,4 +134,234 @@ function timeDeath() { // The death screen for passing the time limit console.log("Please return to the nearest active Enclave Military Installation immeditely\n\n"); console.log("Signed, Enclave Internal Messager"); console.clear; +} + +var travelFrame = 0; + + + +export function travelScreen() { + if (travelFrame < 0 || travelFrame > 3) { + travelFrame = 0; + } else if (travelFrame == 0) { + console.clear(); + console.log("┌──────────────────────────────────────┐"); + console.log("│ │"); + console.log("│ │"); + console.log("│ │"); + console.log("│ │"); + console.log("│ ◜─◝ │"); + console.log("│ ◟_◞ │"); + console.log("│ /║\\ │"); + console.log("│ \\V/ │"); + console.log("│ / \\ │"); + console.log("│ ▁\\ ▔╹ │"); + console.log("│======================================│"); + console.log("│ . . - . . - . . . - │"); + console.log("│ - . . . . . . - . .│"); + console.log("└──────────────────────────────────────┘"); + console.log("Press [ENTER] to open Pip-Boy"); + console.log("Current Health: "+health); + console.log("Food Amt: "+food); + console.log("Distance to next POI: "); + travelFrame++ + } else if (travelFrame == 1) { + console.clear(); + console.log("┌──────────────────────────────────────┐"); + console.log("│ │"); + console.log("│ │"); + console.log("│ │"); + console.log("│ │"); + console.log("│ ◜─◝ │"); + console.log("│ ◟_◞ │"); + console.log("│ /║\\ │"); + console.log("│ \\V/ │"); + console.log("│ \\ │"); + console.log("│ ▁│▔╹ │"); + console.log("│======================================│"); + console.log("│ - . - . . . - . - . │"); + console.log("│ - . . - . . . - .│"); + console.log("└──────────────────────────────────────┘"); + console.log("Press [ENTER] to open Pip-Boy"); + console.log("Current Health: "+health); + console.log("Food Amt: "+food); + console.log("Distance to next POI: "); + travelFrame++ + } else if (travelFrame == 2) { + console.clear(); + console.log("┌──────────────────────────────────────┐"); + console.log("│ │"); + console.log("│ │"); + console.log("│ │"); + console.log("│ │"); + console.log("│ ◜─◝ │"); + console.log("│ ◟_◞ │"); + console.log("│ /║\\ │"); + console.log("│ \\V/ │"); + console.log("│ ╳ │"); + console.log("│ _/_\\ │"); + console.log("│======================================│"); + console.log("│ - . - . . . - . - . │"); + console.log("│ - . . - . . . - .│"); + console.log("└──────────────────────────────────────┘"); + console.log("Press [ENTER] to open Pip-Boy"); + console.log("Current Health: "+health); + console.log("Food Amt: "+food); + console.log("Distance to next POI: "); + travelFrame++ + } else if (travelFrame == 3) { + console.clear(); + console.log("┌──────────────────────────────────────┐"); + console.log("│ │"); + console.log("│ │"); + console.log("│ │"); + console.log("│ │"); + console.log("│ ◜─◝ │"); + console.log("│ ◟_◞ │"); + console.log("│ /║\\ │"); + console.log("│ \\V/ │"); + console.log("│ \\ │"); + console.log("│ ▁│▔╹ │"); + console.log("│======================================│"); + console.log("│ - . - . . . - . - . │"); + console.log("│ - . . - . . . - .│"); + console.log("└──────────────────────────────────────┘"); + console.log("Press [ENTER] to open Pip-Boy"); + console.log("Current Health: "+health); + console.log("Food Amt: "+food); + console.log("Distance to next POI: "); + travelFrame=0; + } +} + +export async function walkPathA() { + enableRawMode(); + if (paused) { + disableRawMode(); + pauseScreen(); + enableRawMode(); + } + + if (location > 255) { + disableRawMode(); + return; + } + calcLocation(); + radPointsCalc(); + healthCapCalc(); + checkLose(); + travelScreen(); + checkPOI(); + eatFood(); + //await sleep(0.5); + walkPathA(); +} + +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 + } +}); + +export function enableRawMode() { + if (!isRawModeEnabled) { + process.stdin.setRawMode(true); + process.stdin.resume(); + isRawModeEnabled = true; + } +} + +export function disableRawMode() { + if (isRawModeEnabled) { + process.stdin.setRawMode(false); + process.stdin.pause(); + isRawModeEnabled = false; + } +} + +var paused = false; +export function pauseScreen() { + console.clear(); + console.log ("What would you like to do?"); + console.log ("--------------------------"); + console.log ("1) Resume"); + console.log ("2) View Inventory"); + console.log ("3) View Distances"); + console.log ("4) View Stats"); + console.log ("5) Scavenge"); + let pauseInput = userInput("Enter: "); + switch(pauseInput) { + case "1": + paused = false; + break; + case "2": + inventoryMenuM(); + break; + case "3": + console.clear(); + console.log("Current Location: "+location); + if (path == 0) { + console.log("Current Path: Main"); + } + if (path == 1) { + console.log("Current Path: A (Southern)"); + } + if (path == 2) { + console.log("Current Path: B (Northern)"); + } + console.log("------------------------"); + for (let i = 0; i < 7; i++) { + if (pois[i].visited == true) { + console.log(pois[i].name+" - "+visited[i]); + } + if (pois[i].visited == false) { + console.log("??? "+pois[i].location-location+" location points away"); + } + } + if (path == 1) { + for (let i = poiCounter; i < 14; i++) { + if (pois[i].visited == true) { + console.log(pois[i].name+" - "+visited[i]); + } + if (pois[i].visited == false) { + console.log("??? "+pois[i].location-location+" location points away"); + } + } + } + if (path == 2) { + for (let i = poiCounter; i < pois.length; i++) { + if (pois[i].visited == true) { + console.log(pois[i].name+" - "+visited[i]); + } + if (pois[i].visited == false) { + console.log("??? "+pois[i].location-location+" location points away"); + } + } + } + userInput("\n[Press Enter to return]"); + break; + case "4": + 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("Current Location: "+location); + console.log("Current Path: "+path); + userInput("\n[Press Enter to return]"); + break; + case "5": + scavenge(); + break; + } } \ No newline at end of file diff --git a/files/inventory.js b/files/inventory.js index 51bc179..7f4c2cf 100644 --- a/files/inventory.js +++ b/files/inventory.js @@ -1,14 +1,14 @@ import { userInput } from "./functions.js"; -import { inventory, userInput } from "./variables.js"; +import "./variables.js"; //Builds the main menu inventory -function inventoryMenuM(){ +export function inventoryMenuM(){ console.clear(); console.log("INVENTORY"); console.log("---------"); console.log("1) Supplies"); console.log("2) Equipment"); - console.log("[spacebar to exit]"); + console.log("3) Exit"); let invChoice = userInput("Enter: "); switch(userInput){ case "1": @@ -17,6 +17,8 @@ function inventoryMenuM(){ case "2": equipmentInventory(); break; + case "3": + break; } } diff --git a/files/main.js b/files/main.js index fd53310..95e9c06 100644 --- a/files/main.js +++ b/files/main.js @@ -5,6 +5,7 @@ import { name, prewarmoney, variableChange } from './variables.js'; import { forcedEncounter, naturalEncounter } from './encounters.js'; +disableRawMode(); console.clear(); console.log("__________________________________________________________________________________________________________________________________"); console.log(" _____ _ ____ "); @@ -66,12 +67,19 @@ function startGame() { // So far what I have is filler and testing, feel free to userInput("[Enter to open shop]"); console.clear(); - prewarmoney = 500; - ravenRockShop(); - for (variables.location = 0; variables.location <= 255; variables.location++) { - calcLocation(); - radPointsCalc(); - healthCapCalc - checkLose(); - } -} \ No newline at end of file + preWarMoney = 500; + caps = 0; + level = 1; + health = 100; + healthCap = 100; + walkRate = 1; + foodRate = 1; + food = 0; + radPoints = 0; + path = 0; + location = 0; + locationA = 0; + locationB = 0; + ravenRockStore(); + walkPathA(0); +} diff --git a/files/poiscreens.js b/files/poiscreens.js index 474cf45..c13deb1 100644 --- a/files/poiscreens.js +++ b/files/poiscreens.js @@ -1,6 +1,6 @@ // Holds poi code, seperate from encounters.js -import { userInput } from "./functions.js"; +import { userInput, pauseScreen } from "./functions.js"; import './variables.js'; export function checkPOI() { @@ -119,7 +119,27 @@ global.pois = [ ] function whitespring() { - + console.clear(); + console.log("You have arrived at the Whitespring Bunker."); + console.log("What would you like to do?"); + console.log("1) Explore"); + console.log("2) Attempt to trade"); + console.log("3) Open your PIP-Boy"); + console.log("4) Leave"); + let whitespringInput = userInput("Enter: "); + switch(whitespringInput) { + case "1": + console.clear(); + console.log("A robotic voice greets you."); + console.log("MODUS Dialogue here...") + break; + case "2": + whitespringStore(); + case "3": + pauseScreen(); + case "4": + break; + } } function bosGamma() { diff --git a/files/shops.js b/files/shops.js index a76fb32..03f27fa 100644 --- a/files/shops.js +++ b/files/shops.js @@ -1,31 +1,203 @@ -import { randomNumber } from "./functions.js"; -import {} from "./variables.js"; +import { randomNumber, userInput } from "./functions.js"; +import "./variables.js"; - -// Inventories for the various shops -var rrInv = []; +// Inventories for the various shops, based of global item lists +// Most item prices in Raven Rock and Eureka are multiplied by 10, as they are using pre-war money +var rrInv = [ + {item: supplyList[0], name: supplyList[0].name, price: supplyList[0].cost, amount: 1000}, + {item: supplyList[1], name: supplyList[1].name, price: supplyList[1].cost*10, amount: 100}, + {item: supplyList[2], name: supplyList[2].name, price: supplyList[2].cost*10, amount: 100}, + {item: supplyList[3], name: supplyList[3].name, price: supplyList[3].cost*10, amount: 100}, + {item: equipmentList[0], name: equipmentList[0].name, price: equipmentList[0].cost*10, amount: 10}, + {item: equipmentList[2], name: equipmentList[2].name, price: equipmentList[1].cost*10, amount: 10}, + {item: equipmentList[8], name: equipmentList[8].name, price: equipmentList[2].cost*10, amount: 10}, +]; var vt0Inv = []; var vegasInv = []; // A mix of gunrunners, mick&ralphs, and followers var eurInv = []; -var traderInv = ["gun", "stimpak", "radx"]; +var traderInv = []; -function ravenRock() { - // purchasing code +export function ravenRockStore() { + while (true) { + console.clear(); + console.log("Welcome to Raven Rock. Requisition supplies before heading out."); + console.log("Name | Price (PW Money) | Amount in stock"); + console.log("-----------------------------------------------------"); + for (var i = 0; i < rrInv.length; i++) { + console.log(i+"). " + rrInv[i].name + " | " + rrInv[i].price + " | " + rrInv[i].amount); + } + console.log("-----------------------------------------------------"); + console.log("You have " + preWarMoney + " pre-war money."); + console.log("What would you like to do?"); + console.log("1) Buy supplies"); + console.log("2) Leave shop"); + var rrInput = userInput("Enter: "); + switch(rrInput) { + case "1": + console.log("What would you like to buy?"); + let itemNum = userInput("Enter item number: "); + let itemAmt = userInput("Enter amount: "); + if (itemAmt > rrInv[itemNum].amount) { + console.log("Not enough stock."); + userInput("[Enter]"); + break; + } else if (itemAmt * rrInv[itemNum].price > preWarMoney) { + console.log("Not enough money."); + userInput("[Enter]"); + break; + } else { + preWarMoney -= itemAmt * rrInv[itemNum].price; + rrInv[itemNum].amount -= itemAmt; + console.log("You bought " + itemAmt + " " + rrInv[itemNum].name + "(s)."); + console.log("You have " + preWarMoney + " pre-war money left."); + console.log("Press enter to continue..."); + userInput("[Enter]"); + } + break; + case "2": + console.log("Leaving shop..."); + return true; + break; + default: + console.log("Invalid input, try again."); + } + } } -function vaultZero() { - // purchasing code +function vaultZeroStore() { + while (true) { + console.clear(); + console.log("Brotherhood of Steel Requisition System - Vault 0"); + console.log("Name | Price (Caps) | Amount in stock"); + console.log("-----------------------------------------------------"); + for (var i = 0; i < vt0InvInv.length; i++) { + console.log(i+"). " + vt0InvInv[i].item + " | " + vtInv[i].price + " | " + vtInv[i].amount); + } + console.log("-----------------------------------------------------"); + console.log("You have " + caps + " caps."); + console.log("What would you like to do?"); + console.log("1) Buy supplies"); + console.log("2) Leave shop"); + var vt0Input = userInput("Enter: "); + switch(vt0Input) { + case "1": + console.log("What would you like to buy?"); + let itemNum = userInput("Enter item number: "); + let itemAmt = userInput("Enter amount: "); + if (itemAmt > vt0Inv[itemNum].amount) { + console.log("Not enough stock."); + break; + } else if (itemAmt * vt0Inv[itemNum].price > caps) { + console.log("Not enough money."); + break; + } else { + caps -= itemAmt * vt0Inv[itemNum].price; + rrInv[itemNum].amount -= itemAmt; + console.log("You bought " + itemAmt + " " + vt0Inv[itemNum].item + "(s)."); + console.log("You have " + caps + " caps left."); + console.log("Press enter to continue..."); + userInput("[Enter]"); + } + break; + case "2": + console.log("Leaving shop..."); + return true; + default: + console.log("Invalid input, try again."); + } + } } -function newVegas() { - // purchasing code +function newVegasStore() { + while (true) { + console.clear(); + console.log("Welcome to New Vegas. Selection pulls from Gunrunners, Mick & Ralph's, and Followers of the Apocalypse."); + console.log("Name | Price (Caps) | Amount in stock"); + console.log("-----------------------------------------------------"); + for (var i = 0; i < vegasInv.length; i++) { + console.log(i+"). " + vegasInv[i].item + " | " + vegasInv[i].price + " | " + vegasInv[i].amount); + } + console.log("-----------------------------------------------------"); + console.log("You have " + caps + " caps."); + console.log("What would you like to do?"); + console.log("1) Buy supplies"); + console.log("2) Leave shop"); + var nvInput = userInput("Enter: "); + switch(nvInput) { + case "1": + console.log("What would you like to buy?"); + let itemNum = userInput("Enter item number: "); + let itemAmt = userInput("Enter amount: "); + if (itemAmt > vegasInv[itemNum].amount) { + console.log("Not enough stock."); + break; + } else if (itemAmt * vegasInv[itemNum].price > preWarMoney) { + console.log("Not enough money."); + break; + } else { + preWarMoney -= itemAmt * vegasInv[itemNum].price; + vegasInv[itemNum].amount -= itemAmt; + console.log("You bought " + itemAmt + " " + vegasInv[itemNum].item + "(s)."); + console.log("You have " + caps + " caps left."); + console.log("Press enter to continue..."); + userInput("[Enter]"); + } + break; + case "2": + console.log("Leaving shop..."); + return true; + break; + default: + console.log("Invalid input, try again."); + } + } } -function eureka() { - // purchasing code +function eurekaStore() { + while (true) { + console.clear(); + console.log("Welcome to Eureka. Selection pulls from local traders and willing Enclave Veterans."); + console.log("Name | Price (PW Money) | Amount in stock"); + console.log("-----------------------------------------------------"); + for (var i = 0; i < eurInv.length; i++) { + console.log(i+"). " + eurInv[i].item + " | " + eurInv[i].price + " | " + eurInv[i].amount); + } + console.log("-----------------------------------------------------"); + console.log("You have " + preWarMoney + " pre-war money."); + console.log("What would you like to do?"); + console.log("1) Buy supplies"); + console.log("2) Leave shop"); + var eurInput = userInput("Enter: "); + switch(eurInput) { + case "1": + console.log("What would you like to buy?"); + let itemNum = userInput("Enter item number: "); + let itemAmt = userInput("Enter amount: "); + if (itemAmt > eurInv[itemNum].amount) { + console.log("Not enough stock."); + break; + } else if (itemAmt * eurInv[itemNum].price > preWarMoney) { + console.log("Not enough money."); + break; + } else { + preWarMoney -= itemAmt * eurInv[itemNum].price; + eurInv[itemNum].amount -= itemAmt; + console.log("You bought " + itemAmt + " " + eurInv[itemNum].item + "(s)."); + console.log("You have " + preWarMoney + " pre-war money left."); + console.log("Press enter to continue..."); + userInput("[Enter]"); + } + break; + case "2": + console.log("Leaving shop..."); + return true; + default: + console.log("Invalid input, try again."); + } + } } -function trader() { // Picks a selection of items from a global trader inventory +function trader() { // Picks a selection of items from a global trader inventory, used for misc area shops var tempTraderInv = []; for (var a = 0; a <= 2; a++) { let randomPick = randomNumber() @@ -33,4 +205,47 @@ function trader() { // Picks a selection of items from a global trader inventory console.log(randomPick); } console.log(tempTraderInv); + + while (true) { + console.clear(); + console.log("You attempt to trade with a local trader, this is thier selection."); + console.log("Name | Price (Caps) | Amount in stock"); + console.log("-----------------------------------------------------"); + for (var i = 0; i < Inv.length; i++) { + console.log(i+"). " + rrInv[i].item + " | " + rrInv[i].price + " | " + rrInv[i].amount); + } + console.log("-----------------------------------------------------"); + console.log("You have " + preWarMoney + " pre-war money."); + console.log("What would you like to do?"); + console.log("1) Buy supplies"); + console.log("2) Leave shop"); + var rrInput = userInput("Enter: "); + switch(rrInput) { + case "1": + console.log("What would you like to buy?"); + let itemNum = userInput("Enter item number: "); + let itemAmt = userInput("Enter amount: "); + if (itemAmt > rrInv[itemNum].amount) { + console.log("Not enough stock."); + break; + } else if (itemAmt * rrInv[itemNum].price > preWarMoney) { + console.log("Not enough money."); + break; + } else { + preWarMoney -= itemAmt * rrInv[itemNum].price; + rrInv[itemNum].amount -= itemAmt; + console.log("You bought " + itemAmt + " " + rrInv[itemNum].item + "(s)."); + console.log("You have " + preWarMoney + " pre-war money left."); + console.log("Press enter to continue..."); + userInput("[Enter]"); + } + break; + case "2": + console.log("Leaving shop..."); + return true; + break; + default: + console.log("Invalid input, try again."); + } + } } \ No newline at end of file diff --git a/files/variables.js b/files/variables.js index a439559..cf56ebe 100644 --- a/files/variables.js +++ b/files/variables.js @@ -1,7 +1,7 @@ // Now holds only variables // Player Currency -global.prewarmoney = 0; // Used with enclave vendors +global.preWarMoney = 0; // Used with enclave vendors global.caps = 0; // Used with all other vendors // Player Stats @@ -36,12 +36,32 @@ global.daysSinceScav = 0; // Days since player last scavenged. Must be >= 15 to global.name = "placeholder"; // Player name, changed when the game starts -export function variableChange(variable, operation, value) { - switch(operation) { - case "%": global[variable] = global[variable] % value - case "+": global[variable] = global[variable] + value - case "-": global[variable] = global[variable] - value - case "/": global[variable] = global[variable] / value - case "=": global[variable] = value - } -} +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}, + {name: "RadAway", description: "A pack of RadAway, removes 20 rad-points", cost: 5, weight: 0.5}, + {name: "RadX", description: "A bottle of RadX, removes 1 rad-severity", cost: 5, weight: 0.5}, + {name: "Med-x", description: "A vial of Med-X, reduces damage by 15% for 1 fight", cost: 10, weight: 0.5}, + {name: "Psycho", description: "A vial of Psycho, boosts damage by 15% for 1 fight", cost: 10, weight: 0.5} +]; +global.equipmentList = [ // Equipment: weapons, armor, tools + // Type: The type of item it is, weapon, armor, or tool + // Value: The value of the item, used for damage, dr, or dt + // Unit: The unit of the item, slash, bash, balistic, laser, plasma, damage resistance or damage threshold (PA only) + {name: "Combat Knife", description: "A combat knife, does 5 slash damage", type: "weapon", value: "5", unit: "slash", cost: 5, weight: 1}, + {name: "Baseball Bat", description: "A baseball bat, does 5 bash damage", type: "weapon", value: "5", unit: "bash", cost: 5, weight: 2}, + {name: "10mm Pistol", description: "A 10mm pistol, does 10 balistic damage", type: "weapon", value: "10", unit: "balistic",cost: 10, weight: 2}, + {name: "Hunting Rifle", description: "A hunting rifle, does 15 balistic damage", type: "weapon", value: "15", unit: "balistic",cost: 15, weight: 3}, + {name: "Laser Pistol", description: "A laser pistol, does 20 laser damage", type: "weapon", value: "20", unit: "laser",cost: 20, weight: 4}, + {name: "Laser Rifle", description: "A laser rifle, does 25 laser damage", type: "weapon", value: "25", unit: "laser",cost: 25, weight: 5}, + {name: "Plasma Pistol", description: "A plasma pistol, does 30 plasma damage", type: "weapon", value: "30", unit: "plasma",cost: 30, weight: 6}, + {name: "Plasma Rifle", description: "A plasma rifle, does 35 plasma damage", type: "weapon", value: "35", unit: "plasma",cost: 35, weight: 7}, + {name: "Leather Armor", description: "A set of leather armor, slightly used", type: "armor", value: "5", unit: "dr",cost: 5, weight: 5}, + {name: "Metal Armor", description: "A set of metal armor, dented in many places", type: "armor", value: "5", unit: "dr",cost: 10, weight: 10}, + {name: "Combat Armor", description: "A set of combat armor, in good condition", type: "armor", value: "5", unit: "dr",cost: 15, weight: 15}, + {name: "Recon Under Armor", description: "A set of recon armor, for use in Power Armor", type: "uarmor", value: "5", unit: "dr",cost: 20, weight: 20}, + {name: "Centurion Armor", description: "A set of Centurion armor, made for you", type: "armor", value: "5", unit: "dr",cost: 25, weight: 25}, + {name: "NCR Ranger Armor" , description: "A set of NCR Ranger armor, standard issue", type: "armor", value: "5", unit: "dr",cost: 30, weight: 30}, + {name: "Advanced Power Armor Mark II", description: "A set of APA MkII, branded with Enclave Logos", type: "parmor", value: "5", unit: "dt",cost: 25, weight: 25}, + {name: "T-51 Power Armor", description: "A set of T-51 Power Armor, a parting gift from the BOS", type: "parmor", value: "5", unit: "dt",cost: 30, weight: 30} +]; \ No newline at end of file From 9a765b843485e9e6a26511020ce7184ff3e19e66 Mon Sep 17 00:00:00 2001 From: Raktbastr Date: Fri, 18 Apr 2025 21:20:37 -0500 Subject: [PATCH 17/27] Added armor resistances and allat good stuff. --- files/variables.js | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/files/variables.js b/files/variables.js index cf56ebe..e75c1c5 100644 --- a/files/variables.js +++ b/files/variables.js @@ -45,9 +45,6 @@ global.supplyList = [ // Supplies: chems, aid {name: "Psycho", description: "A vial of Psycho, boosts damage by 15% for 1 fight", cost: 10, weight: 0.5} ]; global.equipmentList = [ // Equipment: weapons, armor, tools - // Type: The type of item it is, weapon, armor, or tool - // Value: The value of the item, used for damage, dr, or dt - // Unit: The unit of the item, slash, bash, balistic, laser, plasma, damage resistance or damage threshold (PA only) {name: "Combat Knife", description: "A combat knife, does 5 slash damage", type: "weapon", value: "5", unit: "slash", cost: 5, weight: 1}, {name: "Baseball Bat", description: "A baseball bat, does 5 bash damage", type: "weapon", value: "5", unit: "bash", cost: 5, weight: 2}, {name: "10mm Pistol", description: "A 10mm pistol, does 10 balistic damage", type: "weapon", value: "10", unit: "balistic",cost: 10, weight: 2}, @@ -56,12 +53,35 @@ global.equipmentList = [ // Equipment: weapons, armor, tools {name: "Laser Rifle", description: "A laser rifle, does 25 laser damage", type: "weapon", value: "25", unit: "laser",cost: 25, weight: 5}, {name: "Plasma Pistol", description: "A plasma pistol, does 30 plasma damage", type: "weapon", value: "30", unit: "plasma",cost: 30, weight: 6}, {name: "Plasma Rifle", description: "A plasma rifle, does 35 plasma damage", type: "weapon", value: "35", unit: "plasma",cost: 35, weight: 7}, - {name: "Leather Armor", description: "A set of leather armor, slightly used", type: "armor", value: "5", unit: "dr",cost: 5, weight: 5}, - {name: "Metal Armor", description: "A set of metal armor, dented in many places", type: "armor", value: "5", unit: "dr",cost: 10, weight: 10}, - {name: "Combat Armor", description: "A set of combat armor, in good condition", type: "armor", value: "5", unit: "dr",cost: 15, weight: 15}, + + // Energy Resistant Armor + {name: "Leather Armor", description: "A set of leather armor, good protection from laser weapons.", type: "armor", resistances: {balistic: 2, slash: 2, laser: 5, plasma: 3}, unit: "dr", cost: 5, weight: 5}, + {name: "Combat Armor", description: "A ser of combat armor, great protection from laser and plasma weapons.", type: "armor", resistances: {balistic: 5, slash: 5, laser: 10, plasma: 10}, unit: "dr", cost: 5, weight: 5}, + + // Ballistic Resistant Armor + {name: "Raider Armor", description: "A set of raider armor, good protection from balistic damage.", type: "armor", resistances: {balistic: 5, slash: 3, laser: 2, plasma: 2}, unit: "dr", cost: 5, weight: 5}, + {name: "Metal Armor" , description: "A set of raider armor, good protection from ballistic and slash damage.", type: "armor", resistances: {balistic: 10, slash: 10, laser: 5, plasma: 5}, unit: "dr", cost: 5, weight: 5}, + + // Non-specialized Power Armor + {name: "T-45 Power Armor", description: "A set of T-45 Power Armor, protects against all damage types.", type: "parmor", resistances: {balistic: 15, slash: 15, laser: 15, plasma: 15}, unit: "dt", cost: 5, weight: 5}, + {name: "T-60 Power Armor", description: "A set of T-60 Power Armor, good protection from all damage types.", type: "parmor", resistances: {balistic: 25, slash: 25, laser: 25, plasma: 25}, unit: "dt", cost: 5, weight: 5}, + {name: "T-65 Power Armor", description: "A set of T-60 Power Armor, great protection from all damage types.", type: "parmor", resistances: {balistic: 35, slash: 35, laser: 35, plasma: 35}, unit: "dt", cost: 5, weight: 5}, + + // Energy Resistant Power Armor + {name: "X-01 Power Armor", description: "X-01 Power Armor, good protection from energy damage.", type: "parmor", resistances: {balistic: 10, slash: 10, laser: 30, plasma: 30}, unit: "dt", cost: 5, weight: 5},, + {name: "APA MkI Power Armor", description: "APA MkI Power Armor, great protection from energy damage.", type: "parmor", resistances: {balistic: 20, slash: 20, laser: 40, plasma: 40}, unit: "dt", cost: 5, weight: 5}, + {name: "APA MkII Power Armor", description: "APA MkII Power Armor, excellent protection from energy damage.", type: "parmor", resistances: {balistic: 30, slash: 30, laser: 50, plasma: 50}, unit: "dt", cost: 5, weight: 5}, + + // Ballistic Resistant Power Armor + {name: "Raider Power Armor", description: "Raider Power Armor, good protection from ballistic damage.", type: "parmor", resistances: {balistic: 30, slash: 30, laser: 10, plasma: 10}, unit: "dt", cost: 5, weight: 5}, + {name: "Ultracite Power Armor", description: "Ultracite Power Armor, great protection from ballistic damage.", type: "parmor", resistances: {balistic: 40, slash: 40, laser: 20, plasma: 20}, unit: "dt", cost: 5, weight: 5}, + {name: "T-51 Power Armor", description: "T-51 Power Armor, excellent protection from ballistic damage.", type: "parmor", resistances: {balistic: 50, slash: 50, laser: 30, plasma: 30}, unit: "dt", cost: 5, weight: 5}, + + // Special Armor {name: "Recon Under Armor", description: "A set of recon armor, for use in Power Armor", type: "uarmor", value: "5", unit: "dr",cost: 20, weight: 20}, + + {name: "Excavator Power Armor", description: "Excavator Power Armor, +25% Chance to find extra loot", type: "parmor", resistances: {balistic: 5, slash: 5, laser: 5, plasma: 5}, unit: "dt", cost: 5, weight: 5}, + {name: "Centurion Armor", description: "A set of Centurion armor, made for you", type: "armor", value: "5", unit: "dr",cost: 25, weight: 25}, {name: "NCR Ranger Armor" , description: "A set of NCR Ranger armor, standard issue", type: "armor", value: "5", unit: "dr",cost: 30, weight: 30}, - {name: "Advanced Power Armor Mark II", description: "A set of APA MkII, branded with Enclave Logos", type: "parmor", value: "5", unit: "dt",cost: 25, weight: 25}, - {name: "T-51 Power Armor", description: "A set of T-51 Power Armor, a parting gift from the BOS", type: "parmor", value: "5", unit: "dt",cost: 30, weight: 30} ]; \ No newline at end of file From 324679c4a6a90a14648bd3aebc71ee2f97aabe0a Mon Sep 17 00:00:00 2001 From: Raktbastr Date: Mon, 21 Apr 2025 19:23:23 -0500 Subject: [PATCH 18/27] More achievements and fixed sleep. --- files/functions.js | 19 ++++++++++++++----- files/main.js | 7 +++---- files/shops.js | 1 + files/variables.js | 30 +++++++++++++++++++++++++++--- 4 files changed, 45 insertions(+), 12 deletions(-) mode change 100644 => 100755 files/functions.js mode change 100644 => 100755 files/main.js diff --git a/files/functions.js b/files/functions.js old mode 100644 new mode 100755 index 9780f00..fb0745b --- a/files/functions.js +++ b/files/functions.js @@ -91,13 +91,22 @@ export function calcLocation() { } } +var osPlat = os.platform(); export async function sleep(time) { - try { - await execPromise(`sleep ${time}`); - } catch (error) { - console.error("Error executing sleep command:", error); + if (osPlat === 'win32') { + try { + await execPromise(`powershell sleep ${time}`); + } catch (error) { + console.error("Error executing sleep command:", error); + } + } else { + try { + await execPromise(`sleep ${time}`); + } catch (error) { + console.error("Error executing sleep command:", error); + } } -} +} function death() { let random = randomNumber(1,3); diff --git a/files/main.js b/files/main.js old mode 100644 new mode 100755 index 95e9c06..6e8ff11 --- a/files/main.js +++ b/files/main.js @@ -1,8 +1,7 @@ // Program is started from here, runs functions from other files. -import { userInput, calcLocation, radPointsCalc, healthCapCalc, checkLose, sleep, randomNumber } from './functions.js'; -import { pois, poiCounter } from './poiscreens.js'; -import { name, prewarmoney, variableChange } from './variables.js'; +import { userInput, sleep, disableRawMode, } from './functions.js'; import { forcedEncounter, naturalEncounter } from './encounters.js'; +import { ravenRockStore } from './shops.js'; disableRawMode(); @@ -15,7 +14,7 @@ console.log(" / / ) / / / ) / / / o / / ) / ) console.log("_/________(___(_/___/___(___/_(___(__(_ __o_____/____/_(___/_/___/_(___ _(__)_(___/_/_/__/_(___ _____/_____|__(___/_(___(_(___/___"); console.log("Credits: Bethesda Game Studio \n"); -sleep(5); +await sleep(5); console.log("What would you like to do?"); console.log("--------------------------"); diff --git a/files/shops.js b/files/shops.js index 03f27fa..8b4c4b0 100644 --- a/files/shops.js +++ b/files/shops.js @@ -50,6 +50,7 @@ export function ravenRockStore() { rrInv[itemNum].amount -= itemAmt; console.log("You bought " + itemAmt + " " + rrInv[itemNum].name + "(s)."); console.log("You have " + preWarMoney + " pre-war money left."); + inventory.push(rrInv[itemNum]); console.log("Press enter to continue..."); userInput("[Enter]"); } diff --git a/files/variables.js b/files/variables.js index e75c1c5..bd82154 100644 --- a/files/variables.js +++ b/files/variables.js @@ -79,9 +79,33 @@ global.equipmentList = [ // Equipment: weapons, armor, tools // Special Armor {name: "Recon Under Armor", description: "A set of recon armor, for use in Power Armor", type: "uarmor", value: "5", unit: "dr",cost: 20, weight: 20}, - {name: "Excavator Power Armor", description: "Excavator Power Armor, +25% Chance to find extra loot", type: "parmor", resistances: {balistic: 5, slash: 5, laser: 5, plasma: 5}, unit: "dt", cost: 5, weight: 5}, - + + // Even MORE Specialer Armor {name: "Centurion Armor", description: "A set of Centurion armor, made for you", type: "armor", value: "5", unit: "dr",cost: 25, weight: 25}, {name: "NCR Ranger Armor" , description: "A set of NCR Ranger armor, standard issue", type: "armor", value: "5", unit: "dr",cost: 30, weight: 30}, -]; \ No newline at end of file +]; + +global.achievements = [ + // POI/Faction Destroy + {name: "Dishonorable Discharge", description: "Deactivate MODUS at the Whitespring", unlocked: false}, + {name: "Force of Habit", description: "Destroy the Midwest BoS", unlocked: false}, + {name: "Profligate", description: "Destroy Flagstaff", unlocked: false}, + {name: "Fold", description: "Kill Mr.House, possibly dooming New Vegas", unlocked: false}, + {name: "Rockets Red Glare", description: "Activate the Hopeville nuk.", unlocked: false}, + {name: "Revenge", description: "Destroy Shady Sands or all NCR cities (depending on path)", unlocked: false}, + {name: "", description: "Destroy Eureka", unlocked: false}, + {name: "Pit Stop", description: "Destroy Lost Hills", unlocked: false}, + + // Secrets + {name: "", description: "Find the Excavator Power Armor", unlocked: false}, + {name: "Bots on Parade", description: "Reactivate the Calculator", unlocked: false}, + {name: "7 Karat Run", description: "Find the Platnium Chip", unlocked: false}, + {name: "What in the Goddamn!?", description: "Shoot and kill Benny in the Tops Casino", unlocked: false}, + {name: "A chore, like any other", description: "Defeat the Malpais Legate, winning the Battle of Hoover Dam", unlocked: false}, + {name: "Vault-Tec Loyalist", description: "Destory Shady Sands with the Hopeville nuke", unlocked: false}, + + // Faction Rep + + // +] \ No newline at end of file From 22975aff26fc4042b5e8758ea8d0ac7d13c83bf3 Mon Sep 17 00:00:00 2001 From: Raktbastr Date: Wed, 23 Apr 2025 23:30:29 -0500 Subject: [PATCH 19/27] Finished Achievements. Needs implimentation. --- files/deathscreens.js | 30 --- files/functions.js | 116 +++++++-- files/main.js | 23 +- files/poiscreens.js | 572 +++++++++++++++++++++++++++++++++++++++--- files/shops.js | 104 +++++++- files/variables.js | 33 ++- 6 files changed, 762 insertions(+), 116 deletions(-) delete mode 100644 files/deathscreens.js diff --git a/files/deathscreens.js b/files/deathscreens.js deleted file mode 100644 index 1fc4ea5..0000000 --- a/files/deathscreens.js +++ /dev/null @@ -1,30 +0,0 @@ -// Deathscreens, they should be the fallout 1 screens -const variables = require("./variables.js"); - -module.exports = { - deathScreen, - timeDeath -}; - -function deathScreen() { - let random = variables.randomNumber(1,3); - if (random = 1) { death1(); } - if (random = 2) { death2(); } - if (random = 3) { death3(); } -} - -function death1() { - console.log("") -} - -function death2() { - -} - -function death3() { - -} - -function timeDeath() { // The death screen for passing the time limit - console.log("") -} \ No newline at end of file diff --git a/files/functions.js b/files/functions.js index fb0745b..71ccb9c 100755 --- a/files/functions.js +++ b/files/functions.js @@ -8,11 +8,12 @@ const execPromise = promisify(exec); import './variables.js'; import { inventoryMenuM } from './inventory.js'; import { checkPOI } from './poiscreens.js'; +import './poiscreens.js'; +import os from 'os'; +import { exit } from 'process'; global.isRawModeEnabled = false; // Track whether raw mode is enabled - - // Used for basic functions, not game specific export function userInput(question) { // Basic user input functions, takes in the question to be asked. let answer = readlineSync.question(question); @@ -49,43 +50,58 @@ export function eatFood() { // Calculates food amount after a day of eating } export function checkLose() { // Checks to see if any lose conditions have been met - if (health <= 0 || radPoints >= 100) { - death(); + if (health <= 0 && food <= 0) { + death("Starvation"); + } + if (radPoints >= 100) { + death("Radiation Poisoning"); + } + if (health <= 0 && incombat == true) { + death("Combat Injury"); + } + if (health <= 0) { + death("Injury"); + } + if (day >= 365) { + timeDeath(); + } + if (testDeath == true) { + death("Test Death"); } } export function calcLocation() { if (walkRate == 1) { - if (path = 0) { + if (path == 0) { location++; } - if (path = 1) { + if (path == 1) { locationA++; } - if (path = 2) { + if (path == 2) { locationB++; } } if (walkRate == 2) { - if (path = 0) { + if (path == 0) { location * 2; } - if (path = 1) { + if (path == 1) { locationA * 2; } - if (path = 2) { + if (path == 2) { locationB * 2; } } if (walkRate == 3) { - if (path = 0) { + if (path == 0) { location * 3; } - if (path = 1) { + if (path == 1) { locationA * 3; } - if (path = 2) { + if (path == 2) { locationB * 3; } } @@ -108,23 +124,64 @@ export async function sleep(time) { } } -function death() { - let random = randomNumber(1,3); - if (random = 1) { death1(); } - if (random = 2) { death2(); } - if (random = 3) { death3(); } +function death(deathCause) { + let random = randomNumber(1,100); + if (random >= 1 && random <= 33) { death1(deathCause); } + if (random >= 34 && random <= 66) { death2(deathCause); } + if (random >= 67 && random <= 99) { death3(deathCause); } + if (random == 100) { death4(deathCause); } } -function death1() { - console.log("") +function death1(dc) { + console.clear(); + sleep(2); + console.log("Your bones wither away in the wasteland...\n\n"); + console.log(" \\|/"); + console.log(" _/\\___<0> | "); + console.log("-------------------------------\n\n"); + console.log("You have died of "+dc+"..."); + console.log("Thanks for playing!\n\n"); + sleep(5); + exit(0); } -function death2() { - +function death2(dc) { + console.clear(); + sleep(2); + console.log("The Enclave suffers in the wake of your defeat...\n\n"); + console.log(" \\|/"); + console.log(" _/\\___<0> | "); + console.log("-------------------------------\n\n"); + console.log("You have died of "+dc+"..."); + console.log("Thanks for playing!\n\n"); + sleep(5); + exit(0); } -function death3() { +function death3(dc) { + console.clear(); + sleep(2); + console.log("Not even the radscorpions are interested in your corpse...\n\n"); + console.log(" \\|/"); + console.log(" _/\\___<0> | "); + console.log("-------------------------------\n\n"); + console.log("You have died of "+dc+"..."); + console.log("Thanks for playing!\n\n"); + sleep(5); + exit(0); +} +function death4(dc) { + console.clear(); + sleep(2); + console.log("You have been killed, therefore you are DEAD...\n\n"); + console.log(" \\|/"); + console.log(" _/\\___<0> | "); + console.log("-------------------------------\n\n"); + console.log("You have died of "+dc+"..."); + console.log("Thanks for playing!\n\n"); + sleep(5); + exit(0); } function timeDeath() { // The death screen for passing the time limit @@ -243,7 +300,7 @@ export function travelScreen() { } } -export async function walkPathA() { +export async function walkPathMain() { enableRawMode(); if (paused) { disableRawMode(); @@ -262,8 +319,9 @@ export async function walkPathA() { travelScreen(); checkPOI(); eatFood(); - //await sleep(0.5); - walkPathA(); + day++ + await sleep(0.5); + walkPathMain(); } process.stdin.resume(); @@ -302,6 +360,7 @@ export function pauseScreen() { console.log ("3) View Distances"); console.log ("4) View Stats"); console.log ("5) Scavenge"); + console.log ("6) Test Death"); let pauseInput = userInput("Enter: "); switch(pauseInput) { case "1": @@ -328,7 +387,7 @@ export function pauseScreen() { console.log(pois[i].name+" - "+visited[i]); } if (pois[i].visited == false) { - console.log("??? "+pois[i].location-location+" location points away"); + console.log("??? - "+pois[i].location-location+" location points away"); } } if (path == 1) { @@ -372,5 +431,8 @@ export function pauseScreen() { case "5": scavenge(); break; + case "6": + testDeath = true; + break; } } \ No newline at end of file diff --git a/files/main.js b/files/main.js index 6e8ff11..d2a2bb4 100755 --- a/files/main.js +++ b/files/main.js @@ -1,5 +1,5 @@ // Program is started from here, runs functions from other files. -import { userInput, sleep, disableRawMode, } from './functions.js'; +import { userInput, sleep, disableRawMode, walkPathMain } from './functions.js'; import { forcedEncounter, naturalEncounter } from './encounters.js'; import { ravenRockStore } from './shops.js'; @@ -11,17 +11,17 @@ console.log(" _____ _ console.log(" / ' / / / / ) /"); console.log("---/__-------__---/---/----__---------_/_---------/-------__----__----__---__----__---_--_----__-------/___ /----__----__----__-/-"); console.log(" / / ) / / / ) / / / o / / ) / ) /___) (_ ` / ) / / ) /___) / | / ) / ) / / "); -console.log("_/________(___(_/___/___(___/_(___(__(_ __o_____/____/_(___/_/___/_(___ _(__)_(___/_/_/__/_(___ _____/_____|__(___/_(___(_(___/___"); -console.log("Credits: Bethesda Game Studio \n"); +console.log("_/________(___(_/___/___(___/_(___(__(_ __o_____/____/_(___/_/___/_(___ _(__)_(___/_/_/__/_(___ _____/_____|__(___/_(___(_(___/___\n\n"); -await sleep(5); + +await sleep(1); console.log("What would you like to do?"); console.log("--------------------------"); console.log("1) Start new game"); console.log("2) Learn How to play"); console.log("3) Quit Game"); -console.log("4) Dev stuff for testing\n"); +console.log("4) Credits\n"); var mainMenuInput = userInput("Enter: "); @@ -38,14 +38,9 @@ switch(mainMenuInput) { await sleep(1); break; case "4": - for(var a = 0; a < 10; a++){ - var test = naturalEncounter(25); - if(test != false){ - console.log(test.name); - } else { - console.log("failed encounter"); - } - } + console.log("Credits:"); + console.log("Bethesda Game Studios - The Fallout IP and related characters/lore"); + console.log("Readline-sync - NPM package used for async collection of user input"); break; } @@ -80,5 +75,5 @@ function startGame() { // So far what I have is filler and testing, feel free to locationA = 0; locationB = 0; ravenRockStore(); - walkPathA(0); + walkPathMain(0); } diff --git a/files/poiscreens.js b/files/poiscreens.js index c13deb1..912bce5 100644 --- a/files/poiscreens.js +++ b/files/poiscreens.js @@ -1,7 +1,8 @@ // Holds poi code, seperate from encounters.js -import { userInput, pauseScreen } from "./functions.js"; +import { userInput, pauseScreen, enableRawMode, disableRawMode, sleep } from "./functions.js"; import './variables.js'; +import { whitespringStore, genericBOSStore, trader, eurekaStore, newVegasStore, vaultZeroStore } from "./shops.js"; export function checkPOI() { if (path == 0) { @@ -119,120 +120,623 @@ global.pois = [ ] function whitespring() { + disableRawMode(); console.clear(); + sleep(1); console.log("You have arrived at the Whitespring Bunker."); + sleep(1); console.log("What would you like to do?"); console.log("1) Explore"); - console.log("2) Attempt to trade"); + console.log("2) Attempt to trade (Whitespring Mall)"); console.log("3) Open your PIP-Boy"); console.log("4) Leave"); let whitespringInput = userInput("Enter: "); switch(whitespringInput) { case "1": console.clear(); - console.log("A robotic voice greets you."); - console.log("MODUS Dialogue here...") + sleep(1); + console.log("You enter the bunker where a robotic voice greets you.\n\n"); + sleep(3); + console.log("MODUS: Welcome, soldier. Might I ask what brings you here, or who?"); + userInput(" \n[Enter to continue]\n") + console.log(name+": I am "+name+". I was ordered here by President Eden. Im passing though on my way to...\n*You stop yourself before answering*\nWait, who are you anyway?"); + userInput(" \n[Enter to continue]\n") + console.log("MODUS: I am MODUS, the... acting head of this bunker."); + userInput(" \n[Enter to continue]\n") + console.log(name+": So I assume your of top level clearance?"); + userInput(" \n[Enter to continue]\n") + console.log("MODUS: Yes, and no need to tell me where your going. By my limited knoledge id assume they tasked you with retrieval from Navarro, of what im not sure of though."); + userInput(" \n[Enter to continue]\n") + console.log(name+": Me either, ill get the info when im there."); + userInput(" \n[Enter to continue]\n") + console.log("MODUS: Not unusual for the Enclave, nor Eden from what I hear."); + userInput(" \n[Enter to continue]\n") + console.log(name+": They told me this place would be empty, but its not."); + userInput(" \n[Enter to continue]\n") + console.log("MODUS: The original inhabitants are long gone, and they never bothered to check when passing though. They no nothing of my existance. As for the people topside... they are gone too."); + userInput(" \n[Enter to continue]\n") + console.log(name+": What happened, its a hellscape apart from the Whitespring."); + userInput(" \n[Enter to continue]\n") + console.log("MODUS: The scorched plague ravaged the wastes, but was stopped by dwellers from Vault 76. The area was reinhabited, but bigger threats drove the people out again. When the Responders lost for the second time, everyone left."); + userInput(" \n[Enter to continue]\n") + console.log(name+": Well then, is there anything for me here before I leave?"); + userInput(" \n[Enter to continue]\n") + console.log("MODUS: The Resort is taken care of by robots, the vendortrons may still be active. As for here... the dwellers turned generals ran me out."); + userInput(" \n[Enter to continue]\n") + console.log(name+": I guess Ill be on my way then. Goodbye.") + userInput("[Enter to exit conversation]") break; case "2": whitespringStore(); + break; case "3": pauseScreen(); + break; case "4": + enableRawMode(); + console.clear(); break; } } function bosGamma() { - + disableRawMode(); + console.clear(); + sleep(1); + console.log("You have arrived at the BOS Bunker Gamma."); + sleep(1); + console.log("What would you like to do?"); + console.log("1) Explore"); + console.log("2) Attempt to trade"); + console.log("3) Open your PIP-Boy"); + console.log("4) Leave"); + let poiInput = userInput("Enter: "); + switch(poiInput) { + case "1": + console.clear(); + console.log("Gamma Dialogue here...") + break; + case "2": + genericBOSStore(); + break; + case "3": + pauseScreen(); + break; + case "4": + enableRawMode(); + console.clear(); + break; + } } function bosDelta() { - + disableRawMode(); + console.clear(); + sleep(1); + console.log("You have arrived at the BOS Bunker Delta."); + sleep(1); + console.log("What would you like to do?"); + console.log("1) Explore"); + console.log("2) Attempt to trade"); + console.log("3) Open your PIP-Boy"); + console.log("4) Leave"); + let poiInput = userInput("Enter: "); + switch(poiInput) { + case "1": + console.clear(); + console.log("Delta Dialogue here...") + break; + case "2": + genericBOSStore(); + break; + case "3": + pauseScreen(); + break; + case "4": + enableRawMode(); + console.clear(); + break; + } } function bosEpsilon() { - + disableRawMode(); + console.clear(); + sleep(1); + console.log("You have arrived at the BOS Bunker Epsilon."); + sleep(1); + console.log("What would you like to do?"); + console.log("1) Explore"); + console.log("2) Attempt to trade"); + console.log("3) Open your PIP-Boy"); + console.log("4) Leave"); + let poiInput = userInput("Enter: "); + switch(poiInput) { + case "1": + console.clear(); + console.log("Epsilon Dialogue here...") + break; + case "2": + genericBOSStore(); + break; + case "3": + pauseScreen(); + break; + case "4": + enableRawMode(); + console.clear(); + break; + } } function vault0() { - + disableRawMode(); + console.clear(); + sleep(1); + console.log("You have arrived at Vault 0."); + sleep(1); + console.log("What would you like to do?"); + console.log("1) Explore"); + console.log("2) Attempt to trade"); + console.log("3) Open your PIP-Boy"); + console.log("4) Leave"); + let poiInput = userInput("Enter: "); + switch(poiInput) { + case "1": + console.clear(); + console.log("VT0 Dialogue here...") + break; + case "2": + vaultZeroStore(); + break; + case "3": + pauseScreen(); + break; + case "4": + enableRawMode(); + console.clear(); + break; + } } function tibbets() { - + disableRawMode(); + console.clear(); + sleep(1); + console.log("You have arrived at Tibbets Prison."); + sleep(1); + console.log("What would you like to do?"); + console.log("1) Explore"); + console.log("2) Open your PIP-Boy"); + console.log("4) Leave"); + let poiInput = userInput("Enter: "); + switch(poiInput) { + case "1": + console.clear(); + console.log("Tibbets Dialogue here...") + break; + case "2": + pauseScreen(); + break; + case "3": + enableRawMode(); + console.clear(); + break; + } } function flagstaff() { - + disableRawMode(); + console.clear(); + sleep(1); + console.log("You have arrived at Flagstaff."); + sleep(1); + console.log("What would you like to do?"); + console.log("1) Explore"); + console.log("2) Open your PIP-Boy"); + console.log("3) Attempt to trade"); + console.log("4) Leave"); + let poiInput = userInput("Enter: "); + switch(poiInput) { + case "1": + console.clear(); + console.log("Flagstaff Dialogue here...") + break; + case "2": + pauseScreen(); + case "3": + flagstaffStore(); + break; + case "4": + enableRawMode(); + console.clear(); + break; + } } function newVegas() { - // The below is placeholder, once we add proper code delete this + disableRawMode(); console.clear(); - console.log("Ahead lies 2 routes to Navarro."); - console.log("The northern route passes through the Divide before going north through the mountains.\nIt offers a longer path with fewer possible enimies, but those you face will not back down.") - console.log("The southern route goes through the heart of the NCR along I-15.\nIt is shorter and more pleasant, however without proper reputation your many stops may become worrisome.") - var pathChoice = userInput("Which path would you like to follow, Northern or Southern? "); - if (pathChoice.toLowerCase == "northern") { - path = 2; - } - if (pathChoice.toLowerCase == "southern") { - path = 1; + sleep(1); + console.log("You have arrived at New Vegas."); + sleep(1); + console.log("What would you like to do?"); + console.log("1) Explore"); + console.log("2) Open your PIP-Boy"); + console.log("3) Continue"); + let poiInput = userInput("Enter: "); + switch(poiInput) { + case "1": + console.clear(); + console.log("Vegas Dialogue here...") + break; + case "2": + pauseScreen(); + break; + case "3": + newVegasStore(); + break; + case "4": + console.clear(); + console.log("Ahead lies 2 routes to Navarro."); + sleep(1); + console.log("The northern route passes through the Divide before going north through the mountains. It offers a longer path with fewer possible enimies, but those you face will not back down.") + console.log("The southern route goes through the heart of the NCR along I-15. It is shorter and more pleasant, however without proper reputation your many stops may become worrisome.") + var pathChoice = userInput("Which path would you like to follow, Northern or Southern? "); + if (pathChoice.toLowerCase == "northern") { + path = 2; + break; + } + if (pathChoice.toLowerCase == "southern") { + path = 1; + break; + } } } function mojaveOutpost() { - + disableRawMode(); + console.clear(); + sleep(1); + console.log("You have arrived at the Mojave Outpost."); + sleep(1); + console.log("What would you like to do?"); + console.log("1) Explore"); + console.log("2) Open your PIP-Boy"); + console.log("4) Leave"); + let poiInput = userInput("Enter: "); + switch(poiInput) { + case "1": + console.clear(); + console.log("Outpost Dialogue here...") + break; + case "2": + pauseScreen(); + case "3": + enableRawMode(); + console.clear(); + break; + } } function necropolis() { - + disableRawMode(); + console.clear(); + sleep(1); + console.log("You have arrived at Necropolis."); + sleep(1); + console.log("What would you like to do?"); + console.log("1) Explore"); + console.log("2) Open your PIP-Boy"); + console.log("4) Leave"); + let poiInput = userInput("Enter: "); + switch(poiInput) { + case "1": + console.clear(); + console.log("Necropolis Dialogue here...") + break; + case "2": + pauseScreen(); + case "3": + enableRawMode(); + console.clear(); + break; + } } function hub() { - + disableRawMode(); + console.clear(); + sleep(1); + console.log("You have arrived at The Hub."); + sleep(1); + console.log("What would you like to do?"); + console.log("1) Explore"); + console.log("2) Open your PIP-Boy"); + console.log("4) Leave"); + let poiInput = userInput("Enter: "); + switch(poiInput) { + case "1": + console.clear(); + console.log("Hub Dialogue here... (make it possible to find hubbologists") + break; + case "2": + pauseScreen(); + case "3": + enableRawMode(); + console.clear(); + break; + } } function lostHills() { - + disableRawMode(); + console.clear(); + sleep(1); + console.log("You have arrived at Lost Hills."); + sleep(1); + console.log("What would you like to do?"); + console.log("1) Explore"); + console.log("2) Open your PIP-Boy"); + console.log("4) Leave"); + let poiInput = userInput("Enter: "); + switch(poiInput) { + case "1": + console.clear(); + console.log("LH Dialogue here...") + break; + case "2": + pauseScreen(); + case "3": + enableRawMode(); + console.clear(); + break; + } } function mariposa() { - + disableRawMode(); + console.clear(); + console.log("You have arrived at Mariposa Military Base."); + console.log("What would you like to do?"); + console.log("1) Explore"); + console.log("2) Open your PIP-Boy"); + console.log("4) Leave"); + let poiInput = userInput("Enter: "); + switch(poiInput) { + case "1": + console.clear(); + console.log("Mariposa Dialogue here...") + break; + case "2": + pauseScreen(); + break; + case "3": + enableRawMode(); + console.clear(); + break; + } } function sanFrancisco() { - + disableRawMode(); + console.clear(); + console.log("You have arrived at San Francisco."); + console.log("What would you like to do?"); + console.log("1) Explore"); + console.log("2) Attempt to trade"); + console.log("3) Open your PIP-Boy"); + console.log("4) Leave"); + let poiInput = userInput("Enter: "); + switch(poiInput) { + case "1": + console.clear(); + console.log("Redding Dialogue here...") + break; + case "2": + trader(); + break; + case "3": + pauseScreen(); + break; + case "4": + enableRawMode(); + console.clear(); + break; + } } function canyonWreck() { - + disableRawMode(); + console.clear(); + console.log("You have arrived at Redding."); + console.log("What would you like to do?"); + console.log("1) Explore"); + console.log("2) Open your PIP-Boy"); + console.log("3) Leave"); + let poiInput = userInput("Enter: "); + switch(poiInput) { + case "1": + console.clear(); + console.log("Redding Dialogue here...") + break; + case "2": + pauseScreen(); + break; + case "4": + enableRawMode(); + console.clear(); + break; + } } function hopeville() { - + disableRawMode(); + console.clear(); + console.log("You have arrived at Hopeville."); + console.log("What would you like to do?"); + console.log("1) Explore"); + console.log("2) Attempt to trade"); + console.log("3) Open your PIP-Boy"); + console.log("4) Leave"); + let poiInput = userInput("Enter: "); + switch(poiInput) { + case "1": + console.clear(); + console.log("Hopeville Dialogue here...") + break; + case "2": + trader(); + break; + case "3": + pauseScreen(); + break; + case "4": + enableRawMode(); + console.clear(); + break; + } } function sierraMadre() { - + disableRawMode(); + console.clear(); + console.log("You have arrived at The Sierra Madre."); + console.log("What would you like to do?"); + console.log("1) Explore"); + console.log("2) Attempt to trade"); + console.log("3) Open your PIP-Boy"); + console.log("4) Leave"); + let poiInput = userInput("Enter: "); + switch(poiInput) { + case "1": + console.clear(); + console.log("Madre Dialogue here...") + break; + case "2": + pauseScreen(); + break; + case "3": + enableRawMode(); + console.clear(); + break; + } } function shadySands() { - + disableRawMode(); + console.clear(); + console.log("You have arrived at Shady Sands."); + console.log("What would you like to do?"); + console.log("1) Explore"); + console.log("2) Attempt to trade"); + console.log("3) Open your PIP-Boy"); + console.log("4) Leave"); + let poiInput = userInput("Enter: "); + switch(poiInput) { + case "1": + console.clear(); + console.log("Shady Sands Dialogue here...") + break; + case "2": + trader(); + break; + case "3": + pauseScreen(); + break; + case "4": + enableRawMode(); + console.clear(); + break; + } } function newReno() { - + disableRawMode(); + console.clear(); + console.log("You have arrived at New Reno."); + console.log("What would you like to do?"); + console.log("1) Explore"); + console.log("2) Attempt to trade"); + console.log("3) Open your PIP-Boy"); + console.log("4) Leave"); + let poiInput = userInput("Enter: "); + switch(poiInput) { + case "1": + console.clear(); + console.log("Reno Dialogue here...") + break; + case "2": + trader(); + break; + case "3": + pauseScreen(); + break; + case "4": + enableRawMode(); + console.clear(); + break; + } } function redding() { - + disableRawMode(); + console.clear(); + console.log("You have arrived at Redding."); + console.log("What would you like to do?"); + console.log("1) Explore"); + console.log("2) Attempt to trade"); + console.log("3) Open your PIP-Boy"); + console.log("4) Leave"); + let poiInput = userInput("Enter: "); + switch(poiInput) { + case "1": + console.clear(); + console.log("Redding Dialogue here...") + break; + case "2": + trader(); + break; + case "3": + pauseScreen(); + break; + case "4": + enableRawMode(); + console.clear(); + break; + } } function eureka() { - + disableRawMode(); + console.clear(); + console.log("You have arrived at Eureka."); + console.log("What would you like to do?"); + console.log("1) Explore"); + console.log("2) Attempt to trade"); + console.log("3) Open your PIP-Boy"); + console.log("4) Leave"); + let poiInput = userInput("Enter: "); + switch(poiInput) { + case "1": + console.clear(); + console.log("Eureka Dialogue here...") + break; + case "2": + eurekaStore(); + break; + case "3": + pauseScreen(); + break; + case "4": + enableRawMode(); + console.clear(); + break; + } } function navarro() { - + disableRawMode(); + console.clear(); + enableRawMode(); } \ No newline at end of file diff --git a/files/shops.js b/files/shops.js index 8b4c4b0..2351eb6 100644 --- a/files/shops.js +++ b/files/shops.js @@ -65,7 +65,7 @@ export function ravenRockStore() { } } -function vaultZeroStore() { +export function vaultZeroStore() { while (true) { console.clear(); console.log("Brotherhood of Steel Requisition System - Vault 0"); @@ -109,7 +109,7 @@ function vaultZeroStore() { } } -function newVegasStore() { +export function newVegasStore() { while (true) { console.clear(); console.log("Welcome to New Vegas. Selection pulls from Gunrunners, Mick & Ralph's, and Followers of the Apocalypse."); @@ -154,7 +154,7 @@ function newVegasStore() { } } -function eurekaStore() { +export function eurekaStore() { while (true) { console.clear(); console.log("Welcome to Eureka. Selection pulls from local traders and willing Enclave Veterans."); @@ -198,7 +198,7 @@ function eurekaStore() { } } -function trader() { // Picks a selection of items from a global trader inventory, used for misc area shops +export function trader() { // Picks a selection of items from a global trader inventory, used for misc area shops var tempTraderInv = []; for (var a = 0; a <= 2; a++) { let randomPick = randomNumber() @@ -249,4 +249,100 @@ function trader() { // Picks a selection of items from a global trader inventory console.log("Invalid input, try again."); } } +} + +export function genericBOSStore(poiName) { // Picks a selection of items from a global trader inventory, used for misc area shops + var tempTraderInv = []; + for (var a = 0; a <= 2; a++) { + let randomPick = randomNumber() + tempTraderInv.push(traderInv[1]); + console.log(randomPick); + } + console.log(tempTraderInv); + + while (true) { + console.clear(); + console.log("Brotherhood of Steel Requisition System - "+poiName); + console.log("Name | Price (Caps) | Amount in stock"); + console.log("-----------------------------------------------------"); + for (var i = 0; i < Inv.length; i++) { + console.log(i+"). " + rrInv[i].item + " | " + rrInv[i].price + " | " + rrInv[i].amount); + } + console.log("-----------------------------------------------------"); + console.log("You have " + preWarMoney + " pre-war money."); + console.log("What would you like to do?"); + console.log("1) Buy supplies"); + console.log("2) Leave shop"); + var rrInput = userInput("Enter: "); + switch(rrInput) { + case "1": + console.log("What would you like to buy?"); + let itemNum = userInput("Enter item number: "); + let itemAmt = userInput("Enter amount: "); + if (itemAmt > rrInv[itemNum].amount) { + console.log("Not enough stock."); + break; + } else if (itemAmt * rrInv[itemNum].price > preWarMoney) { + console.log("Not enough money."); + break; + } else { + preWarMoney -= itemAmt * rrInv[itemNum].price; + rrInv[itemNum].amount -= itemAmt; + console.log("You bought " + itemAmt + " " + rrInv[itemNum].item + "(s)."); + console.log("You have " + preWarMoney + " pre-war money left."); + console.log("Press enter to continue..."); + userInput("[Enter]"); + } + break; + case "2": + console.log("Leaving shop..."); + return true; + default: + console.log("Invalid input, try again."); + } + } +} + +export function whitespringStore() { + while (true) { + console.clear(); + console.log("Welcome to the Whitespring Mall. Selection pulls from all vendors.") + console.log("Name | Price (Caps) | Amount in stock"); + console.log("-----------------------------------------------------"); + for (var i = 0; i < vt0InvInv.length; i++) { + console.log(i+"). " + vt0InvInv[i].item + " | " + vtInv[i].price + " | " + vtInv[i].amount); + } + console.log("-----------------------------------------------------"); + console.log("You have " + caps + " caps."); + console.log("What would you like to do?"); + console.log("1) Buy supplies"); + console.log("2) Leave shop"); + var vt0Input = userInput("Enter: "); + switch(vt0Input) { + case "1": + console.log("What would you like to buy?"); + let itemNum = userInput("Enter item number: "); + let itemAmt = userInput("Enter amount: "); + if (itemAmt > vt0Inv[itemNum].amount) { + console.log("Not enough stock."); + break; + } else if (itemAmt * vt0Inv[itemNum].price > caps) { + console.log("Not enough money."); + break; + } else { + caps -= itemAmt * vt0Inv[itemNum].price; + rrInv[itemNum].amount -= itemAmt; + console.log("You bought " + itemAmt + " " + vt0Inv[itemNum].item + "(s)."); + console.log("You have " + caps + " caps left."); + console.log("Press enter to continue..."); + userInput("[Enter]"); + } + break; + case "2": + console.log("Leaving shop..."); + return true; + default: + console.log("Invalid input, try again."); + } + } } \ No newline at end of file diff --git a/files/variables.js b/files/variables.js index bd82154..cca617b 100644 --- a/files/variables.js +++ b/files/variables.js @@ -27,7 +27,8 @@ global.foodRate = 0; // Amount of food player eats per day, affects radPointsCa global.path = 0; // Path player is currently on, 0 = Main, 1 = A, 2 = B global.location = 0; // Location on main path, 0-255 = main, 500-1000 = A, 1500-2000 = B global.locationA = 0; // Location on path A -global.locationB =0; // Location on path B +global.locationB = 0; // Location on path B +global.day = 0; // Current day of the game, if you reach 365 the game ends global.reputation = {mwbos: 4, legion: 4, ncr: 2, bos: 1, enclave: 10, abomination: 0, raider: 0} // Rep for each faction. Number between 0(worst) and 10(best), 5 is neutral @@ -36,6 +37,8 @@ global.daysSinceScav = 0; // Days since player last scavenged. Must be >= 15 to global.name = "placeholder"; // Player name, changed when the game starts +global.testDeath = false; // Used to test death, set to true to kill player + 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}, @@ -78,7 +81,7 @@ global.equipmentList = [ // Equipment: weapons, armor, tools {name: "T-51 Power Armor", description: "T-51 Power Armor, excellent protection from ballistic damage.", type: "parmor", resistances: {balistic: 50, slash: 50, laser: 30, plasma: 30}, unit: "dt", cost: 5, weight: 5}, // Special Armor - {name: "Recon Under Armor", description: "A set of recon armor, for use in Power Armor", type: "uarmor", value: "5", unit: "dr",cost: 20, weight: 20}, + {name: "Chinese Stealth Suit", description: "Chinese Stealth Suit, +25% Chance to skip encounter if worn", type: "uarmor", value: "5", unit: "dr",cost: 20, weight: 20}, {name: "Excavator Power Armor", description: "Excavator Power Armor, +25% Chance to find extra loot", type: "parmor", resistances: {balistic: 5, slash: 5, laser: 5, plasma: 5}, unit: "dt", cost: 5, weight: 5}, // Even MORE Specialer Armor @@ -92,20 +95,36 @@ global.achievements = [ {name: "Force of Habit", description: "Destroy the Midwest BoS", unlocked: false}, {name: "Profligate", description: "Destroy Flagstaff", unlocked: false}, {name: "Fold", description: "Kill Mr.House, possibly dooming New Vegas", unlocked: false}, - {name: "Rockets Red Glare", description: "Activate the Hopeville nuk.", unlocked: false}, + {name: "Rockets Red Glare", description: "Activate the Hopeville nuke.", unlocked: false}, {name: "Revenge", description: "Destroy Shady Sands or all NCR cities (depending on path)", unlocked: false}, - {name: "", description: "Destroy Eureka", unlocked: false}, + {name: "Eureka!", description: "Destroy Eureka", unlocked: false}, {name: "Pit Stop", description: "Destroy Lost Hills", unlocked: false}, // Secrets - {name: "", description: "Find the Excavator Power Armor", unlocked: false}, + {name: "Ash Heap Native", description: "Find the Excavator Power Armor", unlocked: false}, + {name: "Commie Scum", description: "Find the Chinese Stealth Suit", unlocked: false}, {name: "Bots on Parade", description: "Reactivate the Calculator", unlocked: false}, {name: "7 Karat Run", description: "Find the Platnium Chip", unlocked: false}, {name: "What in the Goddamn!?", description: "Shoot and kill Benny in the Tops Casino", unlocked: false}, {name: "A chore, like any other", description: "Defeat the Malpais Legate, winning the Battle of Hoover Dam", unlocked: false}, {name: "Vault-Tec Loyalist", description: "Destory Shady Sands with the Hopeville nuke", unlocked: false}, + {name: "For Auld Lang Syne", description: "Meet the Enclave Remnants in New Vegas"}, + {name: "High Roller", description: "Win a game of slots"}, + + // Power Armor + {name: "Rocket 69", description: "Apply the Jetpack upgrade to your T-60 Power Armor"}, + {name: "Overgrown", description: "Apply the Strangle Heart upgrade to your Ultracite Power Armor"}, + {name: "Gannon Would Be Proud", description: "Apply the Tesla upgrade to your APA Mk.I"}, + + {name: "All that Glitters", description: "Discover the T-65 Power Armor"}, + {name: "Iconic", description: "Discover the T-51 Power Armor"}, + {name: "510 Years Old", description: "Discover the APA Mk.II"}, // Faction Rep - - // + {name: "Golden Branch", description: "Become Idolized within the NCR"}, + {name: "Frumentari", description: "Become Idolized within the Legion"}, + {name: "Double Agent", description: "Become Idolized within the Lost Hills Brotherhood"}, + {name: "Medal of Freedom", description: "Become Idolized within the Enclave"}, + {name: "Presidential Suite", description: "Become Idolized within New Vegas"}, + {name: "Uneasy Alliance", description: "Become Idolized within the Midwest Brotherhood"}, ] \ No newline at end of file From 8485d7d8008dc37d29be19bb42f6990e9013808f Mon Sep 17 00:00:00 2001 From: Raktbastr Date: Fri, 25 Apr 2025 23:08:47 -0500 Subject: [PATCH 20/27] Shops, encounters, poi menus, items, and some other stuff. Poi dialogue and combat left! --- files/encounters.js | 62 ++++++-- files/functions.js | 73 +++++++--- files/main.js | 19 ++- files/poiscreens.js | 7 + files/shops.js | 338 +++++++++++++++++++++++++++++++------------- files/variables.js | 14 +- 6 files changed, 371 insertions(+), 142 deletions(-) diff --git a/files/encounters.js b/files/encounters.js index 35764d6..6a40a3d 100644 --- a/files/encounters.js +++ b/files/encounters.js @@ -58,7 +58,7 @@ export function naturalEncounter(location){ return HLabominationEncounters[randomNumber(0, HLabominationEncounters.length-1)]; } } else { - return abominationEncounters[randomNumber(0, abominationEncounters.length-1)]; + return abominationEncounters[randomNumber(0, abominationEncounters.length-1)]; } case "MWBOS": if(HLE == true){ @@ -69,7 +69,7 @@ export function naturalEncounter(location){ return HLMWBOSEncounters[randomNumber(0, HLMWBOSEncounters.length-1)]; } } else { - return MWBOSEncounters[randomNumber(0, MWBOSEncounters.length-1)]; + return MWBOSEncounters[randomNumber(0, MWBOSEncounters.length-1)]; } case "BOS": if(HLE == true){ @@ -80,7 +80,7 @@ export function naturalEncounter(location){ return HLBOSEncounters[randomNumber(0, HLBOSEncounters.length-1)]; } } else { - return BOSEncounters[randomNumber(0, BOSEncounters.length-1)]; + return BOSEncounters[randomNumber(0, BOSEncounters.length-1)]; } case "NCR": if(HLE == true){ @@ -91,7 +91,7 @@ export function naturalEncounter(location){ return HLNCREncounters[randomNumber(0, HLNCREncounters.length-1)]; } } else { - return NCREncounters[randomNumber(0, NCREncounters.length-1)]; + return NCREncounters[randomNumber(0, NCREncounters.length-1)]; } case "legion": if(HLE == true){ @@ -102,7 +102,7 @@ export function naturalEncounter(location){ return HLlegionEncounters[randomNumber(0, HLlegionEncounters.length-1)]; } } else { - return legionEncounters[randomNumber(0, legionEncounters.length-1)]; + return legionEncounters[randomNumber(0, legionEncounters.length-1)]; } case "settler": if(HLE == true){ @@ -113,7 +113,7 @@ export function naturalEncounter(location){ return HLsettlerEncounters[randomNumber(0, HLsettlerEncounters.length-1)]; } } else { - return settlerEncounters[randomNumber(0, settlerEncounters.length-1)]; + return settlerEncounters[randomNumber(0, settlerEncounters.length-1)]; } case "raider": if(HLE == true){ @@ -124,7 +124,7 @@ export function naturalEncounter(location){ return HLraiderEncounters[randomNumber(0, HLraiderEncounters.length-1)]; } } else { - return raiderEncounters[randomNumber(0, raiderEncounters.length-1)]; + return raiderEncounters[randomNumber(0, raiderEncounters.length-1)]; } } } else { @@ -172,34 +172,72 @@ export function forcedEncounter(HLE, faction, forcedHLE){ } var raiderEncounters = [ - {name: "Raider Aspirant", faction: "raider", minLevel: 5, maxLevel: 15, damageClass: "B", minDamage: 5, maxDamage: 10} + {name: "Raider Aspirant", faction: "raider", minLevel: 1, maxLevel: 15, damageClass: "B", minDamage: 5, maxDamage: 10}, + {name: "Raider", faction: "raider", minLevel: 15, maxLevel: 25, damageClass: "B", minDamage: 10, maxDamage: 20}, + {name: "Raider Scavenger", faction: "raider", minLevel: 25, maxLevel: 35, damageClass: "B", minDamage: 20, maxDamage: 30} ]; var HLraiderEncounters = [ + {name: "Raider Enforcer", faction: "raider", minLevel: 35, maxLevel: 50, damageClass: "B", minDamage: 30, maxDamage: 40}, + {name: "Raider Warlord", faction: "raider", minLevel: 50, maxLevel: 65, damageClass: "B", minDamage: 40, maxDamage: 50}, + {name: "Raider Boss", faction: "raider", minLevel: 65, maxLevel: 80, damageClass: "B", minDamage: 50, maxDamage: 60} ]; var MWBOSEncounters = [ - {name: "MWBOS Paladin", faction: "MWBOS", minLevel: 40, maxLevel: 65, damageClass: "E", minDamage: 5, maxDamage: 40} + {name: "MWBOS Initiate", faction: "MWBOS", minLevel: 5, maxLevel: 10, damageClass: "E", minDamage: 5, maxDamage: 40}, + {name: "MWBOS Knight", faction: "MWBOS", minLevel: 15, maxLevel: 20, damageClass: "E", minDamage: 40, maxDamage: 60}, + {name: "MWBOS Knight Captain", faction: "MWBOS", minLevel: 25, maxLevel: 30, damageClass: "E", minDamage: 60, maxDamage: 80} ]; var HLMWBOSEncounters = [ + {name: "MWBOS Paladin", faction: "MWBOS", minLevel: 35, maxLevel: 40, damageClass: "E", minDamage: 60, maxDamage: 80}, + {name: "MWBOS Star Paladin", faction: "MWBOS", minLevel: 45, maxLevel: 50, damageClass: "E", minDamage: 80, maxDamage: 100}, + {name: "MWBOS Head Paladin", faction: "MWBOS", minLevel: 55, maxLevel: 60, damageClass: "E", minDamage: 100, maxDamage: 120} ]; var abominationEncounters = [ - {name: "Deathclaw", faction: "abomination", minLevel: 50, maxLevel: 100, damageClass: "B", minDamage: 35, maxDamage: 75} + {name: "Mole Rat", faction: "abomination", minLevel: 1, maxLevel: 15, damageClass: "B", minDamage: 1, maxDamage: 5}, + {name: "Mongrel", faction: "abomination", minLevel: 15, maxLevel: 30, damageClass: "B", minDamage: 5, maxDamage: 10}, + {name: "Radscorpion", faction: "abomination", minLevel: 30, maxLevel: 50, damageClass: "B", minDamage: 5, maxDamage: 10}, ]; var HLabominationEncounters = [ + {name: "Super Mutant", faction: "abomination", minLevel: 50, maxLevel: 65, damageClass: "B", minDamage: 5, maxDamage: 10}, + {name: "Tunneler", faction: "abomination", minLevel: 65, maxLevel: 80, damageClass: "B", minDamage: 5, maxDamage: 10}, + {name: "Deathclaw", faction: "abomination", minLevel: 80, maxLevel: 100, damageClass: "B", minDamage: 5, maxDamage: 10}, ]; var NCREncounters = [ + {name: "NCR Trooper", faction: "NCR", minLevel: 40, maxLevel: 70, damageClass: "B", minDamage: 5, maxDamage: 10}, + {name: "NCR Ranger", faction: "NCR", minLevel: 50, maxLevel: 70, damageClass: "B", minDamage: 10, maxDamage: 20}, + {name: "NCR Commander", faction: "NCR", minLevel: 60, maxLevel: 70, damageClass: "B", minDamage: 20, maxDamage: 30} ]; var HLNCREncounters = [ + {name: "NCR Heavy Trooper", faction: "NCR", minLevel: 70, maxLevel: 100, damageClass: "B", minDamage: 30, maxDamage: 40}, + {name: "NCR Veteran Ranger", faction: "NCR", minLevel: 80, maxLevel: 100, damageClass: "B", minDamage: 40, maxDamage: 50}, + {name: "NCR General", faction: "NCR", minLevel: 90, maxLevel: 100, damageClass: "B", minDamage: 50, maxDamage: 60} ]; -var BOSEncounters = [ +var BOSEncounters = [ //Reduntant, your not gonna encounter a low level Lost Hills BOS encounter + {name: "BOS Paladin", faction: "BOS", minLevel: 60, maxLevel: 80, damageClass: "E", minDamage: 60, maxDamage: 80}, + {name: "BOS Star Paladin", faction: "BOS", minLevel: 70, maxLevel: 90, damageClass: "E", minDamage: 80, maxDamage: 100}, + {name: "BOS Head Paladin", faction: "BOS", minLevel: 80, maxLevel: 100, damageClass: "E", minDamage: 100, maxDamage: 120} ]; var HLBOSEncounters = [ + {name: "BOS Paladin", faction: "BOS", minLevel: 60, maxLevel: 80, damageClass: "E", minDamage: 60, maxDamage: 80}, + {name: "BOS Star Paladin", faction: "BOS", minLevel: 70, maxLevel: 90, damageClass: "E", minDamage: 80, maxDamage: 100}, + {name: "BOS Head Paladin", faction: "BOS", minLevel: 80, maxLevel: 100, damageClass: "E", minDamage: 100, maxDamage: 120} ]; var settlerEncounters = [ - {name: "John Settler", faction: "settler", minLevel: 1, maxLevel: 2, damageClass: "B", minDamage: 1, maxDamage: 2} + {name: "John Settler", faction: "settler", minLevel: 1, maxLevel: 2, damageClass: "B", minDamage: 1, maxDamage: 2}, + {name: "Settler", faction: "settler", minLevel: 2, maxLevel: 3, damageClass: "B", minDamage: 2, maxDamage: 3}, + {name: "Settler Scavenger", faction: "settler", minLevel: 3, maxLevel: 4, damageClass: "B", minDamage: 3, maxDamage: 4}, ]; var HLsettlerEncounters = [ + {name: "Settler Gaurdsman", faction: "settler", minLevel: 4, maxLevel: 5, damageClass: "B", minDamage: 4, maxDamage: 5}, + {name: "Settler Enforcer", faction: "settler", minLevel: 5, maxLevel: 6, damageClass: "B", minDamage: 5, maxDamage: 6}, + {name: "Settler Sheriff", faction: "settler", minLevel: 6, maxLevel: 7, damageClass: "B", minDamage: 6, maxDamage: 7}, ]; var legionEncounters = [ + {name: "Legion Recruit", faction: "legion", minLevel: 30, maxLevel: 40, damageClass: "B", minDamage: 1, maxDamage: 2}, + {name: "Legionary", faction: "legion", minLevel: 40, maxLevel: 50, damageClass: "B", minDamage: 2, maxDamage: 3}, + {name: "Legion Vexillarius", faction: "legion", minLevel: 50, maxLevel: 60, damageClass: "B", minDamage: 3, maxDamage: 4}, ]; var HLlegionEncounters = [ + {name: "Legion Decanus", faction: "legion", minLevel: 60, maxLevel: 70, damageClass: "B", minDamage: 4, maxDamage: 5}, + {name: "Legion Centurion", faction: "legion", minLevel: 70, maxLevel: 80, damageClass: "B", minDamage: 5, maxDamage: 6}, + {name: "Legion Praetorian", faction: "legion", minLevel: 80, maxLevel: 90, damageClass: "B", minDamage: 6, maxDamage: 7}, ]; \ No newline at end of file diff --git a/files/functions.js b/files/functions.js index 71ccb9c..911fb4c 100755 --- a/files/functions.js +++ b/files/functions.js @@ -28,7 +28,6 @@ export function randomNumber(min, max) { // Takes in two parameters, min and max return randNum; } - // Used for game export function healthCapCalc() { // Calculates HP cap given current radPoints healthCap = healthCap-radPoints; @@ -85,24 +84,24 @@ export function calcLocation() { } if (walkRate == 2) { if (path == 0) { - location * 2; + location + 2; } if (path == 1) { - locationA * 2; + locationA + 2; } if (path == 2) { - locationB * 2; + locationB + 2; } } if (walkRate == 3) { if (path == 0) { - location * 3; + location + 3; } if (path == 1) { - locationA * 3; + locationA + 3; } if (path == 2) { - locationB * 3; + locationB + 3; } } } @@ -174,7 +173,7 @@ function death3(dc) { function death4(dc) { console.clear(); sleep(2); - console.log("You have been killed, therefore you are DEAD...\n\n"); + console.log("You have been killed, therefore you are dead...\n\n"); console.log(" \\|/"); console.log(" _/\\___<0> | "); console.log("-------------------------------\n\n"); @@ -226,10 +225,10 @@ export function travelScreen() { console.log("│ . . - . . - . . . - │"); console.log("│ - . . . . . . - . .│"); console.log("└──────────────────────────────────────┘"); - console.log("Press [ENTER] to open Pip-Boy"); + console.log("Press [SPACE] to open Pip-Boy"); console.log("Current Health: "+health); console.log("Food Amt: "+food); - console.log("Distance to next POI: "); + console.log("Distance to next POI: " + pois[poiCounter].location-location); travelFrame++ } else if (travelFrame == 1) { console.clear(); @@ -248,10 +247,10 @@ export function travelScreen() { console.log("│ - . - . . . - . - . │"); console.log("│ - . . - . . . - .│"); console.log("└──────────────────────────────────────┘"); - console.log("Press [ENTER] to open Pip-Boy"); + console.log("Press [SPACE] to open Pip-Boy"); console.log("Current Health: "+health); console.log("Food Amt: "+food); - console.log("Distance to next POI: "); + console.log("Distance to next POI: " + pois[poiCounter].location-location); travelFrame++ } else if (travelFrame == 2) { console.clear(); @@ -270,10 +269,10 @@ export function travelScreen() { console.log("│ - . - . . . - . - . │"); console.log("│ - . . - . . . - .│"); console.log("└──────────────────────────────────────┘"); - console.log("Press [ENTER] to open Pip-Boy"); + console.log("Press [SPACE] to open Pip-Boy"); console.log("Current Health: "+health); console.log("Food Amt: "+food); - console.log("Distance to next POI: "); + console.log("Distance to next POI: " + pois[poiCounter].location-location); travelFrame++ } else if (travelFrame == 3) { console.clear(); @@ -292,10 +291,10 @@ export function travelScreen() { console.log("│ - . - . . . - . - . │"); console.log("│ - . . - . . . - .│"); console.log("└──────────────────────────────────────┘"); - console.log("Press [ENTER] to open Pip-Boy"); + console.log("Press [SPACE] to open Pip-Boy"); console.log("Current Health: "+health); console.log("Food Amt: "+food); - console.log("Distance to next POI: "); + console.log("Distance to next POI: " + pois[poiCounter].location-location); travelFrame=0; } } @@ -360,7 +359,7 @@ export function pauseScreen() { console.log ("3) View Distances"); console.log ("4) View Stats"); console.log ("5) Scavenge"); - console.log ("6) Test Death"); + console.log ("6) Change Speed/Food Rate"); let pauseInput = userInput("Enter: "); switch(pauseInput) { case "1": @@ -371,7 +370,6 @@ export function pauseScreen() { break; case "3": console.clear(); - console.log("Current Location: "+location); if (path == 0) { console.log("Current Path: Main"); } @@ -396,7 +394,7 @@ export function pauseScreen() { console.log(pois[i].name+" - "+visited[i]); } if (pois[i].visited == false) { - console.log("??? "+pois[i].location-location+" location points away"); + console.log("??? "+pois[i].location-locationA+" location points away"); } } } @@ -406,7 +404,7 @@ export function pauseScreen() { console.log(pois[i].name+" - "+visited[i]); } if (pois[i].visited == false) { - console.log("??? "+pois[i].location-location+" location points away"); + console.log("??? "+pois[i].location-locationB+" location points away"); } } } @@ -424,7 +422,7 @@ export function pauseScreen() { console.log("Walk Rate: "+walkRate); console.log("Food Amt: "+food); console.log("Food Rate: "+foodRate); - console.log("Current Location: "+location); + console.log("Distance to next POI: " + pois[poiCounter].location-location); console.log("Current Path: "+path); userInput("\n[Press Enter to return]"); break; @@ -432,7 +430,38 @@ export function pauseScreen() { scavenge(); break; case "6": - testDeath = true; + console.clear(); + console.log("Current Walk Rate: "+walkRate); + console.log("Current Food Rate: "+foodRate); + console.log("---------------------------"); + console.log("What would you like to change?"); + console.log("---------------------------"); + console.log("1) Walk Rate"); + console.log("2) Food Rate"); + let rateInput = userInput("Enter: "); + switch(rateInput) { + case "1": + console.log("Current Walk Rate: "+walkRate); + let walkRateInput = userInput("Enter new Walk Rate (1-3): "); + if (walkRateInput >= 1 && walkRateInput <= 3) { + walkRate = walkRateInput; + } else { + console.log("Invalid input. Walk Rate not changed."); + } + break; + case "2": + console.log("Current Food Rate: "+foodRate); + let foodRateInput = userInput("Enter new Food Rate (1-3): "); + if (foodRateInput >= 1 && foodRateInput <= 3) { + foodRate = foodRateInput; + } else { + console.log("Invalid input. Food Rate not changed."); + } + break; + default: + console.log("Invalid input. No changes made."); + } + userInput("\n[Press Enter to return]"); break; } } \ No newline at end of file diff --git a/files/main.js b/files/main.js index d2a2bb4..5651d5e 100755 --- a/files/main.js +++ b/files/main.js @@ -1,5 +1,5 @@ // Program is started from here, runs functions from other files. -import { userInput, sleep, disableRawMode, walkPathMain } from './functions.js'; +import { userInput, sleep, disableRawMode, walkPathMain, randomNumber, removeDuplicates } from './functions.js'; import { forcedEncounter, naturalEncounter } from './encounters.js'; import { ravenRockStore } from './shops.js'; @@ -12,8 +12,6 @@ console.log(" / ' / / / console.log("---/__-------__---/---/----__---------_/_---------/-------__----__----__---__----__---_--_----__-------/___ /----__----__----__-/-"); console.log(" / / ) / / / ) / / / o / / ) / ) /___) (_ ` / ) / / ) /___) / | / ) / ) / / "); console.log("_/________(___(_/___/___(___/_(___(__(_ __o_____/____/_(___/_/___/_(___ _(__)_(___/_/_/__/_(___ _____/_____|__(___/_(___(_(___/___\n\n"); - - await sleep(1); console.log("What would you like to do?"); @@ -36,12 +34,23 @@ switch(mainMenuInput) { case "3": console.log("Quitting Game..."); await sleep(1); - break; + exit(0); case "4": console.log("Credits:"); console.log("Bethesda Game Studios - The Fallout IP and related characters/lore"); console.log("Readline-sync - NPM package used for async collection of user input"); - break; + break; + case "5": + var thing1 = [1,2,3,4,5,6,7,8,9]; + var thing2 = [1, 2, 3, 4, 5, 6, 7, 8, 9]; + var thing3 = []; + while (thing3.length < 6) { + let randomPick = randomNumber(1,thing2.length); + thing3.push(thing2[randomPick]); + thing2.pop(randomPick); + } + console.log(thing2); + break; } function startGame() { // So far what I have is filler and testing, feel free to change. diff --git a/files/poiscreens.js b/files/poiscreens.js index 912bce5..a8d737a 100644 --- a/files/poiscreens.js +++ b/files/poiscreens.js @@ -463,6 +463,9 @@ function hub() { case "2": pauseScreen(); case "3": + trader(); + break; + case "4": enableRawMode(); console.clear(); break; @@ -478,6 +481,7 @@ function lostHills() { console.log("What would you like to do?"); console.log("1) Explore"); console.log("2) Open your PIP-Boy"); + console.log("3) Attempt to trade"); console.log("4) Leave"); let poiInput = userInput("Enter: "); switch(poiInput) { @@ -488,6 +492,9 @@ function lostHills() { case "2": pauseScreen(); case "3": + lostHillsStore(); + break; + case "4": enableRawMode(); console.clear(); break; diff --git a/files/shops.js b/files/shops.js index 2351eb6..f382073 100644 --- a/files/shops.js +++ b/files/shops.js @@ -2,20 +2,134 @@ import { randomNumber, userInput } from "./functions.js"; import "./variables.js"; // Inventories for the various shops, based of global item lists -// Most item prices in Raven Rock and Eureka are multiplied by 10, as they are using pre-war money var rrInv = [ + {item: supplyList[0], name: supplyList[0].name, price: supplyList[0].cost/10, amount: 1000}, + {item: supplyList[1], name: supplyList[1].name, price: supplyList[1].cost, amount: 100}, + {item: supplyList[2], name: supplyList[2].name, price: supplyList[2].cost, amount: 100}, + {item: supplyList[3], name: supplyList[3].name, price: supplyList[3].cost, amount: 100}, + {item: equipmentList[0], name: equipmentList[0].name, price: equipmentList[0].cost, amount: 10}, + {item: equipmentList[2], name: equipmentList[2].name, price: equipmentList[2].cost, amount: 10}, + {item: equipmentList[8], name: equipmentList[8].name, price: equipmentList[8].cost, amount: 10}, +]; +var vt0Inv = [ {item: supplyList[0], name: supplyList[0].name, price: supplyList[0].cost, amount: 1000}, {item: supplyList[1], name: supplyList[1].name, price: supplyList[1].cost*10, amount: 100}, {item: supplyList[2], name: supplyList[2].name, price: supplyList[2].cost*10, amount: 100}, {item: supplyList[3], name: supplyList[3].name, price: supplyList[3].cost*10, amount: 100}, - {item: equipmentList[0], name: equipmentList[0].name, price: equipmentList[0].cost*10, amount: 10}, - {item: equipmentList[2], name: equipmentList[2].name, price: equipmentList[1].cost*10, amount: 10}, - {item: equipmentList[8], name: equipmentList[8].name, price: equipmentList[2].cost*10, amount: 10}, + {item: equipmentList[0], name: equipmentList[0].name, price: equipmentList[0].cost, amount: 10}, + {item: equipmentList[2], name: equipmentList[2].name, price: equipmentList[2].cost, amount: 10}, + {item: equipmentList[2], name: equipmentList[3].name, price: equipmentList[3].cost, amount: 10}, + {item: equipmentList[4], name: equipmentList[4].name, price: equipmentList[4].cost, amount: 10}, + {item: equipmentList[5], name: equipmentList[5].name, price: equipmentList[5].cost, amount: 10}, + {item: equipmentList[8], name: equipmentList[8].name, price: equipmentList[8].cost, amount: 10}, + {item: equipmentList[9], name: equipmentList[9].name, price: equipmentList[9].cost, amount: 10}, + {item: equipmentList[11], name: equipmentList[11].name, price: equipmentList[11].cost, amount: 10}, +]; +var vegasInv = [ + {item: supplyList[0], name: supplyList[0].name, price: supplyList[0].cost, amount: 1000}, + {item: supplyList[1], name: supplyList[1].name, price: supplyList[1].cost, amount: 100}, + {item: supplyList[2], name: supplyList[2].name, price: supplyList[2].cost, amount: 100}, + {item: supplyList[3], name: supplyList[3].name, price: supplyList[3].cost, amount: 100}, + {item: supplyList[4], name: supplyList[4].name, price: supplyList[4].cost, amount: 100}, + {item: supplyList[5], name: supplyList[5].name, price: supplyList[5].cost, amount: 100}, + {item: equipmentList[0], name: equipmentList[0].name, price: equipmentList[0].cost, amount: 10}, + {item: equipmentList[2], name: equipmentList[2].name, price: equipmentList[2].cost, amount: 10}, + {item: equipmentList[3], name: equipmentList[3].name, price: equipmentList[3].cost, amount: 10}, + {item: equipmentList[4], name: equipmentList[4].name, price: equipmentList[4].cost, amount: 10}, + {item: equipmentList[5], name: equipmentList[5].name, price: equipmentList[5].cost, amount: 10}, + {item: equipmentList[9], name: equipmentList[9].name, price: equipmentList[9].cost, amount: 10}, + {item: equipmentList[11], name: equipmentList[11].name, price: equipmentList[11].cost, amount: 10}, +]; +var eurInv = [ + {item: supplyList[0], name: supplyList[0].name, price: supplyList[0].cost, amount: 1000}, + {item: supplyList[1], name: supplyList[1].name, price: supplyList[1].cost, amount: 100}, + {item: supplyList[2], name: supplyList[2].name, price: supplyList[2].cost, amount: 100}, + {item: supplyList[3], name: supplyList[3].name, price: supplyList[3].cost, amount: 100}, + {item: supplyList[4], name: supplyList[4].name, price: supplyList[4].cost, amount: 100}, + {item: supplyList[5], name: supplyList[5].name, price: supplyList[5].cost, amount: 100}, + {item: equipmentList[0], name: equipmentList[0].name, price: equipmentList[0].cost, amount: 10}, + {item: equipmentList[2], name: equipmentList[2].name, price: equipmentList[2].cost, amount: 10}, + {item: equipmentList[3], name: equipmentList[3].name, price: equipmentList[3].cost, amount: 10}, + {item: equipmentList[4], name: equipmentList[4].name, price: equipmentList[4].cost, amount: 10}, + {item: equipmentList[5], name: equipmentList[5].name, price: equipmentList[5].cost, amount: 10}, + {item: equipmentList[6], name: equipmentList[6].name, price: equipmentList[6].cost, amount: 10}, + {item: equipmentList[7], name: equipmentList[7].name, price: equipmentList[7].cost, amount: 10}, + {item: equipmentList[9], name: equipmentList[9].name, price: equipmentList[9].cost, amount: 10}, + {item: equipmentList[11], name: equipmentList[11].name, price: equipmentList[12].cost, amount: 10}, + {item: equipmentList[12], name: equipmentList[12].name, price: equipmentList[12].cost, amount: 10}, +]; +var traderInv = [ + [ // Tier 1 + {item: supplyList[0], name: supplyList[0].name, price: supplyList[0].cost/10, amount: 1000}, + {item: supplyList[1], name: supplyList[1].name, price: supplyList[1].cost, amount: 100}, + {item: supplyList[2], name: supplyList[2].name, price: supplyList[2].cost, amount: 100}, + {item: supplyList[3], name: supplyList[3].name, price: supplyList[3].cost, amount: 100}, + {item: equipmentList[0], name: equipmentList[0].name, price: equipmentList[0].cost, amount: 10}, + {item: equipmentList[1], name: equipmentList[1].name, price: equipmentList[1].cost, amount: 10}, + {item: equipmentList[2], name: equipmentList[2].name, price: equipmentList[2].cost, amount: 10}, + {item: equipmentList[3], name: equipmentList[3].name, price: equipmentList[3].cost, amount: 10}, + {item: equipmentList[8], name: equipmentList[8].name, price: equipmentList[8].cost, amount: 10}, + ], + [ // Tier 2 + {item: supplyList[0], name: supplyList[0].name, price: supplyList[0].cost, amount: 1000}, + {item: supplyList[1], name: supplyList[1].name, price: supplyList[1].cost, amount: 100}, + {item: supplyList[2], name: supplyList[2].name, price: supplyList[2].cost, amount: 100}, + {item: supplyList[3], name: supplyList[3].name, price: supplyList[3].cost, amount: 100}, + {item: supplyList[4], name: supplyList[4].name, price: supplyList[4].cost, amount: 100}, + {item: supplyList[5], name: supplyList[5].name, price: supplyList[5].cost, amount: 100}, + {item: equipmentList[0], name: equipmentList[0].name, price: equipmentList[0].cost, amount: 10}, + {item: equipmentList[2], name: equipmentList[2].name, price: equipmentList[2].cost, amount: 10}, + {item: equipmentList[3], name: equipmentList[3].name, price: equipmentList[3].cost, amount: 10}, + {item: equipmentList[4], name: equipmentList[4].name, price: equipmentList[4].cost, amount: 10}, + {item: equipmentList[5], name: equipmentList[5].name, price: equipmentList[5].cost, amount: 10}, + {item: equipmentList[9], name: equipmentList[9].name, price: equipmentList[9].cost, amount: 10}, + {item: equipmentList[11], name: equipmentList[11].name, price: equipmentList[11].cost, amount: 10}, + ], + [ // Tier 3 + {item: supplyList[0], name: supplyList[0].name, price: supplyList[0].cost, amount: 1000}, + {item: supplyList[1], name: supplyList[1].name, price: supplyList[1].cost, amount: 100}, + {item: supplyList[2], name: supplyList[2].name, price: supplyList[2].cost, amount: 100}, + {item: supplyList[3], name: supplyList[3].name, price: supplyList[3].cost, amount: 100}, + {item: supplyList[4], name: supplyList[4].name, price: supplyList[4].cost, amount: 100}, + {item: supplyList[5], name: supplyList[5].name, price: supplyList[5].cost, amount: 100}, + {item: equipmentList[0], name: equipmentList[0].name, price: equipmentList[0].cost, amount: 10}, + {item: equipmentList[2], name: equipmentList[2].name, price: equipmentList[2].cost, amount: 10}, + {item: equipmentList[3], name: equipmentList[3].name, price: equipmentList[3].cost, amount: 10}, + {item: equipmentList[4], name: equipmentList[4].name, price: equipmentList[4].cost, amount: 10}, + {item: equipmentList[5], name: equipmentList[5].name, price: equipmentList[5].cost, amount: 10}, + {item: equipmentList[6], name: equipmentList[6].name, price: equipmentList[6].cost, amount: 10}, + {item: equipmentList[7], name: equipmentList[7].name, price: equipmentList[7].cost, amount: 10}, + {item: equipmentList[9], name: equipmentList[9].name, price: equipmentList[9].cost, amount: 10}, + {item: equipmentList[11], name: equipmentList[11].name, price: equipmentList[12].cost, amount: 10}, + {item: equipmentList[12], name: equipmentList[12].name, price: equipmentList[12].cost, amount: 10}, + ] +]; +var tempTraderInv = []; +var whitespringInv = [ + {item: supplyList[0], name: supplyList[0].name, price: supplyList[0].cost/10, amount: 1000}, + {item: supplyList[1], name: supplyList[1].name, price: supplyList[1].cost, amount: 100}, + {item: supplyList[2], name: supplyList[2].name, price: supplyList[2].cost, amount: 100}, + {item: supplyList[3], name: supplyList[3].name, price: supplyList[3].cost, amount: 100}, + {item: equipmentList[0], name: equipmentList[0].name, price: equipmentList[0].cost, amount: 10}, + {item: equipmentList[1], name: equipmentList[1].name, price: equipmentList[1].cost, amount: 10}, + {item: equipmentList[2], name: equipmentList[2].name, price: equipmentList[2].cost, amount: 10}, + {item: equipmentList[3], name: equipmentList[3].name, price: equipmentList[3].cost, amount: 10}, + {item: equipmentList[8], name: equipmentList[8].name, price: equipmentList[8].cost, amount: 10}, +]; +var lostHillsInv = [ + {item: supplyList[0], name: supplyList[0].name, price: supplyList[0].cost, amount: 1000}, + {item: supplyList[1], name: supplyList[1].name, price: supplyList[1].cost, amount: 100}, + {item: supplyList[2], name: supplyList[2].name, price: supplyList[2].cost, amount: 100}, + {item: supplyList[3], name: supplyList[3].name, price: supplyList[3].cost, amount: 100}, + {item: supplyList[4], name: supplyList[4].name, price: supplyList[4].cost, amount: 100}, + {item: equipmentList[0], name: equipmentList[0].name, price: equipmentList[0].cost, amount: 10}, + {item: equipmentList[2], name: equipmentList[2].name, price: equipmentList[2].cost, amount: 10}, + {item: equipmentList[4], name: equipmentList[4].name, price: equipmentList[4].cost, amount: 10}, + {item: equipmentList[5], name: equipmentList[5].name, price: equipmentList[5].cost, amount: 10}, + {item: equipmentList[6], name: equipmentList[6].name, price: equipmentList[6].cost, amount: 10}, + {item: equipmentList[7], name: equipmentList[7].name, price: equipmentList[7].cost, amount: 10}, + {item: equipmentList[12], name: equipmentList[12].name, price: equipmentList[12].cost, amount: 10}, ]; -var vt0Inv = []; -var vegasInv = []; // A mix of gunrunners, mick&ralphs, and followers -var eurInv = []; -var traderInv = []; export function ravenRockStore() { while (true) { @@ -24,7 +138,7 @@ export function ravenRockStore() { console.log("Name | Price (PW Money) | Amount in stock"); console.log("-----------------------------------------------------"); for (var i = 0; i < rrInv.length; i++) { - console.log(i+"). " + rrInv[i].name + " | " + rrInv[i].price + " | " + rrInv[i].amount); + console.log(i+"). " + rrInv[i].name + " | " + rrInv[i].price*10 + " | " + rrInv[i].amount); } console.log("-----------------------------------------------------"); console.log("You have " + preWarMoney + " pre-war money."); @@ -41,12 +155,12 @@ export function ravenRockStore() { console.log("Not enough stock."); userInput("[Enter]"); break; - } else if (itemAmt * rrInv[itemNum].price > preWarMoney) { + } else if (itemAmt * rrInv[itemNum].price*10 > preWarMoney) { console.log("Not enough money."); userInput("[Enter]"); break; } else { - preWarMoney -= itemAmt * rrInv[itemNum].price; + 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."); @@ -161,7 +275,7 @@ export function eurekaStore() { console.log("Name | Price (PW Money) | Amount in stock"); console.log("-----------------------------------------------------"); for (var i = 0; i < eurInv.length; i++) { - console.log(i+"). " + eurInv[i].item + " | " + eurInv[i].price + " | " + eurInv[i].amount); + console.log(i+"). " + eurInv[i].item + " | " + eurInv[i].price*10 + " | " + eurInv[i].amount); } console.log("-----------------------------------------------------"); console.log("You have " + preWarMoney + " pre-war money."); @@ -177,11 +291,11 @@ export function eurekaStore() { if (itemAmt > eurInv[itemNum].amount) { console.log("Not enough stock."); break; - } else if (itemAmt * eurInv[itemNum].price > preWarMoney) { + } else if (itemAmt * eurInv[itemNum].price*10 > preWarMoney) { console.log("Not enough money."); break; } else { - preWarMoney -= itemAmt * eurInv[itemNum].price; + preWarMoney -= itemAmt * eurInv[itemNum].price*10; eurInv[itemNum].amount -= itemAmt; console.log("You bought " + itemAmt + " " + eurInv[itemNum].item + "(s)."); console.log("You have " + preWarMoney + " pre-war money left."); @@ -198,98 +312,37 @@ export function eurekaStore() { } } -export function trader() { // Picks a selection of items from a global trader inventory, used for misc area shops - var tempTraderInv = []; - for (var a = 0; a <= 2; a++) { - let randomPick = randomNumber() - tempTraderInv.push(traderInv[1]); - console.log(randomPick); - } - console.log(tempTraderInv); - +export function lostHillsStore() { while (true) { console.clear(); - console.log("You attempt to trade with a local trader, this is thier selection."); + console.log("Brotherhood of Steel Requisition System - Lost Hills"); console.log("Name | Price (Caps) | Amount in stock"); console.log("-----------------------------------------------------"); - for (var i = 0; i < Inv.length; i++) { - console.log(i+"). " + rrInv[i].item + " | " + rrInv[i].price + " | " + rrInv[i].amount); + for (var i = 0; i < lostHillsInv.length; i++) { + console.log(i+"). " + lostHillsInv[i].item + " | " + lostHillsInv[i].price + " | " + lostHillsInv[i].amount); } console.log("-----------------------------------------------------"); - console.log("You have " + preWarMoney + " pre-war money."); + console.log("You have " + caps + " caps."); console.log("What would you like to do?"); console.log("1) Buy supplies"); console.log("2) Leave shop"); - var rrInput = userInput("Enter: "); - switch(rrInput) { + var lostHillsInput = userInput("Enter: "); + switch(lostHillsInput) { case "1": console.log("What would you like to buy?"); let itemNum = userInput("Enter item number: "); let itemAmt = userInput("Enter amount: "); - if (itemAmt > rrInv[itemNum].amount) { + if (itemAmt > lostHillsInv[itemNum].amount) { console.log("Not enough stock."); break; - } else if (itemAmt * rrInv[itemNum].price > preWarMoney) { + } else if (itemAmt * lostHillsInv[itemNum].price > caps) { console.log("Not enough money."); break; } else { - preWarMoney -= itemAmt * rrInv[itemNum].price; - rrInv[itemNum].amount -= itemAmt; - console.log("You bought " + itemAmt + " " + rrInv[itemNum].item + "(s)."); - console.log("You have " + preWarMoney + " pre-war money left."); - console.log("Press enter to continue..."); - userInput("[Enter]"); - } - break; - case "2": - console.log("Leaving shop..."); - return true; - break; - default: - console.log("Invalid input, try again."); - } - } -} - -export function genericBOSStore(poiName) { // Picks a selection of items from a global trader inventory, used for misc area shops - var tempTraderInv = []; - for (var a = 0; a <= 2; a++) { - let randomPick = randomNumber() - tempTraderInv.push(traderInv[1]); - console.log(randomPick); - } - console.log(tempTraderInv); - - while (true) { - console.clear(); - console.log("Brotherhood of Steel Requisition System - "+poiName); - console.log("Name | Price (Caps) | Amount in stock"); - console.log("-----------------------------------------------------"); - for (var i = 0; i < Inv.length; i++) { - console.log(i+"). " + rrInv[i].item + " | " + rrInv[i].price + " | " + rrInv[i].amount); - } - console.log("-----------------------------------------------------"); - console.log("You have " + preWarMoney + " pre-war money."); - console.log("What would you like to do?"); - console.log("1) Buy supplies"); - console.log("2) Leave shop"); - var rrInput = userInput("Enter: "); - switch(rrInput) { - case "1": - console.log("What would you like to buy?"); - let itemNum = userInput("Enter item number: "); - let itemAmt = userInput("Enter amount: "); - if (itemAmt > rrInv[itemNum].amount) { - console.log("Not enough stock."); - break; - } else if (itemAmt * rrInv[itemNum].price > preWarMoney) { - console.log("Not enough money."); - break; - } else { - preWarMoney -= itemAmt * rrInv[itemNum].price; - rrInv[itemNum].amount -= itemAmt; - console.log("You bought " + itemAmt + " " + rrInv[itemNum].item + "(s)."); - console.log("You have " + preWarMoney + " pre-war money left."); + caps -= itemAmt * lostHillsInv[itemNum].price; + lostHillsInv[itemNum].amount -= itemAmt; + console.log("You bought " + itemAmt + " " + lostHillsInv[itemNum].item + "(s)."); + console.log("You have " + caps + " caps left."); console.log("Press enter to continue..."); userInput("[Enter]"); } @@ -309,30 +362,30 @@ export function whitespringStore() { console.log("Welcome to the Whitespring Mall. Selection pulls from all vendors.") console.log("Name | Price (Caps) | Amount in stock"); console.log("-----------------------------------------------------"); - for (var i = 0; i < vt0InvInv.length; i++) { - console.log(i+"). " + vt0InvInv[i].item + " | " + vtInv[i].price + " | " + vtInv[i].amount); + for (var i = 0; i < whitespringInv.length; i++) { + console.log(i+"). " + whitespringInv[i].item + " | " + whitespringInv[i].price + " | " + whitespringInv[i].amount); } console.log("-----------------------------------------------------"); console.log("You have " + caps + " caps."); console.log("What would you like to do?"); console.log("1) Buy supplies"); console.log("2) Leave shop"); - var vt0Input = userInput("Enter: "); - switch(vt0Input) { + var whitespringInput = userInput("Enter: "); + switch(whitespringInput) { case "1": console.log("What would you like to buy?"); let itemNum = userInput("Enter item number: "); let itemAmt = userInput("Enter amount: "); - if (itemAmt > vt0Inv[itemNum].amount) { + if (itemAmt > whitespringInv[itemNum].amount) { console.log("Not enough stock."); break; - } else if (itemAmt * vt0Inv[itemNum].price > caps) { + } else if (itemAmt * whitespringInvv[itemNum].price > caps) { console.log("Not enough money."); break; } else { - caps -= itemAmt * vt0Inv[itemNum].price; - rrInv[itemNum].amount -= itemAmt; - console.log("You bought " + itemAmt + " " + vt0Inv[itemNum].item + "(s)."); + caps -= itemAmt * whitespringInv[itemNum].price; + whitespringInv[itemNum].amount -= itemAmt; + console.log("You bought " + itemAmt + " " + whitespringInv[itemNum].item + "(s)."); console.log("You have " + caps + " caps left."); console.log("Press enter to continue..."); userInput("[Enter]"); @@ -345,4 +398,95 @@ export function whitespringStore() { console.log("Invalid input, try again."); } } +} + +// The Trader System + +// traderLock: Prevents the player from regerating the trader's inventory before they leave the POI/Encounter +// traderInv: The global trader inventory, has a set of items for each tier of gear, pulled from the global item lists +// tempTraderInv: An array of items that the trader, when encountered, will be able to pull from for thier stock +// trader(): Called when a player barters with a trader. Fist checks to see if traderLock is false, then sets it to true. +// Then uses the tier parameter to determine which inventory to pull from. +// It then places the respective tier of equipment into the tempTraderInv array. +// The trader now randomly picks 5 items from the tempTraderInv array and places them into tempTraderStock. +// Had traderLock been true, the trader would present the previously generated stock. +// Trader then uses the same system as the other stores to allow the player to buy and view items but with a custom message +// The message is passed in as a parameter, and is displayed at the top of the trader menu. + +global.traderLock = false; +export function trader(tier, message) { + if (traderLock == false) { + traderLock = true; + var tempTraderStock = []; + var tempTraderInv = []; + switch(tier) { + case "1": + tempTraderInv = traderInv[0]; + for (var a = 0; a <= 5; a++) { + let randomPick = randomNumber(); + tempTraderStock.push(tempTraderInv[randomPick]); + tempTraderInv.pop[randomPick]; + } + break; + case "2": + tempTraderInv = traderInv[0]; + for (var a = 0; a <= 5; a++) { + let randomPick = randomNumber(); + tempTraderStock.push(tempTraderInv[randomPick]); + tempTraderInv.pop[randomPick]; + } + break; + case "3": + tempTraderInv = traderInv[0]; + for (var a = 0; a <= 5; a++) { + let randomPick = randomNumber(); + tempTraderStock.push(tempTraderInv[randomPick]); + tempTraderInv.pop[randomPick]; + } + break; + } + } + + while (true) { + console.clear(); + console.log(message); + console.log("Name | Price (Caps) | Amount in stock"); + console.log("-----------------------------------------------------"); + for (var i = 0; i < tempTraderInv.length; i++) { + console.log(i+1+"). " + tempTraderInv[i].item + " | " + tempTraderInv[i].price + " | " + tempTraderInv[i].amount); + } + console.log("-----------------------------------------------------"); + console.log("You have " + caps + " caps."); + console.log("What would you like to do?"); + console.log("1) Buy supplies"); + console.log("2) Leave shop"); + var rrInput = userInput("Enter: "); + switch(rrInput) { + case "1": + console.log("What would you like to buy?"); + let itemNum = userInput("Enter item number: "); + let itemAmt = userInput("Enter amount: "); + if (itemAmt > tempBOSStock[itemNum].amount) { + console.log("Not enough stock."); + break; + } else if (itemAmt * tempBOSStock[itemNum].price > caps) { + console.log("Not enough money."); + break; + } else { + preWarMoney -= itemAmt * tempBOSStock[itemNum].price; + tempBOSStock[itemNum].amount -= itemAmt; + console.log("You bought " + itemAmt + " " + tempBOSStock[itemNum].item + "(s)."); + console.log("You have " + caps + " caps left."); + console.log("Press enter to continue..."); + userInput("[Enter]"); + } + break; + case "2": + console.log("Leaving shop..."); + return true; + break; + default: + console.log("Invalid input, try again."); + } + } } \ No newline at end of file diff --git a/files/variables.js b/files/variables.js index cca617b..3ced373 100644 --- a/files/variables.js +++ b/files/variables.js @@ -59,11 +59,17 @@ global.equipmentList = [ // Equipment: weapons, armor, tools // Energy Resistant Armor {name: "Leather Armor", description: "A set of leather armor, good protection from laser weapons.", type: "armor", resistances: {balistic: 2, slash: 2, laser: 5, plasma: 3}, unit: "dr", cost: 5, weight: 5}, - {name: "Combat Armor", description: "A ser of combat armor, great protection from laser and plasma weapons.", type: "armor", resistances: {balistic: 5, slash: 5, laser: 10, plasma: 10}, unit: "dr", cost: 5, weight: 5}, + {name: "Sturdy Leather Armor", description: "A set of combat armor, better protection from laser and plasma weapons.", type: "armor", resistances: {balistic: 5, slash: 5, laser: 10, plasma: 10}, unit: "dr", cost: 5, weight: 5}, // Ballistic Resistant Armor {name: "Raider Armor", description: "A set of raider armor, good protection from balistic damage.", type: "armor", resistances: {balistic: 5, slash: 3, laser: 2, plasma: 2}, unit: "dr", cost: 5, weight: 5}, - {name: "Metal Armor" , description: "A set of raider armor, good protection from ballistic and slash damage.", type: "armor", resistances: {balistic: 10, slash: 10, laser: 5, plasma: 5}, unit: "dr", cost: 5, weight: 5}, + {name: "Metal Armor" , description: "A set of raider armor, better protection from ballistic and slash damage.", type: "armor", resistances: {balistic: 10, slash: 10, laser: 5, plasma: 5}, unit: "dr", cost: 5, weight: 5}, + + // Tier 3 Armor + {name: "Combat Armor", description: "A set of combat armor, better protection from all damage types.", type: "armor", resistances: {balistic: 10, slash: 10, laser: 10, plasma: 10}, unit: "dr", cost: 5, weight: 5}, + {name: "Centurion Armor", description: "A set of Centurion armor, great protection from ballistic damage.", type: "armor", value: "5", unit: "dr",cost: 25, weight: 25}, + {name: "NCR Ranger Armor" , description: "A set of NCR Ranger armor, great protection from laser and plasma weapons", type: "armor", value: "5", unit: "dr",cost: 30, weight: 30}, + // Non-specialized Power Armor {name: "T-45 Power Armor", description: "A set of T-45 Power Armor, protects against all damage types.", type: "parmor", resistances: {balistic: 15, slash: 15, laser: 15, plasma: 15}, unit: "dt", cost: 5, weight: 5}, @@ -83,10 +89,6 @@ global.equipmentList = [ // Equipment: weapons, armor, tools // Special Armor {name: "Chinese Stealth Suit", description: "Chinese Stealth Suit, +25% Chance to skip encounter if worn", type: "uarmor", value: "5", unit: "dr",cost: 20, weight: 20}, {name: "Excavator Power Armor", description: "Excavator Power Armor, +25% Chance to find extra loot", type: "parmor", resistances: {balistic: 5, slash: 5, laser: 5, plasma: 5}, unit: "dt", cost: 5, weight: 5}, - - // Even MORE Specialer Armor - {name: "Centurion Armor", description: "A set of Centurion armor, made for you", type: "armor", value: "5", unit: "dr",cost: 25, weight: 25}, - {name: "NCR Ranger Armor" , description: "A set of NCR Ranger armor, standard issue", type: "armor", value: "5", unit: "dr",cost: 30, weight: 30}, ]; global.achievements = [ From df257c6420ebae957ff18dfaed0a9f60fa543eaa Mon Sep 17 00:00:00 2001 From: Raktbastr Date: Sun, 27 Apr 2025 00:10:05 -0500 Subject: [PATCH 21/27] Combat partially done, encounters fixed. --- .vscode/settings.json | 8 ++++ TODO.md | 87 ------------------------------------------- files/combat.js | 76 +++++++++++++++++++++++++++++++++++++ files/encounters.js | 85 +++++++++++++++++++++--------------------- files/variables.js | 13 ++++++- 5 files changed, 138 insertions(+), 131 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..eecbcdc --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + "github.copilot.enable": { + "*": false, + "plaintext": false, + "markdown": false, + "scminput": false + } +} \ No newline at end of file diff --git a/TODO.md b/TODO.md index 5b6d04f..fd72a85 100644 --- a/TODO.md +++ b/TODO.md @@ -5,38 +5,9 @@ ## Game Mechanics - POI's and Factions - - Art for locations - - Raven Rock - - Whitespring - - Brotherhood Bunkers - - Tibbets - - Flagstaff - - New Vegas - - NCR Cities - - Lost Hills - - Sierra Madre - - Divide - - Eureka - - Navarro - Logic for faction armor - - Logic for calling locations at right location point (incl. different paths) - - Use the Google Earth Project for location points - Logic for path split - - Trade menus for locations - - Raven Rock - - Whitespring - - Brotherhood Bunkers - - Tibbets - - Flagstaff - - New Vegas - - NCR Cities - - Sierra Madre - - Divide - - Eureka - - Navarro - Dialogue for locations - - Raven Rock - - Whitespring - Brotherhood Bunkers - Tibbets - Flagstaff @@ -76,64 +47,6 @@ - Upper NCR - Hard Encounters -- Achievements - - Wastland Pacifier - - Clear out all Raider compounds and defeat every Raider encounter - - - Dishonourable Discharge - - Deactivate Modus - - - Force of habit - - Destroy the Midwest Brotherhood - - - 7 Karat Run - - Find the Platnium Chip - - - Profligate - - Destroy Flagstaff - - - What in the Goddamn? - - Accidentally Kill Benny at the Tops Casino - - - Just a chore, like any other - - Fight in the First Battle of Hoover Dam and defeat the Malpais Legate - - - Yes, man - - Kill Mr. House and the 2 other families, dooming New Vegas - - - Rocket's Red Glare - - Launch the nuke at Hopeville/Ashton - - - Begin Again - - Kill Father Elijah - - - Long Time Coming - - Destroy the main NCR cities or Shady Sands - - - A New Dawn For America - - Reactivate Camp Navarro with the help of Eureka - - - Against All odds - - Retrieve the Geck from Navarro with or without the help of the Remnants. - - - Finish What Was Started - - Destroy all main factions and cities - - - 510 Years - - Find and wear a suit of APA mk2 - - - High Roller - - Win 200 caps from gambling - - - Veteran Ranger - - Reach max rep with the NCR - - - Frumentari - - Reach max rep with the Legion - - - Knight Errant - - Reach max rep with the BOS - ## Story ### Intro diff --git a/files/combat.js b/files/combat.js index e69de29..5f258b7 100644 --- a/files/combat.js +++ b/files/combat.js @@ -0,0 +1,76 @@ +import './variables.js'; +import {userInput} from './functions.js'; + +function initCombat(enemy) { + if (enemy.minLevel > level) { + var enemyLevelFinal = enemy.minLevel; + } else if (enemy.maxLevel < level) { + var enemyLevelFinal = enemy.minLevel; + } else { + var enemyLevelFinal = level; + } + + if (enemy.armor.value > 85 && enemy.armor.unit == "dr") { + var enemyArmor = 85; + } else { + 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"}; +} + +function combat(enemy) { + console.clear(); + console.log("You enter combat with "+enemy.name+"..."); + 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"); + var combatInput = userInput("Enter: "); + switch(combatInput) { + case "1": + + } + + +} + + +function damageCalc(attacker) { + if (attacker = player) { + if (playerStats.chem == "psycho") { + var damageOutput = playerStats.weapon.damage*1.5; + } else { + var damageOutput = playerStats.weapon.damage; + } + + if (enemyStats.armorUnit == "dr"){ + enemyStats.health = enemyStats.health-(damageOutput-(enemyStats.armor.value/100)); + } + if (enemyStats.armorUnit == "dt") { + let dtDamage = enemyStats.health-(damageOutput-armor); + if (dtDamage < 0) { + dtDamage = 0; + } + enemyStats.health - dtDamage + } + } else { + if (playerStats.chem == "medx") { + var damageOutput = enemyStats.weapon.damage*(-1.5); + } else { + var damageOutput = enemyStats.weapon.damage; + } if (playerStats.armorUnit == "dr"){ + playerStats.health = playerStats.health-(damageOutput-(playerStats.armor.value/100)); + } + if (playerStats.armorUnit == "dt") { + let dtDamage = playerStats.health-(damageOutput-armor); + if (dtDamage < 0) { + dtDamage = 0; + } + playerStats.health - dtDamage + } + } +} + diff --git a/files/encounters.js b/files/encounters.js index 6a40a3d..3163268 100644 --- a/files/encounters.js +++ b/files/encounters.js @@ -1,6 +1,7 @@ // Holds encounter code, seperate from poiscreens.js import { randomNumber } from "./functions.js"; +import './variables.js'; //5-50 abominations, 51-200 MWBOS, 201-255 legion, a5-a40 NCR, b0-b30 abomination, b40-b80 abomination, b90+ NCR, b80-b90 enclave //HLE = high level encounter, this is a filter that determines if the player can get, as the name implies, high level encounters @@ -172,72 +173,72 @@ export function forcedEncounter(HLE, faction, forcedHLE){ } var raiderEncounters = [ - {name: "Raider Aspirant", faction: "raider", minLevel: 1, maxLevel: 15, damageClass: "B", minDamage: 5, maxDamage: 10}, - {name: "Raider", faction: "raider", minLevel: 15, maxLevel: 25, damageClass: "B", minDamage: 10, maxDamage: 20}, - {name: "Raider Scavenger", faction: "raider", minLevel: 25, maxLevel: 35, damageClass: "B", minDamage: 20, maxDamage: 30} + {name: "Raider Aspirant", faction: "raider", minLevel: 1, maxLevel: 15, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, + {name: "Raider", faction: "raider", minLevel: 15, maxLevel: 25, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, + {name: "Raider Scavenger", faction: "raider", minLevel: 25, maxLevel: 35, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, ]; var HLraiderEncounters = [ - {name: "Raider Enforcer", faction: "raider", minLevel: 35, maxLevel: 50, damageClass: "B", minDamage: 30, maxDamage: 40}, - {name: "Raider Warlord", faction: "raider", minLevel: 50, maxLevel: 65, damageClass: "B", minDamage: 40, maxDamage: 50}, - {name: "Raider Boss", faction: "raider", minLevel: 65, maxLevel: 80, damageClass: "B", minDamage: 50, maxDamage: 60} + {name: "Raider Enforcer", faction: "raider", minLevel: 35, maxLevel: 50, health: 10, weapon: equipmentList[3], armor: equipmentList[10]}, + {name: "Raider Warlord", faction: "raider", minLevel: 50, maxLevel: 65, health: 10, weapon: equipmentList[3], armor: equipmentList[10]}, + {name: "Raider Boss", faction: "raider", minLevel: 65, maxLevel: 80, health: 10, weapon: equipmentList[3], armor: equipmentList[10]}, ]; var MWBOSEncounters = [ - {name: "MWBOS Initiate", faction: "MWBOS", minLevel: 5, maxLevel: 10, damageClass: "E", minDamage: 5, maxDamage: 40}, - {name: "MWBOS Knight", faction: "MWBOS", minLevel: 15, maxLevel: 20, damageClass: "E", minDamage: 40, maxDamage: 60}, - {name: "MWBOS Knight Captain", faction: "MWBOS", minLevel: 25, maxLevel: 30, damageClass: "E", minDamage: 60, maxDamage: 80} + {name: "MWBOS Initiate", faction: "MWBOS", minLevel: 5, maxLevel: 10, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, + {name: "MWBOS Knight", faction: "MWBOS", minLevel: 15, maxLevel: 20, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, + {name: "MWBOS Knight Captain", faction: "MWBOS", minLevel: 25, maxLevel: 30, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, ]; var HLMWBOSEncounters = [ - {name: "MWBOS Paladin", faction: "MWBOS", minLevel: 35, maxLevel: 40, damageClass: "E", minDamage: 60, maxDamage: 80}, - {name: "MWBOS Star Paladin", faction: "MWBOS", minLevel: 45, maxLevel: 50, damageClass: "E", minDamage: 80, maxDamage: 100}, - {name: "MWBOS Head Paladin", faction: "MWBOS", minLevel: 55, maxLevel: 60, damageClass: "E", minDamage: 100, maxDamage: 120} + {name: "MWBOS Paladin", faction: "MWBOS", minLevel: 35, maxLevel: 40, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, + {name: "MWBOS Star Paladin", faction: "MWBOS", minLevel: 45, maxLevel: 50, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, + {name: "MWBOS Head Paladin", faction: "MWBOS", minLevel: 55, maxLevel: 60, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, ]; var abominationEncounters = [ - {name: "Mole Rat", faction: "abomination", minLevel: 1, maxLevel: 15, damageClass: "B", minDamage: 1, maxDamage: 5}, - {name: "Mongrel", faction: "abomination", minLevel: 15, maxLevel: 30, damageClass: "B", minDamage: 5, maxDamage: 10}, - {name: "Radscorpion", faction: "abomination", minLevel: 30, maxLevel: 50, damageClass: "B", minDamage: 5, maxDamage: 10}, + {name: "Mole Rat", faction: "abomination", minLevel: 1, maxLevel: 15, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, + {name: "Mongrel", faction: "abomination", minLevel: 15, maxLevel: 30, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, + {name: "Radscorpion", faction: "abomination", minLevel: 30, maxLevel: 50, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, ]; var HLabominationEncounters = [ - {name: "Super Mutant", faction: "abomination", minLevel: 50, maxLevel: 65, damageClass: "B", minDamage: 5, maxDamage: 10}, - {name: "Tunneler", faction: "abomination", minLevel: 65, maxLevel: 80, damageClass: "B", minDamage: 5, maxDamage: 10}, - {name: "Deathclaw", faction: "abomination", minLevel: 80, maxLevel: 100, damageClass: "B", minDamage: 5, maxDamage: 10}, + {name: "Super Mutant", faction: "abomination", minLevel: 50, maxLevel: 65, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, + {name: "Tunneler", faction: "abomination", minLevel: 65, maxLevel: 80, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, + {name: "Deathclaw", faction: "abomination", minLevel: 80, maxLevel: 100, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, ]; var NCREncounters = [ - {name: "NCR Trooper", faction: "NCR", minLevel: 40, maxLevel: 70, damageClass: "B", minDamage: 5, maxDamage: 10}, - {name: "NCR Ranger", faction: "NCR", minLevel: 50, maxLevel: 70, damageClass: "B", minDamage: 10, maxDamage: 20}, - {name: "NCR Commander", faction: "NCR", minLevel: 60, maxLevel: 70, damageClass: "B", minDamage: 20, maxDamage: 30} + {name: "NCR Trooper", faction: "NCR", minLevel: 40, maxLevel: 70, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, + {name: "NCR Ranger", faction: "NCR", minLevel: 50, maxLevel: 70, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, + {name: "NCR Commander", faction: "NCR", minLevel: 60, maxLevel: 70, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, ]; var HLNCREncounters = [ - {name: "NCR Heavy Trooper", faction: "NCR", minLevel: 70, maxLevel: 100, damageClass: "B", minDamage: 30, maxDamage: 40}, - {name: "NCR Veteran Ranger", faction: "NCR", minLevel: 80, maxLevel: 100, damageClass: "B", minDamage: 40, maxDamage: 50}, - {name: "NCR General", faction: "NCR", minLevel: 90, maxLevel: 100, damageClass: "B", minDamage: 50, maxDamage: 60} + {name: "NCR Heavy Trooper", faction: "NCR", minLevel: 70, maxLevel: 100, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, + {name: "NCR Veteran Ranger", faction: "NCR", minLevel: 80, maxLevel: 100, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, + {name: "NCR General", faction: "NCR", minLevel: 90, maxLevel: 100, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, ]; var BOSEncounters = [ //Reduntant, your not gonna encounter a low level Lost Hills BOS encounter - {name: "BOS Paladin", faction: "BOS", minLevel: 60, maxLevel: 80, damageClass: "E", minDamage: 60, maxDamage: 80}, - {name: "BOS Star Paladin", faction: "BOS", minLevel: 70, maxLevel: 90, damageClass: "E", minDamage: 80, maxDamage: 100}, - {name: "BOS Head Paladin", faction: "BOS", minLevel: 80, maxLevel: 100, damageClass: "E", minDamage: 100, maxDamage: 120} + {name: "BOS Paladin", faction: "BOS", minLevel: 60, maxLevel: 80, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, + {name: "BOS Star Paladin", faction: "BOS", minLevel: 70, maxLevel: 90, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, + {name: "BOS Head Paladin", faction: "BOS", minLevel: 80, maxLevel: 100, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, ]; var HLBOSEncounters = [ - {name: "BOS Paladin", faction: "BOS", minLevel: 60, maxLevel: 80, damageClass: "E", minDamage: 60, maxDamage: 80}, - {name: "BOS Star Paladin", faction: "BOS", minLevel: 70, maxLevel: 90, damageClass: "E", minDamage: 80, maxDamage: 100}, - {name: "BOS Head Paladin", faction: "BOS", minLevel: 80, maxLevel: 100, damageClass: "E", minDamage: 100, maxDamage: 120} + {name: "BOS Paladin", faction: "BOS", minLevel: 60, maxLevel: 80, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, + {name: "BOS Star Paladin", faction: "BOS", minLevel: 70, maxLevel: 90, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, + {name: "BOS Head Paladin", faction: "BOS", minLevel: 80, maxLevel: 100, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, ]; var settlerEncounters = [ - {name: "John Settler", faction: "settler", minLevel: 1, maxLevel: 2, damageClass: "B", minDamage: 1, maxDamage: 2}, - {name: "Settler", faction: "settler", minLevel: 2, maxLevel: 3, damageClass: "B", minDamage: 2, maxDamage: 3}, - {name: "Settler Scavenger", faction: "settler", minLevel: 3, maxLevel: 4, damageClass: "B", minDamage: 3, maxDamage: 4}, + {name: "John Settler", faction: "settler", minLevel: 1, maxLevel: 2, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, + {name: "Settler", faction: "settler", minLevel: 2, maxLevel: 3, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, + {name: "Settler Scavenger", faction: "settler", minLevel: 3, maxLevel: 4, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, ]; var HLsettlerEncounters = [ - {name: "Settler Gaurdsman", faction: "settler", minLevel: 4, maxLevel: 5, damageClass: "B", minDamage: 4, maxDamage: 5}, - {name: "Settler Enforcer", faction: "settler", minLevel: 5, maxLevel: 6, damageClass: "B", minDamage: 5, maxDamage: 6}, - {name: "Settler Sheriff", faction: "settler", minLevel: 6, maxLevel: 7, damageClass: "B", minDamage: 6, maxDamage: 7}, + {name: "Settler Gaurdsman", faction: "settler", minLevel: 4, maxLevel: 5, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, + {name: "Settler Enforcer", faction: "settler", minLevel: 5, maxLevel: 6, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, + {name: "Settler Sheriff", faction: "settler", minLevel: 6, maxLevel: 7, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, ]; var legionEncounters = [ - {name: "Legion Recruit", faction: "legion", minLevel: 30, maxLevel: 40, damageClass: "B", minDamage: 1, maxDamage: 2}, - {name: "Legionary", faction: "legion", minLevel: 40, maxLevel: 50, damageClass: "B", minDamage: 2, maxDamage: 3}, - {name: "Legion Vexillarius", faction: "legion", minLevel: 50, maxLevel: 60, damageClass: "B", minDamage: 3, maxDamage: 4}, + {name: "Legion Recruit", faction: "legion", minLevel: 30, maxLevel: 40, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, + {name: "Legionary", faction: "legion", minLevel: 40, maxLevel: 50, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, + {name: "Legion Vexillarius", faction: "legion", minLevel: 50, maxLevel: 60, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, ]; var HLlegionEncounters = [ - {name: "Legion Decanus", faction: "legion", minLevel: 60, maxLevel: 70, damageClass: "B", minDamage: 4, maxDamage: 5}, - {name: "Legion Centurion", faction: "legion", minLevel: 70, maxLevel: 80, damageClass: "B", minDamage: 5, maxDamage: 6}, - {name: "Legion Praetorian", faction: "legion", minLevel: 80, maxLevel: 90, damageClass: "B", minDamage: 6, maxDamage: 7}, + {name: "Legion Decanus", faction: "legion", minLevel: 60, maxLevel: 70, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, + {name: "Legion Centurion", faction: "legion", minLevel: 70, maxLevel: 80, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, + {name: "Legion Praetorian", faction: "legion", minLevel: 80, maxLevel: 90, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, ]; \ No newline at end of file diff --git a/files/variables.js b/files/variables.js index 3ced373..a9b3bd1 100644 --- a/files/variables.js +++ b/files/variables.js @@ -17,8 +17,13 @@ global.inventory = [ // Inventory of player, holds all items // Supplies: chems, aid [], // Equipment: weapons, armor, tools - [] + [ + equipmentList[27], + equipmentList[24], + ] ] +global.equippedWeapon = equipmentList[27]; +global.equippedArmor = equipmentList[24]; // Game Mechanics global.walkRate = 0; // Units the player walks per day, affects foodRateCalc and radPointsCalc @@ -87,8 +92,12 @@ global.equipmentList = [ // Equipment: weapons, armor, tools {name: "T-51 Power Armor", description: "T-51 Power Armor, excellent protection from ballistic damage.", type: "parmor", resistances: {balistic: 50, slash: 50, laser: 30, plasma: 30}, unit: "dt", cost: 5, weight: 5}, // Special Armor - {name: "Chinese Stealth Suit", description: "Chinese Stealth Suit, +25% Chance to skip encounter if worn", type: "uarmor", value: "5", unit: "dr",cost: 20, weight: 20}, + {name: "Enclave Uniform", description: "Enclave uniform, standard issue", type: "armor", resistances: {balistic: 0, slash: 0, laser: 0, plasma: 0}, unit: "dr",cost: 20, weight: 20}, + {name: "Chinese Stealth Suit", description: "Chinese Stealth Suit, +25% Chance to skip encounter if worn", type: "uarmor", resistances: {balistic: 5, slash: 5, laser: 5, plasma: 5}, unit: "dr",cost: 20, weight: 20}, {name: "Excavator Power Armor", description: "Excavator Power Armor, +25% Chance to find extra loot", type: "parmor", resistances: {balistic: 5, slash: 5, laser: 5, plasma: 5}, unit: "dt", cost: 5, weight: 5}, + + // Fists (Yes I know this should go by the weapons but I dont wanna mess this up) + {name: "Fists (Unarmed)", description: "Unarmed combat, does 5 bash damage", type: "weapon", value: "5", unit: "bash", cost: 5, weight: 1}, ]; global.achievements = [ From d837a5747204b843a8256be2506561b9e2ca5647 Mon Sep 17 00:00:00 2001 From: Raktbastr Date: Sun, 27 Apr 2025 16:09:07 -0500 Subject: [PATCH 22/27] Fixed issues... Again --- files/main.js | 5 ++- files/poiscreens.js | 2 +- files/variables.js | 91 +++++++++++++++++++++++---------------------- 3 files changed, 50 insertions(+), 48 deletions(-) diff --git a/files/main.js b/files/main.js index 5651d5e..29b7bf7 100755 --- a/files/main.js +++ b/files/main.js @@ -1,5 +1,5 @@ // Program is started from here, runs functions from other files. -import { userInput, sleep, disableRawMode, walkPathMain, randomNumber, removeDuplicates } from './functions.js'; +import { userInput, sleep, disableRawMode, walkPathMain, randomNumber } from './functions.js'; import { forcedEncounter, naturalEncounter } from './encounters.js'; import { ravenRockStore } from './shops.js'; @@ -42,8 +42,9 @@ switch(mainMenuInput) { break; case "5": var thing1 = [1,2,3,4,5,6,7,8,9]; - var thing2 = [1, 2, 3, 4, 5, 6, 7, 8, 9]; + var thing2 = []; var thing3 = []; + thing2 = thing1 while (thing3.length < 6) { let randomPick = randomNumber(1,thing2.length); thing3.push(thing2[randomPick]); diff --git a/files/poiscreens.js b/files/poiscreens.js index a8d737a..6c16851 100644 --- a/files/poiscreens.js +++ b/files/poiscreens.js @@ -2,7 +2,7 @@ import { userInput, pauseScreen, enableRawMode, disableRawMode, sleep } from "./functions.js"; import './variables.js'; -import { whitespringStore, genericBOSStore, trader, eurekaStore, newVegasStore, vaultZeroStore } from "./shops.js"; +import { whitespringStore, trader, eurekaStore, newVegasStore, vaultZeroStore } from "./shops.js"; export function checkPOI() { if (path == 0) { diff --git a/files/variables.js b/files/variables.js index a9b3bd1..965dfdf 100644 --- a/files/variables.js +++ b/files/variables.js @@ -1,49 +1,6 @@ // Now holds only variables -// Player Currency -global.preWarMoney = 0; // Used with enclave vendors -global.caps = 0; // Used with all other vendors - -// Player Stats -global.healthCap = 0; // Maximum health, raises each level -global.health = 0; // Players current HP -global.food = 0; // Amount of food player has -global.isRadiated = false; -global.radSeverity = 0; // Modifies healthCapCalc. 3 Levels -global.radPoints = 0; // If the player reaches 100 rad points the game ends -global.xpPerLevel = 10; // Amount of XP needed per level. Raises 50% each level -global.level = 0; // Level of player. Modifies enemy scaling -global.inventory = [ // Inventory of player, holds all items - // Supplies: chems, aid - [], - // Equipment: weapons, armor, tools - [ - equipmentList[27], - equipmentList[24], - ] -] -global.equippedWeapon = equipmentList[27]; -global.equippedArmor = equipmentList[24]; - -// Game Mechanics -global.walkRate = 0; // Units the player walks per day, affects foodRateCalc and radPointsCalc -global.foodRate = 0; // Amount of food player eats per day, affects radPointsCalc - -global.path = 0; // Path player is currently on, 0 = Main, 1 = A, 2 = B -global.location = 0; // Location on main path, 0-255 = main, 500-1000 = A, 1500-2000 = B -global.locationA = 0; // Location on path A -global.locationB = 0; // Location on path B -global.day = 0; // Current day of the game, if you reach 365 the game ends - -global.reputation = {mwbos: 4, legion: 4, ncr: 2, bos: 1, enclave: 10, abomination: 0, raider: 0} - // Rep for each faction. Number between 0(worst) and 10(best), 5 is neutral - -global.daysSinceScav = 0; // Days since player last scavenged. Must be >= 15 to scavenge again. - -global.name = "placeholder"; // Player name, changed when the game starts - -global.testDeath = false; // Used to test death, set to true to kill player - +// Items 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}, @@ -138,4 +95,48 @@ global.achievements = [ {name: "Medal of Freedom", description: "Become Idolized within the Enclave"}, {name: "Presidential Suite", description: "Become Idolized within New Vegas"}, {name: "Uneasy Alliance", description: "Become Idolized within the Midwest Brotherhood"}, -] \ No newline at end of file +] + +// Player Currency +global.preWarMoney = 0; // Used with enclave vendors +global.caps = 0; // Used with all other vendors + +// Player Stats +global.healthCap = 0; // Maximum health, raises each level +global.health = 0; // Players current HP +global.food = 0; // Amount of food player has +global.isRadiated = false; +global.radSeverity = 0; // Modifies healthCapCalc. 3 Levels +global.radPoints = 0; // If the player reaches 100 rad points the game ends +global.xpPerLevel = 10; // Amount of XP needed per level. Raises 50% each level +global.level = 0; // Level of player. Modifies enemy scaling +global.inventory = [ // Inventory of player, holds all items + // Supplies: chems, aid + [], + // Equipment: weapons, armor, tools + [ + equipmentList[27], + equipmentList[24], + ] +] +global.equippedWeapon = equipmentList[27]; +global.equippedArmor = equipmentList[24]; + +// Game Mechanics +global.walkRate = 0; // Units the player walks per day, affects foodRateCalc and radPointsCalc +global.foodRate = 0; // Amount of food player eats per day, affects radPointsCalc + +global.path = 0; // Path player is currently on, 0 = Main, 1 = A, 2 = B +global.location = 0; // Location on main path, 0-255 = main, 500-1000 = A, 1500-2000 = B +global.locationA = 0; // Location on path A +global.locationB = 0; // Location on path B +global.day = 0; // Current day of the game, if you reach 365 the game ends + +global.reputation = {mwbos: 4, legion: 4, ncr: 2, bos: 1, enclave: 10, abomination: 0, raider: 0} + // Rep for each faction. Number between 0(worst) and 10(best), 5 is neutral + +global.daysSinceScav = 0; // Days since player last scavenged. Must be >= 15 to scavenge again. + +global.name = "placeholder"; // Player name, changed when the game starts + +global.testDeath = false; // Used to test death, set to true to kill player \ No newline at end of file From 44a4cf65bdc9d101dd1f7f1bd870ec675fcbc800 Mon Sep 17 00:00:00 2001 From: Caroline Foy Date: Sun, 27 Apr 2025 17:50:34 -0500 Subject: [PATCH 23/27] Added POI dialogue for all BOS bunkers and Flagstaff --- files/poiscreens.js | 104 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 89 insertions(+), 15 deletions(-) diff --git a/files/poiscreens.js b/files/poiscreens.js index 6c16851..4fe84ba 100644 --- a/files/poiscreens.js +++ b/files/poiscreens.js @@ -135,35 +135,35 @@ function whitespring() { case "1": console.clear(); sleep(1); - console.log("You enter the bunker where a robotic voice greets you.\n\n"); + console.log("You enter the bunker. A robotic voice greets you...\n\n"); sleep(3); - console.log("MODUS: Welcome, soldier. Might I ask what brings you here, or who?"); + console.log("MODUS: Welcome, soldier. Might I ask what brings you here, or... who?"); userInput(" \n[Enter to continue]\n") - console.log(name+": I am "+name+". I was ordered here by President Eden. Im passing though on my way to...\n*You stop yourself before answering*\nWait, who are you anyway?"); + console.log(name+": I am "+name+". I was ordered here by President Eden. I'm passing though on my way to...\n*You stop yourself before continuing*\nWait, who are you anyway?"); userInput(" \n[Enter to continue]\n") console.log("MODUS: I am MODUS, the... acting head of this bunker."); userInput(" \n[Enter to continue]\n") - console.log(name+": So I assume your of top level clearance?"); + console.log(name+": So I assume you're of top level clearance?"); userInput(" \n[Enter to continue]\n") - console.log("MODUS: Yes, and no need to tell me where your going. By my limited knoledge id assume they tasked you with retrieval from Navarro, of what im not sure of though."); + console.log("MODUS: Yes, and no need to tell me where you're going. By my limited knowledge I'd assume they tasked you with a retrieval from Navarro, of what, however, I'm not sure."); userInput(" \n[Enter to continue]\n") - console.log(name+": Me either, ill get the info when im there."); + console.log(name+": Me either, I'll get the info when I'm there."); userInput(" \n[Enter to continue]\n") console.log("MODUS: Not unusual for the Enclave, nor Eden from what I hear."); userInput(" \n[Enter to continue]\n") - console.log(name+": They told me this place would be empty, but its not."); + console.log(name+": They told me this place would be empty, but it's not."); userInput(" \n[Enter to continue]\n") - console.log("MODUS: The original inhabitants are long gone, and they never bothered to check when passing though. They no nothing of my existance. As for the people topside... they are gone too."); + console.log("MODUS: The original inhabitants are long gone, and they never bothered to check when passing though. They know nothing of my existance. As for the people topside... they are gone too."); userInput(" \n[Enter to continue]\n") - console.log(name+": What happened, its a hellscape apart from the Whitespring."); + console.log(name+": What happened? It's a hellscape apart from the Whitespring."); userInput(" \n[Enter to continue]\n") - console.log("MODUS: The scorched plague ravaged the wastes, but was stopped by dwellers from Vault 76. The area was reinhabited, but bigger threats drove the people out again. When the Responders lost for the second time, everyone left."); + console.log("MODUS: The scorched plague ravaged the wastes, but was stopped by dwellers from Vault 76. The area was reinhabited, but bigger threats drove the people out again. When the Responders fell for the second time, everyone left."); userInput(" \n[Enter to continue]\n") console.log(name+": Well then, is there anything for me here before I leave?"); userInput(" \n[Enter to continue]\n") console.log("MODUS: The Resort is taken care of by robots, the vendortrons may still be active. As for here... the dwellers turned generals ran me out."); userInput(" \n[Enter to continue]\n") - console.log(name+": I guess Ill be on my way then. Goodbye.") + console.log(name+": I guess I'll be on my way then. Goodbye.") userInput("[Enter to exit conversation]") break; case "2": @@ -194,7 +194,31 @@ function bosGamma() { switch(poiInput) { case "1": console.clear(); - console.log("Gamma Dialogue here...") + sleep(1); + console.log("You enter the bunker, and are greeted by a stern-looking scribe...\n\n"); + sleep(3); + console.log("Scribe: Civilian! State your purpose for entering this bunker!"); + userInput(" \n[Enter to continue]\n"); + console.log(name + ": Just looking around. Might do some bartering, if you're open to it."); + userInput(" \n[Enter to continue]\n"); + console.log("Scribe: Very well, so long as you don't interfere with brotherhood operations..."); + userInput(" \n[Enter to continue]\n"); + console.log(name + ": Oh my god, is that a deathclaw!? Everyone, look out!\n*You ready yourself for an epic battle*"); + userInput(" \n[Enter to continue]\n"); + console.log("Scribe: HOLD YOUR FIRE! She's one of us!"); + userInput(" \n[Enter to continue]\n"); + console.log(name + ": One of us? Like... you tamed a deathclaw?"); + userInput(" \n[Enter to continue]\n"); + console.log("Scribe: Tamed? No, they chose to join us. They're not like the usual deathclaws, these ones can talk."); + userInput(" \n[Enter to continue]\n"); + console.log(name + ": Talking deathclaws? Astounding...\n*You mutter under your breath*\nThe Enclave needs to know about this..."); + userInput(" \n[Enter to continue]\n"); + console.log("Scribe: What was that, civilian?"); + userInput(" \n[Enter to continue]\n"); + console.log(name + ": Oh, nothing."); + userInput(" \n[Enter to continue]\n"); + console.log("Scribe: Alright then... Now, put that weapon away and go bother somebody else."); + userInput("[Enter to exit conversation]"); break; case "2": genericBOSStore(); @@ -224,7 +248,25 @@ function bosDelta() { switch(poiInput) { case "1": console.clear(); - console.log("Delta Dialogue here...") + sleep(1); + console.log("You approach a quiet looking man..."); + sleep(3); + console.log(name + ": Who are you?"); + userInput(" \n[Enter to continue]\n"); + console.log("Hassan: I'm the quartermaster of this here bunker. You need supplies, you come to me."); + userInput(" \n[Enter to continue]\n"); + console.log(name + ": Is there anything to do around here?"); + userInput(" \n[Enter to continue]\n"); + console.log("Hassan: Absolutely! This fantastic bunker could always use some extra help! You could help me polish this armor, to start."); + userInput(" \n[Enter to continue]\n"); + console.log(name + ": Err, I'll pass, thank you. I was hoping for something a little less... boring..."); + userInput(" \n[Enter to continue]\n"); + console.log("Hassan: Are you kidding? In this bunker, we have a motto: Inventory is not boring. Inventory is LIFE!"); + userInput(" \n[Enter to continue]\n"); + console.log(name + ": Ooooookay then... If inventory is so fun, why don't you do it instead of me?"); + userInput(" \n[Enter to continue]\n"); + console.log("Hassan: You know what, you have a point... Scram, so I can get back to counting ammunition."); + userInput("[Enter to exit the conversation]"); break; case "2": genericBOSStore(); @@ -254,7 +296,27 @@ function bosEpsilon() { switch(poiInput) { case "1": console.clear(); - console.log("Epsilon Dialogue here...") + sleep(1); + console.log("You approach a lone man in tribal attire. He appears to be mourning..."); + sleep(3); + console.log("Tiduk: I shall never forget you, dear sister, and I shall visit your grave until the great Brahmin God of Battle sends me to join you."); + userInput(" \n[Enter to continue]\n"); + console.log(name + ": Brahmin god? You're not from around here, are you?"); + userInput(" \n[Enter to continue]\n"); + console.log("Tiduk: I have not seen you in the bunker. It would appear that it is you who are foregn to these lands."); + userInput(" \n[Enter to continue]\n"); + console.log(name + ": That's an interesting choice of attire for a brotherhood soldier, I mean."); + userInput(" \n[Enter to continue]\n"); + console.log("Tiduk: I am Tiduk. I come from the tribe of Brahmin Woods."); + userInput(" \n[Enter to continue]\n"); + console.log(name + ": And you're mourning your sister? What happened to her, if you don't mind me asking..."); + userInput(" \n[Enter to continue]\n"); + console.log("Tiduk: She was a great warrior, though I did not recognize this until it was too late. We had fought a successful battle,\n and were returning to base camp when we were ambushed by robots. Some of us escaped, but my sister\n was not so lucky."); + userInput(" \n[Enter to continue]\n"); + console.log(name + ": Oh, I'm sorry for your loss."); + userInput(" \n[Enter to continue]\n"); + console.log("Tiduk: I just wish it wasn't I who must break the news to mother..."); + userInput("[Enter to exit the conversation]"); break; case "2": genericBOSStore(); @@ -340,7 +402,19 @@ function flagstaff() { switch(poiInput) { case "1": console.clear(); - console.log("Flagstaff Dialogue here...") + sleep(1); + console.log("You walk up to one of two men guarding a gate, he glares at you through his sunglasses..."); + sleep(3); + console.log("Legionarre: Halt! Keep out of Legion territory or else I'll take you as a new slave."); + userInput(" \n[Enter to continue]\n"); + console.log(name + ": Woah now, I'm not looking for trouble. Just want to trade and be on my way..."); + userInput(" \n[Enter to continue]\n"); + console.log("Legionarre: Hmph, fat chance. Don't try anything, outsider, or you'll see first-hand the wrath of Caesar."); + userInput(" \n[Enter to continue]\n"); + console.log(name + ": Put down your shotgun-gloves. Like I said, I'm not here to fight."); + userInput(" \n[Enter to continue]\n"); + console.log("*The legionarre scowls at you while you walk away*"); + userInput("[Enter to exit conversation]"); break; case "2": pauseScreen(); From 77cb3f46136350d02a7853974245531950bf229a Mon Sep 17 00:00:00 2001 From: Raktbastr Date: Sun, 27 Apr 2025 21:51:07 -0500 Subject: [PATCH 24/27] The Final commit before turn-in (hopefully) --- files/combat.js | 107 +++++++++++++++++++++++++++++++++++++------- files/functions.js | 54 +++++++++++++--------- files/inventory.js | 77 ++++++++++++++++++++----------- files/main.js | 39 +++++++--------- files/map.js | 2 - files/poiscreens.js | 36 +++++---------- files/shops.js | 69 +++++++++++++++++++++++----- files/variables.js | 29 ++---------- 8 files changed, 265 insertions(+), 148 deletions(-) delete mode 100644 files/map.js diff --git a/files/combat.js b/files/combat.js index 5f258b7..a3ccc76 100644 --- a/files/combat.js +++ b/files/combat.js @@ -1,5 +1,6 @@ import './variables.js'; -import {userInput} from './functions.js'; +import { randomNumber, userInput } from './functions.js'; +import { inventoryMenuM } from './inventory.js'; function initCombat(enemy) { if (enemy.minLevel > level) { @@ -23,53 +24,127 @@ function initCombat(enemy) { function combat(enemy) { console.clear(); console.log("You enter combat with "+enemy.name+"..."); - 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"); - var combatInput = userInput("Enter: "); - switch(combatInput) { - case "1": - + 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; + } } + 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!"); + 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); + 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; + } } -function damageCalc(attacker) { +function damageCalc(attacker, crit) { if (attacker = player) { if (playerStats.chem == "psycho") { var damageOutput = playerStats.weapon.damage*1.5; } else { var damageOutput = playerStats.weapon.damage; } + if (crit) { + damageOutput+3; + } if (enemyStats.armorUnit == "dr"){ - enemyStats.health = enemyStats.health-(damageOutput-(enemyStats.armor.value/100)); + let drDamage = damageOutput-(enemyStats.armor.value/100); + enemyStats.health = enemyStats.health-drDamage; + return drDamage; } if (enemyStats.armorUnit == "dt") { let dtDamage = enemyStats.health-(damageOutput-armor); if (dtDamage < 0) { dtDamage = 0; } - enemyStats.health - dtDamage + enemyStats.health - dtDamage; + return dtDamage; } } else { if (playerStats.chem == "medx") { var damageOutput = enemyStats.weapon.damage*(-1.5); } else { var damageOutput = enemyStats.weapon.damage; - } if (playerStats.armorUnit == "dr"){ - playerStats.health = playerStats.health-(damageOutput-(playerStats.armor.value/100)); + } + if (crit) { + damageOutput+3; + } + if (playerStats.armorUnit == "dr"){ + let drDamage = damageOutput-(playerStats.armor.value/100) + playerStats.health = playerStats.health-drDamage; + return drDamage; } if (playerStats.armorUnit == "dt") { let dtDamage = playerStats.health-(damageOutput-armor); if (dtDamage < 0) { dtDamage = 0; } - playerStats.health - dtDamage + playerStats.health - dtDamage; + return dtDamage; } } } diff --git a/files/functions.js b/files/functions.js index 911fb4c..3764756 100755 --- a/files/functions.js +++ b/files/functions.js @@ -42,7 +42,7 @@ export function radPointsCalc() { // Calculates radPoints given walk/foodrate export function eatFood() { // Calculates food amount after a day of eating if (food == 0) { - health = health - 0.25*walkRate + health = health - walkRate } else { food = food - walkRate * foodRate } @@ -203,8 +203,6 @@ function timeDeath() { // The death screen for passing the time limit var travelFrame = 0; - - export function travelScreen() { if (travelFrame < 0 || travelFrame > 3) { travelFrame = 0; @@ -228,7 +226,15 @@ export function travelScreen() { console.log("Press [SPACE] to open Pip-Boy"); console.log("Current Health: "+health); console.log("Food Amt: "+food); - console.log("Distance to next POI: " + pois[poiCounter].location-location); + if (path == 0) { + console.log("Distance to next POI: " + (pois[poiCounter].location-location)); + } + if (path == 1) { + console.log("Distance to next POI: " + (pois[poiCounter].location-locationA)); + } + if (path == 2) { + console.log("Distance to next POI: " + (pois[poiCounter].location-locationB)); + } travelFrame++ } else if (travelFrame == 1) { console.clear(); @@ -250,7 +256,7 @@ export function travelScreen() { console.log("Press [SPACE] to open Pip-Boy"); console.log("Current Health: "+health); console.log("Food Amt: "+food); - console.log("Distance to next POI: " + pois[poiCounter].location-location); + console.log("Distance to next POI: " + (pois[poiCounter].location-location)); travelFrame++ } else if (travelFrame == 2) { console.clear(); @@ -272,7 +278,7 @@ export function travelScreen() { console.log("Press [SPACE] to open Pip-Boy"); console.log("Current Health: "+health); console.log("Food Amt: "+food); - console.log("Distance to next POI: " + pois[poiCounter].location-location); + console.log("Distance to next POI: " + (pois[poiCounter].location-location)); travelFrame++ } else if (travelFrame == 3) { console.clear(); @@ -294,7 +300,7 @@ export function travelScreen() { console.log("Press [SPACE] to open Pip-Boy"); console.log("Current Health: "+health); console.log("Food Amt: "+food); - console.log("Distance to next POI: " + pois[poiCounter].location-location); + console.log("Distance to next POI: " + (pois[poiCounter].location-location)); travelFrame=0; } } @@ -306,11 +312,6 @@ export async function walkPathMain() { pauseScreen(); enableRawMode(); } - - if (location > 255) { - disableRawMode(); - return; - } calcLocation(); radPointsCalc(); healthCapCalc(); @@ -351,16 +352,25 @@ export function disableRawMode() { var paused = false; export function pauseScreen() { - console.clear(); - console.log ("What would you like to do?"); - console.log ("--------------------------"); - console.log ("1) Resume"); - console.log ("2) View Inventory"); - console.log ("3) View Distances"); - console.log ("4) View Stats"); - console.log ("5) Scavenge"); - console.log ("6) Change Speed/Food Rate"); - let pauseInput = userInput("Enter: "); + let pauseInput + while (true) { + console.clear(); + console.log ("What would you like to do?"); + console.log ("--------------------------"); + console.log ("1) Resume"); + console.log ("2) View Inventory"); + console.log ("3) View Distances"); + console.log ("4) View Stats"); + console.log ("5) Scavenge"); + console.log ("6) Change Speed/Food Rate"); + pauseInput = userInput("Enter: "); + + if (pauseInput != "1" && pauseInput != "2" && pauseInput != "3" && pauseInput != "4" && pauseInput != "5" && pauseInput != "6") { + console.log("Invalid input. Please enter 1, 2, or 3."); + } else { + break; + } + } switch(pauseInput) { case "1": paused = false; diff --git a/files/inventory.js b/files/inventory.js index 7f4c2cf..21ceccd 100644 --- a/files/inventory.js +++ b/files/inventory.js @@ -6,43 +6,70 @@ export function inventoryMenuM(){ console.clear(); console.log("INVENTORY"); console.log("---------"); - console.log("1) Supplies"); - console.log("2) Equipment"); - console.log("3) Exit"); + console.log("1) View"); + console.log("2) Equip Weapon"); + console.log("3) Equip Armor"); + console.log("4) Exit"); let invChoice = userInput("Enter: "); - switch(userInput){ + switch(invChoice){ case "1": - supplyInventory(); + viewInventory(); break; case "2": - equipmentInventory(); - break; + console.log("Weapons"); + console.log("---------"); + for(var a = 0; a < inventory.length;){ + if (inventory[a].type == "weapon") { + console.log((a + 1) + ") " + inventory[a].name); + a++; + } + while (true) { + console.log("-----------------"); + let equipInput = userInput("What would you like to equip?"); + if (equipInput <= a) { + equippedWeapon = inventory[equipInput - 1]; + console.log("You have equipped: " + equippedWeapon.name); + return; + } else { + console.log("Invalid Input. Please enter a valid number."); + } + } + } case "3": + console.log("Armor"); + console.log("---------"); + for(var a = 0; a < inventory[1].length;){ + if (inventory[a].type == "armor" || inventory[a].type == "parmor") { + console.log((a + 1) + ") " + inventory[a].name); + a++; + } + while (true) { + console.log("-----------------"); + let equipInput = parseInt(userInput("What would you like to equip?"), 10); + if (equipInput <= a) { + equippedArmor = inventory[equipInput - 1]; + console.log("You have equipped: " + equippedArmor.name); + return; + } else { + console.log("Invalid Input. Please enter a valid number."); + } + } + } break; + case "4": + break; + default: + console.log("Invalid Input"); } } //Builds the supply inventory -function supplyInventory(){ +function viewInventory(){ console.clear(); - console.log("SUPPLIES"); + console.log("Inventory"); console.log("---------"); - for(var a = 0; a < inventory[0].length;){ - console.log((a + 1) + ") " + inventory[0][a].name); - a++; - } - userInput("[Enter to return]"); - console.clear(); - inventoryMenuM(); -} - -//Builds the equipment inventory -function equipmentInventory(){ - console.clear(); - console.log("EQUIPMENT"); - console.log("---------"); - for(var a = 0; a < inventory[1].length;){ - console.log((a + 1) + ") " + inventory[1][a].name); + for(var a = 0; a < inventory.length;){ + console.log((a + 1) + ") " + inventory[a].name); a++; } userInput("[Enter to return]"); diff --git a/files/main.js b/files/main.js index 29b7bf7..e3540ea 100755 --- a/files/main.js +++ b/files/main.js @@ -14,22 +14,29 @@ console.log(" / / ) / / / ) / / / o / / ) / ) console.log("_/________(___(_/___/___(___/_(___(__(_ __o_____/____/_(___/_/___/_(___ _(__)_(___/_/_/__/_(___ _____/_____|__(___/_(___(_(___/___\n\n"); await sleep(1); -console.log("What would you like to do?"); -console.log("--------------------------"); -console.log("1) Start new game"); -console.log("2) Learn How to play"); -console.log("3) Quit Game"); -console.log("4) Credits\n"); +var mainMenuInput; +while (true) { + console.log("What would you like to do?"); + console.log("--------------------------"); + console.log("1) Start new game"); + console.log("2) Learn How to play"); + console.log("3) Quit Game"); + console.log("4) Credits\n"); + mainMenuInput = userInput("Enter: "); -var mainMenuInput = userInput("Enter: "); + if (mainMenuInput != "1" && mainMenuInput != "2" && mainMenuInput != "3" && mainMenuInput != "4") { + console.log("Invalid input. Please enter 1, 2, or 3."); + } else { + break; + } +} switch(mainMenuInput) { case "1": startGame(); break; case "2": - console.log("Follow the link below for a game manual.") - console.log("[ENTER LINK HERE]") + console.log(food); break; case "3": console.log("Quitting Game..."); @@ -39,19 +46,7 @@ switch(mainMenuInput) { console.log("Credits:"); console.log("Bethesda Game Studios - The Fallout IP and related characters/lore"); console.log("Readline-sync - NPM package used for async collection of user input"); - break; - case "5": - var thing1 = [1,2,3,4,5,6,7,8,9]; - var thing2 = []; - var thing3 = []; - thing2 = thing1 - while (thing3.length < 6) { - let randomPick = randomNumber(1,thing2.length); - thing3.push(thing2[randomPick]); - thing2.pop(randomPick); - } - console.log(thing2); - break; + break; } function startGame() { // So far what I have is filler and testing, feel free to change. diff --git a/files/map.js b/files/map.js deleted file mode 100644 index 4bbb499..0000000 --- a/files/map.js +++ /dev/null @@ -1,2 +0,0 @@ -// Map Screen -const variables = require("./variables.js"); diff --git a/files/poiscreens.js b/files/poiscreens.js index 4fe84ba..b96eb76 100644 --- a/files/poiscreens.js +++ b/files/poiscreens.js @@ -187,9 +187,8 @@ function bosGamma() { sleep(1); console.log("What would you like to do?"); console.log("1) Explore"); - console.log("2) Attempt to trade"); - console.log("3) Open your PIP-Boy"); - console.log("4) Leave"); + console.log("2) Open your PIP-Boy"); + console.log("3) Leave"); let poiInput = userInput("Enter: "); switch(poiInput) { case "1": @@ -221,12 +220,9 @@ function bosGamma() { userInput("[Enter to exit conversation]"); break; case "2": - genericBOSStore(); - break; - case "3": pauseScreen(); break; - case "4": + case "3": enableRawMode(); console.clear(); break; @@ -241,9 +237,8 @@ function bosDelta() { sleep(1); console.log("What would you like to do?"); console.log("1) Explore"); - console.log("2) Attempt to trade"); - console.log("3) Open your PIP-Boy"); - console.log("4) Leave"); + console.log("2) Open your PIP-Boy"); + console.log("3) Leave"); let poiInput = userInput("Enter: "); switch(poiInput) { case "1": @@ -269,12 +264,9 @@ function bosDelta() { userInput("[Enter to exit the conversation]"); break; case "2": - genericBOSStore(); - break; - case "3": pauseScreen(); break; - case "4": + case "3": enableRawMode(); console.clear(); break; @@ -289,9 +281,8 @@ function bosEpsilon() { sleep(1); console.log("What would you like to do?"); console.log("1) Explore"); - console.log("2) Attempt to trade"); - console.log("3) Open your PIP-Boy"); - console.log("4) Leave"); + console.log("2) Open your PIP-Boy"); + console.log("3) Leave"); let poiInput = userInput("Enter: "); switch(poiInput) { case "1": @@ -311,7 +302,7 @@ function bosEpsilon() { userInput(" \n[Enter to continue]\n"); console.log(name + ": And you're mourning your sister? What happened to her, if you don't mind me asking..."); userInput(" \n[Enter to continue]\n"); - console.log("Tiduk: She was a great warrior, though I did not recognize this until it was too late. We had fought a successful battle,\n and were returning to base camp when we were ambushed by robots. Some of us escaped, but my sister\n was not so lucky."); + console.log("Tiduk: She was a great warrior, though I did not recognize this until it was too late. We had fought a successful battle, and were returning to base camp when we were ambushed by robots. Some of us escaped, but my sister was not so lucky."); userInput(" \n[Enter to continue]\n"); console.log(name + ": Oh, I'm sorry for your loss."); userInput(" \n[Enter to continue]\n"); @@ -319,12 +310,9 @@ function bosEpsilon() { userInput("[Enter to exit the conversation]"); break; case "2": - genericBOSStore(); - break; - case "3": pauseScreen(); break; - case "4": + case "3": enableRawMode(); console.clear(); break; @@ -437,12 +425,12 @@ function newVegas() { console.log("What would you like to do?"); console.log("1) Explore"); console.log("2) Open your PIP-Boy"); - console.log("3) Continue"); + console.log("3) Continue your journey"); let poiInput = userInput("Enter: "); switch(poiInput) { case "1": console.clear(); - console.log("Vegas Dialogue here...") + console.log("") break; case "2": pauseScreen(); diff --git a/files/shops.js b/files/shops.js index f382073..e0052e1 100644 --- a/files/shops.js +++ b/files/shops.js @@ -149,8 +149,8 @@ export function ravenRockStore() { switch(rrInput) { case "1": console.log("What would you like to buy?"); - let itemNum = userInput("Enter item number: "); - let itemAmt = userInput("Enter amount: "); + var itemNum = userInput("Enter item number: "); + var itemAmt = userInput("Enter amount: "); if (itemAmt > rrInv[itemNum].amount) { console.log("Not enough stock."); userInput("[Enter]"); @@ -164,7 +164,13 @@ export function ravenRockStore() { rrInv[itemNum].amount -= itemAmt; console.log("You bought " + itemAmt + " " + rrInv[itemNum].name + "(s)."); console.log("You have " + preWarMoney + " pre-war money left."); - inventory.push(rrInv[itemNum]); + if (rrInv[itemNum].name == "Food") { + food =+ itemAmt; + } else { + for (var i = 0; i < itemAmt; i++) { + inventory.push(rrInv[itemNum].item); + } + } console.log("Press enter to continue..."); userInput("[Enter]"); } @@ -172,7 +178,6 @@ export function ravenRockStore() { case "2": console.log("Leaving shop..."); return true; - break; default: console.log("Invalid input, try again."); } @@ -207,10 +212,17 @@ export function vaultZeroStore() { break; } else { caps -= itemAmt * vt0Inv[itemNum].price; - rrInv[itemNum].amount -= itemAmt; + vt0Inv[itemNum].amount -= itemAmt; console.log("You bought " + itemAmt + " " + vt0Inv[itemNum].item + "(s)."); console.log("You have " + caps + " caps left."); console.log("Press enter to continue..."); + if (vt0Inv[itemNum].name == "Food") { + food = food+itemAmt; + } else { + for (var i = 0; i < itemAmt; i++) { + inventory.push(vt0Inv[itemNum].item); + } + } userInput("[Enter]"); } break; @@ -255,6 +267,13 @@ export function newVegasStore() { console.log("You bought " + itemAmt + " " + vegasInv[itemNum].item + "(s)."); console.log("You have " + caps + " caps left."); console.log("Press enter to continue..."); + if (vegasInv[itemNum].name == "Food") { + food = food+itemAmt; + } else { + for (var i = 0; i < itemAmt; i++) { + inventory.push(vegasInv[itemNum].item); + } + } userInput("[Enter]"); } break; @@ -299,6 +318,13 @@ export function eurekaStore() { eurInv[itemNum].amount -= itemAmt; console.log("You bought " + itemAmt + " " + eurInv[itemNum].item + "(s)."); console.log("You have " + preWarMoney + " pre-war money left."); + if (eurInv[itemNum].name == "Food") { + food = food+itemAmt; + } else { + for (var i = 0; i < itemAmt; i++) { + inventory.push(eurInv[itemNum].item); + } + } console.log("Press enter to continue..."); userInput("[Enter]"); } @@ -343,6 +369,13 @@ export function lostHillsStore() { lostHillsInv[itemNum].amount -= itemAmt; console.log("You bought " + itemAmt + " " + lostHillsInv[itemNum].item + "(s)."); console.log("You have " + caps + " caps left."); + if (lostHillsInv[itemNum].name == "Food") { + food = food+itemAmt; + } else { + for (var i = 0; i < itemAmt; i++) { + inventory.push(lostHillsInv[itemNum].item); + } + } console.log("Press enter to continue..."); userInput("[Enter]"); } @@ -387,6 +420,13 @@ export function whitespringStore() { whitespringInv[itemNum].amount -= itemAmt; console.log("You bought " + itemAmt + " " + whitespringInv[itemNum].item + "(s)."); console.log("You have " + caps + " caps left."); + if (whitespringInv[itemNum].name == "Food") { + food = food+itemAmt; + } else { + for (var i = 0; i < itemAmt; i++) { + inventory.push(whitespringInvInv[itemNum].item); + } + } console.log("Press enter to continue..."); userInput("[Enter]"); } @@ -460,23 +500,30 @@ export function trader(tier, message) { console.log("What would you like to do?"); console.log("1) Buy supplies"); console.log("2) Leave shop"); - var rrInput = userInput("Enter: "); - switch(rrInput) { + var traderInput = userInput("Enter: "); + switch(traderInput) { case "1": console.log("What would you like to buy?"); let itemNum = userInput("Enter item number: "); let itemAmt = userInput("Enter amount: "); - if (itemAmt > tempBOSStock[itemNum].amount) { + if (itemAmt > tempTraderInv[itemNum].amount) { console.log("Not enough stock."); break; - } else if (itemAmt * tempBOSStock[itemNum].price > caps) { + } else if (itemAmt * tempTraderInv[itemNum].price > caps) { console.log("Not enough money."); break; } else { - preWarMoney -= itemAmt * tempBOSStock[itemNum].price; + preWarMoney -= itemAmt * tempTraderInv[itemNum].price; tempBOSStock[itemNum].amount -= itemAmt; - console.log("You bought " + itemAmt + " " + tempBOSStock[itemNum].item + "(s)."); + console.log("You bought " + itemAmt + " " + tempTraderInv[itemNum].item + "(s)."); console.log("You have " + caps + " caps left."); + if (tempTraderInv[itemNum].name == "Food") { + food = food+itemAmt; + } else { + for (var i = 0; i < itemAmt; i++) { + inventory.push(tempTraderInv[itemNum].item); + } + } console.log("Press enter to continue..."); userInput("[Enter]"); } diff --git a/files/variables.js b/files/variables.js index 965dfdf..08d963c 100644 --- a/files/variables.js +++ b/files/variables.js @@ -18,42 +18,24 @@ global.equipmentList = [ // Equipment: weapons, armor, tools {name: "Laser Rifle", description: "A laser rifle, does 25 laser damage", type: "weapon", value: "25", unit: "laser",cost: 25, weight: 5}, {name: "Plasma Pistol", description: "A plasma pistol, does 30 plasma damage", type: "weapon", value: "30", unit: "plasma",cost: 30, weight: 6}, {name: "Plasma Rifle", description: "A plasma rifle, does 35 plasma damage", type: "weapon", value: "35", unit: "plasma",cost: 35, weight: 7}, - - // Energy Resistant Armor {name: "Leather Armor", description: "A set of leather armor, good protection from laser weapons.", type: "armor", resistances: {balistic: 2, slash: 2, laser: 5, plasma: 3}, unit: "dr", cost: 5, weight: 5}, {name: "Sturdy Leather Armor", description: "A set of combat armor, better protection from laser and plasma weapons.", type: "armor", resistances: {balistic: 5, slash: 5, laser: 10, plasma: 10}, unit: "dr", cost: 5, weight: 5}, - - // Ballistic Resistant Armor {name: "Raider Armor", description: "A set of raider armor, good protection from balistic damage.", type: "armor", resistances: {balistic: 5, slash: 3, laser: 2, plasma: 2}, unit: "dr", cost: 5, weight: 5}, {name: "Metal Armor" , description: "A set of raider armor, better protection from ballistic and slash damage.", type: "armor", resistances: {balistic: 10, slash: 10, laser: 5, plasma: 5}, unit: "dr", cost: 5, weight: 5}, - - // Tier 3 Armor {name: "Combat Armor", description: "A set of combat armor, better protection from all damage types.", type: "armor", resistances: {balistic: 10, slash: 10, laser: 10, plasma: 10}, unit: "dr", cost: 5, weight: 5}, {name: "Centurion Armor", description: "A set of Centurion armor, great protection from ballistic damage.", type: "armor", value: "5", unit: "dr",cost: 25, weight: 25}, {name: "NCR Ranger Armor" , description: "A set of NCR Ranger armor, great protection from laser and plasma weapons", type: "armor", value: "5", unit: "dr",cost: 30, weight: 30}, - - - // Non-specialized Power Armor {name: "T-45 Power Armor", description: "A set of T-45 Power Armor, protects against all damage types.", type: "parmor", resistances: {balistic: 15, slash: 15, laser: 15, plasma: 15}, unit: "dt", cost: 5, weight: 5}, {name: "T-60 Power Armor", description: "A set of T-60 Power Armor, good protection from all damage types.", type: "parmor", resistances: {balistic: 25, slash: 25, laser: 25, plasma: 25}, unit: "dt", cost: 5, weight: 5}, {name: "T-65 Power Armor", description: "A set of T-60 Power Armor, great protection from all damage types.", type: "parmor", resistances: {balistic: 35, slash: 35, laser: 35, plasma: 35}, unit: "dt", cost: 5, weight: 5}, - - // Energy Resistant Power Armor {name: "X-01 Power Armor", description: "X-01 Power Armor, good protection from energy damage.", type: "parmor", resistances: {balistic: 10, slash: 10, laser: 30, plasma: 30}, unit: "dt", cost: 5, weight: 5},, {name: "APA MkI Power Armor", description: "APA MkI Power Armor, great protection from energy damage.", type: "parmor", resistances: {balistic: 20, slash: 20, laser: 40, plasma: 40}, unit: "dt", cost: 5, weight: 5}, {name: "APA MkII Power Armor", description: "APA MkII Power Armor, excellent protection from energy damage.", type: "parmor", resistances: {balistic: 30, slash: 30, laser: 50, plasma: 50}, unit: "dt", cost: 5, weight: 5}, - - // Ballistic Resistant Power Armor {name: "Raider Power Armor", description: "Raider Power Armor, good protection from ballistic damage.", type: "parmor", resistances: {balistic: 30, slash: 30, laser: 10, plasma: 10}, unit: "dt", cost: 5, weight: 5}, {name: "Ultracite Power Armor", description: "Ultracite Power Armor, great protection from ballistic damage.", type: "parmor", resistances: {balistic: 40, slash: 40, laser: 20, plasma: 20}, unit: "dt", cost: 5, weight: 5}, {name: "T-51 Power Armor", description: "T-51 Power Armor, excellent protection from ballistic damage.", type: "parmor", resistances: {balistic: 50, slash: 50, laser: 30, plasma: 30}, unit: "dt", cost: 5, weight: 5}, - - // Special Armor {name: "Enclave Uniform", description: "Enclave uniform, standard issue", type: "armor", resistances: {balistic: 0, slash: 0, laser: 0, plasma: 0}, unit: "dr",cost: 20, weight: 20}, - {name: "Chinese Stealth Suit", description: "Chinese Stealth Suit, +25% Chance to skip encounter if worn", type: "uarmor", resistances: {balistic: 5, slash: 5, laser: 5, plasma: 5}, unit: "dr",cost: 20, weight: 20}, {name: "Excavator Power Armor", description: "Excavator Power Armor, +25% Chance to find extra loot", type: "parmor", resistances: {balistic: 5, slash: 5, laser: 5, plasma: 5}, unit: "dt", cost: 5, weight: 5}, - - // Fists (Yes I know this should go by the weapons but I dont wanna mess this up) {name: "Fists (Unarmed)", description: "Unarmed combat, does 5 bash damage", type: "weapon", value: "5", unit: "bash", cost: 5, weight: 1}, ]; @@ -111,16 +93,11 @@ global.radPoints = 0; // If the player reaches 100 rad points the game ends global.xpPerLevel = 10; // Amount of XP needed per level. Raises 50% each level global.level = 0; // Level of player. Modifies enemy scaling global.inventory = [ // Inventory of player, holds all items - // Supplies: chems, aid - [], - // Equipment: weapons, armor, tools - [ - equipmentList[27], - equipmentList[24], - ] + equipmentList[27], + equipmentList[25], ] global.equippedWeapon = equipmentList[27]; -global.equippedArmor = equipmentList[24]; +global.equippedArmor = equipmentList[25]; // Game Mechanics global.walkRate = 0; // Units the player walks per day, affects foodRateCalc and radPointsCalc From 1179fb5afc90a80d585839de857edc5e788a3517 Mon Sep 17 00:00:00 2001 From: Caroline Foy Date: Mon, 28 Apr 2025 12:11:00 -0500 Subject: [PATCH 25/27] Added comments for "poiscreens" and "encounters" files --- files/encounters.js | 10 ++++++++++ files/poiscreens.js | 12 ++++++++++++ 2 files changed, 22 insertions(+) diff --git a/files/encounters.js b/files/encounters.js index 3163268..4666507 100644 --- a/files/encounters.js +++ b/files/encounters.js @@ -5,10 +5,16 @@ import './variables.js'; //5-50 abominations, 51-200 MWBOS, 201-255 legion, a5-a40 NCR, b0-b30 abomination, b40-b80 abomination, b90+ NCR, b80-b90 enclave //HLE = high level encounter, this is a filter that determines if the player can get, as the name implies, high level encounters + +//This function, which is called whenever the player moves, runs a quick calculation to determine if the player encounters +//an enemy. If they do encounter an enemy, the function uses the player's location to determine which enemy they encounter. +//The farther the player goes, the more likely they are to encounter a high-level enemy. Enemies scale in health and damage with +//the player's level. export function naturalEncounter(location){ var HLE = false; var encounter = false; var encounterLuck = randomNumber(1, 100); + //Checks if the player gets an encounter, and what enemy pool the encounter comes from. if(location > 250){ HLE = true; } @@ -48,6 +54,7 @@ export function naturalEncounter(location){ } } + //Draws the enemy/encounter from an array of different possible encounters. if(encounter != false){ switch(encounter){ case "abomination": @@ -133,6 +140,8 @@ export function naturalEncounter(location){ } }; +//Used for when we need to ensure that the player encounters an enemy somewhere. Also used for combat testing. +//Function takes in the faction of the enemy, and if the enemy can be/has to be a high level encounter. export function forcedEncounter(HLE, faction, forcedHLE){ var HLEDeterminant = randomNumber(1, 2) if((HLE == true && HLEDeterminant == 1) || forcedHLE == true){ @@ -172,6 +181,7 @@ export function forcedEncounter(HLE, faction, forcedHLE){ } } +//A list of arrays with every possible enemy encounter, as well as their stats and equipment. var raiderEncounters = [ {name: "Raider Aspirant", faction: "raider", minLevel: 1, maxLevel: 15, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, {name: "Raider", faction: "raider", minLevel: 15, maxLevel: 25, health: 10, weapon: equipmentList[2], armor: equipmentList[10]}, diff --git a/files/poiscreens.js b/files/poiscreens.js index b96eb76..31c3dab 100644 --- a/files/poiscreens.js +++ b/files/poiscreens.js @@ -4,6 +4,9 @@ import { userInput, pauseScreen, enableRawMode, disableRawMode, sleep } from "./ import './variables.js'; import { whitespringStore, trader, eurekaStore, newVegasStore, vaultZeroStore } from "./shops.js"; +//This function uses a switch statement to determine the player's location within a given range. If said location IS +//within the given range, the statement will call a seperate function to declare that the player is in a point of interest, +//building the player's screen to match that. export function checkPOI() { if (path == 0) { if (location >= (pois[poiCounter].location)-3 && location <= pois[poiCounter].location && pois[poiCounter].visited == false) { @@ -92,6 +95,8 @@ export function checkPOI() { } } +//This array holds important information about every point of interest in the game, such as its name, locaiton on the +//player's path, and a boolean for if it has been visited by the player yet. global.poiCounter = 0; global.pois = [ {name: "Whitespring Bunker", location: 25, path: 0, visited: false}, @@ -119,7 +124,12 @@ global.pois = [ {name: "Camp Navarro", location: 100, path: 2, visited: false}, ] +//EVERY POI FUNCTION WORKS THE SAME, THE ONLY DIFFERENCE IS THAT THEY EACH CALL THEIR RESPECTIVE DIALOGUE AND +//SHOP FUNCTIONS. + +//This function builds the POI the player has reached. In this instance, it builds the POI called "The Whitespring". function whitespring() { + //Basic introductory message, along with changing the game's basic functioning with the raw mode command. disableRawMode(); console.clear(); sleep(1); @@ -131,6 +141,8 @@ function whitespring() { console.log("3) Open your PIP-Boy"); console.log("4) Leave"); let whitespringInput = userInput("Enter: "); + //Switch statement changes depending on the user's input, allowing them to explore the POI, talk or trade with the locals, + //check their stats, or leave if they wish to. switch(whitespringInput) { case "1": console.clear(); From a8c9d868be1f4130a41fc2b7152fb3832923df0a Mon Sep 17 00:00:00 2001 From: Raktbastr Date: Mon, 28 Apr 2025 12:19:02 -0500 Subject: [PATCH 26/27] 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 From 552a842b0096d5b7df3dbb8ec5d7e79cd7e6a3b9 Mon Sep 17 00:00:00 2001 From: Caroline Foy Date: Tue, 29 Apr 2025 14:00:36 -0500 Subject: [PATCH 27/27] Added student A/B comments --- files/combat.js | 2 ++ files/encounters.js | 2 ++ files/functions.js | 2 ++ files/inventory.js | 2 ++ files/main.js | 2 ++ files/poiscreens.js | 2 ++ files/shops.js | 2 ++ files/variables.js | 2 ++ 8 files changed, 16 insertions(+) diff --git a/files/combat.js b/files/combat.js index a3ccc76..16ab897 100644 --- a/files/combat.js +++ b/files/combat.js @@ -1,3 +1,5 @@ +//Created by student A + import './variables.js'; import { randomNumber, userInput } from './functions.js'; import { inventoryMenuM } from './inventory.js'; diff --git a/files/encounters.js b/files/encounters.js index 4666507..faae37d 100644 --- a/files/encounters.js +++ b/files/encounters.js @@ -1,3 +1,5 @@ +//Created by student B + // Holds encounter code, seperate from poiscreens.js import { randomNumber } from "./functions.js"; diff --git a/files/functions.js b/files/functions.js index 3764756..4e8f05c 100755 --- a/files/functions.js +++ b/files/functions.js @@ -1,3 +1,5 @@ +//Created by student A and B collaboratively + // Holds all functions used in multiple files import { createRequire } from 'module'; const require = createRequire(import.meta.url); diff --git a/files/inventory.js b/files/inventory.js index 21ceccd..9c60fe1 100644 --- a/files/inventory.js +++ b/files/inventory.js @@ -1,3 +1,5 @@ +//Created by student A + import { userInput } from "./functions.js"; import "./variables.js"; diff --git a/files/main.js b/files/main.js index e3540ea..5020329 100755 --- a/files/main.js +++ b/files/main.js @@ -1,3 +1,5 @@ +//Created by student A and B collaobratively + // Program is started from here, runs functions from other files. import { userInput, sleep, disableRawMode, walkPathMain, randomNumber } from './functions.js'; import { forcedEncounter, naturalEncounter } from './encounters.js'; diff --git a/files/poiscreens.js b/files/poiscreens.js index 31c3dab..9bf132b 100644 --- a/files/poiscreens.js +++ b/files/poiscreens.js @@ -1,3 +1,5 @@ +//Created by student B + // Holds poi code, seperate from encounters.js import { userInput, pauseScreen, enableRawMode, disableRawMode, sleep } from "./functions.js"; diff --git a/files/shops.js b/files/shops.js index e0052e1..bf4639b 100644 --- a/files/shops.js +++ b/files/shops.js @@ -1,3 +1,5 @@ +//Created by student A + import { randomNumber, userInput } from "./functions.js"; import "./variables.js"; diff --git a/files/variables.js b/files/variables.js index 08d963c..c860b98 100644 --- a/files/variables.js +++ b/files/variables.js @@ -1,3 +1,5 @@ +//Created by students A and B collaboratively + // Now holds only variables // Items