Browse Source

Initial commit

pull/14/head
Armen138 10 months ago
commit
e128790bd9
19 changed files with 1049 additions and 0 deletions
  1. +1
    -0
      .gitignore
  2. +10
    -0
      data/dark_hallway.yml
  3. +72
    -0
      data/items.yml
  4. +9
    -0
      data/kitchen.yml
  5. +19
    -0
      data/monsters.yml
  6. +3
    -0
      data/recipes.yml
  7. +13
    -0
      data/strange_room.yml
  8. +29
    -0
      game/banner.js
  9. +39
    -0
      game/character.js
  10. +64
    -0
      game/errors.js
  11. +204
    -0
      game/game.js
  12. +35
    -0
      game/items.js
  13. +45
    -0
      game/menu.js
  14. +23
    -0
      game/titles.js
  15. +45
    -0
      game/world.js
  16. +9
    -0
      index.js
  17. +393
    -0
      package-lock.json
  18. +17
    -0
      package.json
  19. +19
    -0
      readme.md

+ 1
- 0
.gitignore View File

@@ -0,0 +1 @@
node_modules

+ 10
- 0
data/dark_hallway.yml View File

@@ -0,0 +1,10 @@
title: When your eyes adjust to the dim light
description: You see something moving in the far corner. It looks like it is coming toward you.
name: dark hallway
monsters:
- rat
items:
- baseball bat
- locked door
connects:
- strange room

+ 72
- 0
data/items.yml View File

@@ -0,0 +1,72 @@
# Prevalence keys: common, uncommon, rare, very rare, unique
# Colors: green, yellow, cyan, magenta, white
# Drop Chances: 60%, 40%, 20%, 10%, 1%

# Optional keys:
# health: restores this amount when eaten
# damage: does this amount of damage when equiped
# durability: will last this many uses or attacks
# equip: which equip slot to use
# static: true if this object can't be added to an inventory
- name: rusty nail
prevalence: uncommon
description: Standard issue rusty nail, probably causes tetanus. Better handle with care.
- name: baseball bat
prevalence: rare
damage: 2
durability: 10
description: Most problems can be solved with a generous dose of blunt force trauma. And this is just the instrument to deliver it.
equip: rightHand
- name: wooden club
prevalence: common
durability: 4
damage: 1
description: It's a crude weapon, but it does the job.
equip: rightHand
- name: newspaper
prevalence: common
durability: 1
damage: 1
description: Contains the latest news. And a weather forecast.
equip: rightHand
- name: orange
prevalence: uncommon
health: 2
description: It looks ripe.
- name: tape
description: Sticky stuff.
prevalence: common
durability: 1
- name: wood
description: A sturdy looking length of wood, could come in handy.
prevalence: common
durability: 1
- name: frying pan
prevalence: unique
description: It sits in the sink, unwashed since its last omelette. A weapon with a breakfast aroma.
damage: 4
equip: rightHand
durability: 50
reacts with: egg
effect: &omelette
removes: egg
adds: omelette
prints: You give the pan a quick rinse before frying an omelette. It looks tasty.
- name: omelette
prevalence: unique
description: Freshly fried, beaten egg. Yum!
health: 6
- name: egg
prevalence: common
description: It looks fresh.
reacts with: frying pan
effect: *omelette
- name: locked door
prevalence: static
description: It is definitely locked. There is a faint scratching noise coming from the other side.
reacts with: rusty nail
static: true
effect:
connects: kitchen
removes: locked door
prints: The rusty nail is a crude tool, but after a while you manage to pick the lock. It looks like the door leads to a kitchen.

+ 9
- 0
data/kitchen.yml View File

@@ -0,0 +1,9 @@
title: A messy kitchen
description: It's a kitchen, and the dishes are left unwashed in the sink.
name: kitchen
items:
- frying pan
- egg
connects:
- dark hallway
- back yard

+ 19
- 0
data/monsters.yml View File

@@ -0,0 +1,19 @@
- name: rat
description: It's a rat. It does not look healthy.
# damage before it goes splat
health: 1
# damage it deals on successful attack
damage: 1
# turns it takes to reach the player
speed: 3
drops:
- rat tail
- coin
- name: Ancient Zombie
description: More bones than flesh, this zombie had obviously spent some time under ground before coming back to ruin your day.
health: 5
damage: 4
speed: 2
drops:
- thigh bone
- leather boots

+ 3
- 0
data/recipes.yml View File

