832 lines
23 KiB
JavaScript
832 lines
23 KiB
JavaScript
#!/usr/bin/env node
|
||
|
||
//libraries
|
||
const yargs = require('yargs/yargs')
|
||
const { hideBin } = require('yargs/helpers')
|
||
const argv = yargs(hideBin(process.argv)).argv
|
||
const Charlatan = require('charlatan');
|
||
const blessed = require('blessed');
|
||
const fs = require("fs");
|
||
const generator = require("project-name-generator");
|
||
const { readdirSync } = require('fs');
|
||
const Troubadour = require('troubadour');
|
||
|
||
//audio players
|
||
const troubadourLoop1 = new Troubadour('mplayer'); //or pass in sox for example
|
||
const troubadourLoop2 = new Troubadour('mplayer'); //or pass in sox for example
|
||
|
||
//save/load files
|
||
const dungeonFile = ".dungeonfile.txt";
|
||
const gameFile = ".gamefile.txt";
|
||
const dateFile = ".datefile.txt";
|
||
const itemsFile = ".itemsfile.txt";
|
||
const descriptionsFile = ".nonKittenItems.txt";
|
||
const verbsFile = ".verbs.txt";
|
||
const inventoryFile = ".inventory.txt";
|
||
const placesFile = ".places.txt";
|
||
const terrainFile = ".terrain.txt";
|
||
const mediaFormatsFile = ".media-formats.json";
|
||
const genresFile = ".genres.json";
|
||
const musicPath = './assets/snd/';
|
||
|
||
// game vars
|
||
program = blessed.program();
|
||
|
||
const width = 24;
|
||
const height = 8;
|
||
const movesInADay = 24;
|
||
let dungeon;
|
||
let roomItems = [];
|
||
let today;
|
||
let eating = false, dropping = false;
|
||
let itemDescriptions = [];
|
||
let verbs = [];
|
||
let inventory = [];
|
||
let terrain = [];
|
||
let places = [];
|
||
let mediaFormats = [];
|
||
let genres = [];
|
||
let player = {"position": {
|
||
"x": null,
|
||
"y": null,
|
||
},
|
||
"avatar": "@",
|
||
"movedToday": false,
|
||
"life": null
|
||
};
|
||
|
||
//----------------------START and LOOP-------------------------------
|
||
function start(){
|
||
|
||
if (argv.new){
|
||
createMap();
|
||
}
|
||
|
||
loadAll();
|
||
|
||
program.alternateBuffer();
|
||
program.clear();
|
||
|
||
program.move(1, 1);
|
||
// program.bg('blue');
|
||
program.write('A Visit to Moaning Cream Camp, and Other Villages', 'red fg');
|
||
//program.setx((program.cols / 4 | 0) );
|
||
program.setx(1);
|
||
program.down(3);
|
||
program.write('Directions: arrow keys (or vimkeys)');
|
||
program.setx(1);
|
||
program.down(1);
|
||
program.write('Q to quit');
|
||
// program.bg('!black');
|
||
program.feed();
|
||
}
|
||
|
||
function loop(){
|
||
program.on('keypress', function(ch, key) {
|
||
|
||
resetScreen();
|
||
|
||
if (!eating && !dropping){
|
||
checkKeys(key);
|
||
} else {
|
||
eatOrDrop(key);
|
||
}
|
||
|
||
|
||
updateDungeon();
|
||
drawDungeon();
|
||
program.setx(1);
|
||
|
||
checkCollision();
|
||
});
|
||
}
|
||
|
||
|
||
//----------------------------functions-------------------------------------
|
||
|
||
function checkKeys(key){
|
||
switch(key.name) {
|
||
case 'q':
|
||
program.disableMouse();
|
||
program.showCursor();
|
||
program.normalBuffer();
|
||
process.exit(0);
|
||
case 'right': //vim key 'l' or right-arrow
|
||
case 'l':
|
||
//program.write('moved right');
|
||
if (player.position.x<width-1){
|
||
player.position.x++;
|
||
stopMusic();
|
||
}
|
||
break;
|
||
case 'left': //vim key 'h' OR left-arrow
|
||
case 'h':
|
||
//program.write('moved left');
|
||
if (player.position.x>0){
|
||
player.position.x--;
|
||
stopMusic();
|
||
}
|
||
break;
|
||
case 'up': //vim key 'k' or up-arrow
|
||
case 'k':
|
||
//program.write('moved up');
|
||
if (player.position.y>0){
|
||
player.position.y--;
|
||
stopMusic();
|
||
}
|
||
break;
|
||
case 'down': //vim key 'j' or down-arrow
|
||
case 'j':
|
||
//program.write('moved down');
|
||
if (player.position.y<height-1){
|
||
player.position.y++;
|
||
stopMusic();
|
||
}
|
||
break;
|
||
case 'p':
|
||
//program.write('picked up something');
|
||
pickup();
|
||
break;
|
||
case 'i':
|
||
//program.write('list inventory');
|
||
inv();
|
||
break;
|
||
case 'e': //eat
|
||
eat();
|
||
break;
|
||
case 'd': //drop
|
||
drop();
|
||
break;
|
||
default: //else
|
||
program.setx(0)
|
||
program.down(10);
|
||
program.write('Unknown action. Press another key');
|
||
|
||
program.up(10);
|
||
|
||
}
|
||
}
|
||
|
||
function pickup(){
|
||
for (let i = 0; i < roomItems.length; i++){
|
||
if ((player.position.x == roomItems[i].position.x) && (player.position.y == roomItems[i].position.y)){
|
||
if (roomItems.length<10){
|
||
console.log("You take "+roomItems[i].name);
|
||
|
||
//add to player inventory
|
||
inventory.push(roomItems[i]);
|
||
|
||
//now remove from room since owned by player now
|
||
roomItems.splice(i, 1);
|
||
} else {
|
||
console.log(roomItems);
|
||
console.log("Your backpack is already full");
|
||
}
|
||
}
|
||
}
|
||
//save to inventory file
|
||
let inventoryData = JSON.stringify(inventory);
|
||
fs.writeFileSync(inventoryFile, inventoryData);
|
||
//save changed items file (without the picked-up item)
|
||
let itemsData = JSON.stringify(roomItems);
|
||
fs.writeFileSync(itemsFile, itemsData);
|
||
}
|
||
|
||
function eat(){
|
||
program.setx(0)
|
||
program.down(9);
|
||
program.write("Eat which item?: ");
|
||
|
||
for (let i = 0; i < inventory.length; i++){
|
||
program.setx(0);
|
||
program.down(1);
|
||
program.write(i+": "+inventory[i].symbol+" "+inventory[i].description);
|
||
}
|
||
|
||
program.setx(0)
|
||
program.sety(0);
|
||
|
||
eating = true;
|
||
}
|
||
|
||
function drop(){
|
||
program.setx(0)
|
||
program.down(9);
|
||
program.write("Drop which item?: ");
|
||
|
||
for (let i = 0; i < inventory.length; i++){
|
||
program.setx(0);
|
||
program.down(1);
|
||
program.write(i+": "+inventory[i].symbol+" "+inventory[i].description);
|
||
}
|
||
|
||
program.setx(0)
|
||
program.sety(0);
|
||
|
||
dropping = true;
|
||
}
|
||
|
||
function inv(){
|
||
|
||
program.setx(0)
|
||
program.down(9);
|
||
program.write("In your backpack: ");
|
||
|
||
for (let i = 0; i < inventory.length; i++){
|
||
program.setx(0);
|
||
program.down(1);
|
||
program.write(inventory[i].symbol+": "+inventory[i].description);
|
||
}
|
||
|
||
program.setx(0)
|
||
program.sety(0);
|
||
}
|
||
|
||
function eatOrDrop(key){
|
||
|
||
if (key.full>=0 && key.full<=9){
|
||
if (inventory[key.full]){
|
||
|
||
if (eating){
|
||
console.log("Delicious, you ate "+lowerFirst(inventory[key.full].description));
|
||
} else if (dropping){
|
||
console.log("You dropped"+lowerFirst(inventory[key.full].description));
|
||
//add back to room
|
||
//
|
||
//
|
||
roomItems.push(
|
||
{
|
||
"name": "",
|
||
"symbol": inventory[key.full].symbol,
|
||
"description": inventory[key.full].description,
|
||
"position":
|
||
{
|
||
"x": player.position.x,
|
||
"y": player.position.y
|
||
}
|
||
}
|
||
)
|
||
|
||
|
||
}
|
||
|
||
inventory.splice(key.full, 1);
|
||
|
||
//save to inventory file
|
||
let inventoryData = JSON.stringify(inventory);
|
||
fs.writeFileSync(inventoryFile, inventoryData);
|
||
|
||
} else {
|
||
console.log("You don't have that");
|
||
}
|
||
} else {
|
||
console.log("You don't have that");
|
||
}
|
||
|
||
eating = false
|
||
dropping = false
|
||
|
||
}
|
||
|
||
function checkCollision() {
|
||
|
||
program.bg('red');
|
||
|
||
//check Collision with Items
|
||
for (let i = 0; i < roomItems.length; i++){
|
||
if ((player.position.x == roomItems[i].position.x) && (player.position.y == roomItems[i].position.y)){
|
||
|
||
if (typeof roomItems[i].audio !== "undefined"){ //checks whether item is music
|
||
//console.log(roomItems[i].audio);
|
||
loop1(roomItems[i].audio[0])
|
||
loop2(roomItems[i].audio[1])
|
||
}
|
||
|
||
program.setx(0)
|
||
program.down(1)
|
||
program.write(roomItems[i].name);
|
||
program.setx(0)
|
||
program.down(2)
|
||
program.write(roomItems[i].description);
|
||
program.down(1)
|
||
program.setx(0)
|
||
}
|
||
}
|
||
|
||
//check Collision with Places
|
||
for (let i = 0; i < places.length; i++){
|
||
if ((player.position.x == places[i].position.x) && (player.position.y == places[i].position.y)){
|
||
//player is standing at this place
|
||
program.setx(0)
|
||
program.write(places[i].name);
|
||
}
|
||
}
|
||
|
||
program.bg('!red');
|
||
}
|
||
|
||
function resetScreen(){
|
||
program.setx(0);
|
||
program.clear();
|
||
}
|
||
|
||
function updateDungeon(){
|
||
//start with dots
|
||
for (let y = 0; y < height; y++){
|
||
for (let x = 0; x < width; x++){
|
||
dungeon[y][x] = ".";
|
||
}
|
||
}
|
||
//add terrain for drawing
|
||
for (let i = 0; i < terrain.length; i++){
|
||
dungeon[terrain[i].position.y][terrain[i].position.x] = terrain[i].symbol;
|
||
}
|
||
|
||
//add items to map
|
||
for (let i = 0; i < roomItems.length; i++){
|
||
dungeon[roomItems[i].position.y][roomItems[i].position.x] = roomItems[i].symbol;
|
||
}
|
||
|
||
//add places to map
|
||
for (let i = 0; i < places.length; i++){
|
||
dungeon[places[i].position.y][places[i].position.x] = places[i].symbol;
|
||
}
|
||
//add player for drawing
|
||
dungeon[player.position.y][player.position.x] = player.avatar;
|
||
|
||
}
|
||
|
||
function drawDungeon(){
|
||
for (let y=0; y < dungeon.length; y++){
|
||
|
||
let dungeonStr = '';
|
||
|
||
for (let x=0; x < dungeon[0].length; x++){
|
||
dungeonStr+=dungeon[y][x];
|
||
}
|
||
|
||
program.setx(1)
|
||
program.write(dungeonStr);
|
||
program.down(1)
|
||
//console.log(dungeonStr);
|
||
|
||
}
|
||
|
||
}
|
||
|
||
//--------------------------CREATE-MAP---------------------------------------
|
||
function createMap(){
|
||
createDungeon();
|
||
|
||
createTerrain();
|
||
createPlayer();
|
||
loadTextFiles();
|
||
createItems();
|
||
createTracks();
|
||
createBooks();
|
||
createPlaces();
|
||
createGraves();
|
||
|
||
saveMap();
|
||
}
|
||
|
||
function createDungeon(){
|
||
let createDungeon = () => {
|
||
dungeon = Array.from(Array(height), () => new Array(width))
|
||
}
|
||
}
|
||
|
||
let createTerrain = () => {
|
||
|
||
let forestTerrain = ['ᚠ','ᚡ','ᚴ','ᚵ','ᚶ','ᛉ','ᛘ','ᛠ'];
|
||
let plants = ['ሥ','ሥ','ቂ','ቁ','ቄ','ቃ','ቅ','ቆ','ቇ','ቈ','ቊ','ቋ','ቌ','ቍ','ቜ','ቝ']
|
||
let water = '⛆'
|
||
|
||
for (let y = 0; y < height; y++){
|
||
for (let x = 0; x < width; x++){
|
||
|
||
let symbol;
|
||
|
||
let chooser = Math.random();
|
||
|
||
if (chooser<0.9) {
|
||
symbol = choose(forestTerrain)
|
||
} else if (chooser<0.97) {
|
||
symbol = choose(plants);
|
||
} else {
|
||
symbol = '⛆';
|
||
|
||
if (Math.random()<0.3){ //30% of time, water to left as well
|
||
terrain[terrain.length-1].symbol = '⛆'; //symbol to left is water
|
||
}
|
||
|
||
//40% of time & if below top line, water above
|
||
if (y>0 && Math.random()<0.4){
|
||
terrain[terrain.length-width].symbol = '⛆';//symbol above is water
|
||
terrain[terrain.length-width-1].symbol = '⛆';//symbol above and left is water
|
||
}
|
||
}
|
||
|
||
terrain.push(
|
||
{
|
||
"symbol": symbol,
|
||
"position":
|
||
{
|
||
"x": x,
|
||
"y": y
|
||
}
|
||
}
|
||
)
|
||
}
|
||
}
|
||
}
|
||
|
||
let createPlayer = () => {
|
||
player.avatar = '@';
|
||
|
||
player.position.x = Math.floor(Math.random()*width)
|
||
player.position.y = Math.floor(Math.random()*height)
|
||
|
||
}
|
||
|
||
let loadTextFiles = () => {
|
||
itemDescriptions = fs.readFileSync(descriptionsFile).toString().split("\n");
|
||
|
||
verbs = fs.readFileSync(verbsFile).toString().split("\n");
|
||
|
||
let media = JSON.parse(fs.readFileSync(mediaFormatsFile).toString());
|
||
mediaFormats = media.instruments;
|
||
|
||
let genresList = JSON.parse(fs.readFileSync(genresFile).toString());
|
||
genres = genresList.genres;
|
||
}
|
||
|
||
let createItems = () => {
|
||
|
||
let numToSpawn = Math.round(Math.random() * 2) + 2
|
||
let currentItemsInRoom = [];
|
||
|
||
for (let i = 0; i < numToSpawn; i++){
|
||
//east asian wide unicode
|
||
//const items = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz,.:;!?"'`^~ ̄_&#%+-*=<>()[]{}⦅⦆|¦/\¬$£¢₩¥".split("");
|
||
const items = "123456789ABCDEFHIJKLMNOPQRSTUVWXYZabcdefghijklmonqrsntuvwxyz,.:!?\"'`^~_&#%+-*=<>(){}/\$".split("");
|
||
|
||
//make sure it wasn't chosen previously in this board
|
||
do {
|
||
whichItem = Math.floor(Math.random()*items.length);
|
||
} while (currentItemsInRoom.includes(items[whichItem]))
|
||
|
||
currentItemsInRoom.push(items[whichItem]);
|
||
|
||
// console.log(items[whichItem]);
|
||
|
||
let whichItemText = Math.floor(Math.random() * itemDescriptions.length);
|
||
itemDescrip = itemDescriptions[whichItemText];
|
||
|
||
|
||
roomItems.push(
|
||
{
|
||
"name": "",
|
||
"symbol": items[whichItem],
|
||
"description": itemDescrip,
|
||
"position":
|
||
{
|
||
"x":Math.floor(Math.random()*width),
|
||
"y":Math.floor(Math.random()*height)
|
||
}
|
||
}
|
||
)
|
||
//roomItems[i].char = items[whichItem];
|
||
//roomItems[i].position.x = Math.floor(Math.random()*width)
|
||
//roomItems[i].position.y = Math.floor(Math.random()*height)
|
||
}
|
||
|
||
//console.log(roomItems);
|
||
}
|
||
|
||
let createBooks = () => {
|
||
|
||
let numToSpawn = Math.round(Math.random() * 2)
|
||
|
||
for (let i = 0; i < numToSpawn; i++){
|
||
//const items = ["📗","📕","📘","📙","📒","📓","📔"];
|
||
const items = ['⎅','⏍','◫'];
|
||
|
||
whichItem = Math.floor(Math.random()*items.length);
|
||
|
||
let firstSubject = generator.generate().spaced;
|
||
let secondSubject = generator.generate({ words: 2, alliterative: true }).spaced;
|
||
|
||
let pre = ["My Year of","A Guide To","Simply","A Cook's Guide to","The Book of","A tale of","To","A","The","The","The","One","Beginning","My","A Manual of","",""];
|
||
let connector = [" of"," for"," for"," with"," and"," on",":",": on"," OR"];
|
||
|
||
let descriptionWords = ["Probably the most complete book on","A treatise on","One of the few books to delve into","An expert description of","Mainly dealing with","An expert's guide to","A gentle introduction to the subject of","This book deals with","A compendium on","A poorly-written book on","A translated tale of","A well-written book on","A turgid tale of","A plain volume on","An old volume. One of a series on","Only the latest of many books about","An informative book on"];
|
||
let secondDescrip = ["Highly recommended.","It's rotting","It's cover is torn off.","It's a shoddy reprint.","This is a well-loved volume.","There is a faint musty odor.","Original edition","A Reprint.","Second edition.","This appears to be a reproduction.","Translated from the original.","Originally a movie and adapted for print.","Based on the film.","Several pages have been torn out.","Several pages are stuck together.","The cover has fallen off.","The spine is cracked.","The book is full of highlighting and notes from a previous reader.","The book has hand-written notes throughout.","The print has faded but it is barely readable.","This volume is quite old.","A great guide for those interested in this timely subject."];
|
||
|
||
//title of book
|
||
let book;
|
||
if (Math.random()<0.4){
|
||
book = choose(pre) + " " + capitalize(firstSubject) + choose(connector) + " " + capitalize(secondSubject);
|
||
} else if (Math.random()<0.5){
|
||
book = choose(pre) + " " + capitalize(firstSubject);
|
||
} else {
|
||
book = choose(pre) + " " + capitalize(secondSubject);
|
||
}
|
||
//description
|
||
let name = Charlatan.Name.name();
|
||
let bookDescrip = choose(descriptionWords) + " " + capitalize(firstSubject) + ". " + choose(secondDescrip) + "\n By " + name + ".";
|
||
|
||
roomItems.push(
|
||
{
|
||
"name": book,
|
||
"symbol": items[whichItem],
|
||
"description": bookDescrip,
|
||
"position":
|
||
{
|
||
"x":Math.floor(Math.random()*width),
|
||
"y":Math.floor(Math.random()*height)
|
||
}
|
||
}
|
||
)
|
||
}
|
||
|
||
}
|
||
|
||
let createTracks = () => {
|
||
|
||
let numToSpawn = Math.round(Math.random() * 2) + 2;
|
||
|
||
for (let i = 0; i < numToSpawn; i++){
|
||
|
||
const items = [ "♥", "♦", "♣", "♠", "•", "◘", "○", "◙", "♂", "♀", "♪", "♫", "☼", "►", "◄", "↕", "‼", "¶", "§", "▬", "↨", "↑", "↓", "→", "←", "∟", "↔", "▲", "▼", "{", "|", "}", "~", "⌂", "Ç", "ü", "é", "â", "ä", "à", "å", "ç", "ê", "ë", "è", "ï", "î", "ì", "Ä", "Å", "É", "æ", "Æ", "ô", "ö", "ò", "û", "ù", "ÿ", "Ö", "Ü", "¢", "£", "¥", "₧", "ƒ", "á", "í", "ó", "ú", "ñ", "Ñ", "ª", "º", "¿", "⌐", "¬", "½", "¼", "¡", "«", "»", "░", "▒", "▓", "│", "┤", "╡", "╢", "╖", "╕", "╣", "║", "╗", "╝", "╜", "╛", "┐", "└", "┴", "┬", "├", "─", "┼", "╞", "╟", "╚", "╔", "╩", "╦", "╠", "═", "╬", "╧", "╨", "╤", "╥", "╙", "╘", "╒", "╓", "╫", "╪", "┘", "┌", "█", "▄", "▌", "▐", "▀", "α", "ß", "Γ", "π", "Σ", "σ", "µ", "τ", "Φ", "Θ", "Ω", "δ", "∞", "φ", "ε", "∩", "≡", "±", "≥", "≤", "⌠", "⌡", "÷", "≈", "°", "∙", "·", "√", "ⁿ", "²", "■" ]
|
||
|
||
whichItem = Math.floor(Math.random()*items.length);
|
||
|
||
//pick bandname
|
||
let pre = ["The ",""];
|
||
|
||
let band;
|
||
|
||
if (Math.random()<0.8){
|
||
|
||
band = choose(pre)+generator.generate().spaced;
|
||
} else if (Math.random()<0.6){
|
||
band = choose(pre)+generator.generate({ words: 3, alliterative: true}).spaced;
|
||
} else {
|
||
band = choose(pre)+generator.generate({ words: 1}).spaced;
|
||
}
|
||
band=capitalize(band);
|
||
|
||
let trackNameLength = Math.round(Math.random()*3)+1;
|
||
let trackName = generator.generate({ words: trackNameLength}).spaced;
|
||
trackName = capitalize(trackName);
|
||
|
||
//assemble
|
||
let nuGenre = choose([generator.generate({ words: 1}).spaced+"-", "post-", "neo-","avant-","anti-","","",""]) + lowerFirst(choose(genres));
|
||
let format = choose(mediaFormats);
|
||
let name = trackName + " " + format;
|
||
let symbol = choose(items);
|
||
let adj = ["killer","new","old","classic","nu-skool","heavy","thrilling","drugged-out","trippy","ethereal","hard","sublime","serene","airy","brilliant","beautiful","celebratory","chill","cold","serene","damaged","draining","dark","echoy","earnest","elated","elevated","erratic","ergodic","fantastic","freak","great","gleeful","iridescent","ultra","ill","crooked","light","sick","original","powerful","pretty","playful","quiet","rewarding","ripped","rave","roaring","raucous","severe","slick","superior","tortured","tinged","vanity","victorious","vicious","wicked","wailing","wizardly","wavy","max-ed out","zooted"];
|
||
|
||
let descrip = capitalize(choose(adj)) + " " + nuGenre + " " + format + " " + trackName + " by " + band + ".";
|
||
|
||
let track1 = pickATrack();
|
||
let track2 = pickATrack();
|
||
|
||
roomItems.push(
|
||
{
|
||
"name": name,
|
||
"symbol": symbol,
|
||
"description": descrip,
|
||
"position":
|
||
{
|
||
"x":Math.floor(Math.random()*width),
|
||
"y":Math.floor(Math.random()*height)
|
||
},
|
||
"audio":[track1,track2]
|
||
}
|
||
)
|
||
}
|
||
|
||
}
|
||
|
||
let choose = arr => arr[Math.floor(Math.random()*arr.length)];
|
||
|
||
let capitalize = (str) => {
|
||
let arr = str.split(' ');
|
||
for(let i = 0; i < arr.length; i++ ) {
|
||
arr[i] = arr[i].replace(arr[i].charAt(0), arr[i].charAt(0).toUpperCase());
|
||
}
|
||
return arr.join(' ');
|
||
}
|
||
|
||
let lowerFirst = (str) => {
|
||
let arr = str.split(' ');
|
||
for(let i = 0; i < arr.length; i++ ) {
|
||
arr[i] = arr[i].replace(arr[i].charAt(0), arr[i].charAt(0).toLowerCase());
|
||
}
|
||
return arr.join(' ');
|
||
}
|
||
|
||
let createPlaces = () => {
|
||
|
||
let numToSpawn = Math.round(Math.random() * 3) + 4
|
||
|
||
for (let i = 0; i < numToSpawn; i++){
|
||
|
||
//const buildings = ['🏛️','⛺','🏚️','⛩️','🗿']
|
||
const buildings = ['⌂','⏏','☖','☗','⛫']
|
||
const placeTypes = ['Radio','Village','House','Pirate Station','Autonomous Zone','Market','Basement','Place','Outpost','Trading Post','Space','Place','Gallery','Floor','House','Shack','Meeting Place','Record Studio','Shop','Squat','Yard','Cart','Warehouse','Bar','Camp','Zone']
|
||
|
||
let whichBuilding = buildings[Math.floor(Math.random()*buildings.length)];
|
||
|
||
let locationTitle = generator.generate().spaced;
|
||
|
||
let typeOfPlace = placeTypes[Math.floor(Math.random() * placeTypes.length)];
|
||
|
||
let locName = capitalize(locationTitle) + " " + capitalize(typeOfPlace);
|
||
|
||
places.push(
|
||
{
|
||
"name": locName,
|
||
"symbol": whichBuilding,
|
||
"position":
|
||
{
|
||
"x":Math.floor(Math.random()*width),
|
||
"y":Math.floor(Math.random()*height)
|
||
}
|
||
}
|
||
)
|
||
}
|
||
|
||
//let's also create some tombstones?
|
||
|
||
//console.log(places)
|
||
}
|
||
|
||
let createGraves = () => {
|
||
|
||
let name = Charlatan.Name.name();
|
||
|
||
let gravestones = ['✝','✟','☨','✞','⛼'];
|
||
let whichGravestone = choose(gravestones);
|
||
let prefix = ["Here lies","RIP","","","","Resting place of ","Beloved"]
|
||
let reason = ["Made an enemy","Wasn't afraid to be","Tried","Died while","Passed while performing","Tried out","Dissapeared investigating","Wandered off while looking for","Last seen","Loved","Adored","A lifelong fan of","Our favorite at","The best at","Always in our hearts","Keep","Always be","Always","Just","Tried","Couldn't stop","Only ever found","Died","Passed while","Couldn't stop","Forgot to try","Never stopped","We'll always think of you when we're","It's not the same"]
|
||
|
||
let epitaph = prefix[Math.floor(Math.random() * prefix.length)] + " " + name +"\n"+reason[Math.floor(Math.random() * reason.length)]+" " + verbs[Math.floor(Math.random()*verbs.length)] + ".";
|
||
|
||
places.push(
|
||
{
|
||
"name": epitaph,
|
||
// "symbol": "⚰️",
|
||
"symbol": whichGravestone,
|
||
"position":
|
||
{
|
||
"x":Math.floor(Math.random()*width),
|
||
"y":Math.floor(Math.random()*height)
|
||
}
|
||
}
|
||
)
|
||
}
|
||
|
||
function saveMap(){
|
||
//write terrain to file
|
||
let terrainStr = JSON.stringify(terrain)
|
||
fs.writeFileSync(terrainFile, terrainStr);
|
||
|
||
//save player info to file
|
||
let playerData = JSON.stringify(player);
|
||
fs.writeFileSync(gameFile, playerData);
|
||
|
||
//write dates to dateFile
|
||
fs.appendFileSync(dateFile, today+'\n');
|
||
|
||
//write items in current dungeon to file
|
||
let itemsData = JSON.stringify(roomItems);
|
||
fs.writeFileSync(itemsFile, itemsData);
|
||
|
||
//save places to file
|
||
let placesData = JSON.stringify(places);
|
||
fs.writeFileSync(placesFile, placesData);
|
||
}
|
||
|
||
//-------------------------LOADING HELPERS------------------------------------
|
||
//
|
||
//
|
||
//
|
||
const getDirectories = source =>
|
||
readdirSync(source, { withFileTypes: true })
|
||
.filter(dirent => dirent.isDirectory())
|
||
.map(dirent => dirent.name);
|
||
|
||
function loadAll(){
|
||
loadDungeon();
|
||
loadTerrain();
|
||
loadItems();
|
||
loadPlaces();
|
||
loadPlayer();
|
||
loadInventory();
|
||
}
|
||
|
||
function loadDungeon(){
|
||
dungeon = Array.from(Array(height), () => new Array(width))
|
||
}
|
||
|
||
function loadTerrain() {
|
||
const terrainStr = fs.readFileSync(terrainFile, 'utf8');
|
||
|
||
terrain = JSON.parse(terrainStr);
|
||
}
|
||
|
||
let loadPlayer = () => {
|
||
const playerFile = fs.readFileSync(gameFile,'utf8');
|
||
|
||
player = JSON.parse(playerFile);
|
||
}
|
||
|
||
let loadItems = () => {
|
||
const itemsStr = fs.readFileSync(itemsFile, 'utf8');
|
||
|
||
roomItems = JSON.parse(itemsStr)
|
||
}
|
||
|
||
let loadPlaces = () => {
|
||
const placesStr = fs.readFileSync(placesFile, 'utf8');
|
||
|
||
places = JSON.parse(placesStr)
|
||
}
|
||
|
||
let loadInventory = () => {
|
||
const invFile = fs.readFileSync(inventoryFile,'utf8');
|
||
|
||
inventory = JSON.parse(invFile);
|
||
}
|
||
|
||
function pickATrack(){
|
||
let soundDirs = getDirectories(musicPath);
|
||
|
||
let whichDir = Math.floor(Math.random()*soundDirs.length);
|
||
|
||
let filesInDir = fs.readdirSync(musicPath+soundDirs[whichDir]).length;
|
||
|
||
let whichTrack = Math.floor(Math.random()*filesInDir);
|
||
|
||
let trackLoc = musicPath+soundDirs[whichDir]+'/'+whichTrack+'.mp3';
|
||
|
||
return trackLoc;
|
||
}
|
||
|
||
//--------------------------AUDIO HELPERS----------------------
|
||
function loop1(file){
|
||
|
||
troubadourLoop1.play(file);
|
||
|
||
troubadourLoop1.on('start', () => {
|
||
troubadourLoop1.playing = true;
|
||
// Do something here when the audio starts playing
|
||
});
|
||
|
||
troubadourLoop1.on('end', () => {
|
||
//keep playing if in loop (at location)
|
||
if (troubadourLoop1.playing){
|
||
troubadourLoop1.play(file);
|
||
}
|
||
|
||
});
|
||
|
||
}
|
||
|
||
function loop2(file){
|
||
|
||
troubadourLoop2.play(file);
|
||
|
||
troubadourLoop2.on('start', () => {
|
||
troubadourLoop2.playing = true;
|
||
});
|
||
|
||
troubadourLoop2.on('end', () => {
|
||
//keep playing if in loop (at location)
|
||
if (troubadourLoop2.playing){
|
||
troubadourLoop2.play(file);
|
||
}
|
||
|
||
});
|
||
|
||
}
|
||
|
||
function stopMusic(){
|
||
if (troubadourLoop1.playing){
|
||
troubadourLoop1.playing = false;
|
||
troubadourLoop1.stop();
|
||
}
|
||
if (troubadourLoop2.playing){
|
||
troubadourLoop2.playing = false;
|
||
troubadourLoop2.stop();
|
||
}
|
||
}
|
||
|
||
//--------------------------MAIN-------------------------------
|
||
|
||
start();
|
||
loop();
|