Compare commits

...
Sign in to create a new pull request.

30 commits

Author SHA1 Message Date
Caroline Foy
a540fb6518 Merge branch 'main' of https://github.com/Raktbastr/Create-Task 2025-04-29 14:01:20 -05:00
Caroline Foy
552a842b00 Added student A/B comments 2025-04-29 14:00:36 -05:00
2e68c920ff Merge branch 'Temp-main-for-fixing' 2025-04-28 13:33:28 -05:00
a8c9d868be My comments. 2025-04-28 12:19:02 -05:00
Caroline Foy
1179fb5afc Added comments for "poiscreens" and "encounters"
files
2025-04-28 12:11:00 -05:00
77cb3f4613 The Final commit before turn-in (hopefully) 2025-04-27 21:53:42 -05:00
Caroline Foy
44a4cf65bd Added POI dialogue for all BOS bunkers and
Flagstaff
2025-04-27 17:50:34 -05:00
d837a57472 Fixed issues... Again 2025-04-27 16:09:07 -05:00
df257c6420 Combat partially done, encounters fixed. 2025-04-27 00:10:05 -05:00
8485d7d800 Shops, encounters, poi menus, items, and some other stuff. Poi dialogue and combat left! 2025-04-25 23:08:47 -05:00
22975aff26 Finished Achievements. Needs implimentation. 2025-04-23 23:30:29 -05:00
324679c4a6 More achievements and fixed sleep. 2025-04-21 19:23:23 -05:00
9a765b8434 Added armor resistances and allat good stuff. 2025-04-18 21:20:37 -05:00
82565a2be9 A lot, i dont rembr 2025-04-14 11:40:21 -05:00
fdd58af63e Fixed sleep function issue and writing to global variables. 2025-04-14 11:39:23 -05:00
Caroline Foy
dbd27cfa7d Added a working "forced encounter" function and a
yet to be functional natural encounter function.
2025-04-12 09:38:55 -05:00
6714250079 variablefilevariablechangefunction 2025-04-03 12:15:48 -05:00
7846f80f11 We can finally rest... 2025-04-03 11:23:51 -05:00
e5fe71ce46 Rewrite 2025-04-03 11:10:35 -05:00
8871c644fb Stashing changes for later 2025-03-30 18:52:44 -05:00
49f93574af Begin work on rep system. Finished encounter generation for the most part. Needs testing. 2025-03-20 11:34:26 -05:00
42bf2a484a Merge remote-tracking branch 'origin/Finishing-Menuing' 2025-03-12 11:09:10 -05:00
Caroline Foy
6ca88b7c6f More changes to menuing, added a basic inventory
system
2025-03-10 12:05:17 -05:00
Caroline Foy
f732586c24 Finally got the encounter menu function working 2025-03-04 17:55:42 -06:00
e4b96a8537 Finish Achievement to-do section. 2025-02-27 14:56:49 -06:00
Caroline Foy
0c36b89ff6 Mess around with the POI menu stuff 2025-02-27 13:44:22 -06:00
93c65c3627 Todo and Story 2025-02-26 15:56:21 -06:00
Caroline Foy
0dfc20e470 Hi 2025-02-26 15:38:51 -06:00
6e476dcf14 Edit TODO. 2025-02-26 10:22:58 -06:00
3178ef479b Add game,js and modify calcLocation. Added variable exports to every file. 2025-02-26 09:51:09 -06:00
21 changed files with 2669 additions and 272 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

8
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,8 @@
{
"github.copilot.enable": {
"*": false,
"plaintext": false,
"markdown": false,
"scminput": false
}
}

128
TODO.md
View file

@ -1,32 +1,106 @@
## Basic ### POIs, Enemy Selection, Random Encounters: Car
* See if we can split things across multiple files for readability ### Combat, Achievements, People: Finn
* Graphics
* Dialogue, make in function
* __Story__
## Game Mechanics ## Game Mechanics
* Scavenging (random num 1-100, items based on that) - POI's and Factions
* POI Menu (talk with people, trade, map, etc) - Logic for faction armor
* Stop Menu (scavenge, change settings) - Logic for path split
* River crossing menu - Dialogue for locations
* Random Encounters - Brotherhood Bunkers
* Trading - Tibbets
* Movement/Time (day counter that multiplies stats by certain amt) - Flagstaff
* POI Chosing based on location in world (NCR bases in Cali, Legion in CO, BOS in Midwest) - New Vegas
* Hunting minigame (only if we can make the terminal blankout and not just add lines) - 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
## Misc - Random Encounters
* Credit Bethesda if needed - 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
## Locations (Please Read) ## Story
* 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
### Other Location notes ### Intro
* MODUS at the Whitespring directs you to the Midwest Brotherhood 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.
* 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 ### 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".

