Refactored binary data format code.

This commit is contained in:
Daan Vanden Bosch 2019-07-01 08:53:16 +02:00
parent 8d9016bb30
commit 43a4c7503d
39 changed files with 249 additions and 276 deletions

View File

@ -1,83 +0,0 @@
import { Object3D } from 'three';
import { Section } from '../../domain';
import { get_area_render_data, get_area_collision_data } from './binary_assets';
import { parseCRel, parseNRel } from '../parsing/geometry';
//
// Caches
//
const sections_cache: Map<string, Promise<Section[]>> = new Map();
const render_geometry_cache: Map<string, Promise<Object3D>> = new Map();
const collision_geometry_cache: Map<string, Promise<Object3D>> = new Map();
export async function get_area_sections(
episode: number,
area_id: number,
area_variant: number
): Promise<Section[]> {
const sections = sections_cache.get(`${episode}-${area_id}-${area_variant}`);
if (sections) {
return sections;
} else {
return get_area_sections_and_render_geometry(
episode, area_id, area_variant
).then(({ sections }) => sections);
}
}
export async function get_area_render_geometry(
episode: number,
area_id: number,
area_variant: number
): Promise<Object3D> {
const object_3d = render_geometry_cache.get(`${episode}-${area_id}-${area_variant}`);
if (object_3d) {
return object_3d;
} else {
return get_area_sections_and_render_geometry(
episode, area_id, area_variant
).then(({ object3d }) => object3d);
}
}
export function get_area_collision_geometry(
episode: number,
area_id: number,
area_variant: number
): Promise<Object3D> {
const object_3d = collision_geometry_cache.get(`${episode}-${area_id}-${area_variant}`);
if (object_3d) {
return object_3d;
} else {
const object_3d = get_area_collision_data(
episode, area_id, area_variant
).then(parseCRel);
collision_geometry_cache.set(`${area_id}-${area_variant}`, object_3d);
return object_3d;
}
}
function get_area_sections_and_render_geometry(
episode: number,
area_id: number,
area_variant: number
): Promise<{ sections: Section[], object3d: Object3D }> {
const promise = get_area_render_data(
episode, area_id, area_variant
).then(parseNRel);
const sections = new Promise<Section[]>((resolve, reject) => {
promise.then(({ sections }) => resolve(sections)).catch(reject);
});
const object_3d = new Promise<Object3D>((resolve, reject) => {
promise.then(({ object3d }) => resolve(object3d)).catch(reject);
});
sections_cache.set(`${episode}-${area_id}-${area_variant}`, sections);
render_geometry_cache.set(`${episode}-${area_id}-${area_variant}`, object_3d);
return promise;
}

View File

@ -1,53 +0,0 @@
import { BufferGeometry } from 'three';
import { NpcType, ObjectType } from '../../domain';
import { ninja_object_to_buffer_geometry } from '../../rendering/models';
import { BufferCursor } from '../BufferCursor';
import { parse_nj, parse_xj } from '../parsing/ninja';
import { get_npc_data, get_object_data } from './binary_assets';
const npc_cache: Map<string, Promise<BufferGeometry>> = new Map();
const object_cache: Map<string, Promise<BufferGeometry>> = new Map();
export function get_npc_geometry(npc_type: NpcType): Promise<BufferGeometry> {
let mesh = npc_cache.get(String(npc_type.id));
if (mesh) {
return mesh;
} else {
mesh = get_npc_data(npc_type).then(({ url, data }) => {
const cursor = new BufferCursor(data, true);
const nj_objects = url.endsWith('.nj') ? parse_nj(cursor) : parse_xj(cursor);
if (nj_objects.length) {
return ninja_object_to_buffer_geometry(nj_objects[0]);
} else {
throw new Error(`Could not parse ${url}.`);
}
});
npc_cache.set(String(npc_type.id), mesh);
return mesh;
}
}
export function get_object_geometry(object_type: ObjectType): Promise<BufferGeometry> {
let geometry = object_cache.get(String(object_type.id));
if (geometry) {
return geometry;
} else {
geometry = get_object_data(object_type).then(({ url, data }) => {
const cursor = new BufferCursor(data, true);
const nj_objects = url.endsWith('.nj') ? parse_nj(cursor) : parse_xj(cursor);
if (nj_objects.length) {
return ninja_object_to_buffer_geometry(nj_objects[0]);
} else {
throw new Error('File could not be parsed into a BufferGeometry.');
}
});
object_cache.set(String(object_type.id), geometry);
return geometry;
}
}

View File

@ -1,76 +0,0 @@
import { PlayerModel } from "../../domain";
import { BufferCursor } from "../BufferCursor";
import { NinjaModel, NinjaObject, parse_nj } from "../parsing/ninja";
import { get_player_data } from "./binary_assets";
const cache: Map<string, Promise<NinjaObject<NinjaModel>>> = new Map();
export function get_player_ninja_object(model: PlayerModel): Promise<NinjaObject<NinjaModel>> {
let ninja_object = cache.get(model.name);
if (ninja_object) {
return ninja_object;
} else {
ninja_object = get_all_assets(model);
cache.set(model.name, ninja_object);
return ninja_object;
}
}
async function get_all_assets(model: PlayerModel): Promise<NinjaObject<NinjaModel>> {
const body_data = await get_player_data(model.name, 'Body');
const body = parse_nj(new BufferCursor(body_data, true))[0];
if (!body) {
throw new Error(`Couldn't parse body for player class ${model.name}.`);
}
const head_data = await get_player_data(model.name, 'Head', 0);
const head = parse_nj(new BufferCursor(head_data, true))[0];
if (head) {
add_to_bone(body, head, 59);
}
if (model.hair_styles_count > 0) {
const hair_data = await get_player_data(model.name, 'Hair', 0);
const hair = parse_nj(new BufferCursor(hair_data, true))[0];
if (hair) {
add_to_bone(body, hair, 59);
}
if (model.hair_styles_with_accessory.has(0)) {
const accessory_data = await get_player_data(model.name, 'Accessory', 0);
const accessory = parse_nj(new BufferCursor(accessory_data, true))[0];
if (accessory) {
add_to_bone(body, accessory, 59);
}
}
}
return body;
}
function add_to_bone(
object: NinjaObject<NinjaModel>,
head_part: NinjaObject<NinjaModel>,
bone_id: number,
id_ref: [number] = [0]
) {
if (!object.evaluation_flags.skip) {
const id = id_ref[0]++;
if (id === bone_id) {
object.evaluation_flags.hidden = false;
object.evaluation_flags.break_child_trace = false;
object.children.push(head_part);
return;
}
}
for (const child of object.children) {
add_to_bone(child, head_part, bone_id, id_ref);
}
}

View File

@ -1,7 +1,7 @@
import { BufferCursor } from '../../BufferCursor';
import Logger from 'js-logger';
const logger = Logger.get('bin_data/compression/prs/decompress');
const logger = Logger.get('data_formats/compression/prs/decompress');
export function decompress(cursor: BufferCursor) {
const ctx = new Context(cursor);

View File

@ -14,7 +14,7 @@ import {
import { Vec3, Section } from '../../domain';
import Logger from 'js-logger';
const logger = Logger.get('bin_data/parsing/geometry');
const logger = Logger.get('data_formats/parsing/geometry');
export function parseCRel(arrayBuffer: ArrayBuffer): Object3D {
const dv = new DataView(arrayBuffer);

View File

@ -1,9 +1,9 @@
import Logger from 'js-logger';
import { BufferCursor } from '../../BufferCursor';
import { Vec3 } from '../../../domain';
import { NinjaVertex } from '.';
import { NinjaVertex } from '../ninja';
const logger = Logger.get('bin_data/parsing/ninja/nj');
const logger = Logger.get('data_formats/parsing/ninja/nj');
// TODO:
// - textures

View File

@ -1,6 +1,6 @@
import { BufferCursor } from '../../BufferCursor';
import { Vec3 } from '../../../domain';
import { NinjaVertex } from '.';
import { NinjaVertex } from '../ninja';
// TODO:
// - textures

View File

@ -3,7 +3,7 @@ import { decrypt } from "../encryption/prc";
import { decompress } from "../compression/prs";
import Logger from 'js-logger';
const logger = Logger.get('bin_data/parsing/prc');
const logger = Logger.get('data_formats/parsing/prc');
/**
* Decrypts and decompresses a .prc file.

View File

@ -1,7 +1,7 @@
import { BufferCursor } from '../../BufferCursor';
import Logger from 'js-logger';
const logger = Logger.get('bin_data/parsing/quest/bin');
const logger = Logger.get('data_formats/parsing/quest/bin');
export interface BinFile {
questNumber: number;

View File

@ -2,7 +2,7 @@ import { groupBy } from 'lodash';
import { BufferCursor } from '../../BufferCursor';
import Logger from 'js-logger';
const logger = Logger.get('bin_data/parsing/quest/dat');
const logger = Logger.get('data_formats/parsing/quest/dat');
const OBJECT_SIZE = 68;
const NPC_SIZE = 72;

View File

@ -15,7 +15,7 @@ import {
import { area_store } from '../../../stores/AreaStore';
import Logger from 'js-logger';
const logger = Logger.get('bin_data/parsing/quest');
const logger = Logger.get('data_formats/parsing/quest');
/**
* High level parsing function that delegates to lower level parsing functions.

View File

@ -1,7 +1,7 @@
import { BufferCursor } from '../../BufferCursor';
import Logger from 'js-logger';
const logger = Logger.get('bin_data/parsing/quest/qst');
const logger = Logger.get('data_formats/parsing/quest/qst');
interface QstContainedFile {
name: string;

View File

@ -2,7 +2,7 @@ import { BufferCursor } from "../BufferCursor";
import Logger from 'js-logger';
import { parse_prc } from "./prc";
const logger = Logger.get('bin_data/parsing/rlc');
const logger = Logger.get('data_formats/parsing/rlc');
const MARKER = 'RelChunkVer0.20';
/**

View File

@ -1,7 +1,7 @@
import { computed, observable } from 'mobx';
import { Object3D } from 'three';
import { BufferCursor } from '../bin_data/BufferCursor';
import { DatNpc, DatObject, DatUnknown } from '../bin_data/parsing/quest/dat';
import { BufferCursor } from '../data_formats/BufferCursor';
import { DatNpc, DatObject, DatUnknown } from '../data_formats/parsing/quest/dat';
import { NpcType } from './NpcType';
import { ObjectType } from './ObjectType';
import { enumValues as enum_values } from '../enums';

View File

@ -1,6 +1,6 @@
import { Intersection, Mesh, MeshLambertMaterial, Object3D, Plane, Raycaster, Vector2, Vector3 } from "three";
import { get_area_collision_geometry, get_area_render_geometry } from "../bin_data/loading/areas";
import { Area, Quest, QuestEntity, QuestNpc, QuestObject, Section, Vec3 } from "../domain";
import { area_store } from "../stores/AreaStore";
import { quest_editor_store } from "../stores/QuestEditorStore";
import { NPC_COLOR, NPC_HOVER_COLOR, NPC_SELECTED_COLOR, OBJECT_COLOR, OBJECT_HOVER_COLOR, OBJECT_SELECTED_COLOR } from "./entities";
import { Renderer } from "./Renderer";
@ -100,7 +100,7 @@ export class QuestRenderer extends Renderer {
this.renderer.render(this.scene, this.camera);
}
private update_geometry() {
private async update_geometry() {
this.scene.remove(this.obj_geometry);
this.scene.remove(this.npc_geometry);
this.obj_geometry = new Object3D();
@ -117,22 +117,22 @@ export class QuestRenderer extends Renderer {
const variant = this.quest.area_variants.find(v => v.area.id === area_id);
const variant_id = (variant && variant.id) || 0;
get_area_collision_geometry(episode, area_id, variant_id).then(geometry => {
if (this.quest && this.area) {
this.scene.remove(this.collision_geometry);
const collision_geometry = await area_store.get_area_collision_geometry(episode, area_id, variant_id);
this.reset_camera(new Vector3(0, 800, 700), new Vector3(0, 0, 0));
if (this.quest && this.area) {
this.scene.remove(this.collision_geometry);
this.collision_geometry = geometry;
this.scene.add(geometry);
}
});
this.reset_camera(new Vector3(0, 800, 700), new Vector3(0, 0, 0));
get_area_render_geometry(episode, area_id, variant_id).then(geometry => {
if (this.quest && this.area) {
this.render_geometry = geometry;
}
});
this.collision_geometry = collision_geometry;
this.scene.add(collision_geometry);
}
const render_geometry = await area_store.get_area_render_geometry(episode, area_id, variant_id);
if (this.quest && this.area) {
this.render_geometry = render_geometry;
}
}
}

View File

@ -1,5 +1,5 @@
import { AnimationClip, Euler, InterpolateLinear, InterpolateSmooth, KeyframeTrack, Quaternion, QuaternionKeyframeTrack, VectorKeyframeTrack } from "three";
import { NjAction, NjInterpolation, NjKeyframeTrackType } from "../bin_data/parsing/ninja/motion";
import { NjAction, NjInterpolation, NjKeyframeTrackType } from "../data_formats/parsing/ninja/motion";
const PSO_FRAME_RATE = 30;

View File

@ -1,12 +1,12 @@
import { CylinderBufferGeometry, MeshLambertMaterial, Object3D, Vector3 } from 'three';
import { DatNpc, DatObject } from '../bin_data/parsing/quest/dat';
import { DatNpc, DatObject } from '../data_formats/parsing/quest/dat';
import { NpcType, ObjectType, QuestNpc, QuestObject, Vec3 } from '../domain';
import { create_npc_mesh, create_object_mesh, NPC_COLOR, OBJECT_COLOR } from './entities';
const cylinder = new CylinderBufferGeometry(3, 3, 20).translate(0, 10, 0);
test('create geometry for quest objects', () => {
const object = new QuestObject(7, 13, new Vec3(17, 19, 23), new Vec3(), ObjectType.PrincipalWarp, {} as DatObject);
const object = new QuestObject(7, 13, new Vec3(17, 19, 23), new Vec3(0, 0, 0), ObjectType.PrincipalWarp, {} as DatObject);
const geometry = create_object_mesh(object, cylinder);
expect(geometry).toBeInstanceOf(Object3D);
@ -19,7 +19,7 @@ test('create geometry for quest objects', () => {
});
test('create geometry for quest NPCs', () => {
const npc = new QuestNpc(7, 13, new Vec3(17, 19, 23), new Vec3(), NpcType.Booma, {} as DatNpc);
const npc = new QuestNpc(7, 13, new Vec3(17, 19, 23), new Vec3(0, 0, 0), NpcType.Booma, {} as DatNpc);
const geometry = create_npc_mesh(npc, cylinder);
expect(geometry).toBeInstanceOf(Object3D);
@ -32,7 +32,7 @@ test('create geometry for quest NPCs', () => {
});
test('geometry position changes when entity position changes element-wise', () => {
const npc = new QuestNpc(7, 13, new Vec3(17, 19, 23), new Vec3(), NpcType.Booma, {} as DatNpc);
const npc = new QuestNpc(7, 13, new Vec3(17, 19, 23), new Vec3(0, 0, 0), NpcType.Booma, {} as DatNpc);
const geometry = create_npc_mesh(npc, cylinder);
npc.position = new Vec3(2, 3, 5).add(npc.position);
@ -40,7 +40,7 @@ test('geometry position changes when entity position changes element-wise', () =
});
test('geometry position changes when entire entity position changes', () => {
const npc = new QuestNpc(7, 13, new Vec3(17, 19, 23), new Vec3(), NpcType.Booma, {} as DatNpc);
const npc = new QuestNpc(7, 13, new Vec3(17, 19, 23), new Vec3(0, 0, 0), NpcType.Booma, {} as DatNpc);
const geometry = create_npc_mesh(npc, cylinder);
npc.position = new Vec3(2, 3, 5);

View File

@ -1,8 +1,8 @@
import { Bone, BufferGeometry, DoubleSide, Euler, Float32BufferAttribute, Material, Matrix3, Matrix4, MeshLambertMaterial, Quaternion, Skeleton, SkinnedMesh, Uint16BufferAttribute, Vector3 } from 'three';
import { vec3_to_threejs } from '.';
import { NinjaModel, NinjaObject } from '../bin_data/parsing/ninja';
import { NjModel } from '../bin_data/parsing/ninja/nj';
import { XjModel } from '../bin_data/parsing/ninja/xj';
import { NinjaModel, NinjaObject } from '../data_formats/parsing/ninja';
import { NjModel } from '../data_formats/parsing/ninja/nj';
import { XjModel } from '../data_formats/parsing/ninja/xj';
const DEFAULT_MATERIAL = new MeshLambertMaterial({
color: 0xFF00FF,

View File

@ -1,4 +1,7 @@
import { Area, AreaVariant } from '../domain';
import { Area, AreaVariant, Section } from '../domain';
import { Object3D } from 'three';
import { parseCRel, parseNRel } from '../data_formats/parsing/geometry';
import { get_area_render_data, get_area_collision_data } from './binary_assets';
function area(id: number, name: string, order: number, variants: number) {
const area = new Area(id, name, order, []);
@ -7,6 +10,10 @@ function area(id: number, name: string, order: number, variants: number) {
return area;
}
const sections_cache: Map<string, Promise<Section[]>> = new Map();
const render_geometry_cache: Map<string, Promise<Object3D>> = new Map();
const collision_geometry_cache: Map<string, Promise<Object3D>> = new Map();
class AreaStore {
areas: Area[][];
@ -84,6 +91,78 @@ class AreaStore {
return area_variant;
}
async get_area_sections(
episode: number,
area_id: number,
area_variant: number
): Promise<Section[]> {
const sections = sections_cache.get(`${episode}-${area_id}-${area_variant}`);
if (sections) {
return sections;
} else {
return this.get_area_sections_and_render_geometry(
episode, area_id, area_variant
).then(({ sections }) => sections);
}
}
async get_area_render_geometry(
episode: number,
area_id: number,
area_variant: number
): Promise<Object3D> {
const object_3d = render_geometry_cache.get(`${episode}-${area_id}-${area_variant}`);
if (object_3d) {
return object_3d;
} else {
return this.get_area_sections_and_render_geometry(
episode, area_id, area_variant
).then(({ object3d }) => object3d);
}
}
async get_area_collision_geometry(
episode: number,
area_id: number,
area_variant: number
): Promise<Object3D> {
const object_3d = collision_geometry_cache.get(`${episode}-${area_id}-${area_variant}`);
if (object_3d) {
return object_3d;
} else {
const object_3d = get_area_collision_data(
episode, area_id, area_variant
).then(parseCRel);
collision_geometry_cache.set(`${area_id}-${area_variant}`, object_3d);
return object_3d;
}
}
private get_area_sections_and_render_geometry(
episode: number,
area_id: number,
area_variant: number
): Promise<{ sections: Section[], object3d: Object3D }> {
const promise = get_area_render_data(
episode, area_id, area_variant
).then(parseNRel);
const sections = new Promise<Section[]>((resolve, reject) => {
promise.then(({ sections }) => resolve(sections)).catch(reject);
});
const object_3d = new Promise<Object3D>((resolve, reject) => {
promise.then(({ object3d }) => resolve(object3d)).catch(reject);
});
sections_cache.set(`${episode}-${area_id}-${area_variant}`, sections);
render_geometry_cache.set(`${episode}-${area_id}-${area_variant}`, object_3d);
return promise;
}
}
export const area_store = new AreaStore();

57
src/stores/EntityStore.ts Normal file
View File

@ -0,0 +1,57 @@
import { BufferGeometry } from "three";
import { NpcType, ObjectType } from "../domain";
import { BufferCursor } from "../data_formats/BufferCursor";
import { get_npc_data, get_object_data } from "./binary_assets";
import { ninja_object_to_buffer_geometry } from "../rendering/models";
import { parse_nj, parse_xj } from "../data_formats/parsing/ninja";
const npc_cache: Map<number, Promise<BufferGeometry>> = new Map();
const object_cache: Map<number, Promise<BufferGeometry>> = new Map();
class EntityStore {
async get_npc_geometry(npc_type: NpcType): Promise<BufferGeometry> {
let mesh = npc_cache.get(npc_type.id);
if (mesh) {
return mesh;
} else {
mesh = get_npc_data(npc_type).then(({ url, data }) => {
const cursor = new BufferCursor(data, true);
const nj_objects = url.endsWith('.nj') ? parse_nj(cursor) : parse_xj(cursor);
if (nj_objects.length) {
return ninja_object_to_buffer_geometry(nj_objects[0]);
} else {
throw new Error(`Could not parse ${url}.`);
}
});
npc_cache.set(npc_type.id, mesh);
return mesh;
}
}
async get_object_geometry(object_type: ObjectType): Promise<BufferGeometry> {
let geometry = object_cache.get(object_type.id);
if (geometry) {
return geometry;
} else {
geometry = get_object_data(object_type).then(({ url, data }) => {
const cursor = new BufferCursor(data, true);
const nj_objects = url.endsWith('.nj') ? parse_nj(cursor) : parse_xj(cursor);
if (nj_objects.length) {
return ninja_object_to_buffer_geometry(nj_objects[0]);
} else {
throw new Error('File could not be parsed into a BufferGeometry.');
}
});
object_cache.set(object_type.id, geometry);
return geometry;
}
}
}
export const entity_store = new EntityStore();

View File

@ -1,15 +1,16 @@
import Logger from 'js-logger';
import { action, observable } from "mobx";
import { AnimationClip, AnimationMixer, Object3D } from "three";
import { BufferCursor } from "../bin_data/BufferCursor";
import { NinjaModel, NinjaObject, parse_nj, parse_xj } from "../bin_data/parsing/ninja";
import { parse_njm_4 } from "../bin_data/parsing/ninja/motion";
import { BufferCursor } from "../data_formats/BufferCursor";
import { NinjaModel, NinjaObject, parse_nj, parse_xj } from "../data_formats/parsing/ninja";
import { parse_njm_4 } from "../data_formats/parsing/ninja/motion";
import { create_animation_clip } from "../rendering/animation";
import { ninja_object_to_skinned_mesh } from "../rendering/models";
import { PlayerModel } from '../domain';
import { get_player_ninja_object } from '../bin_data/loading/player';
import { get_player_data } from './binary_assets';
const logger = Logger.get('stores/ModelViewerStore');
const cache: Map<string, Promise<NinjaObject<NinjaModel>>> = new Map();
class ModelViewerStore {
readonly models: PlayerModel[] = [
@ -32,7 +33,7 @@ class ModelViewerStore {
@observable.ref animation_mixer?: AnimationMixer;
load_model = async (model: PlayerModel) => {
const object = await get_player_ninja_object(model);
const object = await this.get_player_ninja_object(model);
this.set_model(object);
}
@ -51,7 +52,7 @@ class ModelViewerStore {
if (model) {
if (this.current_model && filename && /^pl[A-Z](hed|hai|cap)\d\d.nj$/.test(filename)) {
this.add_to_bone(this.current_model, model, 59, [0]);
this.add_to_bone(this.current_model, model, 59);
} else {
this.current_model = model;
}
@ -93,7 +94,7 @@ class ModelViewerStore {
object: NinjaObject<NinjaModel>,
head_part: NinjaObject<NinjaModel>,
bone_id: number,
id_ref: [number]
id_ref: [number] = [0]
) {
if (!object.evaluation_flags.skip) {
const id = id_ref[0]++;
@ -123,6 +124,54 @@ class ModelViewerStore {
const action = this.animation_mixer.clipAction(clip);
action.play();
})
private get_player_ninja_object(model: PlayerModel): Promise<NinjaObject<NinjaModel>> {
let ninja_object = cache.get(model.name);
if (ninja_object) {
return ninja_object;
} else {
ninja_object = this.get_all_assets(model);
cache.set(model.name, ninja_object);
return ninja_object;
}
}
private async get_all_assets(model: PlayerModel): Promise<NinjaObject<NinjaModel>> {
const body_data = await get_player_data(model.name, 'Body');
const body = parse_nj(new BufferCursor(body_data, true))[0];
if (!body) {
throw new Error(`Couldn't parse body for player class ${model.name}.`);
}
const head_data = await get_player_data(model.name, 'Head', 0);
const head = parse_nj(new BufferCursor(head_data, true))[0];
if (head) {
this.add_to_bone(body, head, 59);
}
if (model.hair_styles_count > 0) {
const hair_data = await get_player_data(model.name, 'Hair', 0);
const hair = parse_nj(new BufferCursor(hair_data, true))[0];
if (hair) {
this.add_to_bone(body, hair, 59);
}
if (model.hair_styles_with_accessory.has(0)) {
const accessory_data = await get_player_data(model.name, 'Accessory', 0);
const accessory = parse_nj(new BufferCursor(accessory_data, true))[0];
if (accessory) {
this.add_to_bone(body, accessory, 59);
}
}
}
return body;
}
}
export const model_viewer_store = new ModelViewerStore();

View File

@ -1,11 +1,11 @@
import Logger from 'js-logger';
import { action, observable } from 'mobx';
import { BufferCursor } from '../bin_data/BufferCursor';
import { get_area_sections } from '../bin_data/loading/areas';
import { get_npc_geometry, get_object_geometry } from '../bin_data/loading/entities';
import { parse_quest, write_quest_qst } from '../bin_data/parsing/quest';
import { BufferCursor } from '../data_formats/BufferCursor';
import { parse_quest, write_quest_qst } from '../data_formats/parsing/quest';
import { Area, Quest, QuestEntity, Section, Vec3 } from '../domain';
import { create_npc_mesh as create_npc_object_3d, create_object_mesh as create_object_object_3d } from '../rendering/entities';
import { area_store } from './AreaStore';
import { entity_store } from './EntityStore';
const logger = Logger.get('stores/QuestEditorStore');
@ -65,7 +65,7 @@ class QuestEditorStore {
if (quest) {
// Load section data.
for (const variant of quest.area_variants) {
const sections = await get_area_sections(
const sections = await area_store.get_area_sections(
quest.episode,
variant.area.id,
variant.id
@ -75,7 +75,7 @@ class QuestEditorStore {
// Generate object geometry.
for (const object of quest.objects.filter(o => o.area_id === variant.area.id)) {
try {
const object_geom = await get_object_geometry(object.type);
const object_geom = await entity_store.get_object_geometry(object.type);
this.set_section_on_visible_quest_entity(object, sections);
object.object_3d = create_object_object_3d(object, object_geom);
} catch (e) {
@ -86,7 +86,7 @@ class QuestEditorStore {
// Generate NPC geometry.
for (const npc of quest.npcs.filter(npc => npc.area_id === variant.area.id)) {
try {
const npc_geom = await get_npc_geometry(npc.type);
const npc_geom = await entity_store.get_npc_geometry(npc.type);
this.set_section_on_visible_quest_entity(npc, sections);
npc.object_3d = create_npc_object_3d(npc, npc_geom);
} catch (e) {

View File

@ -1,4 +1,4 @@
import { NpcType, ObjectType } from '../../domain';
import { NpcType, ObjectType } from '../domain';
export function get_area_render_data(
episode: number,
@ -145,7 +145,7 @@ function get_area_asset(
function npc_type_to_url(npc_type: NpcType): string {
switch (npc_type) {
// The dubswitch model in in XJ format.
// The dubswitch model is in XJ format.
case NpcType.Dubswitch: return `/npcs/${npc_type.code}.xj`;
// Episode II VR Temple
@ -196,10 +196,10 @@ function object_type_to_url(object_type: ObjectType): string {
case ObjectType.FallingRock:
case ObjectType.DesertFixedTypeBoxBreakableCrystals:
case ObjectType.BeeHive:
return `/objects/${String(object_type.pso_id)}.nj`;
return `/objects/${object_type.pso_id}.nj`;
default:
return `/objects/${String(object_type.pso_id)}.xj`;
return `/objects/${object_type.pso_id}.xj`;
}
}

View File

@ -1,12 +1,12 @@
import fs from 'fs';
import { BufferCursor } from '../src/bin_data/BufferCursor';
import { parseItemPmt, ItemPmt } from '../src/bin_data/parsing/itempmt';
import { parseUnitxt, Unitxt } from '../src/bin_data/parsing/unitxt';
import { BufferCursor } from '../src/data_formats/BufferCursor';
import { parseItemPmt, ItemPmt } from '../src/data_formats/parsing/itempmt';
import { parseUnitxt, Unitxt } from '../src/data_formats/parsing/unitxt';
import { Difficulties, Difficulty, Episode, Episodes, NpcType, SectionId, SectionIds } from '../src/domain';
import { NpcTypes } from '../src/domain/NpcType';
import { BoxDropDto, EnemyDropDto, ItemTypeDto, QuestDto } from '../src/dto';
import { updateDropsFromWebsite } from './update_drops_ephinea';
import { parse_quest } from '../src/bin_data/parsing/quest';
import { parse_quest } from '../src/data_formats/parsing/quest';
import Logger from 'js-logger';
const logger = Logger.get('static/update_ephinea_data');
@ -14,8 +14,8 @@ const logger = Logger.get('static/update_ephinea_data');
Logger.useDefaults({ defaultLevel: Logger.ERROR });
logger.setLevel(Logger.INFO);
Logger.get('static/update_drops_ephinea').setLevel(Logger.INFO);
Logger.get('bin_data/parsing/quest').setLevel(Logger.OFF);
Logger.get('bin_data/parsing/quest/bin').setLevel(Logger.OFF);
Logger.get('data_formats/parsing/quest').setLevel(Logger.OFF);
Logger.get('data_formats/parsing/quest/bin').setLevel(Logger.OFF);
/**
* Used by static data generation scripts.

View File

@ -1,7 +1,7 @@
import fs from "fs";
import Logger from 'js-logger';
import { BufferCursor } from "../src/bin_data/BufferCursor";
import { parse_rlc } from "../src/bin_data/parsing/rlc";
import { BufferCursor } from "../src/data_formats/BufferCursor";
import { parse_rlc } from "../src/data_formats/parsing/rlc";
const logger = Logger.get('static/update_generic_data');