kraft
Version:
A mysterious command line game with lots of secrets
316 lines (213 loc) • 12.5 kB
JavaScript
/**
* Created by vanraar on 24/09/16.
*/
const Locations = require(__base+'model/data/locations');
const Buildings = require(__base+'model/data/Buildings');
const Items = require(__base+'model/data/Items');
const Config = require(__base+'config/Config');
const Lenses = require(__base+'helpers/Lenses');
const View = require(__base+'view/PlayerViews');
const getCurrentMillis = () => new Date().getTime();
const sanitizeNumber = (input) => input ? input : 0;
const P = require(__base+'model/player/PlayerModel');
const Check = require(__base+'model/player/PlayerValidations');
exports.startGathering = (resource, building) => {
if (building) {
Check.isIdle();
Check.isValidBuilding(building);
Check.isNotBuiltAtLocation(P.location.view(), building);
Check.doesBuildingGenerateResource(building, resource);
P.buildingActionType(P.location.view(), building).set('gathering');
P.buildingActionStart(P.location.view(), building).set(getCurrentMillis());
P.buildingActionArguments(P.location.view(), building).set(resource);
Output.afterSave(Lenses.config(), 'You started gathering', resource.green, 'at your', building.green);
} else {
Check.isIdle();
P.actionType.set("gathering");
P.actionStart.set(getCurrentMillis());
P.actionArguments.set(resource);
Output.afterSave(Lenses.config(), 'You started gathering', resource.green);
}
};
exports.stopGathering = (building) => {
if (building) {
Check.isIdle();
Check.isValidBuilding(building);
Check.isNotBuiltAtLocation(P.location.view(), building);
Check.buildingIsNotGatheringAtLocation(P.location.view(), building);
const resource = P.buildingActionArguments(P.location.view(), building).view();
const amount = P.buildingResource(P.location.view(), building, resource).view();
P.buildingActionType(P.location.view(), building).set(undefined);
P.buildingActionStart(P.location.view(), building).set(undefined);
P.buildingActionArguments(P.location.view(), building).set(undefined);
Output.afterSave(Lenses.config(), 'Your',building.green,'now has', amount.toString().green, resource.green);
} else {
Check.isGathering();
const resource = P.actionArguments.view();
const ticks = (new Date().getTime() - P.actionStart.view()) / Config.resourceRate;
const amount = Math.floor(sanitizeNumber(Locations[P.location.view()].resources[resource]) * ticks);
P.actionType.set("idle");
P.actionStart.set(0);
P.actionArguments.set(null);
P.resource(resource).add(amount);
Output.afterSave(Lenses.config(), 'You gathered', amount.toString().green, resource.green);
}
};
exports.travel = (location) => {
Check.isIdle();
Check.isExistingLocation(location);
Check.isAlreadyAtLocation(location);
P.actionType.set("travelling");
P.actionStart.set(getCurrentMillis());
P.actionEnd.set(getCurrentMillis() + 10000);
P.actionArguments.set(location);
Output.afterSave(Lenses.config(), 'You started travelling to', location.green);
};
exports.location = (subCommand) => {
if (subCommand === 'buildings') Output.show('At', P.location.view().green,' you have built ', View.buildings(P.locationBuildings(P.location.view()).view()).green);
if (subCommand === 'resources') Output.show('The following resources can be gathered in',P.location.view().green,'\n', View.resourcesWithoutValues(Locations[P.location.view()].resources).green);
Output.show('You are currently in', P.location.view().green,': ',P.locationDescription().green);
};
exports.inventory = (resource) => {
if (resource) Output.show('You have', P.resource(resource).view().toString().green, resource.green);
else Output.show(
R.keys(P.resources.view())
.filter((resource) => P.resource(resource).view() > 0)
.map((resource) => resource.green+': '+P.resource(resource).view().toString().green).join('\n')
);
};
exports.supply = (building, amount, resource) => {
Check.hasBuildingHere(building);
Check.hasEnoughResources(amount, resource);
P.buildingResource(P.location.view(), building, resource).add(amount);
P.resource(resource).min(amount);
Output.afterSave(Lenses.config(), 'You transfered', amount.toString().green, resource.green, 'to your', building.green);
};
exports.takeFrom = (building, amount, resource) => {
Check.hasBuildingHere(building);
Check.buildingHasEnoughResources(building, amount, resource);
P.buildingResource(P.location.view(), building, resource).min(amount);
P.resource(resource).add(amount);
Output.afterSave(Lenses.config(), 'You got ', amount.toString().green, resource.green, ' from your ', building.green);
};
exports.build = (building) => {
Check.isValidBuilding(building);
Check.isAlreadyBuiltAtLocation(P.location.view(), building);
Check.hasEnoughResourcesToBuild(building);
R.keys(Buildings[building].requires).forEach((resource) => P.resource(resource).min(Buildings[building].requires[resource]));
P.actionType.set('building');
P.actionStart.set(getCurrentMillis());
P.actionEnd.set(getCurrentMillis() + Buildings[building].timeToBuild);
P.actionArguments.set(building);
Output.afterSave(Lenses.config(), 'You started building a ', building.green, ' at ', P.location.view().green);
};
exports.demolish = (building) => {
Check.isValidBuilding(building);
Check.isNotBuiltAtLocation(P.location.view(), building);
R.keys(P.building(P.location.view(), building).view()).forEach((resource) => P.resource(resource).add(P.buildingResource(P.location.view(), building, resource).view()));
P.building(P.location.view(), building).set(undefined);
Output.afterSave(Lenses.config(), 'You successfully demolished ', building.green, ' at ', P.location.view().green);
};
exports.craft = (item) => {
Check.isIdle();
Check.isValidItem(item);
Check.hasBuildingHere(Items[item].requires.building);
R.keys(Items[item].requires.resources).forEach((resource) => Check.hasEnoughResources(Items[item].requires.resources[resource], resource));
P.actionType.set("crafting");
P.actionStart.set(getCurrentMillis());
P.actionEnd.set(getCurrentMillis() + Items[item].requires.time);
P.actionArguments.set(item);
R.keys(Items[item].requires.resources).forEach((resource) => P.resource(resource).min(Items[item].requires.resources[resource]));
Output.afterSave(Lenses.config(), 'You started crafting ', item.green);
};
exports.status = () => {
Check.isNotIdle();
let display = ['You are currently ', P.actionType.view().green];
if (P.actionArguments.view()) display = display.concat('[', P.actionArguments.view().green ,']');
if (P.actionStart.view() && P.actionEnd.view()) display = display.concat('(', Math.round(((getCurrentMillis()-P.actionStart.view()) / (P.actionEnd.view() - P.actionStart.view())) * 100).toString().green ,'% complete).');
if (P.actionStart.view() && !P.actionEnd.view()) display = display.concat('. And you have been doing that for �', Math.round((getCurrentMillis() - P.actionStart.view()) / (1000 * 60)).toString().green ,' minutes now.');
Output.show.apply(null, display);
};
exports.getItemInfo = (item) => {
Check.isValidItem(item);
const resources = Items[item].requires.resources;
const resourceStr = R.keys(resources).map((r) => resources[r]+' '+r).join(', ');
const time = Items[item].requires.time;
const building = Items[item].requires.building;
const value = Items[item].value;
let display = [item.green,' will cost you ', resourceStr.green];
if (building) display = display.concat(['\nYou need a ', building.green, ' to craft this']);
display = display.concat(['\nIt will take about ', (time/1000).toString().green, 'seconds to craft']);
display = display.concat(['\nIt values around ', value.toString().green, 'gp']);
Output.show.apply(null, display);
};
exports.getAllItems = () => {
const value = (item) => Items[item].value ? Items[item].value.toString() : '0';
const display = R.keys(Items)
.filter((item) => !Items[item].secret)
.map((item) => item.green+' with a value of '+value(item).green+'gp').join('\n ');
Output.show('You are able to craft the following items:\n', display);
};
exports.scheduleJobForBuilding = (building, item) => {
Check.isIdle();
Check.isValidItem(item);
Check.isNotBuiltAtLocation(P.location.view(), building);
Check.itemCanBeMadeAtBuilding(building, item);
Check.alreadyCraftingAtBuilding(P.location.view(), building);
P.buildingActionType(P.location.view(), building).set('job');
P.buildingActionStart(P.location.view(), building).set(getCurrentMillis());
P.buildingActionArguments(P.location.view(), building).set(item);
Output.afterSave(Lenses.config(), 'You started crafting', item.green, 'at your', building.green, '. Make sure to keep it', 'supplied'.green, 'to make sure that items will be crafted.');
};
exports.showJobsRunning = () => {
Check.hasBuildingsAt(P.location.view());
const buildings = P.locationBuildings(P.location.view()).view();
const filtered = R.keys(buildings).filter((building) => P.buildingActionType(P.location.view(), building).view() === 'job');
if (filtered.length === 0) Output.show('You do not have any jobs running'.red);
const display = ['You have the following jobs running\n'];
display.push(filtered.map((building) => building.green+' is currently making '+P.buildingActionArguments(P.location.view(), building).view().green).join('\n '));
Output.show.apply(null, display);
};
exports.stopJobForBuilding = (building) => {
Check.isIdle();
Check.isValidBuilding(building);
Check.isNotBuiltAtLocation(P.location.view(), building);
Check.noJobRunningAtBuildingAtLocation(P.location.view(), building);
const item = P.buildingActionArguments(P.location.view(), building).view();
P.buildingActionType(P.location.view(), building).set(undefined);
P.buildingActionStart(P.location.view(), building).set(undefined);
P.buildingActionArguments(P.location.view(), building).set(undefined);
const amount = P.buildingResource(P.location.view(), building, item).view(0);
Output.afterSave(Lenses.config(), 'You now have', amount.toString().green, item.green, 'at your', building.green);
};
exports.visit = (building) => {
Check.isIdle();
Check.isValidBuilding(building);
Check.isNotBuiltAtLocation(P.location.view(), building);
const resources = P.buildingResources(P.location.view(), building).view();
Output.show('Your', building.green, 'currently has:\n', View.resources(resources));
};
exports.exists = (subject) => {
if (Items[subject]) Output.show('There is an','item'.green,'that is named ', subject.green);
if (Buildings[subject]) Output.show('There is a ','building'.green,' called ', subject.green);
if (Locations[subject]) Output.show('There is a ','location'.green,' called ', subject.green);
Output.show('That does not exist');
};
exports.getAllLocations = () => {
const getBuildingsForLocation = (location) => "\n You have built there: "+View.buildings(P.locationBuildings(location).view()).green+'\n';
const value = (_) => Locations[_].description ? Locations[_].description : 'has no description';
const display = R.keys(Locations)
.filter((location) => !Locations[location].secret)
.map((location) => location.green+': '+value(location)+getBuildingsForLocation(location))
.join('\n ');
Output.show('You are able to travel to following locations:\n', display);
};
exports.getAllBuildings = () => {
const timeToBuild = (_) => Buildings[_].timeToBuild / 60 / 1000;
const resourcesToBuild = (_) => R.keys(Buildings[_].requires).map((resource) => Buildings[_].requires[resource].toString().green+' '+resource.green).join(', ');
const display = R.keys(Buildings)
.filter((building) => !Buildings[building].secret)
.map((building) => building.green+' requires '+resourcesToBuild(building)+' and takes '+timeToBuild(building).toString().green+' minutes to build')
.join('\n ');
Output.show('You are able to build the following buildings:\n', display);
};