View file

@ -1,14 +1 @@
// Adding from other files console.log(time.now)
// main.js
const variables = require("./variables.js");
variables.sleep(1000);
// variables.js
module.exports = { //add any functions or variables you want to export in here
sleep
}
function sleep(time) {
setTimeout(() => {}, time);
}

BIN
files/.DS_Store vendored Normal file

Binary file not shown.

164
files/combat.js Normal file
View file

@ -0,0 +1,164 @@
//Created by student A
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;
} 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"};
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 (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!");
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;
}
}
}
// 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") {
var damageOutput = playerStats.weapon.damage*1.5;
} else {
var damageOutput = playerStats.weapon.damage;
}
if (crit) {
damageOutput+3;
}
if (enemyStats.armorUnit == "dr"){
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;
return dtDamage;
}
} else {
if (playerStats.chem == "medx") {
var damageOutput = enemyStats.weapon.damage*(-1.5);
} else {
var damageOutput = enemyStats.weapon.damage;
}
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;
return dtDamage;
}
}
}

View file

@ -1,29 +0,0 @@
// Deathscreens, they should be the fallout 1 screens
module.exports = {
deathScreen,
timeDeath
};
function deathScreen() {
let random = Math.random(1,3);
if (random = 1) { death1(); }
if (random = 2) { death2(); }
if (random = 3) { death3(); }
}
function death1() {
}
function death2() {
}
function death3() {
}
function timeDeath() { // The death screen for passing the time limit
}

256
files/encounters.js Normal file
View file

@ -0,0 +1,256 @@
//Created by student B
// 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
//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;
}
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";
}
}
//Draws the enemy/encounter from an array of different possible encounters.
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;
}
};
//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){
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)];
}
}
}
//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]},
{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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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]},
];

496
files/functions.js Executable file
View file

@ -0,0 +1,496 @@
//Created by student A and B collaboratively
// Holds all functions used in multiple files
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 './variables.js';
import { inventoryMenuM } from './inventory.js';
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
// 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
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 - walkRate
} else {
food = food - walkRate * foodRate
}
}
export function checkLose() { // Checks to see if any lose conditions have been met
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");
}
}
// 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) {
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;
}
}
}
// 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') {
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);
}
}
}
// 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); }
if (random >= 34 && random <= 66) { death2(deathCause); }
if (random >= 67 && random <= 99) { death3(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);
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(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(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
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;
}
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;
} 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 [SPACE] to open Pip-Boy");
console.log("Current Health: "+health);
console.log("Food Amt: "+food);
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();
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 [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));
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 [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));
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 [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));
travelFrame=0;
}
}
// 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) {
disableRawMode();
pauseScreen();
enableRawMode();
}
calcLocation();
radPointsCalc();
healthCapCalc();
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
}
});
// 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);
process.stdin.resume();
isRawModeEnabled = true;
}
}
// Turns raw mode off and sets the variable isRawModeEnabled to true
export function disableRawMode() {
if (isRawModeEnabled) {
process.stdin.setRawMode(false);
process.stdin.pause();
isRawModeEnabled = false;
}
}
// 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
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: ");
// 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 {
break;
}
}
switch(pauseInput) {
// Shows all pois on the main path, and the chosen path if the player choses one.
case "1":
paused = false;
break;
case "2":
inventoryMenuM();
break;
case "3":
console.clear();
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-locationA+" 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-locationB+" location points away");
}
}
}
userInput("\n[Press Enter to return]");
break;
case "4":
// Displays many player stat variables.
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;
case "5":
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);
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;
}
}

View file

@ -1 +0,0 @@
// Hunting Game, if we even decide to do it.

86
files/inventory.js Normal file
View file

@ -0,0 +1,86 @@
//Created by student A
import { userInput } from "./functions.js";
import "./variables.js";
// 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");
console.log("---------");
console.log("1) View");
console.log("2) Equip Weapon");
console.log("3) Equip Armor");
console.log("4) Exit");
let invChoice = userInput("Enter: ");
switch(invChoice){
case "1":
viewInventory();
break;
case "2":
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");
}
}
// viewInventory()
// Lists all items in the inventory array.
function viewInventory(){
console.clear();
console.log("Inventory");
console.log("---------");
for(var a = 0; a < inventory.length;){
console.log((a + 1) + ") " + inventory[a].name);
a++;
}
userInput("[Enter to return]");
console.clear();
inventoryMenuM();
}

