UNPKG

@abextm/cache2

Version:

Utilities for reading OSRS "caches"

276 lines (275 loc) 9.1 kB
import { PerFileLoadable } from "../Loadable.js"; import { Typed } from "../reflect.js"; import { AmbientSoundCurve, ObjType, Params, } from "../types.js"; export class Obj extends PerFileLoadable { id; constructor(id) { super(); this.id = id; } static index = 2; static archive = 6; static gameval = 6; models = null; name = "null"; width = 1; length = 1; clipType = 2; blocksProjectile = true; isDoor = -1; contouredGround = -1; flatShading = false; modelClipped = false; animationId = -1; decorDisplacement = 16; ambient = 0; contrast = 0; category = -1; actions = [null, null, null, null, null]; recolorFrom = []; recolorTo = []; retextureFrom = []; retextureTo = []; mapIconId = -1; mapSceneId = -1; isRotated = false; shadow = true; modelSizeX = 128; modelSizeHeight = 128; modelSizeY = 128; offsetX = 0; offsetHeight = 0; offsetY = 0; obstructsGround = false; isHollow = false; supportItems = -1; varbit = -1; varp = -1; multiChildren = []; oobChild = -1; ambientSoundID = -1; multiAmbientSoundIDs = []; ambientSoundDistance = 0; ambientSoundRetain = 0; ambientSoundDistanceFadeCurve = AmbientSoundCurve.Linear; ambientSoundFadeInDuration = 300; ambientSoundFadeOutDuration = 300; ambientSoundFadeInCurve = AmbientSoundCurve.Linear; ambientSoundFadeOutCurve = AmbientSoundCurve.Linear; ambientSoundChangeTicksMin = 0; ambientSoundChangeTicksMax = 0; randomizeAnimationStart = true; blockingMask = undefined; deferAnimChange = false; params = new Params(); static decode(r, id) { const v = new Obj(id); for (let opcode; (opcode = r.u8()) != 0;) { switch (opcode) { case 1: case 5: { let len = r.u8(); v.models = new Array(len); for (let i = 0; i < len; i++) { v.models[i] = { model: r.u16(), type: opcode == 5 ? ObjType.CentrepieceStraight : r.u8(), }; } break; } case 2: v.name = r.string(); break; case 14: v.width = r.u8(); break; case 15: v.length = r.u8(); break; case 17: v.clipType = 0; v.blocksProjectile = false; break; case 18: v.blocksProjectile = false; break; case 19: v.isDoor = r.u8(); break; case 21: v.contouredGround = 0; break; case 22: v.flatShading = true; break; case 23: v.modelClipped = true; break; case 24: v.animationId = r.u16n(); break; case 27: v.clipType = 1; break; case 28: v.decorDisplacement = r.u8(); break; case 29: v.ambient = r.u8(); break; case 39: v.contrast = r.u8() * 25; break; case 30: case 31: case 32: case 33: case 34: v.actions[opcode - 30] = r.stringNullHidden(); break; case 40: { let len = r.u8(); v.recolorFrom = new Array(len); v.recolorTo = new Array(len); for (let i = 0; i < len; i++) { v.recolorFrom[i] = r.u16(); v.recolorTo[i] = r.u16(); } break; } case 41: { let len = r.u8(); v.retextureFrom = new Array(len); v.retextureTo = new Array(len); for (let i = 0; i < len; i++) { v.retextureFrom[i] = r.u16(); v.retextureTo[i] = r.u16(); } break; } case 61: v.category = r.u16(); break; case 62: v.isRotated = true; break; case 64: v.shadow = false; break; case 65: v.modelSizeX = r.u16(); break; case 66: v.modelSizeHeight = r.u16(); break; case 67: v.modelSizeY = r.u16(); break; case 68: v.mapSceneId = r.u16(); break; case 69: v.blockingMask = r.u8(); break; case 70: v.offsetX = r.i16(); break; case 71: v.offsetHeight = r.i16(); break; case 72: v.offsetY = r.i16(); break; case 73: v.obstructsGround = true; break; case 74: v.isHollow = true; break; case 75: v.supportItems = r.u8(); break; case 77: { v.varbit = r.u16n(); v.varp = r.u16n(); let len = r.u8p1(); v.multiChildren = new Array(len); for (let i = 0; i < len; i++) { v.multiChildren[i] = r.u16n(); } break; } case 78: v.ambientSoundID = r.u16(); v.ambientSoundDistance = r.u8(); if (r.isAfter({ era: "osrs", indexRevision: 4106 })) { v.ambientSoundRetain = r.u8(); } break; case 79: { v.ambientSoundChangeTicksMin = r.u16(); v.ambientSoundChangeTicksMax = r.u16(); v.ambientSoundDistance = r.u8(); if (r.isAfter({ era: "osrs", indexRevision: 4106 })) { v.ambientSoundRetain = r.u8(); } let len = r.u8(); v.multiAmbientSoundIDs = new Array(len); for (let i = 0; i < len; i++) { v.multiAmbientSoundIDs[i] = r.u16(); } break; } case 81: v.contouredGround = r.u8() * 256; break; case 82: v.mapIconId = r.u16(); break; case 89: v.randomizeAnimationStart = false; break; case 90: v.deferAnimChange = true; break; case 91: v.ambientSoundDistanceFadeCurve = r.u8(); break; case 92: { v.varbit = r.u16n(); v.varp = r.u16n(); v.oobChild = r.u16n(); let len = r.u8p1(); v.multiChildren = new Array(len); for (let i = 0; i < len; i++) { v.multiChildren[i] = r.u16n(); } break; } case 93: v.ambientSoundFadeInCurve = r.u8(); v.ambientSoundFadeInDuration = r.u16(); v.ambientSoundFadeOutCurve = r.u8(); v.ambientSoundFadeOutDuration = r.u16(); break; case 249: v.params = r.params(); break; default: throw new Error(`unknown opcode ${opcode}`); } } if (v.isDoor === -1) { v.isDoor = 0; if (v.models?.[0]?.type === ObjType.CentrepieceStraight || v.actions.some(a => a !== null)) { v.isDoor = 1; } } if (v.supportItems === -1) { v.supportItems = v.clipType != 0 ? 1 : 0; } return v; } }