diff --git a/cache2-ts/src/Reader.ts b/cache2-ts/src/Reader.ts index b2c0590..49e8f4d 100644 --- a/cache2-ts/src/Reader.ts +++ b/cache2-ts/src/Reader.ts @@ -171,6 +171,13 @@ export class Reader { return this.i32() & (-1 >>> 1); } } + public u32o16n(): number { // rl BigSmart2 + if (this.view.getUint8(this.offset) & 0x80) { + return this.i32() & (-1 >>> 1); + } else { + return this.u16n(); + } + } public leVarInt(): number { // rl LEVarInt let v = 0; let shift = 0; diff --git a/cache2-ts/src/loaders/HealthBar.ts b/cache2-ts/src/loaders/HealthBar.ts new file mode 100644 index 0000000..72b66b2 --- /dev/null +++ b/cache2-ts/src/loaders/HealthBar.ts @@ -0,0 +1,70 @@ +import { PerFileLoadable } from "../Loadable.js"; +import { Reader } from "../Reader.js"; +import { Typed } from "../reflect.js"; +import { HealthBarID, SpriteID } from "../types.js"; + +export class HealthBar extends PerFileLoadable { + constructor(public id: HealthBarID) { + super(); + } + + declare public [Typed.type]: Typed.Any; + + public static readonly index = 2; + public static readonly archive = 33; + + public unused1: number | undefined = undefined; + public sortOrder: number = 255; + public despawnPriority: number = 255; + public fadeOutAt = -1; + public duration = 70; + public unused2: number | undefined = undefined; + public filledSprite = -1 as SpriteID; + public emptySprite = -1 as SpriteID; + public denominator = 30; + public borderSize = 0; + + public static decode(r: Reader, id: HealthBarID): HealthBar { + const v = new HealthBar(id); + for (let opcode: number; (opcode = r.u8()) != 0;) { + switch (opcode) { + case 1: + v.unused1 = r.u16(); + break; + case 2: + v.sortOrder = r.u8(); + break; + case 3: + v.despawnPriority = r.u8(); + break; + case 4: + v.fadeOutAt = 0; + break; + case 5: + v.duration = r.u16(); + break; + case 6: + v.unused2 = r.u8(); + break; + case 7: + v.filledSprite = r.u32o16n() as SpriteID; + break; + case 8: + v.emptySprite = r.u32o16n() as SpriteID; + break; + case 11: + v.fadeOutAt = r.u16(); + break; + case 14: + v.denominator = r.u8(); + break; + case 15: + v.borderSize = r.u8(); + break; + default: + throw new Error(`unknown opcode ${opcode}`); + } + } + return v; + } +} diff --git a/cache2-ts/src/loaders/index.ts b/cache2-ts/src/loaders/index.ts index db575b2..4840902 100644 --- a/cache2-ts/src/loaders/index.ts +++ b/cache2-ts/src/loaders/index.ts @@ -1,5 +1,6 @@ export * from "./DBRow.js"; export * from "./Enum.js"; +export * from "./HealthBar.js"; export * from "./Hitsplat.js"; export * from "./Item.js"; export * from "./NPC.js"; diff --git a/cache2-ts/src/types.ts b/cache2-ts/src/types.ts index baea0b0..9486e02 100644 --- a/cache2-ts/src/types.ts +++ b/cache2-ts/src/types.ts @@ -45,6 +45,7 @@ export type DBTableID = NewType; export type DBColumnID = NewType; export type EnumID = NewType; export type FontID = NewType; +export type HealthBarID = NewType; export type HitsplatID = NewType; export type ItemID = NewType; export type MapElementID = NewType; diff --git a/viewer/src/common/Runner.ts b/viewer/src/common/Runner.ts index fd33387..605d86e 100644 --- a/viewer/src/common/Runner.ts +++ b/viewer/src/common/Runner.ts @@ -11,6 +11,7 @@ export const lookupTypes = { DBTableID: "dbtable", EnumID: "enum", ItemID: "item", + HealthBarID: "healthbar", HitsplatID: "hitsplat", NPCID: "npc", ObjID: "obj", @@ -25,6 +26,7 @@ export type LookupType = | "enum" | "index" | "item" + | "healthbar" | "hitsplat" | "npc" | "obj" @@ -37,6 +39,7 @@ const uiNameOverride = { dbrow: "DBRow", dbtable: "DBTable", npc: "NPC", + healthbar: "HealthBar", } satisfies Partial>; export function uiType(t: LookupType): string { return uiNameOverride[t as keyof typeof uiNameOverride] ?? capitalize(t); diff --git a/viewer/src/main/viewer/Viewer.svelte b/viewer/src/main/viewer/Viewer.svelte index 56cf074..81dbd40 100644 --- a/viewer/src/main/viewer/Viewer.svelte +++ b/viewer/src/main/viewer/Viewer.svelte @@ -39,6 +39,7 @@ + diff --git a/viewer/src/runner/Runner.ts b/viewer/src/runner/Runner.ts index 373dcf4..d1ee3a4 100644 --- a/viewer/src/runner/Runner.ts +++ b/viewer/src/runner/Runner.ts @@ -255,6 +255,7 @@ let types: Record> = { dbtable: c2.DBTable, enum: c2.Enum, item: c2.Item, + healthbar: c2.HealthBar, hitsplat: c2.Hitsplat, npc: c2.NPC, obj: c2.Obj,