83
files/main.js Normal file → Executable file
View file

@ -1,52 +1,97 @@
// Program is started from here, runs functions from other files. //Created by student A and B collaobratively
const variables = require("./variables.js");
const shops = require("./shops");
const readline = require('node:readline');
// 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 { 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(); console.clear();
console.log("__________________________________________________________________________________________________________________________________"); console.log("__________________________________________________________________________________________________________________________________");
console.log(" _____ _ ____ "); console.log(" _____ _ ____ ");
console.log(" / ' / / / / ) /"); console.log(" / ' / / / / ) /");
console.log("---/__-------__---/---/----__---------_/_---------/-------__----__----__---__----__---_--_----__-------/___ /----__----__----__-/-"); console.log("---/__-------__---/---/----__---------_/_---------/-------__----__----__---__----__---_--_----__-------/___ /----__----__----__-/-");
console.log(" / / ) / / / ) / / / o / / ) / ) /___) (_ ` / ) / / ) /___) / | / ) / ) / / "); console.log(" / / ) / / / ) / / / o / / ) / ) /___) (_ ` / ) / / ) /___) / | / ) / ) / / ");
console.log("_/________(___(_/___/___(___/_(___(__(_ __o_____/____/_(___/_/___/_(___ _(__)_(___/_/_/__/_(___ _____/_____|__(___/_(___(_(___/___"); console.log("_/________(___(_/___/___(___/_(___(__(_ __o_____/____/_(___/_/___/_(___ _(__)_(___/_/_/__/_(___ _____/_____|__(___/_(___(_(___/___\n\n");
console.log("Credits: Bethesda Game Studio"); await sleep(1);
variables.sleep(1000);
// Collects player input for menus
var mainMenuInput;
while (true) {
console.log("What would you like to do?"); console.log("What would you like to do?");
console.log("--------------------------"); console.log("--------------------------");
console.log("1) Start new game"); console.log("1) Start new game");
console.log("2) Learn How to play"); console.log("2) Learn How to play");
console.log("3) Quit Game"); console.log("3) Quit Game");
console.log("4) Credits\n");
mainMenuInput = userInput("Enter: ");
var mainMenuInput = variables.userInput("Enter: ") // Input validation
if (mainMenuInput != "1" && mainMenuInput != "2" && mainMenuInput != "3" && mainMenuInput != "4") {
console.log("Invalid input. Please enter 1, 2, or 3.");
} else {
break;
}
}
switch(mainMenuInput) { switch(mainMenuInput) {
case "1": case "1":
startGame(); startGame();
break; break;
case "2": case "2":
while (true) { console.log(variables.randomNumber(10,15)); } console.log(food);
break; break;
case "3": case "3":
console.log("Quitting Game..."); console.log("Quitting Game...");
variables.sleep(1000); await sleep(1);
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;
} }
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(); console.clear();
variables.sleep(1000); name = userInput("What is your name? ");
variables.name = variables.userInput("What is your name? "); console.log(name+" Is now your name...")
console.log(variables.name+" Is now your name...")
variables.sleep(2000);
console.clear(); console.clear();
console.log("Intro:"); 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(); console.clear();
variables.prewarmoney = 500; preWarMoney = 500;
shops.trader(); 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();
walkPathMain(0);
} }

View file

@ -1 +0,0 @@
// Map Screen

View file

