shoot arrow WIP
This commit is contained in:
parent
8567bec9f9
commit
dbcb7aef8d
9 changed files with 731 additions and 500 deletions
|
@ -116,5 +116,10 @@ p.Example {
|
||||||
|
|
||||||
h3.Reference {
|
h3.Reference {
|
||||||
margin-top: 30px;
|
margin-top: 30px;
|
||||||
margin-bottom: 0
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3.Reference2 {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,12 +29,7 @@ export class CommandInitialize implements Command {
|
||||||
state.initialize(this.stacks);
|
state.initialize(this.stacks);
|
||||||
}
|
}
|
||||||
public getDisplayString(): string {
|
public getDisplayString(): string {
|
||||||
const parts = ["Initialize"];
|
return joinItemStackString("Initialize", this.stacks);
|
||||||
this.stacks.forEach(({item, count})=>{
|
|
||||||
parts.push(""+count);
|
|
||||||
parts.push(item);
|
|
||||||
});
|
|
||||||
return parts.join(" ");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -104,7 +99,239 @@ export class CommandBreakSlots implements Command {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class CommandAdd implements Command {
|
||||||
|
private verb: string;
|
||||||
|
private count: number;
|
||||||
|
private item: Item;
|
||||||
|
constructor(verb: string, count: number, item: Item){
|
||||||
|
this.verb = verb;
|
||||||
|
this.count = count;
|
||||||
|
this.item = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public execute(state: SimulationState): void {
|
||||||
|
state.obtain(this.item, this.count);
|
||||||
|
}
|
||||||
|
public getDisplayString(): string {
|
||||||
|
return `${this.verb} ${this.count} ${this.item}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CommandAddWithoutCount implements Command {
|
||||||
|
private verb: string;
|
||||||
|
private item: Item;
|
||||||
|
constructor(verb: string, item: Item){
|
||||||
|
this.verb = verb;
|
||||||
|
this.item = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public execute(state: SimulationState): void {
|
||||||
|
state.obtain(this.item, 1);
|
||||||
|
}
|
||||||
|
public getDisplayString(): string {
|
||||||
|
return `${this.verb} ${this.item}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CommandAddMultiple implements Command {
|
||||||
|
private verb: string;
|
||||||
|
private stacks: ItemStack[];
|
||||||
|
constructor(verb: string, stacks: ItemStack[]){
|
||||||
|
this.verb = verb;
|
||||||
|
this.stacks = stacks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public execute(state: SimulationState): void {
|
||||||
|
this.stacks.forEach(({item, count})=>state.obtain(item,count));
|
||||||
|
}
|
||||||
|
public getDisplayString(): string {
|
||||||
|
return joinItemStackString(this.verb, this.stacks);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CommandRemove implements Command {
|
||||||
|
private verb: string;
|
||||||
|
private count: number;
|
||||||
|
private item: Item;
|
||||||
|
private slot: number;
|
||||||
|
private noSlot: boolean;
|
||||||
|
constructor(verb: string, count: number, item: Item, slot: number, noSlot: boolean){
|
||||||
|
this.verb = verb;
|
||||||
|
this.count = count;
|
||||||
|
this.item = item;
|
||||||
|
this.slot = slot;
|
||||||
|
this.noSlot = noSlot;
|
||||||
|
}
|
||||||
|
public execute(state: SimulationState): void {
|
||||||
|
state.remove(this.item, this.count, this.slot);
|
||||||
|
}
|
||||||
|
public getDisplayString(): string {
|
||||||
|
const slotString = this.noSlot ? "" : ` From Slot ${this.slot+1}`;
|
||||||
|
return `${this.verb} ${this.count} ${this.item}${slotString}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CommandRemoveWithoutCount implements Command {
|
||||||
|
private verb: string;
|
||||||
|
private item: Item;
|
||||||
|
private slot: number;
|
||||||
|
private noSlot: boolean;
|
||||||
|
constructor(verb: string, item: Item, slot: number, noSlot: boolean){
|
||||||
|
this.verb = verb;
|
||||||
|
this.item = item;
|
||||||
|
this.slot = slot;
|
||||||
|
this.noSlot = noSlot;
|
||||||
|
}
|
||||||
|
public execute(state: SimulationState): void {
|
||||||
|
state.remove(this.item, 1, this.slot);
|
||||||
|
}
|
||||||
|
public getDisplayString(): string {
|
||||||
|
const slotString = this.noSlot ? "" : ` From Slot ${this.slot+1}`;
|
||||||
|
return `${this.verb} ${this.item}${slotString}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CommandRemoveMultiple implements Command {
|
||||||
|
private verb: string;
|
||||||
|
private stacks: ItemStack[];
|
||||||
|
constructor(verb: string, stacks: ItemStack[]){
|
||||||
|
this.verb = verb;
|
||||||
|
this.stacks = stacks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public execute(state: SimulationState): void {
|
||||||
|
this.stacks.forEach(({item, count})=>state.remove(item,count,0));
|
||||||
|
}
|
||||||
|
public getDisplayString(): string {
|
||||||
|
return joinItemStackString(this.verb, this.stacks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const joinItemStackString = (initial: string, stacks: ItemStack[]): string => {
|
||||||
|
const parts: string[] = [initial];
|
||||||
|
stacks.forEach(({item, count})=>{
|
||||||
|
parts.push(""+count);
|
||||||
|
parts.push(item);
|
||||||
|
});
|
||||||
|
return parts.join(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CommandDaP implements Command {
|
||||||
|
private count: number;
|
||||||
|
private item: Item;
|
||||||
|
|
||||||
|
constructor(count: number, item: Item,){
|
||||||
|
this.count = count;
|
||||||
|
this.item = item;
|
||||||
|
}
|
||||||
|
public execute(state: SimulationState): void {
|
||||||
|
state.remove(this.item, this.count, 0);
|
||||||
|
state.obtain(this.item, this.count);
|
||||||
|
}
|
||||||
|
public getDisplayString(): string {
|
||||||
|
return `D&P ${this.count} ${this.item}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CommandEquip implements Command {
|
||||||
|
private item: Item;
|
||||||
|
private slot: number;
|
||||||
|
private noSlot: boolean;
|
||||||
|
constructor(item: Item, slot: number, noSlot: boolean){
|
||||||
|
this.item = item;
|
||||||
|
this.slot = slot;
|
||||||
|
this.noSlot = noSlot;
|
||||||
|
}
|
||||||
|
|
||||||
|
public execute(state: SimulationState): void {
|
||||||
|
state.equip(this.item, this.slot);
|
||||||
|
}
|
||||||
|
public getDisplayString(): string {
|
||||||
|
const slotString = this.noSlot ? "" : ` In Slot ${this.slot+1}`;
|
||||||
|
return `Equip ${this.item}${slotString}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CommandUnequip implements Command {
|
||||||
|
private item: Item;
|
||||||
|
private slot: number;
|
||||||
|
private noSlot: boolean;
|
||||||
|
constructor(item: Item, slot: number, noSlot: boolean){
|
||||||
|
this.item = item;
|
||||||
|
this.slot = slot;
|
||||||
|
this.noSlot = noSlot;
|
||||||
|
}
|
||||||
|
|
||||||
|
public execute(state: SimulationState): void {
|
||||||
|
state.unequip(this.item, this.slot);
|
||||||
|
}
|
||||||
|
public getDisplayString(): string {
|
||||||
|
const slotString = this.noSlot ? "" : ` In Slot ${this.slot+1}`;
|
||||||
|
return `Unequip ${this.item}${slotString}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CommandShootArrow implements Command {
|
||||||
|
private count: number
|
||||||
|
constructor(count: number){
|
||||||
|
this.count = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public execute(state: SimulationState): void {
|
||||||
|
state.shootArrow(this.count);
|
||||||
|
}
|
||||||
|
public getDisplayString(): string {
|
||||||
|
return `Shoot ${this.count} Arrow`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// export class CommandEquipArrow implements Command {
|
||||||
|
// private item: Item;
|
||||||
|
// private slot: number;
|
||||||
|
// private noSlot: boolean;
|
||||||
|
// constructor(item: Item, slot: number, noSlot: boolean){
|
||||||
|
// this.item = item;
|
||||||
|
// this.slot = slot;
|
||||||
|
// this.noSlot = noSlot;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public execute(inv: Inventory): void {
|
||||||
|
// inv.equipEquipmentOrArrow(this.item, this.slot);
|
||||||
|
// }
|
||||||
|
// public getDisplayString(): string {
|
||||||
|
// const slotString = this.noSlot ? "" : ` In Slot ${this.slot+1}`;
|
||||||
|
// return `Equip ${itemToArrowType(this.item)} Arrow${slotString}`;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// export class CommandCloseGame implements Command {
|
||||||
|
// public execute(inv: Inventory): void {
|
||||||
|
// inv.closeGame();
|
||||||
|
// }
|
||||||
|
// public getDisplayString(): string {
|
||||||
|
// return "Close Game";
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
export class CommandComment implements Command {
|
||||||
|
private name: string;
|
||||||
|
constructor(name: string){
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
public execute(_state: SimulationState): void {
|
||||||
|
// nothing
|
||||||
|
}
|
||||||
|
public getDisplayString(): string {
|
||||||
|
return `# ${this.name}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// export class CommandSortKey implements Command {
|
// export class CommandSortKey implements Command {
|
||||||
// static Op = 0x5;
|
// static Op = 0x5;
|
||||||
|
@ -141,182 +368,3 @@ export class CommandBreakSlots implements Command {
|
||||||
// return "Sort Material";
|
// return "Sort Material";
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// const Verbs = ["?", "Remove", "Drop", "Sell", "Eat", "Cook", "Get", "Add", "Pickup"];
|
|
||||||
// const VerbToId = {
|
|
||||||
// "Remove" : 1,
|
|
||||||
// "Drop": 2,
|
|
||||||
// "Sell": 3,
|
|
||||||
// "Eat": 4,
|
|
||||||
// "Cook": 5,
|
|
||||||
// "Get": 6,
|
|
||||||
// "Add": 7,
|
|
||||||
// "Pickup": 8
|
|
||||||
// };
|
|
||||||
|
|
||||||
// export class CommandRemoveMaterial implements Command {
|
|
||||||
// static Op = 0x7;
|
|
||||||
// private verb: number;
|
|
||||||
// private count: number;
|
|
||||||
// private item: Item;
|
|
||||||
// private slot: number;
|
|
||||||
// private noSlot: boolean;
|
|
||||||
// constructor(verb: string, count: number, item: Item, slot: number, noSlot: boolean){
|
|
||||||
// this.verb = VerbToId[verb as keyof typeof VerbToId] || 0;
|
|
||||||
// this.count = count;
|
|
||||||
// this.item = item;
|
|
||||||
// this.slot = slot;
|
|
||||||
// this.noSlot = noSlot;
|
|
||||||
// }
|
|
||||||
// public execute(inv: Inventory): void {
|
|
||||||
// inv.remove(this.item, this.count, this.slot);
|
|
||||||
// }
|
|
||||||
// public getDisplayString(): string {
|
|
||||||
// const slotString = this.noSlot ? "" : ` From Slot ${this.slot+1}`;
|
|
||||||
// return `${Verbs[this.verb]} ${this.count} ${this.item}${slotString}`;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// export class CommandRemoveUnstackableMaterial implements Command {
|
|
||||||
// static Op = 0x8;
|
|
||||||
// private verb: number;
|
|
||||||
// private item: Item;
|
|
||||||
// private slot: number;
|
|
||||||
// private noSlot: boolean;
|
|
||||||
// constructor(verb: string,item: Item, slot: number, noSlot: boolean){
|
|
||||||
// this.verb = VerbToId[verb as keyof typeof VerbToId] || 0;
|
|
||||||
// this.item = item;
|
|
||||||
// this.slot = slot;
|
|
||||||
// this.noSlot = noSlot;
|
|
||||||
// }
|
|
||||||
// public execute(inv: Inventory): void {
|
|
||||||
// inv.remove(this.item, 1, this.slot);
|
|
||||||
// }
|
|
||||||
// public getDisplayString(): string {
|
|
||||||
// const slotString = this.noSlot ? "" : ` From Slot ${this.slot+1}`;
|
|
||||||
// return `${Verbs[this.verb]} ${this.item}${slotString}`;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// export class CommandAddMaterial implements Command {
|
|
||||||
// static Op = 0x9;
|
|
||||||
// private verb: number;
|
|
||||||
// private count: number;
|
|
||||||
// private item: Item;
|
|
||||||
// constructor(verb: string, count: number, item: Item){
|
|
||||||
// this.verb = VerbToId[verb as keyof typeof VerbToId] || 0;
|
|
||||||
// this.count = count;
|
|
||||||
// this.item = item;
|
|
||||||
// }
|
|
||||||
// // public fromBuffer(buf: Buffer): number {
|
|
||||||
// // let read = 0;
|
|
||||||
// // const id = buf.readInt8(read);
|
|
||||||
// // read+=1;
|
|
||||||
// // this.item = idToItemData(id).item;
|
|
||||||
|
|
||||||
// // this.count = buf.readInt16LE(read);
|
|
||||||
// // read+=2;
|
|
||||||
// // this.verb = buf.readInt8(read);
|
|
||||||
// // read++;
|
|
||||||
// // return read;
|
|
||||||
// // }
|
|
||||||
// // public toBuffer(): Buffer {
|
|
||||||
// // const buf: Buffer = Buffer.alloc(1+1+2+1);
|
|
||||||
// // let write = 0;
|
|
||||||
// // buf.writeInt8(CommandAddMaterial.Op);
|
|
||||||
// // write++;
|
|
||||||
// // buf.writeInt8(itemToItemData(this.item).id, write);
|
|
||||||
// // write++;
|
|
||||||
// // buf.writeInt16LE(this.count, write);
|
|
||||||
// // write+=2;
|
|
||||||
// // buf.writeInt8(this.verb, write);
|
|
||||||
// // return buf;
|
|
||||||
// // }
|
|
||||||
// public execute(inv: Inventory): void {
|
|
||||||
// inv.add(this.item, this.count);
|
|
||||||
// }
|
|
||||||
// public getDisplayString(): string {
|
|
||||||
// return `${Verbs[this.verb]} ${this.count} ${this.item}`;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// export class CommandEquipArrow implements Command {
|
|
||||||
// private item: Item;
|
|
||||||
// private slot: number;
|
|
||||||
// private noSlot: boolean;
|
|
||||||
// constructor(item: Item, slot: number, noSlot: boolean){
|
|
||||||
// this.item = item;
|
|
||||||
// this.slot = slot;
|
|
||||||
// this.noSlot = noSlot;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// public execute(inv: Inventory): void {
|
|
||||||
// inv.equipEquipmentOrArrow(this.item, this.slot);
|
|
||||||
// }
|
|
||||||
// public getDisplayString(): string {
|
|
||||||
// const slotString = this.noSlot ? "" : ` In Slot ${this.slot+1}`;
|
|
||||||
// return `Equip ${itemToArrowType(this.item)} Arrow${slotString}`;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// export class CommandEquip implements Command {
|
|
||||||
// private item: Item;
|
|
||||||
// private slot: number;
|
|
||||||
// private noSlot: boolean;
|
|
||||||
// constructor(item: Item, slot: number, noSlot: boolean){
|
|
||||||
// this.item = item;
|
|
||||||
// this.slot = slot;
|
|
||||||
// this.noSlot = noSlot;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// public execute(inv: Inventory): void {
|
|
||||||
// inv.equipEquipmentOrArrow(this.item, this.slot);
|
|
||||||
// }
|
|
||||||
// public getDisplayString(): string {
|
|
||||||
// const slotString = this.noSlot ? "" : ` In Slot ${this.slot+1}`;
|
|
||||||
// return `Equip ${this.item}${slotString}`;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// export class CommandUnequip implements Command {
|
|
||||||
// private item: Item;
|
|
||||||
// private slot: number;
|
|
||||||
// private noSlot: boolean;
|
|
||||||
// constructor(item: Item, slot: number, noSlot: boolean){
|
|
||||||
// this.item = item;
|
|
||||||
// this.slot = slot;
|
|
||||||
// this.noSlot = noSlot;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// public execute(inv: Inventory): void {
|
|
||||||
// inv.unequipEquipment(this.item, this.slot);
|
|
||||||
// }
|
|
||||||
// public getDisplayString(): string {
|
|
||||||
// const slotString = this.noSlot ? "" : ` In Slot ${this.slot+1}`;
|
|
||||||
// return `Unequip ${this.item}${slotString}`;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// export class CommandCloseGame implements Command {
|
|
||||||
// public execute(inv: Inventory): void {
|
|
||||||
// inv.closeGame();
|
|
||||||
// }
|
|
||||||
// public getDisplayString(): string {
|
|
||||||
// return "Close Game";
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
export class CommandComment implements Command {
|
|
||||||
private name: string;
|
|
||||||
constructor(name: string){
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
public execute(_state: SimulationState): void {
|
|
||||||
// nothing
|
|
||||||
}
|
|
||||||
public getDisplayString(): string {
|
|
||||||
return `# ${this.name}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { DisplayableInventory, DisplayableSlot, itemStackToDisplayableSlot } from "./DisplayableInventory";
|
import { DisplayableInventory, DisplayableSlot, itemStackToDisplayableSlot } from "./DisplayableInventory";
|
||||||
|
import { Item, itemToItemData } from "./Item";
|
||||||
import { Slots } from "./Slots";
|
import { Slots } from "./Slots";
|
||||||
import { VisibleInventory } from "./VisibleInventory";
|
import { VisibleInventory } from "./VisibleInventory";
|
||||||
|
|
||||||
|
@ -20,6 +21,10 @@ export class GameData implements DisplayableInventory {
|
||||||
this.slots = pouch.getSlots().deepClone();
|
this.slots = pouch.getSlots().deepClone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public updateDurability(durability: number, slot: number){
|
||||||
|
this.slots.corrupt(durability, slot);
|
||||||
|
}
|
||||||
|
|
||||||
public addAllToPouchOnReload(pouch: VisibleInventory) {
|
public addAllToPouchOnReload(pouch: VisibleInventory) {
|
||||||
this.slots.getSlotsRef().forEach(stack=>pouch.addWhenReload(stack.item, stack.count, stack.equipped));
|
this.slots.getSlotsRef().forEach(stack=>pouch.addWhenReload(stack.item, stack.count, stack.equipped));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,22 @@
|
||||||
import {
|
import {
|
||||||
Command,
|
Command,
|
||||||
|
CommandAdd,
|
||||||
|
CommandAddMultiple,
|
||||||
|
CommandAddWithoutCount,
|
||||||
CommandBreakSlots,
|
CommandBreakSlots,
|
||||||
CommandComment,
|
CommandComment,
|
||||||
|
CommandDaP,
|
||||||
|
CommandEquip,
|
||||||
CommandInitialize,
|
CommandInitialize,
|
||||||
CommandNothing,
|
CommandNothing,
|
||||||
CommandReload,
|
CommandReload,
|
||||||
|
CommandRemove,
|
||||||
|
CommandRemoveMultiple,
|
||||||
|
CommandRemoveWithoutCount,
|
||||||
CommandSave,
|
CommandSave,
|
||||||
CommandSaveAs,
|
CommandSaveAs,
|
||||||
|
CommandShootArrow,
|
||||||
|
CommandUnequip,
|
||||||
CommandUse
|
CommandUse
|
||||||
} from "./Command";
|
} from "./Command";
|
||||||
import { Item, ItemStack } from "./Item";
|
import { Item, ItemStack } from "./Item";
|
||||||
|
@ -21,23 +31,9 @@ export const parseCommand = (cmdString: string): Command | undefined => {
|
||||||
return new CommandNothing();
|
return new CommandNothing();
|
||||||
}
|
}
|
||||||
// intialize
|
// intialize
|
||||||
if(tokens.length>1 && tokens[0] === "Initialize" && tokens.length%2 === 1){
|
if(tokens.length>1 && tokens[0] === "Initialize"){
|
||||||
const stacks: ItemStack[] = [];
|
const stacks = parseItemStacks(tokens, 1);
|
||||||
for(let i=1;i<tokens.length;i+=2){
|
return stacks ? new CommandInitialize(stacks) : undefined;
|
||||||
const count = parseInt(tokens[i]);
|
|
||||||
if(!Number.isInteger(count)){
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
const item = tokens[i+1];
|
|
||||||
if (item in Item){
|
|
||||||
stacks.push({
|
|
||||||
item: Item[item as keyof typeof Item], count, equipped:false
|
|
||||||
});
|
|
||||||
}else{
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new CommandInitialize(stacks);
|
|
||||||
}
|
}
|
||||||
// Save/Reload
|
// Save/Reload
|
||||||
if(tokens.length===1 && tokens[0] === "Save"){
|
if(tokens.length===1 && tokens[0] === "Save"){
|
||||||
|
@ -65,6 +61,121 @@ export const parseCommand = (cmdString: string): Command | undefined => {
|
||||||
return new CommandBreakSlots(slots);
|
return new CommandBreakSlots(slots);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add material
|
||||||
|
if (tokens.length === 3 && isAddVerb(tokens[0])){
|
||||||
|
const count = parseInt(tokens[1]);
|
||||||
|
const item = tokens[2];
|
||||||
|
if(Number.isInteger(count) && item in Item){
|
||||||
|
return new CommandAdd(tokens[0], count, Item[item as keyof typeof Item]);
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
if (tokens.length === 2 && isAddVerb(tokens[0])){
|
||||||
|
const item = tokens[1];
|
||||||
|
if(item in Item){
|
||||||
|
return new CommandAddWithoutCount(tokens[0], Item[item as keyof typeof Item]);
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
if(tokens.length>2 && isAddVerb(tokens[0])){
|
||||||
|
const stacks = parseItemStacks(tokens, 1);
|
||||||
|
return stacks ? new CommandAddMultiple(tokens[0], stacks) : undefined;
|
||||||
|
}
|
||||||
|
// remove X item From Slot Y
|
||||||
|
if (tokens.length === 6 && isRemoveVerb(tokens[0]) && tokens[3] === "From" && tokens[4] ==="Slot" ){
|
||||||
|
const count = parseInt(tokens[1]);
|
||||||
|
const item = tokens[2];
|
||||||
|
const slot = parseInt(tokens[5]);
|
||||||
|
if(Number.isInteger(count) && Number.isInteger(slot) && item in Item){
|
||||||
|
return new CommandRemove(tokens[0], count, Item[item as keyof typeof Item], slot-1, false);
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
// remove X item
|
||||||
|
if (tokens.length === 3 && isRemoveVerb(tokens[0]) ){
|
||||||
|
const count = parseInt(tokens[1]);
|
||||||
|
const item = tokens[2];
|
||||||
|
if(Number.isInteger(count) && item in Item){
|
||||||
|
return new CommandRemove(tokens[0], count, Item[item as keyof typeof Item], 0, true);
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
// remove item From Slot Y
|
||||||
|
if (tokens.length === 5 && isRemoveVerb(tokens[0]) && tokens[2] === "From" && tokens[3] ==="Slot" ){
|
||||||
|
const item = tokens[1];
|
||||||
|
const slot = parseInt(tokens[4]);
|
||||||
|
if(Number.isInteger(slot) && item in Item){
|
||||||
|
return new CommandRemoveWithoutCount(tokens[0], Item[item as keyof typeof Item], slot-1, false);
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
// remove item
|
||||||
|
if (tokens.length === 2 && isRemoveVerb(tokens[0]) ){
|
||||||
|
const item = tokens[1];
|
||||||
|
if(item in Item){
|
||||||
|
return new CommandRemoveWithoutCount(tokens[0], Item[item as keyof typeof Item], 0, true);
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
// remove multiple
|
||||||
|
if(tokens.length>2 && isRemoveVerb(tokens[0])){
|
||||||
|
const stacks = parseItemStacks(tokens, 1);
|
||||||
|
return stacks ? new CommandRemoveMultiple(tokens[0], stacks) : undefined;
|
||||||
|
}
|
||||||
|
//Shortcut for drop and pick up
|
||||||
|
if (tokens.length === 3 && tokens[0] === "D&P" ){
|
||||||
|
const count = parseInt(tokens[1]);
|
||||||
|
const item = tokens[2];
|
||||||
|
if(Number.isInteger(count) && item in Item){
|
||||||
|
return new CommandDaP(count, Item[item as keyof typeof Item]);
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Equip item In Slot X
|
||||||
|
if (tokens.length === 5 && tokens[0] === "Equip" && tokens[2] === "In" && tokens[3] ==="Slot" ){
|
||||||
|
const item = tokens[1];
|
||||||
|
const slot = parseInt(tokens[4]);
|
||||||
|
if( Number.isInteger(slot) && item in Item){
|
||||||
|
return new CommandEquip(Item[item as keyof typeof Item], slot-1, false);
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
// Equip item
|
||||||
|
if (tokens.length === 2 && tokens[0] === "Equip"){
|
||||||
|
const item = tokens[1];
|
||||||
|
if( item in Item){
|
||||||
|
return new CommandEquip(Item[item as keyof typeof Item], 0, true);
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
// Unequip item in slot X
|
||||||
|
if (tokens.length === 5 && tokens[0] === "Unequip" && tokens[2] === "In" && tokens[3] ==="Slot" ){
|
||||||
|
const item = tokens[1];
|
||||||
|
const slot = parseInt(tokens[4]);
|
||||||
|
if( Number.isInteger(slot) && item in Item){
|
||||||
|
return new CommandUnequip(Item[item as keyof typeof Item], slot-1, false);
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
// Unequip item
|
||||||
|
if (tokens.length === 2 && tokens[0] === "Unequip"){
|
||||||
|
const item = tokens[1];
|
||||||
|
if( item in Item){
|
||||||
|
return new CommandUnequip(Item[item as keyof typeof Item], -1, true);
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
// Shoot X Arrow
|
||||||
|
if (tokens.length === 3 && tokens[0] === "Shoot" && tokens[2] === "Arrow"){
|
||||||
|
const count = parseInt(tokens[1]);
|
||||||
|
if( Number.isInteger(count) ){
|
||||||
|
return new CommandShootArrow(count);
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
// if(tokens.length===2 && tokens[0] === "Sort" && tokens[1] === "Key"){
|
// if(tokens.length===2 && tokens[0] === "Sort" && tokens[1] === "Key"){
|
||||||
// return new CommandSortKey();
|
// return new CommandSortKey();
|
||||||
// }
|
// }
|
||||||
|
@ -78,80 +189,10 @@ export const parseCommand = (cmdString: string): Command | undefined => {
|
||||||
// return undefined;
|
// return undefined;
|
||||||
// }
|
// }
|
||||||
// // remove material
|
// // remove material
|
||||||
// if (tokens.length === 6 && (tokens[0] === "Remove" || tokens[0] === "Sell" || tokens[0] === "Drop"|| tokens[0] === "Eat") && tokens[3] === "From" && tokens[4] ==="Slot" ){
|
|
||||||
// const count = parseInt(tokens[1]);
|
|
||||||
// const item = tokens[2];
|
|
||||||
// const slot = parseInt(tokens[5]);
|
|
||||||
// if(Number.isInteger(count) && Number.isInteger(slot) && item in Item){
|
|
||||||
// return new CommandRemoveMaterial(tokens[0], count, Item[item as keyof typeof Item], slot-1, false);
|
|
||||||
// }
|
|
||||||
// return undefined;
|
|
||||||
// }
|
|
||||||
// if (tokens.length === 3 && (tokens[0] === "Remove" || tokens[0] === "Sell" || tokens[0] === "Drop"|| tokens[0] === "Eat")){
|
|
||||||
// const count = parseInt(tokens[1]);
|
|
||||||
// const item = tokens[2];
|
|
||||||
// if(Number.isInteger(count) && item in Item){
|
|
||||||
// return new CommandRemoveMaterial(tokens[0], count, Item[item as keyof typeof Item], 0, true);
|
|
||||||
// }
|
|
||||||
// return undefined;
|
|
||||||
// }
|
|
||||||
// // remove 1 material
|
|
||||||
// if (tokens.length === 5 && (tokens[0] === "Remove" || tokens[0] === "Sell" || tokens[0] === "Eat") && tokens[2] === "From" && tokens[3] ==="Slot" ){
|
|
||||||
// const item = tokens[1];
|
|
||||||
// const slot = parseInt(tokens[4]);
|
|
||||||
// if(Number.isInteger(slot) && item in Item){
|
|
||||||
// return new CommandRemoveUnstackableMaterial(tokens[0], Item[item as keyof typeof Item], slot-1, false);
|
|
||||||
// }
|
|
||||||
// return undefined;
|
|
||||||
// }
|
|
||||||
// if (tokens.length === 2 && (tokens[0] === "Remove" || tokens[0] === "Sell" || tokens[0] === "Eat")){
|
|
||||||
// const item = tokens[1];
|
|
||||||
// if(item in Item){
|
|
||||||
// return new CommandRemoveUnstackableMaterial(tokens[0], Item[item as keyof typeof Item], 0, true);
|
|
||||||
// }
|
|
||||||
// return undefined;
|
|
||||||
// }
|
|
||||||
// // add material
|
|
||||||
// if (tokens.length === 3 && (tokens[0] === "Get" || tokens[0] === "Cook" || tokens[0] === "Add" || tokens[0] === "Pickup")){
|
|
||||||
// const count = parseInt(tokens[1]);
|
|
||||||
// const item = tokens[2];
|
|
||||||
// if(Number.isInteger(count) && item in Item){
|
|
||||||
// return new CommandAddMaterial(tokens[0], count, Item[item as keyof typeof Item]);
|
|
||||||
// }
|
|
||||||
// return undefined;
|
|
||||||
// }
|
|
||||||
// // Equip Equipment
|
|
||||||
// if (tokens.length === 5 && tokens[0] === "Equip" && tokens[2] === "In" && tokens[3] ==="Slot" ){
|
|
||||||
// const item = tokens[1];
|
|
||||||
// const slot = parseInt(tokens[4]);
|
|
||||||
// if( Number.isInteger(slot) && item in Item){
|
|
||||||
// return new CommandEquip(Item[item as keyof typeof Item], slot-1, false);
|
|
||||||
// }
|
|
||||||
// return undefined;
|
|
||||||
// }
|
|
||||||
// if (tokens.length === 2 && tokens[0] === "Equip"){
|
|
||||||
// const item = tokens[1];
|
|
||||||
// if( item in Item){
|
|
||||||
// return new CommandEquip(Item[item as keyof typeof Item], 0, true);
|
|
||||||
// }
|
|
||||||
// return undefined;
|
|
||||||
// }
|
|
||||||
// // Unequip Equipment
|
|
||||||
// if (tokens.length === 5 && tokens[0] === "Unequip" && tokens[2] === "In" && tokens[3] ==="Slot" ){
|
|
||||||
// const item = tokens[1];
|
|
||||||
// const slot = parseInt(tokens[4]);
|
|
||||||
// if( Number.isInteger(slot) && item in Item){
|
|
||||||
// return new CommandUnequip(Item[item as keyof typeof Item], slot-1, false);
|
|
||||||
// }
|
|
||||||
// return undefined;
|
|
||||||
// }
|
|
||||||
// if (tokens.length === 2 && tokens[0] === "Unequip"){
|
|
||||||
// const item = tokens[1];
|
|
||||||
// if( item in Item){
|
|
||||||
// return new CommandUnequip(Item[item as keyof typeof Item], -1, true);
|
|
||||||
// }
|
|
||||||
// return undefined;
|
|
||||||
// }
|
|
||||||
// // Equip Arrow
|
// // Equip Arrow
|
||||||
// if (tokens.length === 6 && tokens[0] === "Equip" && tokens[2] === "Arrow" && tokens[3] === "In" && tokens[4] ==="Slot" ){
|
// if (tokens.length === 6 && tokens[0] === "Equip" && tokens[2] === "Arrow" && tokens[3] === "In" && tokens[4] ==="Slot" ){
|
||||||
// const item = tokens[1]+"Arrow";
|
// const item = tokens[1]+"Arrow";
|
||||||
|
@ -171,3 +212,34 @@ export const parseCommand = (cmdString: string): Command | undefined => {
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isAddVerb = (token: string): boolean => {
|
||||||
|
return token === "Get" || token === "Cook" || token === "Add" || token === "Pickup"
|
||||||
|
}
|
||||||
|
|
||||||
|
const isRemoveVerb = (token: string): boolean => {
|
||||||
|
return token === "Remove" || token === "Sell" || token === "Eat" || token === "Drop"
|
||||||
|
}
|
||||||
|
|
||||||
|
const parseItemStacks = (tokens: string[], from: number): ItemStack[] | undefined => {
|
||||||
|
if((tokens.length-from)%2 !== 0){
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const stacks: ItemStack[] = [];
|
||||||
|
for(let i=from;i<tokens.length;i+=2){
|
||||||
|
const count = parseInt(tokens[i]);
|
||||||
|
if(!Number.isInteger(count)){
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
const item = tokens[i+1];
|
||||||
|
if (item in Item){
|
||||||
|
stacks.push({
|
||||||
|
item: Item[item as keyof typeof Item], count, equipped:false
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return stacks;
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { DisplayableInventory } from "./DisplayableInventory";
|
import { DisplayableInventory } from "./DisplayableInventory";
|
||||||
import { GameData } from "./GameData";
|
import { GameData } from "./GameData";
|
||||||
import { ItemStack } from "./Item";
|
import { Item, ItemStack } from "./Item";
|
||||||
import { Slots } from "./Slots";
|
import { Slots } from "./Slots";
|
||||||
import { VisibleInventory } from "./VisibleInventory";
|
import { VisibleInventory } from "./VisibleInventory";
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ export class SimulationState {
|
||||||
private namedSaves: {[name: string]: GameData} = {};
|
private namedSaves: {[name: string]: GameData} = {};
|
||||||
private pouch: VisibleInventory;
|
private pouch: VisibleInventory;
|
||||||
private nextReloadName?: string;
|
private nextReloadName?: string;
|
||||||
|
private isOnEventide: boolean = false;
|
||||||
|
|
||||||
constructor(gameData: GameData, manualSave: GameData | null, namedSaves: {[name: string]: GameData}, pouch: VisibleInventory){
|
constructor(gameData: GameData, manualSave: GameData | null, namedSaves: {[name: string]: GameData}, pouch: VisibleInventory){
|
||||||
this.gameData = gameData;
|
this.gameData = gameData;
|
||||||
|
@ -34,12 +35,16 @@ export class SimulationState {
|
||||||
for(const name in this.namedSaves){
|
for(const name in this.namedSaves){
|
||||||
copyNamedSaves[name] = this.namedSaves[name].deepClone();
|
copyNamedSaves[name] = this.namedSaves[name].deepClone();
|
||||||
}
|
}
|
||||||
return new SimulationState(
|
const newState = new SimulationState(
|
||||||
this.gameData.deepClone(),
|
this.gameData.deepClone(),
|
||||||
this.manualSave ? this.manualSave.deepClone() : null,
|
this.manualSave ? this.manualSave.deepClone() : null,
|
||||||
copyNamedSaves,
|
copyNamedSaves,
|
||||||
this.pouch.deepClone()
|
this.pouch.deepClone()
|
||||||
);
|
);
|
||||||
|
newState.nextReloadName = this.nextReloadName;
|
||||||
|
newState.isOnEventide = this.isOnEventide;
|
||||||
|
|
||||||
|
return newState;
|
||||||
}
|
}
|
||||||
|
|
||||||
public initialize(stacks: ItemStack[]) {
|
public initialize(stacks: ItemStack[]) {
|
||||||
|
@ -79,6 +84,7 @@ export class SimulationState {
|
||||||
this.gameData = data.deepClone();
|
this.gameData = data.deepClone();
|
||||||
this.pouch.clearForReload();
|
this.pouch.clearForReload();
|
||||||
this.gameData.addAllToPouchOnReload(this.pouch);
|
this.gameData.addAllToPouchOnReload(this.pouch);
|
||||||
|
this.pouch.updateEquipmentDurability(this.gameData);
|
||||||
}
|
}
|
||||||
|
|
||||||
public useSaveForNextReload(name: string){
|
public useSaveForNextReload(name: string){
|
||||||
|
@ -89,6 +95,37 @@ export class SimulationState {
|
||||||
this.pouch.modifyCount(-n);
|
this.pouch.modifyCount(-n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public obtain(item: Item, count: number) {
|
||||||
|
this.pouch.addInGame(item, count);
|
||||||
|
this.syncGameDataWithPouch();
|
||||||
|
}
|
||||||
|
|
||||||
|
public remove(item: Item, count: number, slot: number) {
|
||||||
|
this.pouch.remove(item, count, slot);
|
||||||
|
this.syncGameDataWithPouch();
|
||||||
|
}
|
||||||
|
|
||||||
|
public equip(item: Item, slot: number) {
|
||||||
|
this.pouch.equip(item, slot);
|
||||||
|
this.syncGameDataWithPouch();
|
||||||
|
}
|
||||||
|
|
||||||
|
public unequip(item: Item, slot: number){
|
||||||
|
this.pouch.unequip(item, slot);
|
||||||
|
this.syncGameDataWithPouch();
|
||||||
|
}
|
||||||
|
|
||||||
|
public shootArrow(count: number){
|
||||||
|
this.pouch.shootArrow(count, this.gameData);
|
||||||
|
// does not sync
|
||||||
|
}
|
||||||
|
|
||||||
|
public syncGameDataWithPouch() {
|
||||||
|
if(!this.isOnEventide){
|
||||||
|
this.gameData.syncWith(this.pouch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public get displayableGameData(): DisplayableInventory {
|
public get displayableGameData(): DisplayableInventory {
|
||||||
return this.gameData;
|
return this.gameData;
|
||||||
}
|
}
|
||||||
|
@ -116,21 +153,13 @@ export class SimulationState {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save - save to hard save slot
|
|
||||||
// Save As <name> - save to a auto save slot
|
|
||||||
// Reload - reload hard save
|
|
||||||
// Reload <name> - reload a named auto save
|
|
||||||
// Use <name> - no effect, but next Reload reloads the named auto save
|
|
||||||
// Break X Slots
|
|
||||||
// Sort Key (In Tab X)
|
|
||||||
// Sort Material (In Tab X)
|
|
||||||
// Get/Add/Cook/Pickup X <item>, X can be omitted and default to 1
|
|
||||||
// Get/Add/Cook/Pickup X <item> Y <item2> ...
|
|
||||||
// Remove/Drop/Sell/Eat X <item> From Slot Y, X can be omitted and default to 1
|
|
||||||
// Remove/Drop/Sell/Eat X <item1> Y <item2> ...
|
|
||||||
// D&P X <item>, drop and pick up (to sort)
|
|
||||||
// Equip <item> (In Slot X)
|
|
||||||
// Unequip <item> (In Slot X), without slot, it unequipps the first equipped
|
|
||||||
// Shoot X Arrow, x can be ommited and default to 1
|
// Shoot X Arrow, x can be ommited and default to 1
|
||||||
|
|
||||||
// Close Game
|
// Close Game
|
||||||
// Close Inventory, same as Resync GameData
|
// Close Inventory, same as Resync GameData
|
||||||
|
// Enter Eventide / Leave Eventide
|
||||||
|
// Sort Key (In Tab X) - need more research on which tab is sorted. (might not be possible to select which tab to sort)
|
||||||
|
// Sort Material (In Tab X) - need more research on which tab is sorted
|
||||||
|
|
|
@ -61,7 +61,7 @@ export class Slots {
|
||||||
public addStackDirectly(stack: ItemStack): number {
|
public addStackDirectly(stack: ItemStack): number {
|
||||||
const data = itemToItemData(stack.item);
|
const data = itemToItemData(stack.item);
|
||||||
if(data.stackable){
|
if(data.stackable){
|
||||||
this.internalSlots.push(stack);
|
this.internalSlots.push({...stack});
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
for(let i=0;i<stack.count;i++){
|
for(let i=0;i<stack.count;i++){
|
||||||
|
@ -70,7 +70,7 @@ export class Slots {
|
||||||
return stack.count;
|
return stack.count;
|
||||||
}
|
}
|
||||||
public addSlot(stack: ItemStack, mCount: number | null) {
|
public addSlot(stack: ItemStack, mCount: number | null) {
|
||||||
this.internalSlots.push(stack);
|
this.internalSlots.push({...stack});
|
||||||
this.sortItemType(mCount);
|
this.sortItemType(mCount);
|
||||||
}
|
}
|
||||||
// public addStackCopy(stack: ItemStack) {
|
// public addStackCopy(stack: ItemStack) {
|
||||||
|
@ -85,27 +85,33 @@ export class Slots {
|
||||||
// const end = this.internalSlots.splice(-count, count);
|
// const end = this.internalSlots.splice(-count, count);
|
||||||
// return new Slots(end);
|
// return new Slots(end);
|
||||||
// }
|
// }
|
||||||
// public remove(item: Item, count: number, slot: number) {
|
|
||||||
// let s = 0;
|
// remove item(s) start from slot
|
||||||
// for(let i = 0; i<this.internalSlots.length && count > 0;i++){
|
// return number of slots removed
|
||||||
// if(this.internalSlots[i].item === item){
|
public remove(item: Item, count: number, slot: number): number {
|
||||||
// if(s<slot){
|
const oldLength = this.internalSlots.length;
|
||||||
// s++;
|
let s = 0;
|
||||||
// }else{
|
for(let i = 0; i<this.internalSlots.length && count > 0;i++){
|
||||||
// if(this.internalSlots[i].count<count){
|
if(this.internalSlots[i].item === item){
|
||||||
// count-=this.internalSlots[i].count;
|
if(s<slot){
|
||||||
// this.internalSlots[i].count=0;
|
s++;
|
||||||
|
}else{
|
||||||
|
if(this.internalSlots[i].count<count){
|
||||||
|
count-=this.internalSlots[i].count;
|
||||||
|
this.internalSlots[i].count=0;
|
||||||
|
|
||||||
// }else{
|
}else{
|
||||||
// this.internalSlots[i].count-=count;
|
this.internalSlots[i].count-=count;
|
||||||
// break;
|
break;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// this.internalSlots = this.internalSlots.filter(({count})=>count>0);
|
|
||||||
// }
|
this.internalSlots = this.internalSlots.filter(({count})=>count>0);
|
||||||
|
return oldLength-this.internalSlots.length;
|
||||||
|
}
|
||||||
|
|
||||||
// Add something to inventory in game
|
// Add something to inventory in game
|
||||||
// returns number of slots added
|
// returns number of slots added
|
||||||
|
@ -153,140 +159,140 @@ export class Slots {
|
||||||
|
|
||||||
// Checks finish, do add new slot
|
// Checks finish, do add new slot
|
||||||
if(data.stackable){
|
if(data.stackable){
|
||||||
if(data.type===ItemType.Arrow){
|
if(reloading){
|
||||||
// if currently equipped arrow == 0. new arrows are equiped
|
this.addSlot({item,count,equipped:equippedDuringReload}, mCount+1);
|
||||||
// TODO: botw needs more testing on how arrows are handled in various cases
|
|
||||||
const shouldEquipNew = this.internalSlots.filter(s=>{
|
|
||||||
const sData = itemToItemData(s.item);
|
|
||||||
return sData.type === data.type && s.equipped && s.count > 0;
|
|
||||||
}).length === 0;
|
|
||||||
this.addSlot({item,count,equipped:shouldEquipNew}, mCount+1);
|
|
||||||
}else{
|
}else{
|
||||||
this.addSlot({item,count,equipped:false}, mCount+1);
|
if(data.type===ItemType.Arrow){
|
||||||
|
// if currently equipped arrow == 0. new arrows are equiped
|
||||||
|
// TODO: botw needs more testing on how arrows are handled in various cases
|
||||||
|
const shouldEquipNew = this.internalSlots.filter(s=>{
|
||||||
|
const sData = itemToItemData(s.item);
|
||||||
|
return sData.type === data.type && s.equipped && s.count > 0;
|
||||||
|
}).length === 0;
|
||||||
|
this.addSlot({item,count,equipped:shouldEquipNew}, mCount+1);
|
||||||
|
}else{
|
||||||
|
this.addSlot({item,count,equipped:false}, mCount+1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(data.type===ItemType.Weapon || data.type===ItemType.Bow || data.type===ItemType.Shield){
|
if(reloading){
|
||||||
//Check equip
|
for(let i=0;i<count;i++){
|
||||||
const shouldEquipNew = !reloading && this.internalSlots.filter(s=>{
|
this.addSlot({item,count:1,equipped: equippedDuringReload}, mCount+i+1);
|
||||||
const sData = itemToItemData(s.item);
|
|
||||||
return sData.type === data.type && s.equipped;
|
|
||||||
}).length === 0;
|
|
||||||
this.addSlot({item,count:1,equipped: shouldEquipNew}, mCount+1);
|
|
||||||
for(let i=1;i<count;i++){
|
|
||||||
this.addSlot({item,count:1,equipped: false}, mCount+i+1);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
for(let i=0;i<count;i++){
|
if(data.type===ItemType.Weapon || data.type===ItemType.Bow || data.type===ItemType.Shield){
|
||||||
this.addSlot({item,count:1,equipped: false}, mCount+i+1);
|
//Check equip
|
||||||
|
const shouldEquipNew = this.internalSlots.filter(s=>{
|
||||||
|
const sData = itemToItemData(s.item);
|
||||||
|
return sData.type === data.type && s.equipped;
|
||||||
|
}).length === 0;
|
||||||
|
this.addSlot({item,count:1,equipped: shouldEquipNew}, mCount+1);
|
||||||
|
for(let i=1;i<count;i++){
|
||||||
|
this.addSlot({item,count:1,equipped: false}, mCount+i+1);
|
||||||
|
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
for(let i=0;i<count;i++){
|
||||||
|
this.addSlot({item,count:1,equipped: false}, mCount+i+1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return how many slots are added
|
|
||||||
// public add(item: Item, count: number, equipped: boolean, isReloading: boolean, mCount: number): number {
|
|
||||||
// let added = false;
|
|
||||||
// const data = itemToItemData(item);
|
|
||||||
// if(data.stackable){
|
|
||||||
// for(let i = 0; i<this.internalSlots.length;i++){
|
|
||||||
// if(this.internalSlots[i].item === item){
|
|
||||||
// if(isReloading){
|
|
||||||
// if(mCount > 0 && this.internalSlots[i].count + count > 999){
|
|
||||||
// return 0; // Skip, do not add new stack at all
|
|
||||||
// }
|
|
||||||
// // Otherwise push the entire new stack
|
|
||||||
// this.internalSlots.push({item, count, equipped});
|
|
||||||
// }else{
|
|
||||||
// this.internalSlots[i].count = Math.min(999, this.internalSlots[i].count+count);
|
|
||||||
// added = true;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if(!added){
|
|
||||||
// const after = this.removeFromEnd(this.getAfterType(data.type).length);
|
|
||||||
// if(data.stackable){
|
|
||||||
// if(data.type===ItemType.Arrow){
|
|
||||||
// // if currently equipped arrow == 0. new arrows are equiped
|
|
||||||
// const shouldEquipNew = this.internalSlots.filter(s=>{
|
|
||||||
// const sData = itemToItemData(s.item);
|
|
||||||
// return sData.type === data.type && s.equipped && s.count > 0;
|
|
||||||
// }).length === 0;
|
|
||||||
// this.addStack({item,count,equipped:shouldEquipNew});
|
|
||||||
// }else{
|
|
||||||
// this.addStack({item,count,equipped:false});
|
|
||||||
// }
|
|
||||||
|
|
||||||
// }else{
|
|
||||||
// if(data.type===ItemType.Weapon || data.type===ItemType.Bow || data.type===ItemType.Shield){
|
|
||||||
// //Check equip
|
|
||||||
// const shouldEquipNew = this.internalSlots.filter(s=>{
|
|
||||||
// const sData = itemToItemData(s.item);
|
|
||||||
// return sData.type === data.type && s.equipped;
|
|
||||||
// }).length === 0;
|
|
||||||
// this.addStack({item,count:1,equipped: shouldEquipNew});
|
|
||||||
// for(let i=1;i<count;i++){
|
|
||||||
// this.addStack({item,count:1,equipped: false});
|
|
||||||
|
|
||||||
// }
|
// this is for both equipments and arrows
|
||||||
// }else{
|
public equip(item: Item, slot: number) {
|
||||||
// for(let i=0;i<count;i++){
|
let s = 0;
|
||||||
// this.addStack({item,count:1,equipped: false});
|
// unequip same type in first tab
|
||||||
// }
|
const type = itemToItemData(item).type;
|
||||||
// }
|
let i=0;
|
||||||
|
while(i<this.internalSlots.length && itemToItemData(this.internalSlots[i].item).type < type){
|
||||||
// }
|
i++;
|
||||||
|
}
|
||||||
|
for(;i<this.internalSlots.length && itemToItemData(this.internalSlots[i].item).type === type;i++){
|
||||||
|
this.internalSlots[i].equipped = false;
|
||||||
|
}
|
||||||
|
// now search for the one the player selects and equip it
|
||||||
|
for(let i = 0; i<this.internalSlots.length;i++){
|
||||||
|
if(this.internalSlots[i].item === item){
|
||||||
|
if (s===slot){
|
||||||
|
this.internalSlots[i].equipped=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public unequip(item:Item, slot: number) {
|
||||||
|
let s = 0;
|
||||||
|
const type = itemToItemData(item).type;
|
||||||
|
if (type===ItemType.Arrow){
|
||||||
|
return; // cannot unequip arrow
|
||||||
|
}
|
||||||
|
for(let i = 0; i<this.internalSlots.length;i++){
|
||||||
|
if(this.internalSlots[i].item === item){
|
||||||
|
if(slot < 0){
|
||||||
|
if(this.internalSlots[i].equipped){
|
||||||
|
this.internalSlots[i].equipped=false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if(s<slot){
|
||||||
|
s++;
|
||||||
|
}else{
|
||||||
|
this.internalSlots[i].equipped=false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// this.addSlotsToEnd(after);
|
public corrupt(durability: number, slot: number) {
|
||||||
// }
|
if(slot < 0 || slot >= this.internalSlots.length){
|
||||||
// }
|
return;
|
||||||
|
}
|
||||||
|
const thisData = itemToItemData(this.internalSlots[slot].item);
|
||||||
|
if(thisData.stackable){
|
||||||
|
this.internalSlots[slot].count = durability;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// // this is for both equipments and arrows
|
// shoot count arrows. return the slot that was updated, or -1
|
||||||
// public equip(item: Item, slot: number) {
|
public shootArrow(count: number): number {
|
||||||
// let s = 0;
|
// first find equipped arrow, search entire inventory
|
||||||
// const type = itemToItemData(item).type;
|
let i=0;
|
||||||
// const filtered = this.internalSlots.filter(s=>itemToItemData(s.item).type === type);
|
for(;i<this.internalSlots.length;i++){
|
||||||
// for(let i = 0; i<filtered.length;i++){
|
if(this.internalSlots[i].equipped){
|
||||||
// filtered[i].equipped=false;
|
const data = itemToItemData(this.internalSlots[i].item);
|
||||||
// if(filtered[i].item === item){
|
if(data.type === ItemType.Arrow){
|
||||||
// if (s===slot){
|
break;
|
||||||
// filtered[i].equipped=true;
|
}
|
||||||
// }
|
}
|
||||||
// s++;
|
}
|
||||||
// }
|
if(i>=this.internalSlots.length){
|
||||||
// }
|
//can't find equipped arrow
|
||||||
// }
|
return -1;
|
||||||
// public unequip(item:Item, slot: number) {
|
}
|
||||||
// let s = 0;
|
const equippedArrow = this.internalSlots[i].item;
|
||||||
// const type = itemToItemData(item).type;
|
// now find the first slot of that arrow and update
|
||||||
// if (type===ItemType.Arrow){
|
for(let j=0;j<this.internalSlots.length;j++){
|
||||||
// return; // cannot unequip arrow
|
if(this.internalSlots[j].item === equippedArrow){
|
||||||
// }
|
this.internalSlots[j].count = Math.max(0, this.internalSlots[j].count-count);
|
||||||
// for(let i = 0; i<this.internalSlots.length;i++){
|
return j;
|
||||||
// if(this.internalSlots[i].item === item){
|
}
|
||||||
// if(slot < 0){
|
}
|
||||||
// if(this.internalSlots[i].equipped){
|
//for some reason cannot find that arrow now?
|
||||||
// this.internalSlots[i].equipped=false;
|
return -1;
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }else{
|
|
||||||
// if(s<slot){
|
|
||||||
// s++;
|
|
||||||
// }else{
|
|
||||||
// this.internalSlots[i].equipped=false;
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
}
|
||||||
// // Difference between shoot and remove:
|
// // Difference between shoot and remove:
|
||||||
// // 1. can only be from first (leftmost) slot
|
// // 1. can only be from first (leftmost) slot
|
||||||
// // 2. empty slots not removed
|
// // 2. empty slots not removed
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { DisplayableInventory, DisplayableSlot, itemStackToDisplayableSlot } from "./DisplayableInventory";
|
import { DisplayableInventory, DisplayableSlot, itemStackToDisplayableSlot } from "./DisplayableInventory";
|
||||||
import { Item, ItemStack } from "./Item";
|
import { GameData } from "./GameData";
|
||||||
|
import { Item, ItemStack, itemToItemData, ItemType } from "./Item";
|
||||||
import { Slots } from "./Slots";
|
import { Slots } from "./Slots";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -35,7 +36,23 @@ export class VisibleInventory implements DisplayableInventory{
|
||||||
this.count+=slotsAdded;
|
this.count+=slotsAdded;
|
||||||
}
|
}
|
||||||
|
|
||||||
//public addInGame
|
public addInGame(item: Item, count: number) {
|
||||||
|
const slotsAdded = this.slots.add(item, count, false, false, this.count);
|
||||||
|
this.count+=slotsAdded;
|
||||||
|
}
|
||||||
|
|
||||||
|
public remove(item: Item, count: number, slot: number) {
|
||||||
|
const slotsRemoved = this.slots.remove(item, count, slot);
|
||||||
|
this.count-=slotsRemoved;
|
||||||
|
}
|
||||||
|
|
||||||
|
public equip(item: Item, slot: number) {
|
||||||
|
this.slots.equip(item, slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
public unequip(item: Item, slot: number) {
|
||||||
|
this.slots.unequip(item, slot);
|
||||||
|
}
|
||||||
|
|
||||||
// Only clears first this.count
|
// Only clears first this.count
|
||||||
public clearForReload() {
|
public clearForReload() {
|
||||||
|
@ -45,6 +62,38 @@ export class VisibleInventory implements DisplayableInventory{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public updateEquipmentDurability(gameData: GameData) {
|
||||||
|
// find first weapon/bow/shield. this one searches entire inventory
|
||||||
|
let foundWeapon = false;
|
||||||
|
let foundBow = false;
|
||||||
|
let foundShield = false;
|
||||||
|
this.slots.getSlotsRef().forEach(({item, equipped}, i)=>{
|
||||||
|
if(equipped){
|
||||||
|
const type = itemToItemData(item).type;
|
||||||
|
if(type === ItemType.Weapon && !foundWeapon){
|
||||||
|
gameData.updateDurability(999, i);
|
||||||
|
foundWeapon = true;
|
||||||
|
}
|
||||||
|
if(type === ItemType.Bow && !foundBow){
|
||||||
|
gameData.updateDurability(999, i);
|
||||||
|
foundBow = true;
|
||||||
|
}
|
||||||
|
if(type === ItemType.Shield && !foundShield){
|
||||||
|
gameData.updateDurability(999, i);
|
||||||
|
foundShield = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
public shootArrow(count: number, gameData: GameData) {
|
||||||
|
const updatedSlot = this.slots.shootArrow(count);
|
||||||
|
if(updatedSlot>=0){
|
||||||
|
const durability = this.slots.getSlotsRef()[updatedSlot].count;
|
||||||
|
gameData.updateDurability(durability, updatedSlot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public getCount(): number {
|
public getCount(): number {
|
||||||
return this.count;
|
return this.count;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,66 +0,0 @@
|
||||||
export {};
|
|
||||||
// import { Command, CommandAddMaterial, CommandBreakSlots, CommandInitialize, CommandNothing, CommandReload, CommandRemoveMaterial, CommandRemoveUnstackableMaterial, CommandSave, CommandSortKey, CommandSortMaterial } from "./Command";
|
|
||||||
// import { Item } from "./Item";
|
|
||||||
|
|
||||||
// const Buffer = require("buffer/").Buffer; /* eslint-disable-line @typescript-eslint/no-var-requires*/
|
|
||||||
|
|
||||||
// export const serializeCommands = (commands: Command[]): string => {
|
|
||||||
// const sizeBuf: Buffer = Buffer.alloc(4);
|
|
||||||
// sizeBuf.writeInt32LE(commands.length);
|
|
||||||
|
|
||||||
// const commandBuffers = commands.map(c=>c.toBuffer());
|
|
||||||
// const allBufs = Buffer.concat([sizeBuf, ...commandBuffers]);
|
|
||||||
|
|
||||||
// return allBufs.toString("base64");
|
|
||||||
// };
|
|
||||||
|
|
||||||
// export const deserialzeCommands = (base64str: string): Command[] => {
|
|
||||||
// const buf: Buffer = Buffer.from(base64str, "base64");
|
|
||||||
// const size = buf.readInt32LE();
|
|
||||||
// let off = 4;
|
|
||||||
// const commands: Command[] = [];
|
|
||||||
// for(let i=0;i<size;i++){
|
|
||||||
// const op = buf.readUInt8(off);
|
|
||||||
// off++;
|
|
||||||
// let command: Command | undefined = undefined;
|
|
||||||
// switch(op){
|
|
||||||
// case CommandNothing.Op:
|
|
||||||
// command = new CommandNothing();
|
|
||||||
// break;
|
|
||||||
// case CommandInitialize.Op:
|
|
||||||
// command = new CommandInitialize([]);
|
|
||||||
// break;
|
|
||||||
// case CommandBreakSlots.Op:
|
|
||||||
// command = new CommandBreakSlots(0);
|
|
||||||
// break;
|
|
||||||
// case CommandSave.Op:
|
|
||||||
// command = new CommandSave();
|
|
||||||
// break;
|
|
||||||
// case CommandReload.Op:
|
|
||||||
// command = new CommandReload();
|
|
||||||
// break;
|
|
||||||
// case CommandSortKey.Op:
|
|
||||||
// command = new CommandSortKey();
|
|
||||||
// break;
|
|
||||||
// case CommandSortMaterial.Op:
|
|
||||||
// command = new CommandSortMaterial();
|
|
||||||
// break;
|
|
||||||
// case CommandRemoveMaterial.Op:
|
|
||||||
// command = new CommandRemoveMaterial("",0,Item.Slate,0);
|
|
||||||
// break;
|
|
||||||
// case CommandRemoveUnstackableMaterial.Op:
|
|
||||||
// command = new CommandRemoveUnstackableMaterial("", Item.Slate, 0);
|
|
||||||
// break;
|
|
||||||
// case CommandAddMaterial.Op:
|
|
||||||
// command = new CommandAddMaterial("",0,Item.Slate);
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// if(command){
|
|
||||||
// off += command.fromBuffer(buf.slice(off));
|
|
||||||
// commands.push(command);
|
|
||||||
// }else{
|
|
||||||
// console.error("invalid opcode: "+op);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return commands;
|
|
||||||
// };
|
|
|
@ -78,8 +78,91 @@ export const ReferencePage: React.FC = React.memo(()=>{
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p className="Reference Example">Example: Break 4 Slots</p>
|
<p className="Reference Example">Example: Break 4 Slots</p>
|
||||||
|
|
||||||
|
<h3 className="Reference">Get/Add/Cook/Pickup item</h3>
|
||||||
|
<h3 className="Reference2">Get/Add/Cook/Pickup X item</h3>
|
||||||
|
<h3 className="Reference2">Get/Add/Cook/Pickup X item1 Y item2 Z item3 ...</h3>
|
||||||
|
<h4 className="Reference">Simulate obtaining items in game</h4>
|
||||||
|
<p className="Reference">
|
||||||
|
Add the item(s) to visible inventory. Sync with Game Data unless you are on Eventide or inside TOTS
|
||||||
|
</p>
|
||||||
|
<p className="Reference">
|
||||||
|
Like in game, you won't be able to obtain multiple unstackable key items, or multiple master sword in this way.
|
||||||
|
If a stackable item is at 999 or more when you invoke this command, the count is set to 999 (not fully accurate since you won't be able to pick up more items in game).
|
||||||
|
</p>
|
||||||
|
<p className="Reference">
|
||||||
|
If you specify a count for unstackable items, they are added in different slots as if you pick them up in game, one after another.
|
||||||
|
</p>
|
||||||
|
<p className="Reference">
|
||||||
|
Note that you must not enter plural forms for the item name.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p className="Reference Example">Example 1: Add Apple</p>
|
||||||
|
<p className="Reference Example">Example 2: Get 10 Apple</p>
|
||||||
|
<p className="Reference Example">Example 3: Pickup 10 Apple 5 Diamond 1 Slate 5 MasterSword</p>
|
||||||
|
|
||||||
|
<h3 className="Reference">Remove/Sell/Eat/Drop item</h3>
|
||||||
|
<h3 className="Reference2">Remove/Sell/Eat/Drop X item</h3>
|
||||||
|
<h3 className="Reference2">Remove/Sell/Eat/Drop item From Slot Y</h3>
|
||||||
|
<h3 className="Reference2">Remove/Sell/Eat/Drop X item From Slot Y</h3>
|
||||||
|
<h3 className="Reference2">Remove/Sell/Eat/Drop X item1 Y item2 Z item3 ...</h3>
|
||||||
|
<h4 className="Reference">Simulate removing items in game</h4>
|
||||||
|
<p className="Reference">
|
||||||
|
Remove the item(s) to visible inventory. Sync with Game Data unless you are on Eventide or inside TOTS
|
||||||
|
</p>
|
||||||
|
<p className="Reference">
|
||||||
|
When number of item is not specified, it defaults to 1. Up to X items will be removed from inventory, even when they span multiple slots.
|
||||||
|
If X > total number of items in inventory, all of them will be removed.
|
||||||
|
</p>
|
||||||
|
<p className="Reference">
|
||||||
|
When slot is specified, it starts removing from slot X (slot 1 is the leftmost slot with that item, slot 2 is the second leftmost slot with that item).
|
||||||
|
</p>
|
||||||
|
<p className="Reference">
|
||||||
|
Note that you must not enter plural forms for the item name.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p className="Reference Example">Example 1: Remove Apple</p>
|
||||||
|
<p className="Reference Example">Example 2: Drop 10 Diamond</p>
|
||||||
|
<p className="Reference Example">Example 3: Sell 10 Apple 5 Diamond</p>
|
||||||
|
<p className="Reference Example">Example 4: Sell 5 Apple From Slot 3</p>
|
||||||
|
|
||||||
|
<h3 className="Reference">D&P X item</h3>
|
||||||
|
<h4 className="Reference">Shortcut for drop and pick up, for sorting inventory</h4>
|
||||||
|
<p className="Reference">
|
||||||
|
This command drops X item from the first slot, then pick them up
|
||||||
|
</p>
|
||||||
|
<p className="Reference Example">Example: D&P 5 Diamond</p>
|
||||||
|
|
||||||
|
<h3 className="Reference">Equip item</h3>
|
||||||
|
<h3 className="Reference2">Equip item In Slot X</h3>
|
||||||
|
<h4 className="Reference">Simulates equipping something</h4>
|
||||||
|
<p className="Reference">
|
||||||
|
When equipping an item, all other item of the same type in the first tab is unequipped, then the item selected is equipped.
|
||||||
|
</p>
|
||||||
|
<p className="Reference">
|
||||||
|
Slot can be used if you have multiple of the same item. When slot is not specified, the leftmost item will be equipped.
|
||||||
|
Note that you can use this command to equip something that is already equipped, which is not possible in game.
|
||||||
|
You can also equip unequippable items like materials, but it is not meaningful
|
||||||
|
</p>
|
||||||
|
<p className="Reference Example">Example 1: Equip Weapon</p>
|
||||||
|
<p className="Reference Example">Example 2: Equip Weapon In Slot 3</p>
|
||||||
|
|
||||||
|
<h3 className="Reference">Unequip item</h3>
|
||||||
|
<h3 className="Reference2">Unequip item In Slot X</h3>
|
||||||
|
<h4 className="Reference">Simulates unequipping something</h4>
|
||||||
|
<p className="Reference">
|
||||||
|
When unequipping an item, only the selected item is unequipped.
|
||||||
|
</p>
|
||||||
|
<p className="Reference">
|
||||||
|
Slot can be used if you have multiple of the same item. When slot is not specified, the leftmost equipped item will be unequipped.
|
||||||
|
Note that you can use this command to unequip something that is already unequipped, which is useless.
|
||||||
|
You cannot unequip arrows.
|
||||||
|
</p>
|
||||||
|
<p className="Reference Example">Example 1: Unequip Shield</p>
|
||||||
|
<p className="Reference Example">Example 2: Unequip Shield In Slot 5</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</TitledList>
|
</TitledList>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
Reference in a new issue