Skip to content

Commit

Permalink
add sort material super command (#26)
Browse files Browse the repository at this point in the history
  • Loading branch information
Pistonight authored Mar 29, 2024
1 parent cead194 commit 433a3bb
Show file tree
Hide file tree
Showing 10 changed files with 106 additions and 6 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "botw-ist",
"version": "3.1.5",
"version": "3.1.6",
"homepage": "https://ist.itntpiston.app/",
"private": true,
"dependencies": {
Expand Down
5 changes: 5 additions & 0 deletions src/core/SimulationState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,4 +314,9 @@ export class SimulationState {
this.pouch.swap(i,j);
}

public inaccuratelySortMaterials() {
this.pouch.inaccuratelySortMaterials();
this.syncGameDataWithPouch();
}

}
45 changes: 43 additions & 2 deletions src/core/command/ast/ast.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ const parseCommand: ParseFunction<ASTCommand> = (tokens) => {
return ParseResultFail;
};
export type ASTCommand = ASTCommandInitGameData | ASTCommandInitialize | ASTCommandCook | ASTCommandCookCrit | ASTCommandAdd | ASTCommandPickUp | ASTCommandRemoveAll | ASTCommandRemove | ASTCommandDrop | ASTCommandEat | ASTCommandDnp | ASTCommandEquip | ASTCommandUnequipAll | ASTCommandUnequip | ASTCommandShoot | ASTCommandEnterTrial | ASTCommandExitTrial | ASTCommandWriteMetadata | ASTCommandSave | ASTCommandReload | ASTCommandBreakSlots | ASTCommandCloseGame | ASTCommandSyncGameData | ASTCommandHas;
// (derivation union) SuperCommand => SuperCommandAddSlot | SuperCommandRemoveSlot | SuperCommandSwap | SuperCommandForCommand
// (derivation union) SuperCommand => SuperCommandAddSlot | SuperCommandRemoveSlot | SuperCommandSwap | SuperCommandSortMaterial | SuperCommandForCommand
const parseSuperCommand: ParseFunction<ASTSuperCommand> = (tokens) => {
let result: ASTSuperCommand | undefined;
result = parseSuperCommandAddSlot(tokens);
Expand All @@ -119,11 +119,13 @@ const parseSuperCommand: ParseFunction<ASTSuperCommand> = (tokens) => {
if(result !== ParseResultFail) return result;
result = parseSuperCommandSwap(tokens);
if(result !== ParseResultFail) return result;
result = parseSuperCommandSortMaterial(tokens);
if(result !== ParseResultFail) return result;
result = parseSuperCommandForCommand(tokens);
if(result !== ParseResultFail) return result;
return ParseResultFail;
};
export type ASTSuperCommand = ASTSuperCommandAddSlot | ASTSuperCommandRemoveSlot | ASTSuperCommandSwap | ASTSuperCommandForCommand;
export type ASTSuperCommand = ASTSuperCommandAddSlot | ASTSuperCommandRemoveSlot | ASTSuperCommandSwap | ASTSuperCommandSortMaterial | ASTSuperCommandForCommand;
// (derivation) CommandInitGameData => LiteralInitialize <gamedata> ZeroOrMoreItems
export const isCommandInitGameData = <T extends {type: string}>(node: T | ASTCommandInitGameData | null): node is ASTCommandInitGameData => Boolean(node && node.type === "ASTCommandInitGameData");
export type ASTCommandInitGameData = {
Expand Down Expand Up @@ -1089,6 +1091,45 @@ const parseSuperCommandSwap: ParseFunction<ASTSuperCommandSwap> = (tokens) => {
mInteger3,
};
};
// (derivation) SuperCommandSortMaterial => <!> <sort> LiteralMaterial
export const isSuperCommandSortMaterial = <T extends {type: string}>(node: T | ASTSuperCommandSortMaterial | null): node is ASTSuperCommandSortMaterial => Boolean(node && node.type === "ASTSuperCommandSortMaterial");
export type ASTSuperCommandSortMaterial = {
readonly type: "ASTSuperCommandSortMaterial",
readonly literal0: readonly [number, number],
readonly literal1: readonly [number, number],
readonly mLiteralMaterial2: ASTLiteralMaterial,
};
const parseSuperCommandSortMaterial: ParseFunction<ASTSuperCommandSortMaterial> = (tokens) => {
let rangeTokens: Token[];
tokens.push();
rangeTokens = [];
if(tokens.consume(rangeTokens) !== "!") {
tokens.restore();
tokens.pop();
return ParseResultFail;
}
const literal0 = [rangeTokens[0].start, rangeTokens[rangeTokens.length-1].end] as const;
rangeTokens = [];
if(tokens.consume(rangeTokens) !== "sort") {
tokens.restore();
tokens.pop();
return ParseResultFail;
}
const literal1 = [rangeTokens[0].start, rangeTokens[rangeTokens.length-1].end] as const;
const mLiteralMaterial2 = parseLiteralMaterial(tokens);
if(mLiteralMaterial2 === ParseResultFail) {
tokens.restore();
tokens.pop();
return ParseResultFail;
}
tokens.pop();
return {
type: "ASTSuperCommandSortMaterial",
literal0,
literal1,
mLiteralMaterial2,
};
};
// (literal union) LiteralInitialize => <initialize> | <init>
export const isLiteralInitialize = <T extends {type: string}>(node: T | ASTLiteralInitialize | null): node is ASTLiteralInitialize => Boolean(node && node.type === "ASTLiteralInitialize");
export type ASTLiteralInitialize = {
Expand Down
2 changes: 2 additions & 0 deletions src/core/command/ast/grammar.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ SuperCommand =>
SuperCommandAddSlot # ! add slot ... [from slot X]
| SuperCommandRemoveSlot # ! remove slot X
| SuperCommandSwap # ! swap i j
| SuperCommandSortMaterial # ! sort material
| SuperCommandForCommand
---

Expand Down Expand Up @@ -92,6 +93,7 @@ CommandHas => <has> LiteralMaybeNot ValueValue OneOrMoreIdentifiers
SuperCommandAddSlot => <!> <add> LiteralSlot ArgumentOneOrMoreItemsMaybeFromSlot
SuperCommandRemoveSlot => <!> <remove> LiteralSlot Integer
SuperCommandSwap => <!> <swap> Integer Integer
SuperCommandSortMaterial => <!> <sort> LiteralMaterial

## Literals
LiteralInitialize => <initialize> | <init>
Expand Down
9 changes: 8 additions & 1 deletion src/core/command/parse.cmd.super.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createMockItems, createMockItemSearch } from "data/test";
import { ItemStackArg } from "./ItemStackArg";
import { SuperCommandAddSlot, SuperCommandSwap } from "./parse.cmd.super";
import { SuperCommandAddSlot, SuperCommandSortMaterial, SuperCommandSwap } from "./parse.cmd.super";

describe("core/command/parse.super !swap", ()=>{
it("parses", ()=>{
Expand All @@ -9,6 +9,13 @@ describe("core/command/parse.super !swap", ()=>{

});

describe("core/command/parse.super !sort material", ()=>{
it("parses", ()=>{
expect("!sort material").toParseIntoCommand(undefined, new SuperCommandSortMaterial([]));
});

});

describe("core/command/parse.super !add slot", ()=>{
it("parses", ()=>{
const MockItems = createMockItems([
Expand Down
24 changes: 23 additions & 1 deletion src/core/command/parse.cmd.super.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { SimulationState } from "core/SimulationState";
import { arrayEqual } from "data/util";
import { getSlotsToAdd, ItemStackArg } from "./ItemStackArg";
import { ASTSuperCommandAddSlot, ASTSuperCommandSwap } from "./ast";
import { ASTSuperCommandAddSlot, ASTSuperCommandSortMaterial, ASTSuperCommandSwap } from "./ast";
import { AbstractProperCommand, Command } from "./command";
import { parseASTInteger } from "./parse.basis";
import { parseASTArgumentOneOrMoreItemsAllowAllMaybeFromSlot } from "./parse.clause.with.fromslot";
Expand Down Expand Up @@ -69,3 +69,25 @@ export const parseASTSuperCommandAddSlot: ParserItem<ASTSuperCommandAddSlot, Sup
codeBlocks
);
};

export class SuperCommandSortMaterial extends AbstractProperCommand {

constructor(codeBlocks: CodeBlockTree){
super(codeBlocks);
}
public execute(state: SimulationState): void {
state.inaccuratelySortMaterials();
}
public equals(other: Command): boolean {
return other instanceof SuperCommandSortMaterial;
}
}

export const parseASTSuperCommandSortMaterial: ParserSafe<ASTSuperCommandSortMaterial, SuperCommandSortMaterial> = (ast) => {
const codeBlocks: CodeBlockTree = [
codeBlockFromRange(ast.literal0, "keyword.super"),
codeBlockFromRange(ast.literal1, "keyword.super"),
];

return [new SuperCommandSortMaterial(codeBlocks), codeBlocks];
};
6 changes: 5 additions & 1 deletion src/core/command/parsev2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
isCommandWriteMetadata,
isSuperCommandAddSlot,
isSuperCommandForCommand,
isSuperCommandSortMaterial,
isSuperCommandSwap
} from "./ast";
import { CmdErr, Command, CommandHint, CommandNop, ErrorCommand } from "./command";
Expand All @@ -40,7 +41,7 @@ import { parseASTCommandReload } from "./parse.cmd.reload";
import { parseASTCommandDnp, parseASTCommandDrop, parseASTCommandEat, parseASTCommandRemove, parseASTCommandRemoveAll } from "./parse.cmd.remove";
import { parseASTCommandSave } from "./parse.cmd.save";
import { parseASTCommandShoot } from "./parse.cmd.shoot";
import { parseASTSuperCommandAddSlot, parseASTSuperCommandSwap } from "./parse.cmd.super";
import { parseASTSuperCommandAddSlot, parseASTSuperCommandSortMaterial, parseASTSuperCommandSwap } from "./parse.cmd.super";
import { parseASTCommandSyncGameData } from "./parse.cmd.sync";
import { parseASTCommandEnterTrial, parseASTCommandExitTrial } from "./parse.cmd.trial";
import { parseASTCommandWriteMetadata } from "./parse.cmd.write";
Expand Down Expand Up @@ -271,6 +272,9 @@ const parseASTTarget: ParserItem<ASTTarget, Command> = (ast, search) => {
if(isSuperCommandSwap(ast)){
return withNoError(parseASTSuperCommandSwap(ast));
}
if(isSuperCommandSortMaterial(ast)){
return withNoError(parseASTSuperCommandSortMaterial(ast));
}

if(isSuperCommandForCommand(ast)){
const codeBlocks = [codeBlockFromRange(ast.literal0, "keyword.super")];
Expand Down
4 changes: 4 additions & 0 deletions src/core/inventory/Slots.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,4 +177,8 @@ export class Slots {
this.core.swap(i, j);
}

public inaccuratelySortMaterials() {
this.core.sortMaterials();
}

}
11 changes: 11 additions & 0 deletions src/core/inventory/SlotsCore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,17 @@ export class SlotsCore {
this.internalSlots[j] = temp;
}

public sortMaterials() {
stableSort(this.internalSlots, (a,b)=>{
const itemA = a.get().item;
const itemB = b.get().item;
if(itemA.type === ItemType.Material && itemB.type === ItemType.Material){
return itemA.sortOrder - itemB.sortOrder;
}
return 0;
});
}

// Used to decide if game data is synced with inventory
// Two Slots are equal if the ItemStacks equal, including metadata equality
public equals(other: SlotsCore): boolean {
Expand Down
4 changes: 4 additions & 0 deletions src/core/inventory/VisibleInventory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,10 @@ export class VisibleInventory implements DisplayableInventory{
this.slots.swap(i, j);
}

public inaccuratelySortMaterials() {
this.slots.inaccuratelySortMaterials();
}

// public countItems(type: ItemType, countAnyWeapon: boolean): number {
// // [confirmed] iTNTPiston: when mcount === 0, nothing is checked (only when =0)
// const mcount = this.getMCount();
Expand Down

0 comments on commit 433a3bb

Please sign in to comment.