@ -1,5 +1,5 @@
{ {
"name": "files", "name": "CT Rewrite",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {

View file

@ -1,5 +1,5 @@
{ {
"name": "files", "name": "CT Rewrite",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {

View file

@ -1,5 +1,6 @@
{ {
"dependencies": { "dependencies": {
"readline-sync": "^1.4.10" "readline-sync": "^1.4.10"
} },
"type": "module"
} }

View file

@ -1 +1,825 @@
// Holds the screens for every POI including thier menus. //Created by student B
// Holds poi code, seperate from encounters.js
import { userInput, pauseScreen, enableRawMode, disableRawMode, sleep } from "./functions.js";
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) {
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();
}
}
}
}
//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},
{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},
]
//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);
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 (Whitespring Mall)");
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();
sleep(1);
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?");
userInput(" \n[Enter to continue]\n")
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 you're of top level clearance?");
userInput(" \n[Enter to continue]\n")
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, 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 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 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? 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 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 I'll 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) Open your PIP-Boy");
console.log("3) Leave");
let poiInput = userInput("Enter: ");
switch(poiInput) {
case "1":
console.clear();
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":
pauseScreen();
break;
case "3":
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) Open your PIP-Boy");
console.log("3) Leave");
let poiInput = userInput("Enter: ");
switch(poiInput) {
case "1":
console.clear();
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":
pauseScreen();
break;
case "3":
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) Open your PIP-Boy");
console.log("3) Leave");
let poiInput = userInput("Enter: ");
switch(poiInput) {
case "1":
console.clear();
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, 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");
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":
pauseScreen();
break;
case "3":
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();
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();
case "3":
flagstaffStore();
break;
case "4":
enableRawMode();
console.clear();
break;
}
}
function newVegas() {
disableRawMode();
console.clear();
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 your journey");
let poiInput = userInput("Enter: ");
switch(poiInput) {
case "1":
console.clear();
console.log("")
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":
trader();
break;
case "4":
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("3) Attempt to trade");
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":
lostHillsStore();
break;
case "4":
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();
}

View file

@ -1 +0,0 @@
// River crossing screens and options.

View file

@ -1,43 +1,556 @@
const readline = require('readline-sync'); //Created by student A
const variables = require("./variables");
module.exports = { import { randomNumber, userInput } from "./functions.js";
ravenRock, import "./variables.js";
vaultZero,
newVegas,
eureka,
trader,
}
// Inventories for the various shops // Inventories for the various shops, based of global item lists
var rrInv = []; var rrInv = [
var vt0Inv = []; {item: supplyList[0], name: supplyList[0].name, price: supplyList[0].cost/10, amount: 1000},
var vegasInv = []; // A mix of gunrunners, mick&ralphs, and followers {item: supplyList[1], name: supplyList[1].name, price: supplyList[1].cost, amount: 100},
var eurInv = []; {item: supplyList[2], name: supplyList[2].name, price: supplyList[2].cost, amount: 100},
var traderInv = ["gun", "stimpak", "radx"]; {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},
function ravenRock() { {item: equipmentList[2], name: equipmentList[2].name, price: equipmentList[2].cost, amount: 10},
// purchasing code {item: equipmentList[8], name: equipmentList[8].name, price: equipmentList[8].cost, amount: 10},
} ];
var vt0Inv = [
function vaultZero() { {item: supplyList[0], name: supplyList[0].name, price: supplyList[0].cost, amount: 1000},
// purchasing code {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},
function newVegas() { {item: equipmentList[0], name: equipmentList[0].name, price: equipmentList[0].cost, amount: 10},
// purchasing code {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},
function eureka() { {item: equipmentList[5], name: equipmentList[5].name, price: equipmentList[5].cost, amount: 10},
// purchasing code {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},
function trader() { // One of the 3 trader inventories, chosen randomly ];
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 tempTraderInv = [];
for (var a = 0; a <= 2; a++) { var whitespringInv = [
let randomPick = Math.m {item: supplyList[0], name: supplyList[0].name, price: supplyList[0].cost/10, amount: 1000},
tempTraderInv.push(traderInv[1]); {item: supplyList[1], name: supplyList[1].name, price: supplyList[1].cost, amount: 100},
console.log(randomPick); {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},
];
// 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();
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*10 + " | " + 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?");
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 {
for (var i = 0; i < itemAmt; i++) {
inventory.push(rrInv[itemNum].item);
}
}
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 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;
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;
case "2":
console.log("Leaving shop...");
return true;
default:
console.log("Invalid input, try again.");
}
}
}
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.");
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...");
if (vegasInv[itemNum].name == "Food") {
food = food+itemAmt;
} else {
for (var i = 0; i < itemAmt; i++) {
inventory.push(vegasInv[itemNum].item);
}
}
userInput("[Enter]");
}
break;
case "2":
console.log("Leaving shop...");
return true;
break;
default:
console.log("Invalid input, try again.");
}
}
}
export 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*10 + " | " + 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*10 > preWarMoney) {
console.log("Not enough money.");
break;
} else {
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.");
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]");
}
break;
case "2":
console.log("Leaving shop...");
return true;
default:
console.log("Invalid input, try again.");
}
}
}
export function lostHillsStore() {
while (true) {
console.clear();
console.log("Brotherhood of Steel Requisition System - Lost Hills");
console.log("Name | Price (Caps) | Amount in stock");
console.log("-----------------------------------------------------");
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 " + caps + " caps.");
console.log("What would you like to do?");
console.log("1) Buy supplies");
console.log("2) Leave shop");
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 > lostHillsInv[itemNum].amount) {
console.log("Not enough stock.");
break;
} else if (itemAmt * lostHillsInv[itemNum].price > caps) {
console.log("Not enough money.");
break;
} else {
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.");
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]");
}
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 < 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 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 > whitespringInv[itemNum].amount) {
console.log("Not enough stock.");
break;
} else if (itemAmt * whitespringInvv[itemNum].price > caps) {
console.log("Not enough money.");
break;
} else {
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.");
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]");
}
break;
case "2":
console.log("Leaving shop...");
return true;
default:
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 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 > tempTraderInv[itemNum].amount) {
console.log("Not enough stock.");
break;
} else if (itemAmt * tempTraderInv[itemNum].price > caps) {
console.log("Not enough money.");
break;
} else {
preWarMoney -= itemAmt * tempTraderInv[itemNum].price;
tempBOSStock[itemNum].amount -= itemAmt;
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]");
}
break;
case "2":
console.log("Leaving shop...");
return true;
break;
default:
console.log("Invalid input, try again.");
}
} }
console.log(tempTraderInv);
} }