@@ -0,0 +1,3 @@
baseball bat:
- wood
- tape

+ 13
- 0
data/strange_room.yml View File

@@ -0,0 +1,13 @@
title: A rough night
description: >
You wake up in a strange room. There is a portait on hanging on the wall, it looks like a happy family. They don't look familiar.

There is table in the center of the room, on it is a fruit bowl with a single orange in it. It looks ripe.
A door that looks like it leads outside is clumsily barricaded with scraps of wood and rusty nails. One of the nails has fallen on the floor.
name: strange room
items:
- rusty nail
- orange
connects:
- dark hallway

+ 29
- 0
game/banner.js View File

@@ -0,0 +1,29 @@
const chalk = require('chalk');
const titles = require('./titles');

const banner = {
text: `@@@ @@@ @@@ @@@@@@@@ @@@ @@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@
@@@@ @@@ @@@ @@@@@@@@@ @@@ @@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@
@@!@!@@@ @@! !@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@@
!@!!@!@! !@! !@! !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! @!@
@!@ !!@! !!@ !@! @!@!@ @!@!@!@! @!! @!! @!!!:! @!@!!@! @!@!!@! @!@ !@! @!@!!@!
!@! !!! !!! !!! !!@!! !!!@!!!! !!! !!! !!!!!: !!@!@! !!@!@! !@! !!! !!@!@!
!!: !!! !!: :!! !!: !!: !!! !!: !!: !!: !!: :!! !!: :!! !!: !!! !!: :!!
:!: !:! :!: :!: !:: :!: !:! :!: :!: :!: :!: !:! :!: !:! :!: !:! :!: !:!
:: :: :: ::: :::: :: ::: :: :: :: :::: :: ::: :: ::: ::::: :: :: :::
:: : : :: :: : : : : : : : :: :: : : : : : : : : : : : : `,
colored: function () {
let lines = banner.text.split("\n");
let aligned = [];
for(let line of lines) {
if(line.length < 106) {
line += " ".repeat(106 - line.length);
}
aligned.push(titles.header(line, banner.width));
}
return chalk.red(aligned.join('\n'));
},
width: process.stdout.columns //106
};

module.exports = banner;

+ 39
- 0
game/character.js View File

@@ -0,0 +1,39 @@
const errors = require('./errors');

class Character {
constructor() {
this.inventory = [];
this.inventorySlots = 2;
this.health = 10;
this.maxHealth = 10;
this.armor = 0;
this.equipment = {
leftHand: null, // secondary weapon
rightHand: null, // weapon
finger: null, // rings
head: null, // head covering armor
torso: null, // shirts
legs: null, // pants
feet: null, // boots or shoes
neck: null, // amulets and charms
}
}
take(world, item) {
let promise = new Promise((resolve, reject) => {
if(this.inventory.length < this.inventorySlots) {
let worldItem = world.take(item);
if(worldItem.error) {
reject(worldItem.error);
} else {
this.inventory.push(worldItem.item);
resolve(`You have added ${item} to your inventory.`);
}
} else {
reject(errors.inventoryfull());
}
});
return promise;
}
}

module.exports = Character;

+ 64
- 0
game/errors.js View File

@@ -0,0 +1,64 @@
const errors = {
_not_found: [
"This item doesn't appear to be around here.",
"You look around for a bit, but can't find that anywhere.",
"You want WHAT?",
"Are you sure you saw that here?"
],
_not_in_inventory: [
"You don't have any of those",
"You're not carrying that.",
"You checked all your pockets, it's not there."
],
_inventory_full: [
"You don't have space to carry more items!",
"No pockets left to stuff that into.",
"No can do, buckaroo. No space!",
"You need more pockets!",
"Your inventory is full. Drop stuff to make space!"
],
_not_edible: [
"You can't eat that.",
"Pretty sure that won't taste good.",
"That doesn't look healthy.",
"Ew, that's nasty."
],
_static_item: [
"You can't take that.",
"You try to move it, but it won't budge.",
"Looks like it's stuck.",
"But... how??",
"That won't work.",
"Hmm.... looks heavy, better leave that where it is."
],
_cant_use: [
"You can't use that here.",
"There's nothing here to use that with",
"You can't do that.",
"No way, dude."
],
random_error(list) {
let idx = Math.floor(Math.random() * list.length);
return list[idx];
},
notfound() {
return errors.random_error(errors._not_found);
},
inventoryfull() {
return errors.random_error(errors._inventory_full);
},
notedible() {
return errors.random_error(errors._not_edible);
},
notininventory() {
return errors.random_error(errors._not_in_inventory);
},
staticitem() {
return errors.random_error(errors._static_item);
},
cantuse() {
return errors.random_error(errors._cant_use);
}
}

