1
0
Fork 0

inventory corruption working

This commit is contained in:
iTNTPiston 2022-06-20 22:47:31 -07:00
parent b8ac12086c
commit 367a08b2c2
15 changed files with 193 additions and 28 deletions

View file

@ -2,3 +2,6 @@ deploy:
rm -rf docs/
npm run build
mv -T build docs
git add .
git commit -m "Local Build Deployment"
git push

View file

@ -19,8 +19,9 @@ h1 {
background-color: #eeaaaa;
}
.CommandItemError{
color: red;
.CommandItemComment{
color: green;
font-size: 10pt;
}
.CommandItem {
@ -29,7 +30,7 @@ h1 {
}
.CommandItem:hover {
border: 1px solid black
background-color: #eeeeee;
}
.InputError {
@ -77,4 +78,4 @@ h1 {
left:8px;
color:#eeeeee;
float: left;
}
}

View file

@ -55,6 +55,9 @@ export const App: React.FC = () => {
const [contextMenuY, setContextMenuY] = useState<number>(0);
const [contextMenuShowing, setContextMenuShowing] = useState<boolean>(false);
const [contextIndex, setContextIndex] = useState<number>(-1);
const uploadRef = useRef<HTMLInputElement>(null);
const contextMenuRef = useRef<HTMLDivElement>(null);
// compute props
const inventories = useMemo(()=>{
const inventories: Inventory[] = [];
@ -85,7 +88,16 @@ export const App: React.FC = () => {
}, [commands]);
const uploadRef = useRef<HTMLInputElement>(null);
useEffect(()=>{
if(contextMenuRef.current && contextMenuShowing){
const rect = contextMenuRef.current.getBoundingClientRect();
if (rect.bottom > window.innerHeight){
setContextMenuY(contextMenuY-rect.height);
}
}
}, [contextMenuRef, contextMenuShowing])
return (
<div className='Calamity'
@ -130,7 +142,7 @@ export const App: React.FC = () => {
key={i}
isSelected={displayIndex===i}
isContextSelected={contextIndex===i}
error={inventories[i].isInaccurate()}
comment={c.getDisplayString().startsWith("#")}
>
{c.getDisplayString()}
</CommandItem>
@ -140,12 +152,21 @@ export const App: React.FC = () => {
const arrCopy = [...commands];
arrCopy.push(new CommandNothing());
setCommands(arrCopy);
}} onContextMenu={()=>{
const arrCopy = [...commands];
arrCopy.push(new CommandNothing());
setCommands(arrCopy);
}}>(new)</CommandItem>
<CommandItem onClick={(x,y)=>{
setContextIndex(-1);
setContextMenuX(x);
setContextMenuY(y);
setContextMenuShowing(true);
}} onContextMenu={(x,y)=>{
setContextIndex(-1);
setContextMenuX(x);
setContextMenuY(y);
setContextMenuShowing(true);
}}>(options)</CommandItem>
</ul>
@ -154,7 +175,8 @@ export const App: React.FC = () => {
<DisplayPane
overlaySave={overlaySave}
displayIndex={displayIndex}
command={commands[displayIndex].getDisplayString()}
command={commands[displayIndex].getDisplayString()}
orbs={inventories[displayIndex].getTurnedInOrbs()}
slots={inventories[displayIndex].getSlots()}
savedSlots={inventories[displayIndex].getSavedSlots()}
numBroken={inventories[displayIndex].getNumBroken()}
@ -181,7 +203,7 @@ export const App: React.FC = () => {
setContextIndex(-1);
e.preventDefault();
}}>
<div style={{
<div ref={contextMenuRef} style={{
position: "absolute",
top: contextMenuY,
left: contextMenuX,
@ -202,7 +224,20 @@ export const App: React.FC = () => {
setContextMenuShowing(false);
setContextIndex(-1);
}}>Insert Above</CommandItem>
<CommandItem error onClick={()=>{
<CommandItem onClick={()=>{
if(contextIndex > 0){
const arrCopy = [...commands];
const temp = arrCopy[contextIndex];
arrCopy[contextIndex] = arrCopy[contextIndex-1];
arrCopy[contextIndex-1] = temp;
setCommands(arrCopy);
setContextMenuShowing(false);
setContextIndex(-1);
}
}}>Move Up</CommandItem>
<CommandItem onClick={()=>{
if(confirm("Delete?")){
setCommands(commands.filter((_,i)=>i!==contextIndex));
if(displayIndex >= commands.length){

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

BIN
src/assets/img/Rushroom.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
src/assets/img/Screw.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

View file

@ -3,15 +3,15 @@ import { PropsWithChildren } from "react";
type CommandItemProps = PropsWithChildren<{
isSelected?: boolean,
comment?:boolean,
isContextSelected?: boolean,
error?: boolean,
onClick: (x: number, y: number)=>void,
onContextMenu?: (x: number, y: number)=>void
}>;
export const CommandItem: React.FC<CommandItemProps> = ({isSelected, isContextSelected,error, children, onClick, onContextMenu}) => {
export const CommandItem: React.FC<CommandItemProps> = ({isSelected, isContextSelected, comment,children, onClick, onContextMenu}) => {
return <li
className={clsx("CommandItem", isSelected && "CommandItemSelected", isContextSelected&& "CommandItemContextSelected",error && "CommandItemError")}
className={clsx("CommandItem", isSelected && "CommandItemSelected", isContextSelected&& "CommandItemContextSelected",comment && "CommandItemComment")}
onClick={(e)=>{
onClick(e.clientX, e.clientY);
}}

View file

@ -322,4 +322,53 @@ export class CommandUnequip implements Command {
const slotString = this.noSlot ? "" : ` In Slot ${this.slot+1}`
return `Unequip ${this.item}${slotString}`;
}
}
}
export class CommandSetTag implements Command {
private name: string;
constructor(name: string){
this.name = name;
}
public execute(inv: Inventory): void {
inv.save();
inv.setTag(this.name);
}
public getDisplayString(): string {
return `Save As ${this.name}`
}
}
export class CommandApplyTag implements Command {
private name: string;
constructor(name: string){
this.name = name;
}
public execute(inv: Inventory): void {
inv.applyTag(this.name);
}
public getDisplayString(): string {
return `Use ${this.name}`
}
}
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(inv: Inventory): void {
}
public getDisplayString(): string {
return `# ${this.name}`;
}
}

View file

@ -6,10 +6,12 @@ import { Slots } from "./Slots";
export class Inventory {
private slots: Slots = new Slots([]);
private savedSlots: Slots = new Slots([]);
private namedSlots: {[name: string]: Slots} = {};
private numBroken = 0;
private isInitialSort = false;
private isAltered = true;
private inaccurate = false;
private turnedInOrbs = 0;
public deepClone(): Inventory {
const other = new Inventory();
other.slots = this.slots.deepClone();
@ -18,6 +20,11 @@ export class Inventory {
other.isInitialSort = this.isInitialSort;
other.isAltered = this.isAltered;
other.inaccurate = this.inaccurate;
other.turnedInOrbs = this.turnedInOrbs;
other.namedSlots = {};
for(const name in this.namedSlots){
other.namedSlots[name] = this.namedSlots[name].deepClone();
}
return other;
}
@ -37,6 +44,10 @@ export class Inventory {
return this.inaccurate;
}
public getTurnedInOrbs(): number {
return this.turnedInOrbs;
}
public init(stacks: ItemStack[]) {
this.slots = new Slots([]);
stacks.forEach(s=>{
@ -48,10 +59,30 @@ export class Inventory {
this.inaccurate = false;
}
public closeGame() {
this.numBroken = 0;
this.isInitialSort = false;
this.isAltered = true;
this.inaccurate = false;
this.slots = new Slots([]);
}
public addBrokenSlots(num: number) {
this.numBroken+=num;
}
public setTag(name: string){
this.namedSlots[name] = this.savedSlots.deepClone();
}
public applyTag(name: string){
if(name in this.namedSlots){
this.savedSlots = this.namedSlots[name].deepClone();
}else{
this.savedSlots = new Slots([]);
}
}
public save() {
if(this.isAltered){
this.savedSlots = this.slots.deepClone();
@ -150,6 +181,9 @@ export class Inventory {
public remove(item: Item, count: number, slot: number) {
this.slots.remove(item, count, slot);
if(item===Item.SpiritOrb){
this.turnedInOrbs+=count;
}
this.isAltered=true;
}

View file

@ -3,8 +3,8 @@ import ImageGlider from "assets/img/Glider.png";
import ImageSpiritOrb from "assets/img/SpiritOrb.png";
import ImageLotus from "assets/img/Lotus.png";
import ImageSilentPrincess from "assets/img/SilentPrincess.png";
import ImageHoney from "assets/img/Lotus.png";
import ImageAcorn from "assets/img/SilentPrincess.png";
import ImageHoney from "assets/img/Honey.png";
import ImageAcorn from "assets/img/Acorn.png";
import ImageFaroshScale from "assets/img/FaroshScale.png";
import ImageFaroshClaw from "assets/img/FaroshClaw.png";
import ImageFaroshHorn from "assets/img/FaroshHorn.png";
@ -27,6 +27,11 @@ import ImageShockArrow from "assets/img/ShockArrow.png";
import ImageBombArrow from "assets/img/BombArrow.png";
import ImageAncientArrow from "assets/img/AncientArrow.png";
import ImageShield from "assets/img/PotLid.png";
import ImageRushroom from "assets/img/Rushroom.png";
import ImageScrew from "assets/img/Screw.png";
import ImageHyruleBass from "assets/img/HyruleBass.png";
import ImageLizalfosHorn from "assets/img/LizalfosHorn.png";
import ImageLizalfosTalon from "assets/img/LizalfosTalon.png";
export enum ItemType {
Weapon = 0,
@ -76,6 +81,12 @@ export enum Item {
Core = "Core",
Wood = "Wood",
Rushroom = "Rushroom",
Screw = "Screw",
HyruleBass = "HyruleBass",
LizalfosHorn = "LizalfosHorn",
LizalfosTalon = "LizalfosTalon",
SpeedFood = "SpeedFood",
Weapon = "Weapon",
Bow = "Bow",
@ -122,6 +133,9 @@ const register = (id: number, item: Item, type: ItemType, image: string, options
sortOrder,
...(options||{})
};
if(id in IdToData){
console.error("Multiple items registered to the same id: "+id+", ("+item+")");
}
IdToData[id] = data;
ItemToData[item] = data;
}
@ -137,6 +151,7 @@ register(0x01, Item.Glider, ItemType.Key, ImageGlider, {
register(0x02, Item.SpiritOrb, ItemType.Key, ImageSpiritOrb);
register(0x11, Item.Lotus, ItemType.Material, ImageLotus);
register(0x20, Item.Rushroom, ItemType.Material, ImageRushroom);
register(0x12, Item.SilentPrincess, ItemType.Material, ImageSilentPrincess);
register(0x13, Item.Honey, ItemType.Material, ImageHoney);
register(0x14, Item.Acorn, ItemType.Material, ImageAcorn);
@ -144,10 +159,14 @@ register(0x15, Item.FaroshScale, ItemType.Material, ImageFaroshScale);
register(0x16, Item.FaroshClaw, ItemType.Material, ImageFaroshClaw);
register(0x17, Item.FaroshHorn, ItemType.Material, ImageFaroshHorn);
register(0x18, Item.HeartyBass, ItemType.Material, ImageHeartyBass);
register(0x21, Item.HyruleBass, ItemType.Material, ImageHyruleBass);
register(0x19, Item.Beetle, ItemType.Material, ImageBeetle);
register(0x1a, Item.Opal, ItemType.Material, ImageOpal);
register(0x10, Item.Diamond, ItemType.Material, ImageDiamond);
register(0x23, Item.LizalfosHorn, ItemType.Material, ImageLizalfosHorn);
register(0x24, Item.LizalfosTalon, ItemType.Material, ImageLizalfosTalon);
register(0x1b, Item.Tail, ItemType.Material, ImageTail);
register(0x22, Item.Screw, ItemType.Material, ImageScrew);
register(0x1c, Item.Spring, ItemType.Material, ImageSpring);
register(0x1d, Item.Shaft, ItemType.Material, ImageShaft);
register(0x1e, Item.Core, ItemType.Material, ImageCore);
@ -170,7 +189,7 @@ register(0x72, Item.IceArrow, ItemType.Arrow, ImageIceArrow);
register(0x73, Item.ShockArrow, ItemType.Arrow, ImageShockArrow);
register(0x74, Item.BombArrow, ItemType.Arrow, ImageBombArrow);
register(0x75, Item.AncientArrow, ItemType.Arrow, ImageAncientArrow);
register(0x60, Item.Shield, ItemType.Shield, ImageShield, {
register(0x80, Item.Shield, ItemType.Shield, ImageShield, {
stackable: false
});

View file

@ -1,7 +1,10 @@
import { Command, CommandAddMaterial, CommandBreakSlots, CommandEquip, CommandEquipArrow, CommandInitialize, CommandNothing, CommandReload, CommandRemoveMaterial, CommandRemoveUnstackableMaterial, CommandSave, CommandSortKey, CommandSortMaterial, CommandUnequip } from "./Command";
import { Command, CommandAddMaterial, CommandApplyTag, CommandBreakSlots, CommandCloseGame, CommandComment, CommandEquip, CommandEquipArrow, CommandInitialize, CommandNothing, CommandReload, CommandRemoveMaterial, CommandRemoveUnstackableMaterial, CommandSave, CommandSetTag, CommandSortKey, CommandSortMaterial, CommandUnequip } from "./Command";
import { Item, ItemStack } from "./Item";
export const parseCommand = (cmdString: string): Command | undefined => {
if(cmdString.startsWith("# ")){
return new CommandComment(cmdString.substring(2));
}
const tokens = cmdString.split(" ").filter(i=>i);
if(tokens.length===0){
return new CommandNothing();
@ -39,6 +42,9 @@ export const parseCommand = (cmdString: string): Command | undefined => {
if(tokens.length===2 && tokens[0] === "Sort" && tokens[1] === "Material"){
return new CommandSortMaterial();
}
if(tokens.length===2 && tokens[0] === "Close" && tokens[1] === "Game"){
return new CommandCloseGame();
}
// break
if (tokens.length > 2 && tokens[0] === "Break" && tokens[2]=== "Slots" ){
const slots = parseInt(tokens[1]);
@ -138,6 +144,14 @@ export const parseCommand = (cmdString: string): Command | undefined => {
}
return undefined;
}
// Multi Save
if (tokens.length === 3 && tokens[0] === "Save" && tokens[1] === "As"){
const name = tokens[2];
return new CommandSetTag(name);
}
if (tokens.length === 2 && tokens[0] === "Use"){
const name = tokens[1];
return new CommandApplyTag(name);
}
return undefined;
};

View file

@ -55,13 +55,20 @@ export class Slots {
}
public remove(item: Item, count: number, slot: number) {
let s = 0;
for(let i = 0; i<this.internalSlots.length;i++){
for(let i = 0; i<this.internalSlots.length && count > 0;i++){
if(this.internalSlots[i].item === item){
if(s<slot){
s++;
}else{
this.internalSlots[i].count-=count;
break;
if(this.internalSlots[i].count<count){
count-=this.internalSlots[i].count;
this.internalSlots[i].count=0;
}else{
this.internalSlots[i].count-=count;
break;
}
}
}
}
@ -187,4 +194,4 @@ export class Slots {
}
return -1;
}
}
}

View file

@ -10,6 +10,7 @@ import React, { useEffect, useState } from "react";
type DisplayPaneProps = {
command: string,
orbs: number,
displayIndex: number,
slots: Slots,
savedSlots: Slots,
@ -35,7 +36,7 @@ const stackToItemProps = ({item, count, equipped}: ItemStack): ItemListItemProps
return {image: data.image, count: data.stackable ? count : 0, isEquipped:equipped};
}
export const DisplayPane: React.FC<DisplayPaneProps> = ({command,editCommand,displayIndex, slots, savedSlots, numBroken, overlaySave})=>{
export const DisplayPane: React.FC<DisplayPaneProps> = ({command,orbs,editCommand,displayIndex, slots, savedSlots, numBroken, overlaySave})=>{
const [commandString, setCommandString] = useState<string>("");
const [hasError, setHasError] = useState<boolean>(false);
const listProps = stacksToItemListProps(slots, numBroken, false);
@ -78,7 +79,9 @@ export const DisplayPane: React.FC<DisplayPaneProps> = ({command,editCommand,dis
setHasError(true);
}
}}></input>
<span>
Orbs: {orbs}
</span>
</div>
{overlaySave ?
<div style={{
@ -93,20 +96,20 @@ export const DisplayPane: React.FC<DisplayPaneProps> = ({command,editCommand,dis
(()=>{
const doubleSlots: JSX.Element[] = [];
for(let i=0;i<savedSlots.length && i<slots.length;i++){
doubleSlots.push(<DoubleItemSlot
doubleSlots.push(<DoubleItemSlot key={i}
first={{...stackToItemProps(savedSlots.get(i)), isBroken:false, isSave:true}}
second={{...stackToItemProps(slots.get(i)), isBroken:i>=slots.length-numBroken, isSave:false}}
/>);
}
if(savedSlots.length>slots.length){
for(let i=slots.length;i<savedSlots.length;i++){
doubleSlots.push(<DoubleItemSlot
doubleSlots.push(<DoubleItemSlot key={i+slots.length}
first={{...stackToItemProps(savedSlots.get(i)), isBroken:false, isSave:true}}
/>);
}
}else if(slots.length > savedSlots.length){
for(let i=savedSlots.length;i<slots.length;i++){
doubleSlots.push(<DoubleItemSlot
doubleSlots.push(<DoubleItemSlot key={i + savedSlots.length}
second={{...stackToItemProps(slots.get(i)), isBroken:i>=slots.length-numBroken, isSave:false}}
/>);
}
@ -128,7 +131,7 @@ export const DisplayPane: React.FC<DisplayPaneProps> = ({command,editCommand,dis
height: "calc( ( 99vh - 60px ) / 2)",
overflowY: "auto"
} }>
<div>Inventory of (Hard) Save</div>
<div>Inventory of Save</div>
<ItemList {...listSaveProps}/>
</div>
<div style={{