View file

@ -1 +0,0 @@
// Halt travel screen and menu.

View file

@ -1,148 +1,124 @@
// Holds the global variables, functions, and math operations such as the day counter and food eaten.. //Created by students A and B collaboratively
const readline = require('readline-sync');
module.exports = { // Lets variables and functions be used in other files // Now holds only variables
day,
location,
ammo,
food,
foodAmt,
health,
travelSpeed,
isRadiated,
radSeverity,
isSick,
sickSeverity,
inventory,
name,
prewarmoney,
caps,
eatfood,
calcLocation,
calcSickPoints,
scavenge,
sleep,
checkLose,
userInput,
randomNumber
};
var name = ''; // To allow a variable to be read/wrote from across files you must begin them with "global.variablename"
var prewarmoney = 0; // Used in Enclave Stores // 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},
{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
{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, 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},
{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},
{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},
{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},
{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},
{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},
{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: "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: "Fists (Unarmed)", description: "Unarmed combat, does 5 bash damage", type: "weapon", value: "5", unit: "bash", cost: 5, weight: 1},
];
var caps = 0; // Used everywhere // 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},
{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 nuke.", unlocked: false},
{name: "Revenge", description: "Destroy Shady Sands or all NCR cities (depending on path)", unlocked: false},
{name: "Eureka!", description: "Destroy Eureka", unlocked: false},
{name: "Pit Stop", description: "Destroy Lost Hills", unlocked: false},
var day = 0; // Should we add a definite end? 365 Days? // Secrets
{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"},
var location = 0; // Location in the world, 0 is Raven Rock, 255 is New Vegas // Power Armor
var locationA = 0; // Location on path A, {name: "Rocket 69", description: "Apply the Jetpack upgrade to your T-60 Power Armor"},
var locationB = 0; // Location on path B, 225 is Navarro {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"},
var ammo = 0; // Used in encounters and hunting, No cap :) {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"},
var food = 0; // Max: 200 // Faction Rep
var foodAmt = 0; // Amt of food eaten per day, 3 levels, starting at 1 {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"},
]
var health = 0; // Max: 100 // Player Currency
global.preWarMoney = 0; // Used with enclave vendors
global.caps = 0; // Used with all other vendors
var travelSpeed = 0; // Location points per day, 3 levels, starting at 1 // 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
equipmentList[27],
equipmentList[25],
]
global.equippedWeapon = equipmentList[27]; // Players currently equipped weapon
global.equippedArmor = equipmentList[25]; // PLayers currently equipped armor
var isRadiated = false; // Game Mechanics
var radSeverity = 0; // Modifies many things, 3 levels, starting at 1 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
var isSick = false; global.path = 0; // Path player is currently on, 0 = Main, 1 = A, 2 = B
var sickPoints = 0; // If you accumulate 50 sick points you lose global.location = 0; // Location on main path, 0-255 = main, 500-1000 = A, 1500-2000 = B
var sickSeverity = 0; // 3 levls, starting at 1 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
var inventory = []; // Max of 5 items 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
var lootTables = [[],[],[],[],[]] // Only small things like food and ammo, 5 Loot tables per scavenge score, 3 items in each, first is best global.daysSinceScav = 0; // Days since player last scavenged. Must be >= 15 to scavenge again.
function eatfood() { global.name = "placeholder"; // Player name, changed when the game starts
if (food == 0) { health - 20 }
if (isSick == true) { food = food-((travelSpeed*foodAmt)+sickSeverity); }
else { food = food-(travelSpeed*foodAmt); }
health = health+(5*foodAmt);
}
function calcSickPoints() { global.testDeath = false; // Used to test death, set to true to kill player
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);
}
}
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);
}
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;
}