Add item states
parent
f8f4c555b8
commit
8d74237a6d
|
@ -5,6 +5,7 @@
|
|||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "assassin-bug",
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
|
@ -568,7 +569,6 @@
|
|||
"dependencies": {
|
||||
"anymatch": "~3.1.2",
|
||||
"braces": "~3.0.2",
|
||||
"fsevents": "~2.3.2",
|
||||
"glob-parent": "~5.1.2",
|
||||
"is-binary-path": "~2.1.0",
|
||||
"is-glob": "~4.0.1",
|
||||
|
|
|
@ -1,56 +1,61 @@
|
|||
import Item from '../item';
|
||||
|
||||
export default class ItemBuilder {
|
||||
constructor() {
|
||||
this.item = new Item();
|
||||
}
|
||||
|
||||
withID(ID) {
|
||||
this.item.id = ID;
|
||||
return this;
|
||||
}
|
||||
|
||||
withName(name) {
|
||||
this.item.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
withDescription(description) {
|
||||
this.item.description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
isUsable(value) {
|
||||
this.item.usable = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
isTakeable(value) {
|
||||
this.item.takeable = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
withUseCallback(callback) {
|
||||
this.item.addUseCallback(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
withTakeCallback(callback) {
|
||||
this.item.addTakeCallback(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
withDropCallback(callback) {
|
||||
this.item.addDropCallback(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
withTickCallback(callback) {
|
||||
this.item.addTickCallback(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
create() {
|
||||
return this.item;
|
||||
}
|
||||
import Item from '../item';
|
||||
|
||||
export default class ItemBuilder {
|
||||
constructor() {
|
||||
this.item = new Item();
|
||||
}
|
||||
|
||||
withID(ID) {
|
||||
this.item.id = ID;
|
||||
return this;
|
||||
}
|
||||
|
||||
withName(name) {
|
||||
this.item.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
withDescription(description) {
|
||||
this.item.description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
withState(key, value) {
|
||||
this.item.setState(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
isUsable(value) {
|
||||
this.item.usable = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
isTakeable(value) {
|
||||
this.item.takeable = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
withUseCallback(callback) {
|
||||
this.item.addUseCallback(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
withTakeCallback(callback) {
|
||||
this.item.addTakeCallback(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
withDropCallback(callback) {
|
||||
this.item.addDropCallback(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
withTickCallback(callback) {
|
||||
this.item.addTickCallback(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
create() {
|
||||
return this.item;
|
||||
}
|
||||
}
|
|
@ -1,160 +1,160 @@
|
|||
import State from './state';
|
||||
import Room from './room';
|
||||
import Player from './player';
|
||||
import Output from './output';
|
||||
import Input from './input';
|
||||
import Commands from './commands';
|
||||
import Serialization from './serialization';
|
||||
|
||||
export default class Game {
|
||||
constructor(newGame = true) {
|
||||
this.newGame = newGame;
|
||||
this.player = new Player();
|
||||
this.state = State;
|
||||
this.rooms = [];
|
||||
this.items = [];
|
||||
this.output = new Output();
|
||||
this.commandHandler = new Commands(this);
|
||||
this.input = new Input(this.commandHandler, this.output);
|
||||
this.visitedRooms = new Map();
|
||||
this.interval = null;
|
||||
this.Serialization = new Serialization(this);
|
||||
}
|
||||
|
||||
print(string) {
|
||||
this.output.say(string);
|
||||
}
|
||||
|
||||
async tell(lines, time) {
|
||||
for (let line of lines) {
|
||||
this.print(line);
|
||||
await this.wait(time);
|
||||
}
|
||||
}
|
||||
|
||||
init(data) {
|
||||
this.rooms = data.rooms.map((room) => {
|
||||
room.context = this;
|
||||
return room;
|
||||
});
|
||||
this.items = data.items.map((item) => {
|
||||
item.context = this;
|
||||
return item;
|
||||
});
|
||||
this.state = data.state || State;
|
||||
this.commandHandler.addCommands(data.commands);
|
||||
this.player = new Player();
|
||||
this.player.context = this;
|
||||
if (this.newGame) {
|
||||
this.move(this.player.currentRoom);
|
||||
} else {
|
||||
this.Serialization.load();
|
||||
}
|
||||
this.start();
|
||||
}
|
||||
|
||||
advanceTick() {
|
||||
this.items.forEach((item) => item.onTick());
|
||||
this.rooms.forEach((room) => room.onTick());
|
||||
}
|
||||
|
||||
start() {
|
||||
this.interval = setInterval(() => this.advanceTick(), 1000);
|
||||
}
|
||||
|
||||
stop() {
|
||||
clearInterval(this.interval);
|
||||
this.interval = null;
|
||||
}
|
||||
|
||||
examineRoom() {
|
||||
const room = this.getRoom(this.player.currentRoom);
|
||||
this.output.say(room.title);
|
||||
if (!this.visitedRooms.get(this.player.currentRoom) && room.firstDescription != "") {
|
||||
this.output.say(room.firstDescription);
|
||||
} else {
|
||||
this.output.say(room.description);
|
||||
}
|
||||
this.examineItems();
|
||||
this.examineExits();
|
||||
}
|
||||
|
||||
examineItems() {
|
||||
const room = this.getRoom(this.player.currentRoom);
|
||||
const items = room.getItems();
|
||||
if (items.length < 1) return;
|
||||
let itemDescription = `You see `;
|
||||
items.forEach((item, index) => {
|
||||
if (index < items.length - 2) {
|
||||
itemDescription += `${item.name}, `;
|
||||
} else if (index < items.length - 1) {
|
||||
itemDescription += `${item.name} and `;
|
||||
} else {
|
||||
itemDescription += item.name
|
||||
}
|
||||
});
|
||||
this.output.say(itemDescription + ".");
|
||||
}
|
||||
|
||||
examineExits() {
|
||||
const room = this.getRoom(this.player.currentRoom);
|
||||
let exits = [];
|
||||
let exitDescription = "You can go ";
|
||||
const exitKeys = room.exits.keys();
|
||||
for (let exit of exitKeys) {
|
||||
exits.push(exit);
|
||||
}
|
||||
exits.forEach((item, index) => {
|
||||
if (index < exits.length - 2) {
|
||||
exitDescription += `${item}, `;
|
||||
} else if (index < exits.length - 1) {
|
||||
exitDescription += `${item} and `;
|
||||
} else {
|
||||
exitDescription += item
|
||||
}
|
||||
});
|
||||
this.output.say(exitDescription + ".");
|
||||
}
|
||||
|
||||
getRoom(id) {
|
||||
return this.rooms.find((room) => room.id == id);
|
||||
}
|
||||
|
||||
getItem(id) {
|
||||
return this.items.find((item) => item.id == id);
|
||||
}
|
||||
|
||||
wait(ms) {
|
||||
return new Promise((resolve, reject) => {
|
||||
setTimeout(resolve, ms);
|
||||
});
|
||||
}
|
||||
|
||||
async move(roomID) {
|
||||
const currentRoom = this.getRoom(this.player.currentRoom);
|
||||
const newRoom = this.getRoom(roomID);
|
||||
if (currentRoom.canExit() && newRoom.canEnter()) {
|
||||
await currentRoom.onExit();
|
||||
await newRoom.onEnter();
|
||||
this.player.currentRoom = roomID;
|
||||
this.examineRoom();
|
||||
this.visitedRooms.set(roomID, true);
|
||||
}
|
||||
}
|
||||
|
||||
enableCommandInput(value) {
|
||||
this.commandHandler.enabled = value;
|
||||
}
|
||||
|
||||
setInputEcho(value) {
|
||||
this.input.setEcho(value);
|
||||
}
|
||||
|
||||
save() {
|
||||
this.Serialization.save();
|
||||
}
|
||||
|
||||
load() {
|
||||
this.Serialization.load();
|
||||
}
|
||||
import State from './state';
|
||||
import Room from './room';
|
||||
import Player from './player';
|
||||
import Output from './output';
|
||||
import Input from './input';
|
||||
import Commands from './commands';
|
||||
import Serialization from './serialization';
|
||||
|
||||
export default class Game {
|
||||
constructor(newGame = true) {
|
||||
this.newGame = newGame;
|
||||
this.player = new Player();
|
||||
this.state = new State();
|
||||
this.rooms = [];
|
||||
this.items = [];
|
||||
this.output = new Output();
|
||||
this.commandHandler = new Commands(this);
|
||||
this.input = new Input(this.commandHandler, this.output);
|
||||
this.visitedRooms = new Map();
|
||||
this.interval = null;
|
||||
this.Serialization = new Serialization(this);
|
||||
}
|
||||
|
||||
print(string) {
|
||||
this.output.say(string);
|
||||
}
|
||||
|
||||
async tell(lines, time) {
|
||||
for (let line of lines) {
|
||||
this.print(line);
|
||||
await this.wait(time);
|
||||
}
|
||||
}
|
||||
|
||||
init(data) {
|
||||
this.rooms = data.rooms.map((room) => {
|
||||
room.context = this;
|
||||
return room;
|
||||
});
|
||||
this.items = data.items.map((item) => {
|
||||
item.context = this;
|
||||
return item;
|
||||
});
|
||||
this.state = data.state || new State();
|
||||
this.commandHandler.addCommands(data.commands);
|
||||
this.player = new Player();
|
||||
this.player.context = this;
|
||||
if (this.newGame) {
|
||||
this.move(this.player.currentRoom);
|
||||
} else {
|
||||
this.Serialization.load();
|
||||
}
|
||||
this.start();
|
||||
}
|
||||
|
||||
advanceTick() {
|
||||
this.items.forEach((item) => item.onTick());
|
||||
this.rooms.forEach((room) => room.onTick());
|
||||
}
|
||||
|
||||
start() {
|
||||
this.interval = setInterval(() => this.advanceTick(), 1000);
|
||||
}
|
||||
|
||||
stop() {
|
||||
clearInterval(this.interval);
|
||||
this.interval = null;
|
||||
}
|
||||
|
||||
examineRoom() {
|
||||
const room = this.getRoom(this.player.currentRoom);
|
||||
this.output.say(room.title);
|
||||
if (!this.visitedRooms.get(this.player.currentRoom) && room.firstDescription != "") {
|
||||
this.output.say(room.firstDescription);
|
||||
} else {
|
||||
this.output.say(room.description);
|
||||
}
|
||||
this.examineItems();
|
||||
this.examineExits();
|
||||
}
|
||||
|
||||
examineItems() {
|
||||
const room = this.getRoom(this.player.currentRoom);
|
||||
const items = room.getItems();
|
||||
if (items.length < 1) return;
|
||||
let itemDescription = `You see `;
|
||||
items.forEach((item, index) => {
|
||||
if (index < items.length - 2) {
|
||||
itemDescription += `${item.name}, `;
|
||||
} else if (index < items.length - 1) {
|
||||
itemDescription += `${item.name} and `;
|
||||
} else {
|
||||
itemDescription += item.name
|
||||
}
|
||||
});
|
||||
this.output.say(itemDescription + ".");
|
||||
}
|
||||
|
||||
examineExits() {
|
||||
const room = this.getRoom(this.player.currentRoom);
|
||||
let exits = [];
|
||||
let exitDescription = "You can go ";
|
||||
const exitKeys = room.exits.keys();
|
||||
for (let exit of exitKeys) {
|
||||
exits.push(exit);
|
||||
}
|
||||
exits.forEach((item, index) => {
|
||||
if (index < exits.length - 2) {
|
||||
exitDescription += `${item}, `;
|
||||
} else if (index < exits.length - 1) {
|
||||
exitDescription += `${item} and `;
|
||||
} else {
|
||||
exitDescription += item
|
||||
}
|
||||
});
|
||||
this.output.say(exitDescription + ".");
|
||||
}
|
||||
|
||||
getRoom(id) {
|
||||
return this.rooms.find((room) => room.id == id);
|
||||
}
|
||||
|
||||
getItem(id) {
|
||||
return this.items.find((item) => item.id == id);
|
||||
}
|
||||
|
||||
wait(ms) {
|
||||
return new Promise((resolve, reject) => {
|
||||
setTimeout(resolve, ms);
|
||||
});
|
||||
}
|
||||
|
||||
async move(roomID) {
|
||||
const currentRoom = this.getRoom(this.player.currentRoom);
|
||||
const newRoom = this.getRoom(roomID);
|
||||
if (currentRoom.canExit() && newRoom.canEnter()) {
|
||||
await currentRoom.onExit();
|
||||
await newRoom.onEnter();
|
||||
this.player.currentRoom = roomID;
|
||||
this.examineRoom();
|
||||
this.visitedRooms.set(roomID, true);
|
||||
}
|
||||
}
|
||||
|
||||
enableCommandInput(value) {
|
||||
this.commandHandler.enabled = value;
|
||||
}
|
||||
|
||||
setInputEcho(value) {
|
||||
this.input.setEcho(value);
|
||||
}
|
||||
|
||||
save() {
|
||||
this.Serialization.save();
|
||||
}
|
||||
|
||||
load() {
|
||||
this.Serialization.load();
|
||||
}
|
||||
}
|
|
@ -1,45 +1,56 @@
|
|||
export default class Item {
|
||||
constructor() {
|
||||
this.id = "item";
|
||||
this.name = "An item";
|
||||
this.description = "You see nothing special about this item";
|
||||
this.usable = true;
|
||||
this.takeable = true;
|
||||
this.useCallback = null;
|
||||
this.takeCallback = null;
|
||||
this.dropCallback = null;
|
||||
this.tickCallback = null;
|
||||
this.context = null;
|
||||
}
|
||||
|
||||
async onUse() {
|
||||
if (this.useCallback) return this.useCallback(this.context);
|
||||
}
|
||||
|
||||
async onTake() {
|
||||
if (this.takeCallback) return this.takeCallback(this.context);
|
||||
}
|
||||
|
||||
async onDrop() {
|
||||
if (this.dropCallback) return this.dropCallback(this.context);
|
||||
}
|
||||
async onTick() {
|
||||
if (this.tickCallback) return this.tickCallback(this.context);
|
||||
}
|
||||
|
||||
addUseCallback(callback) {
|
||||
this.useCallback = callback.bind(this);
|
||||
}
|
||||
|
||||
addTakeCallback(callback) {
|
||||
this.takeCallback = callback.bind(this);
|
||||
}
|
||||
|
||||
addDropCallback(callback) {
|
||||
this.dropCallback = callback.bind(this);
|
||||
}
|
||||
|
||||
addTickCallback(callback) {
|
||||
this.tickCallback = callback.bind(this);
|
||||
}
|
||||
import State from "./state";
|
||||
|
||||
export default class Item {
|
||||
constructor() {
|
||||
this.id = "item";
|
||||
this.name = "An item";
|
||||
this.description = "You see nothing special about this item";
|
||||
this.state = new State();
|
||||
this.usable = true;
|
||||
this.takeable = true;
|
||||
this.useCallback = null;
|
||||
this.takeCallback = null;
|
||||
this.dropCallback = null;
|
||||
this.tickCallback = null;
|
||||
this.context = null;
|
||||
}
|
||||
|
||||
async onUse() {
|
||||
if (this.useCallback) return this.useCallback(this.context);
|
||||
}
|
||||
|
||||
async onTake() {
|
||||
if (this.takeCallback) return this.takeCallback(this.context);
|
||||
}
|
||||
|
||||
async onDrop() {
|
||||
if (this.dropCallback) return this.dropCallback(this.context);
|
||||
}
|
||||
async onTick() {
|
||||
if (this.tickCallback) return this.tickCallback(this.context);
|
||||
}
|
||||
|
||||
addUseCallback(callback) {
|
||||
this.useCallback = callback.bind(this);
|
||||
}
|
||||
|
||||
addTakeCallback(callback) {
|
||||
this.takeCallback = callback.bind(this);
|
||||
}
|
||||
|
||||
addDropCallback(callback) {
|
||||
this.dropCallback = callback.bind(this);
|
||||
}
|
||||
|
||||
addTickCallback(callback) {
|
||||
this.tickCallback = callback.bind(this);
|
||||
}
|
||||
|
||||
setState(key, value) {
|
||||
return this.state.set(key, value);
|
||||
}
|
||||
|
||||
getState(key) {
|
||||
return this.state.get(key);
|
||||
}
|
||||
}
|
|
@ -1,52 +1,67 @@
|
|||
export default class Serialization {
|
||||
constructor(context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
save() {
|
||||
const saveobj = {
|
||||
state: this.context.state.serialize(),
|
||||
itemLocations: this.serializeItemLocations(),
|
||||
player: {
|
||||
currentRoom: this.context.player.currentRoom,
|
||||
inventory: this.context.player.inventory
|
||||
},
|
||||
volumes: {
|
||||
music: this.context.output.sound.musicVolume,
|
||||
sfx: this.context.output.sound.sfxVolume,
|
||||
ambience: this.context.output.sound.ambienceVolume
|
||||
}
|
||||
};
|
||||
localStorage.setItem("save", JSON.stringify(saveobj));
|
||||
}
|
||||
|
||||
load() {
|
||||
const loadobj = JSON.parse(localStorage.getItem("save"));
|
||||
this.context.state.deserialize(loadobj.state);
|
||||
this.deserializeItemLocations(loadobj.itemLocations);
|
||||
this.deserializePlayer(loadobj.player);
|
||||
this.context.output.sound.setSFXVolume(loadobj.volumes.sfx);
|
||||
this.context.output.sound.setMusicVolume(loadobj.volumes.music);
|
||||
this.context.output.sound.setAmbienceVolume(loadobj.volumes.ambience);
|
||||
}
|
||||
|
||||
serializeItemLocations() {
|
||||
return this.context.rooms.map((item) => {
|
||||
return [item.id,
|
||||
item.objects
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
deserializeItemLocations(items) {
|
||||
items.forEach((item) => {
|
||||
const room = this.context.getRoom(item[0]);
|
||||
room.objects = item[1];
|
||||
})
|
||||
}
|
||||
|
||||
deserializePlayer(player) {
|
||||
this.context.move(player.currentRoom);
|
||||
this.context.player.inventory = player.inventory;
|
||||
}
|
||||
export default class Serialization {
|
||||
constructor(context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
save() {
|
||||
const saveobj = {
|
||||
state: this.context.state.serialize(),
|
||||
itemLocations: this.serializeItemLocations(),
|
||||
itemStates: this.serializeItemStates(),
|
||||
player: {
|
||||
currentRoom: this.context.player.currentRoom,
|
||||
inventory: this.context.player.inventory
|
||||
},
|
||||
volumes: {
|
||||
music: this.context.output.sound.musicVolume,
|
||||
sfx: this.context.output.sound.sfxVolume,
|
||||
ambience: this.context.output.sound.ambienceVolume
|
||||
}
|
||||
};
|
||||
localStorage.setItem("save", JSON.stringify(saveobj));
|
||||
}
|
||||
|
||||
load() {
|
||||
const loadobj = JSON.parse(localStorage.getItem("save"));
|
||||
this.context.state.deserialize(loadobj.state);
|
||||
this.deserializeItemLocations(loadobj.itemLocations);
|
||||
this.deserializeItemStates(loadobj.itemStates);
|
||||
this.deserializePlayer(loadobj.player);
|
||||
this.context.output.sound.setSFXVolume(loadobj.volumes.sfx);
|
||||
this.context.output.sound.setMusicVolume(loadobj.volumes.music);
|
||||
this.context.output.sound.setAmbienceVolume(loadobj.volumes.ambience);
|
||||
}
|
||||
|
||||
serializeItemLocations() {
|
||||
return this.context.rooms.map((item) => {
|
||||
return [item.id,
|
||||
item.objects
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
deserializeItemLocations(items) {
|
||||
items.forEach((item) => {
|
||||
const room = this.context.getRoom(item[0]);
|
||||
room.objects = item[1];
|
||||
})
|
||||
}
|
||||
|
||||
deserializeItemStates(items) {
|
||||
items.forEach((item) => {
|
||||
const obj = this.context.getItem(item[0]);
|
||||
obj.state.deserialize(item[1]);
|
||||
})
|
||||
}
|
||||
|
||||
deserializePlayer(player) {
|
||||
this.context.move(player.currentRoom);
|
||||
this.context.player.inventory = player.inventory;
|
||||
}
|
||||
|
||||
serializeItemStates() {
|
||||
return this.context.items.map((item) => {
|
||||
return [item.id, item.state.serialize()]
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,38 +1,36 @@
|
|||
class State {
|
||||
constructor() {
|
||||
this.states = new Map();
|
||||
}
|
||||
|
||||
get(key, defaultValue = null) {
|
||||
if (!this.states.has(key)) {
|
||||
this.states.set(key, defaultValue);
|
||||
return defaultValue;
|
||||
}
|
||||
return this.states.get(key);
|
||||
}
|
||||
|
||||
set(key, value) {
|
||||
return this.states.set(key, value);
|
||||
}
|
||||
|
||||
change(key, amount = 1) {
|
||||
let val = this.get(key, 0);
|
||||
val += amount;
|
||||
this.set(key, val);
|
||||
}
|
||||
|
||||
serialize() {
|
||||
const entries = this.states.entries();
|
||||
const entrymap = [];
|
||||
for (let state of entries) {
|
||||
entrymap.push(state);
|
||||
}
|
||||
return entrymap;
|
||||
}
|
||||
|
||||
deserialize(data) {
|
||||
this.states = new Map(data);
|
||||
}
|
||||
}
|
||||
|
||||
export default new State();
|
||||
export default class State {
|
||||
constructor() {
|
||||
this.states = new Map();
|
||||
}
|
||||
|
||||
get(key, defaultValue = null) {
|
||||
if (!this.states.has(key)) {
|
||||
this.states.set(key, defaultValue);
|
||||
return defaultValue;
|
||||
}
|
||||
return this.states.get(key);
|
||||
}
|
||||
|
||||
set(key, value) {
|
||||
return this.states.set(key, value);
|
||||
}
|
||||
|
||||
change(key, amount = 1) {
|
||||
let val = this.get(key, 0);
|
||||
val += amount;
|
||||
this.set(key, val);
|
||||
}
|
||||
|
||||
serialize() {
|
||||
const entries = this.states.entries();
|
||||
const entrymap = [];
|
||||
for (let state of entries) {
|
||||
entrymap.push(state);
|
||||
}
|
||||
return entrymap;
|
||||
}
|
||||
|
||||
deserialize(data) {
|
||||
this.states = new Map(data);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue