@abextm/cache2
Version:
Utilities for reading OSRS "caches"
276 lines (275 loc) • 9.1 kB
JavaScript
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;
}
}