module.exports = errors;

+ 204
- 0
game/game.js View File

@@ -0,0 +1,204 @@
const Vorpal = require('vorpal');
const chalk = require('chalk');
const errors = require('./errors');

const World = require('./world');
const Character = require('./character');
const Items = require('./items');

let world = new World();
let character = new Character();
let items = new Items();


let healthScale = [
"red",
"orange",
"yellow",
"green"
];

let Game = () => {

let game = Vorpal();
game.look = function() {
if(world.location.title) {
this.log(chalk.white.bold(world.location.title));
}
this.log(world.location.description);
if(world.location.items && world.location.items.length > 0) {
let worldItems = world.location.items.map(itemName => items.render(itemName));
this.log(`Items here:\n${worldItems.join('\n')}`);
}
if(world.location.connects) {
this.log(`This place connects to:\n${world.location.connects.join('\n')}`);
}
}
game.command('menu', 'Return to main menu')
.action(function (args, callback) {
process.stdout.write ("\u001B[2J\u001B[0;0f");
this.log(game.menu.intro);
game.menu.show();
callback();
});

game.command('look', 'Look around')
.action(function (args, callback) {
game.look.call(this);
callback();
});

game.command('inventory', 'See what you have stored in your inventory')
.action(function (args, callback) {
let usable = function(itemName, itemRender) {
let prefix = "";
for(let worldItem of world.location.items) {
let item = items.get(worldItem);
if(item["reacts with"] && item["reacts with"] === itemName) {
prefix = chalk.magenta("*");
}
}
return prefix + itemRender;
}
this.log(`${character.inventorySlots} slots, ${character.inventorySlots - character.inventory.length} free.`)
if (character.inventory.length > 0) {
this.log(character.inventory.map(item => usable(item, items.render(item))).join('\n'));
}
callback();
});

game.command('go <place...>', 'Go to connecting location')
.autocomplete(() => world.location.connects)
.action(function (args, callback) {
let place = args.place.join(" ");
world.go(place).then(data => {
process.stdout.write ("\u001B[2J\u001B[0;0f");
this.delimiter(`[${chalk.yellow(data.name)}]$`);
game.look.call(this);
callback();
});
});

game.command('take <item...>', 'Take an item')
.autocomplete(() => world.location.items)
.action(function (args, callback) {
let item = args.item.join(" ");
character.take(world, item).then(message => {
this.log(message);
}).catch(error => {
this.log(chalk.red(error));
});
callback();
});

game.command('drop <item...>', 'Drop an item')
.autocomplete(() => character.inventory)
.action(function (args, callback) {
let itemName = args.item.join(" ");
let inventorySlot = character.inventory.indexOf(itemName);
if (inventorySlot === -1) {
this.log(chalk.red(errors.notininventory()));
} else {
world.location.items.push(itemName);
character.inventory.splice(inventorySlot, 1);
this.log(`You drop the ${itemName}.`);
}
callback();
});

game.command('use <item...>', 'Use an item from your inventory')
.autocomplete(() => character.inventory)
.action(function (args, callback) {
let used = false;
let itemName = args.item.join(" ");
let inventorySlot = character.inventory.indexOf(itemName);
if (inventorySlot === -1) {
this.log(chalk.red(errors.notininventory()));
used = true;
} else {
for(let worldItemName of world.location.items) {
let worldItem = items.get(worldItemName);
if(worldItem["reacts with"] && worldItem["reacts with"].indexOf(itemName) !== -1) {
if(worldItem.effect.connects) {
world.location.connects.push(worldItem.effect.connects);
}
if(worldItem.effect.removes) {
if(worldItem.effect.removes === itemName) {
// remove item from inventory
let removeItem = character.inventory.indexOf(worldItem.effect.removes);
if(removeItem !== -1) {
character.inventory.splice(removeItem, 1);
}
} else {
// remove item from world
let removeItem = world.location.items.indexOf(worldItem.effect.removes);
if(removeItem !== -1) {
world.location.items.splice(removeItem, 1);
}
}
}
if(worldItem.effect.adds) {
world.location.items.push(worldItem.effect.adds);
}
if(worldItem.effect.prints) {
this.log(worldItem.effect.prints);
}
used = true;
break;
}
}
}
if(!used) {
this.log(chalk.red(errors.cantuse()));
}
callback();
});


game.command('eat <item...>', 'Eat something from your inventory')
.autocomplete(() => character.inventory)
.action(function (args, callback) {
let itemName = args.item.join(" ");
let inventorySlot = character.inventory.indexOf(itemName);
if (inventorySlot === -1) {
this.log(chalk.red(errors.notininventory()));
} else {
let item = items.get(itemName);
if (!item.health) {
this.log(chalk.red(errors.notedible()));
} else {
character.health += item.health;
if (character.health > character.maxHealth) {
character.health = character.maxHealth;
}
character.inventory.splice(inventorySlot, 1);
let color = (healthScale.length / character.maxHealth * character.health | 0) - 1;
let health = chalk[healthScale[color]](`${character.health}/${character.maxHealth}`);
this.log(`You ate the ${items.render(itemName)}. Your health is now ${health}`);
}
}
callback();
});

game.command('examine <item...>', 'Examine an item')
.autocomplete(() => character.inventory.concat(world.location.items))
.action(function (args, callback) {
let item = args.item.join(" ");
let allItems = character.inventory.concat(world.location.items);
if (allItems.indexOf(item) !== -1) {
this.log(items.get(item).description);
} else {
this.log(chalk.red(errors.notfound()));
}
callback();
});
// game.help(cmd => {
// return "HALP";
// });
game.delimiter(`[${world.location.name}]$`)

return game;
}

