Create-Task/files/functions.js
2025-04-28 12:19:02 -05:00

494 lines
No EOL
20 KiB
JavaScript
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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;
}
}