module.exports = Game;

+ 35
- 0
game/items.js View File

@@ -0,0 +1,35 @@
const fs = require('fs');
const yaml = require('js-yaml');
const chalk = require('chalk');

const itemColors = {
"common": "green",
"uncommon": "yellow",
"rare": "cyan",
"very rare": "magenta",
"unique": "white",
"static": "grey"
};

class Items {
constructor() {
this.data = yaml.safeLoad(fs.readFileSync(`data/items.yml`, 'utf8'));
}
get(itemName) {
for(let item of this.data) {
if(item.name == itemName) {
return item;
}
}
return null;
}
render(itemName) {
let item = this.get(itemName);
let damage = item.damage ? "🗡️".repeat(item.damage) : "";
let health = item.health ? chalk.red("❤︎".repeat(item.health)) : "";
let armor = item.armor ? chalk.yellow("🛡️".repeat(item.armor)) : "";
return item ? chalk[itemColors[item.prevalence]](item.name) + " " + damage + health + armor: "unknown item";
}
}

module.exports = Items;

+ 45
- 0
game/menu.js View File

@@ -0,0 +1,45 @@
const Vorpal = require('vorpal');
const chalk = require('chalk');
const banner = require('./banner');
const titles = require('./titles');

let Menu = (game) => {
let menu = Vorpal();

menu.delimiter("[menu]$");
menu.command('play', 'Play ' + chalk.red('Night Terror'))
.action(function (args, callback) {
this.log("Starting game. Beware the dark.")
setTimeout(function() {
process.stdout.write ("\u001B[2J\u001B[0;0f");
game.look();
game.show();
callback();
}, 2000);
});
menu.command('save', 'Save game')
.action(function (args, callback) {
game.show();
callback();
});
menu.command('load', 'Load game')
.action(function (args, callback) {
game.show();
callback();
});
let header = chalk.white.bgHex("##540a00");
menu.intro = [
header.bold(titles.header("A text horror adventure by Armen138", banner.width)),
banner.colored(),
header(titles.random(banner.width))
].join("\n");
menu.intro += "\n";
let help = [
"play", "save", "load", "exit"
];
menu.intro += titles.header(help.map(item => chalk.black.bgYellow(` ${item} `)).join(" "), banner.width);
return menu;
}

module.exports = Menu;

+ 23
- 0
game/titles.js View File

@@ -0,0 +1,23 @@
let titles = {
_titles: [
"I think I heard something. Did you hear something?",
"Welcome, unfortunate soul. Make yourself comfortable.",
"There are things that go GHAWRAWARAAAAGGHHH in the night."
],
header: (title, container_size) => {
// strip ansi escape codes (colors) that artificially inflate the text length
let clean_title = title.replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, "");
if(clean_title.length < container_size) {
let spacer = " ".repeat((container_size - clean_title.length) / 2);
title = spacer + title + spacer;
}
return title;
},
random: (container_size) => {
let idx = Math.random() * titles._titles.length | 0;
let title = titles._titles[idx];
return titles.header(title, container_size);
}
}

module.exports = titles;

+ 45
- 0
game/world.js View File

@@ -0,0 +1,45 @@
const yaml = require('js-yaml');
const fs = require('fs');
const banner = require('./banner');
const errors = require('./errors');
const items = require('./items');

class World {
constructor() {
this.location = yaml.safeLoad(fs.readFileSync(`data/strange_room.yml`, 'utf8'));
}
go(location) {
let promise = new Promise((resolve, reject) => {
this.loadLocation(location).then(data => {
this.location = data;
resolve(data);
}).catch(e => {
reject(e);
});
});
return promise;
}
take(item) {
let idx = this.location.items.indexOf(item);
if(idx == -1) {
return { error: errors.notfound() };
}
if(this.location.items[idx].static) {
return { error: errors.staticitem() };
}
return { item: this.location.items.splice(idx, 1)[0] };
}
loadLocation(location) {
let promise = new Promise((resolve, reject) => {
try {
let data = yaml.safeLoad(fs.readFileSync(`data/${location.replace(/ /g, '_')}.yml`, 'utf8'));
resolve(data);
} catch (e) {
reject(e);
}
});
return promise;
}
}

module.exports = World;

+ 9
- 0
index.js View File

@@ -0,0 +1,9 @@
const Menu = require('./game/menu');
const Game = require('./game/game');

let game = Game();
let menu = Menu(game);

game.menu = menu;
console.log(menu.intro);
menu.show();

+ 393
- 0
package-lock.json View File

@@ -0,0 +1,393 @@
{
"name": "night_terror",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"ansi-escapes": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
"integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4="
},
"ansi-regex": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
},
"ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"requires": {
"color-convert": "^1.9.0"
}
},
"argparse": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
"requires": {
"sprintf-js": "~1.0.2"
}
},
"babel-polyfill": {
"version": "6.26.0",
"resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz",
"integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=",
"requires": {
"babel-runtime": "^6.26.0",
"core-js": "^2.5.0",
"regenerator-runtime": "^0.10.5"
}
},
"babel-runtime": {
"version": "6.26.0",
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
"integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
"requires": {
"core-js": "^2.4.0",
"regenerator-runtime": "^0.11.0"
},
"dependencies": {
"regenerator-runtime": {
"version": "0.11.1",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
"integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
}
}
},
"chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
}
},
"cli-cursor": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz",
"integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=",
"requires": {
"restore-cursor": "^1.0.1"
}
},
"cli-width": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/cli-width/-/cli-width-1.1.1.tgz",
"integrity": "sha1-pNKT72frt7iNSk1CwMzwDE0eNm0="
},
"code-point-at": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
},
"color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"requires": {
"color-name": "1.1.3"
}
},
"color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
},
"core-js": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz",
"integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A=="
},
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
},
"esprima": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
},
"exit-hook": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz",
"integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g="
},
"figures": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
"integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=",
"requires": {
"escape-string-regexp": "^1.0.5",
"object-assign": "^4.1.0"
}
},
"has-ansi": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
"integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
"requires": {
"ansi-regex": "^2.0.0"
}
},
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
},
"in-publish": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz",
"integrity": "sha1-4g/146KvwmkDILbcVSaCqcf631E="
},
"inquirer": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.11.0.tgz",
"integrity": "sha1-dEi/qSQJKvMR1HFzu6uZDK4rsCc=",
"requires": {
"ansi-escapes": "^1.1.0",
"ansi-regex": "^2.0.0",
"chalk": "^1.0.0",
"cli-cursor": "^1.0.1",
"cli-width": "^1.0.1",
"figures": "^1.3.5",
"lodash": "^3.3.1",
"readline2": "^1.0.1",
"run-async": "^0.1.0",
"rx-lite": "^3.1.2",
"strip-ansi": "^3.0.0",
"through": "^2.3.6"
},
"dependencies": {
"ansi-styles": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
},
"chalk": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"requires": {
"ansi-styles": "^2.2.1",
"escape-string-regexp": "^1.0.2",
"has-ansi": "^2.0.0",
"strip-ansi": "^3.0.0",
"supports-color": "^2.0.0"
}
},
"lodash": {
"version": "3.10.1",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
"integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y="
},
"supports-color": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
}
}
},
"is-fullwidth-code-point": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
"requires": {
"number-is-nan": "^1.0.0"
}
},
"js-yaml": {
"version": "3.13.1",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
"integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
"requires": {
"argparse": "^1.0.7",
"esprima": "^4.0.0"
}
},
"lodash": {
"version": "4.17.15",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
},
"log-update": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/log-update/-/log-update-1.0.2.tgz",
"integrity": "sha1-GZKfZMQJPS0ucHWh2tivWcKWuNE=",
"requires": {
"ansi-escapes": "^1.0.0",
"cli-cursor": "^1.0.2"
}
},
"minimist": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
},
"mute-stream": {
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz",
"integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA="
},
"node-localstorage": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/node-localstorage/-/node-localstorage-0.6.0.tgz",
"integrity": "sha1-RaBgHGky395mRKIzYfG+Fzx1068="
},
"number-is-nan": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
},
"object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"requires": {
"wrappy": "1"
}
},
"onetime": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
"integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k="
},
"readline2": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz",
"integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=",
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
"mute-stream": "0.0.5"
}
},
"regenerator-runtime": {
"version": "0.10.5",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz",
"integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg="
},
"restore-cursor": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz",
"integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=",
"requires": {
"exit-hook": "^1.0.0",
"onetime": "^1.0.0"
}
},
"run-async": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz",
"integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=",
"requires": {
"once": "^1.3.0"
}
},
"rx-lite": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz",
"integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI="
},
"sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
},
"string-width": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
"strip-ansi": "^3.0.0"
}
},
"strip-ansi": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"requires": {
"ansi-regex": "^2.0.0"
}
},
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"requires": {
"has-flag": "^3.0.0"
}
},
"through": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
},
"vorpal": {
"version": "1.12.0",
"resolved": "https://registry.npmjs.org/vorpal/-/vorpal-1.12.0.tgz",
"integrity": "sha1-S+eypOSPj8/JzzZIxBnTEcUiFZ0=",
"requires": {
"babel-polyfill": "^6.3.14",
"chalk": "^1.1.0",
"in-publish": "^2.0.0",
"inquirer": "0.11.0",
"lodash": "^4.5.1",
"log-update": "^1.0.2",
"minimist": "^1.2.0",
"node-localstorage": "^0.6.0",
"strip-ansi": "^3.0.0",
"wrap-ansi": "^2.0.0"
},
"dependencies": {
"ansi-styles": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
},
"chalk": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"requires": {
"ansi-styles": "^2.2.1",
"escape-string-regexp": "^1.0.2",
"has-ansi": "^2.0.0",
"strip-ansi": "^3.0.0",
"supports-color": "^2.0.0"
}
},
"supports-color": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
}
}
},
"wrap-ansi": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
"integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
"requires": {
"string-width": "^1.0.1",
"strip-ansi": "^3.0.1"
}
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
}
}
}

+ 17
- 0
package.json View File

@@ -0,0 +1,17 @@
{
"name": "night_terror",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node index.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"chalk": "^2.4.2",
"js-yaml": "^3.13.1",
"vorpal": "^1.12.0"
}
}

+ 19
- 0
readme.md View File

@@ -0,0 +1,19 @@
@@@ @@@ @@@ @@@@@@@@ @@@ @@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@
@@@@ @@@ @@@ @@@@@@@@@ @@@ @@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@
@@!@!@@@ @@! !@@ @@! @@@ @@! @@! @@! @@! @@@ @@! @@@ @@! @@@ @@! @@@
!@!!@!@! !@! !@! !@! @!@ !@! !@! !@! !@! @!@ !@! @!@ !@! @!@ !@! @!@
@!@ !!@! !!@ !@! @!@!@ @!@!@!@! @!! @!! @!!!:! @!@!!@! @!@!!@! @!@ !@! @!@!!@!
!@! !!! !!! !!! !!@!! !!!@!!!! !!! !!! !!!!!: !!@!@! !!@!@! !@! !!! !!@!@!
!!: !!! !!: :!! !!: !!: !!! !!: !!: !!: !!: :!! !!: :!! !!: !!! !!: :!!
:!: !:! :!: :!: !:: :!: !:! :!: :!: :!: :!: !:! :!: !:! :!: !:! :!: !:!
:: :: :: ::: :::: :: ::: :: :: :: :::: :: ::: :: ::: ::::: :: :: :::
:: : : :: :: : : : : : : : :: :: : : : : : : : : : : : :

# A horror text adventure by Armen138

Run with terminal front end:

```
npm install
npm start
```

Loading…
Cancel
Save