This commit is contained in:
jtuu 2019-11-16 18:07:21 +02:00
parent 47f68674f6
commit 8582a25bc3
24 changed files with 367 additions and 163 deletions

View File

@ -36,7 +36,10 @@ test("PRS compression and decompression, worst case", () => {
const prng = new Prng(); const prng = new Prng();
// Compression factor: 1.125 // Compression factor: 1.125
test_with_bytes(new Array(10000).fill(0).map(() => prng.next_integer(0, 255)), 11253); test_with_bytes(
new Array(10000).fill(0).map(() => prng.next_integer(0, 255)),
11253,
);
}); });
test("PRS compression and decompression, typical case", () => { test("PRS compression and decompression, typical case", () => {

View File

@ -238,11 +238,7 @@ export abstract class AbstractCursor implements Cursor {
return String.fromCodePoint(...code_points); return String.fromCodePoint(...code_points);
} }
string_ascii_at( string_ascii_at(offset: number, max_byte_length: number, null_terminated: boolean): string {
offset: number,
max_byte_length: number,
null_terminated: boolean,
): string {
const code_points: number[] = []; const code_points: number[] = [];
for (let i = 0; i < max_byte_length; i++) { for (let i = 0; i < max_byte_length; i++) {
@ -258,11 +254,7 @@ export abstract class AbstractCursor implements Cursor {
return String.fromCodePoint(...code_points); return String.fromCodePoint(...code_points);
} }
string_utf16_at( string_utf16_at(offset: number, max_byte_length: number, null_terminated: boolean): string {
offset: number,
max_byte_length: number,
null_terminated: boolean,
): string {
const code_points: number[] = []; const code_points: number[] = [];
const len = Math.floor(max_byte_length / 2); const len = Math.floor(max_byte_length / 2);

View File

@ -61,7 +61,13 @@ test_all(
"simple properties and invariants", "simple properties and invariants",
() => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], () => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
(cursor, endianness) => { (cursor, endianness) => {
for (const [seek_to, expected_pos] of [[0, 0], [3, 3], [5, 8], [2, 10], [-10, 0]]) { for (const [seek_to, expected_pos] of [
[0, 0],
[3, 3],
[5, 8],
[2, 10],
[-10, 0],
]) {
cursor.seek(seek_to); cursor.seek(seek_to);
expect(cursor.size).toBe(10); expect(cursor.size).toBe(10);

View File

@ -172,20 +172,12 @@ export interface Cursor {
/** /**
* Reads an ASCII-encoded string at the given absolute offset. Doesn't increment position. * Reads an ASCII-encoded string at the given absolute offset. Doesn't increment position.
*/ */
string_ascii_at( string_ascii_at(offset: number, max_byte_length: number, null_terminated: boolean): string;
offset: number,
max_byte_length: number,
null_terminated: boolean,
): string;
/** /**
* Reads an UTF-16-encoded string at the given absolute offset. Doesn't increment position. * Reads an UTF-16-encoded string at the given absolute offset. Doesn't increment position.
*/ */
string_utf16_at( string_utf16_at(offset: number, max_byte_length: number, null_terminated: boolean): string;
offset: number,
max_byte_length: number,
null_terminated: boolean,
): string;
array_buffer(size?: number): ArrayBuffer; array_buffer(size?: number): ArrayBuffer;

View File

@ -55,7 +55,8 @@ type NjcmChunk = {
| NjcmVertexChunk | NjcmVertexChunk
| NjcmVolumeChunk | NjcmVolumeChunk
| NjcmStripChunk | NjcmStripChunk
| NjcmEndChunk); | NjcmEndChunk
);
type NjcmUnknownChunk = { type NjcmUnknownChunk = {
type: NjcmChunkType.Unknown; type: NjcmChunkType.Unknown;

View File

@ -1125,7 +1125,10 @@ define_object_type_data(ObjectType.MedicalCenterDoor, 73, "Medical Center Door",
[Episode.I, [0]], [Episode.I, [0]],
[Episode.IV, [0]], [Episode.IV, [0]],
]); ]);
define_object_type_data(ObjectType.Elevator, 74, "Elevator", [[Episode.I, [0]], [Episode.IV, [0]]]); define_object_type_data(ObjectType.Elevator, 74, "Elevator", [
[Episode.I, [0]],
[Episode.IV, [0]],
]);
define_object_type_data(ObjectType.EasterEgg, 75, "Easter Egg", [ define_object_type_data(ObjectType.EasterEgg, 75, "Easter Egg", [
[Episode.I, [0]], [Episode.I, [0]],
[Episode.II, [0]], [Episode.II, [0]],
@ -1179,7 +1182,11 @@ define_object_type_data(
ObjectType.MainRagolTeleporterBattleInNextArea, ObjectType.MainRagolTeleporterBattleInNextArea,
85, 85,
"Main Ragol Teleporter (Battle in next area?)", "Main Ragol Teleporter (Battle in next area?)",
[[Episode.I, [0]], [Episode.II, [0]], [Episode.IV, [0]]], [
[Episode.I, [0]],
[Episode.II, [0]],
[Episode.IV, [0]],
],
); );
define_object_type_data(ObjectType.LabTeleporterDoor, 86, "Lab Teleporter Door", [ define_object_type_data(ObjectType.LabTeleporterDoor, 86, "Lab Teleporter Door", [
[Episode.II, [0]], [Episode.II, [0]],
@ -1188,7 +1195,11 @@ define_object_type_data(
ObjectType.Pioneer2InvisibleTouchplate, ObjectType.Pioneer2InvisibleTouchplate,
87, 87,
"Pioneer 2 Invisible Touchplate", "Pioneer 2 Invisible Touchplate",
[[Episode.I, [0]], [Episode.II, [0]], [Episode.IV, [0]]], [
[Episode.I, [0]],
[Episode.II, [0]],
[Episode.IV, [0]],
],
); );
define_object_type_data(ObjectType.ForestDoor, 128, "Forest Door", [[Episode.I, [1, 2]]]); define_object_type_data(ObjectType.ForestDoor, 128, "Forest Door", [[Episode.I, [1, 2]]]);
define_object_type_data(ObjectType.ForestSwitch, 129, "Forest Switch", [ define_object_type_data(ObjectType.ForestSwitch, 129, "Forest Switch", [
@ -1388,7 +1399,10 @@ define_object_type_data(
ObjectType.GreenScreenOpeningAndClosing, ObjectType.GreenScreenOpeningAndClosing,
261, 261,
"Green Screen opening and closing", "Green Screen opening and closing",
[[Episode.I, [6, 7]], [Episode.II, [17]]], [
[Episode.I, [6, 7]],
[Episode.II, [17]],
],
); );
define_object_type_data(ObjectType.FloatingRobot, 262, "Floating Robot", [[Episode.I, [6, 7]]]); define_object_type_data(ObjectType.FloatingRobot, 262, "Floating Robot", [[Episode.I, [6, 7]]]);
define_object_type_data(ObjectType.FloatingBlueLight, 263, "Floating Blue Light", [ define_object_type_data(ObjectType.FloatingBlueLight, 263, "Floating Blue Light", [
@ -1575,7 +1589,10 @@ define_object_type_data(
ObjectType.BreakableWallWallButUnbreakable, ObjectType.BreakableWallWallButUnbreakable,
417, 417,
'"breakable wall wall, but unbreakable"', '"breakable wall wall, but unbreakable"',
[[Episode.I, [17]], [Episode.II, [1, 2]]], [
[Episode.I, [17]],
[Episode.II, [1, 2]],
],
); );
define_object_type_data(ObjectType.BrokenCylinderAndRubble, 418, "Broken cylinder and rubble", [ define_object_type_data(ObjectType.BrokenCylinderAndRubble, 418, "Broken cylinder and rubble", [
[Episode.I, [17]], [Episode.I, [17]],
@ -1585,7 +1602,10 @@ define_object_type_data(
ObjectType.ThreeBrokenWallPiecesOnFloor, ObjectType.ThreeBrokenWallPiecesOnFloor,
419, 419,
"3 broken wall pieces on floor", "3 broken wall pieces on floor",
[[Episode.I, [17]], [Episode.II, [1, 2]]], [
[Episode.I, [17]],
[Episode.II, [1, 2]],
],
); );
define_object_type_data(ObjectType.HighBrickCylinder, 420, "high brick cylinder", [ define_object_type_data(ObjectType.HighBrickCylinder, 420, "high brick cylinder", [
[Episode.I, [17]], [Episode.I, [17]],
@ -1612,13 +1632,19 @@ define_object_type_data(
ObjectType.SmallBrownBrickRisingBridge, ObjectType.SmallBrownBrickRisingBridge,
425, 425,
"small brown brick rising bridge", "small brown brick rising bridge",
[[Episode.I, [17]], [Episode.II, [1, 2]]], [
[Episode.I, [17]],
[Episode.II, [1, 2]],
],
); );
define_object_type_data( define_object_type_data(
ObjectType.LongRisingBridgeWithPinkHighEdges, ObjectType.LongRisingBridgeWithPinkHighEdges,
426, 426,
"long rising bridge (with pink high edges)", "long rising bridge (with pink high edges)",
[[Episode.I, [17]], [Episode.II, [1, 2]]], [
[Episode.I, [17]],
[Episode.II, [1, 2]],
],
); );
define_object_type_data(ObjectType.FourSwitchTempleDoor, 427, "4 switch temple door", [ define_object_type_data(ObjectType.FourSwitchTempleDoor, 427, "4 switch temple door", [
[Episode.II, [1, 2]], [Episode.II, [1, 2]],

View File

@ -1,15 +1,19 @@
import Logger = require("js-logger");
const logger = Logger.get("core/decorators");
/** /**
* Prints a warning when the method is called. * Prints a warning when the method is called.
*/ */
export const stub: MethodDecorator = function stub( export const stub: MethodDecorator = function stub(
target: Object, target: Record<string, any>,
prop_key: PropertyKey, prop_key: PropertyKey,
descriptor: PropertyDescriptor, descriptor: PropertyDescriptor,
) { ) {
const orig_method: Function = descriptor.value; const orig_method: Function = descriptor.value;
descriptor.value = function(...args: any[]): any { descriptor.value = function(...args: any[]): any {
console.warn(`Stub: ${target.constructor.name}.prototype.${String(prop_key)}`); logger.warn(`Stub: ${target.constructor.name}.prototype.${String(prop_key)}`);
return orig_method.apply(this, args); return orig_method.apply(this, args);
}; };

View File

@ -87,7 +87,10 @@ export class ComboBox<T> extends LabelledControl {
this.bind_hidden(down_arrow_element, this.menu.visible); this.bind_hidden(down_arrow_element, this.menu.visible);
const up_arrow_element = el.span({}, icon(Icon.TriangleUp)); const up_arrow_element = el.span({}, icon(Icon.TriangleUp));
this.bind_hidden(up_arrow_element, this.menu.visible.map(v => !v)); this.bind_hidden(
up_arrow_element,
this.menu.visible.map(v => !v),
);
const button_element = el.span( const button_element = el.span(
{ class: "core_ComboBox_button" }, { class: "core_ComboBox_button" },

View File

@ -7,7 +7,7 @@ export class LazyWidget extends ResizableWidget {
readonly element = el.div({ class: "core_LazyView" }); readonly element = el.div({ class: "core_LazyView" });
private initialized = false; private initialized = false;
private view: Widget & Resizable | undefined; private view: (Widget & Resizable) | undefined;
constructor(private create_view: () => Promise<Widget & Resizable>) { constructor(private create_view: () => Promise<Widget & Resizable>) {
super(); super();

View File

@ -190,7 +190,12 @@ class GeometryCreator {
} }
} }
const bones = [[0, 0], [0, 0], [0, 0], [0, 0]]; const bones = [
[0, 0],
[0, 0],
[0, 0],
[0, 0],
];
for (let j = vertices.length - 1; j >= 0; j--) { for (let j = vertices.length - 1; j >= 0; j--) {
const vertex = vertices[j]; const vertex = vertices[j];

View File

@ -37,9 +37,9 @@ class HuntOptimizerStore implements Disposable {
readonly wanted_items: ListProperty<WantedItemModel>; readonly wanted_items: ListProperty<WantedItemModel>;
readonly result: Property<OptimalResultModel | undefined>; readonly result: Property<OptimalResultModel | undefined>;
private readonly _wanted_items: WritableListProperty<WantedItemModel> = list_property( private readonly _wanted_items: WritableListProperty<
wanted_item => [wanted_item.amount], WantedItemModel
); > = list_property(wanted_item => [wanted_item.amount]);
private readonly disposer = new Disposer(); private readonly disposer = new Disposer();
constructor( constructor(

View File

@ -1,7 +1,7 @@
import { ExecutionResult, VirtualMachine, ExecutionLocation } from "./scripting/vm"; import { ExecutionResult, VirtualMachine, ExecutionLocation } from "./scripting/vm";
import { QuestModel } from "./model/QuestModel"; import { QuestModel } from "./model/QuestModel";
import { VirtualMachineIO } from "./scripting/vm/io"; import { VirtualMachineIO } from "./scripting/vm/io";
import { AsmToken, SegmentType, InstructionSegment, Segment, Instruction } from "./scripting/instructions"; import { AsmToken, SegmentType, InstructionSegment, Instruction } from "./scripting/instructions";
import { quest_editor_store, Logger } from "./stores/QuestEditorStore"; import { quest_editor_store, Logger } from "./stores/QuestEditorStore";
import { defined, assert } from "../core/util"; import { defined, assert } from "../core/util";
import { import {
@ -27,10 +27,6 @@ function srcloc_to_string(srcloc: AsmToken): string {
return `[${srcloc.line_no}:${srcloc.col}]`; return `[${srcloc.line_no}:${srcloc.col}]`;
} }
function execloc_to_string(execloc: ExecutionLocation) {
return `[${execloc.seg_idx}:${execloc.inst_idx}]`;
}
export class QuestRunner { export class QuestRunner {
private readonly vm: VirtualMachine; private readonly vm: VirtualMachine;
private quest?: QuestModel; private quest?: QuestModel;
@ -144,7 +140,7 @@ export class QuestRunner {
} }
public step_out(): void { public step_out(): void {
// unimplemented
} }
public stop(): void { public stop(): void {
@ -164,7 +160,7 @@ export class QuestRunner {
let need_emit_unpause = this.paused.val; let need_emit_unpause = this.paused.val;
exec_loop: while (true) { exec_loop: while (true) {
if (this.first_frame || this.executed_since_advance) { if (this.first_frame || this.executed_since_advance) {
if (!this.first_frame) { if (!this.first_frame) {
this.vm.advance(); this.vm.advance();
@ -281,7 +277,7 @@ export class QuestRunner {
return this.get_instruction_segment_by_index(seg_idx); return this.get_instruction_segment_by_index(seg_idx);
} }
private get_step_innable_instruction_label_argument(instr: Instruction): number | undefined { private get_step_innable_instruction_label_argument(instr: Instruction): number | undefined {
switch (instr.opcode.code) { switch (instr.opcode.code) {
case OP_VA_CALL.code: case OP_VA_CALL.code:
case OP_CALL.code: case OP_CALL.code:
@ -317,7 +313,7 @@ export class QuestRunner {
return dst_srcloc; return dst_srcloc;
} }
private get_next_source_location(execloc: ExecutionLocation): AsmToken | undefined { private get_next_source_location(execloc: ExecutionLocation): AsmToken | undefined {
defined(this.quest); defined(this.quest);
const next_loc = new ExecutionLocation(execloc.seg_idx, execloc.inst_idx); const next_loc = new ExecutionLocation(execloc.seg_idx, execloc.inst_idx);

View File

@ -89,7 +89,10 @@ export class AsmEditorView extends ResizableWidget {
asm_editor_store.model.observe( asm_editor_store.model.observe(
({ value: model }) => { ({ value: model }) => {
this.editor.updateOptions({ readOnly: model == undefined && !quest_editor_store.quest_runner.running.val }); this.editor.updateOptions({
readOnly:
model == undefined && !quest_editor_store.quest_runner.running.val,
});
this.editor.setModel(model || DUMMY_MODEL); this.editor.setModel(model || DUMMY_MODEL);
this.history.reset(); this.history.reset();
@ -102,11 +105,12 @@ export class AsmEditorView extends ResizableWidget {
), ),
// disable editor when quest is running // disable editor when quest is running
quest_editor_store.quest_runner.running.observe(({value}) => this.editor.updateOptions({readOnly: value})), quest_editor_store.quest_runner.running.observe(({ value }) =>
this.editor.updateOptions({ readOnly: value }),
),
asm_editor_store.breakpoints.observe_list(change => { asm_editor_store.breakpoints.observe_list(change => {
if (change.type === ListChangeType.ListChange) { if (change.type === ListChangeType.ListChange) {
// remove // remove
for (const line_num of change.removed) { for (const line_num of change.removed) {
const cur_decos = this.editor.getLineDecorations(line_num); const cur_decos = this.editor.getLineDecorations(line_num);
@ -129,17 +133,29 @@ export class AsmEditorView extends ResizableWidget {
for (const line_num of change.inserted) { for (const line_num of change.inserted) {
const cur_decos = this.editor.getLineDecorations(line_num); const cur_decos = this.editor.getLineDecorations(line_num);
// don't allow duplicates // don't allow duplicates
if (!cur_decos?.some(deco => this.breakpoint_decoration_ids.includes(deco.id))) { if (
!cur_decos?.some(deco =>
this.breakpoint_decoration_ids.includes(deco.id),
)
) {
// add new decoration, don't overwrite anything, save decoration id // add new decoration, don't overwrite anything, save decoration id
this.breakpoint_decoration_ids.push(this.editor.deltaDecorations([], [{ this.breakpoint_decoration_ids.push(
range: new Range(line_num, 0, line_num, 0), this.editor.deltaDecorations(
options: { [],
glyphMarginClassName: "quest_editor_AsmEditorView_breakpoint-enabled", [
glyphMarginHoverMessage: { {
value: "Breakpoint" range: new Range(line_num, 0, line_num, 0),
} options: {
} glyphMarginClassName:
}])[0]); "quest_editor_AsmEditorView_breakpoint-enabled",
glyphMarginHoverMessage: {
value: "Breakpoint",
},
},
},
],
)[0],
);
} }
} }
} }
@ -160,13 +176,18 @@ export class AsmEditorView extends ResizableWidget {
// add new // add new
if (new_line_num !== undefined) { if (new_line_num !== undefined) {
this.execloc_decoration_id = this.editor.deltaDecorations([], [{ this.execloc_decoration_id = this.editor.deltaDecorations(
range: new Range(new_line_num, 0, new_line_num, 0), [],
options: { [
className: "quest_editor_AsmEditorView_execution-location", {
isWholeLine: true, range: new Range(new_line_num, 0, new_line_num, 0),
} options: {
}])[0]; className: "quest_editor_AsmEditorView_execution-location",
isWholeLine: true,
},
},
],
)[0];
} }
}), }),
@ -175,11 +196,13 @@ export class AsmEditorView extends ResizableWidget {
this.editor.onMouseDown(e => { this.editor.onMouseDown(e => {
switch (e.target.type) { switch (e.target.type) {
case editor.MouseTargetType.GUTTER_GLYPH_MARGIN: case editor.MouseTargetType.GUTTER_GLYPH_MARGIN:
const pos = e.target.position; {
if (!pos) { const pos = e.target.position;
return; if (!pos) {
return;
}
asm_editor_store.toggle_breakpoint(pos.lineNumber);
} }
asm_editor_store.toggle_breakpoint(pos.lineNumber);
break; break;
default: default:
break; break;

View File

@ -1,4 +1,3 @@
import { ResizableWidget } from "../../core/gui/ResizableWidget";
import { quest_editor_store } from "../stores/QuestEditorStore"; import { quest_editor_store } from "../stores/QuestEditorStore";
import { MessageLog } from "../../core/gui/MessageLog"; import { MessageLog } from "../../core/gui/MessageLog";
import "./QuestMessageLogView.css"; import "./QuestMessageLogView.css";

View File

@ -634,7 +634,11 @@ class CreationState implements State {
new Euler(0, 0, 0, "ZXY"), new Euler(0, 0, 0, "ZXY"),
new Vector3(1, 1, 1), new Vector3(1, 1, 1),
// TODO: do the following values make sense? // TODO: do the following values make sense?
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0]], [
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0],
],
); );
} else { } else {
this.entity = new QuestObjectModel( this.entity = new QuestObjectModel(
@ -648,7 +652,10 @@ class CreationState implements State {
// TODO: which default properties? // TODO: which default properties?
new Map(), new Map(),
// TODO: do the following values make sense? // TODO: do the following values make sense?
[[0, 0, 0, 0, 0, 0], [0, 0]], [
[0, 0, 0, 0, 0, 0],
[0, 0],
],
); );
} }

View File

@ -2,6 +2,7 @@ import { stub } from "../../../core/decorators";
import { AsmToken } from "../instructions"; import { AsmToken } from "../instructions";
import { VirtualMachineIO } from "./io"; import { VirtualMachineIO } from "./io";
/* eslint-disable */
/** /**
* All methods of VirtualMachineIO implemented as stubs. * All methods of VirtualMachineIO implemented as stubs.
*/ */
@ -15,3 +16,4 @@ export class VMIOStub implements VirtualMachineIO {
@stub warning(msg: string, srcloc?: AsmToken): void {} @stub warning(msg: string, srcloc?: AsmToken): void {}
@stub error(err: Error, srcloc?: AsmToken): void {} @stub error(err: Error, srcloc?: AsmToken): void {}
} }
/* eslint-enable */

View File

@ -10,7 +10,7 @@ import { srand } from "./windows";
test("integer arithmetic opcodes", () => { test("integer arithmetic opcodes", () => {
class TestIO extends VMIOStub { class TestIO extends VMIOStub {
error = jest.fn((err: Error, srcloc: any) => { error = jest.fn((err: Error) => {
throw err; throw err;
}); });
} }
@ -77,7 +77,7 @@ test("integer arithmetic opcodes", () => {
// TODO: add more fp tests // TODO: add more fp tests
test("floating point arithmetic opcodes", () => { test("floating point arithmetic opcodes", () => {
class TestIO extends VMIOStub { class TestIO extends VMIOStub {
error = jest.fn((err: Error, srcloc: any) => { error = jest.fn((err: Error) => {
throw err; throw err;
}); });
} }
@ -101,7 +101,7 @@ test("floating point arithmetic opcodes", () => {
last_result = vm.execute(); last_result = vm.execute();
} while (last_result !== ExecutionResult.Halted); } while (last_result !== ExecutionResult.Halted);
expect(vm.get_register_float(100)).toBeCloseTo(7.4505806e-09, precision); expect(vm.get_register_float(100)).toBeCloseTo(7.4505806e-9, precision);
expect(vm.get_register_float(101)).toBeCloseTo(134217728, precision); expect(vm.get_register_float(101)).toBeCloseTo(134217728, precision);
}); });
@ -133,7 +133,7 @@ test("basic window_msg output", () => {
winend = jest.fn(() => {}); winend = jest.fn(() => {});
error = jest.fn((err: Error, loc: any) => { error = jest.fn((err: Error) => {
throw err; throw err;
}); });
} }
@ -214,9 +214,7 @@ test("opcode get_random", () => {
}); });
test("opcode list", () => { test("opcode list", () => {
const list_items = [ const list_items = ["a", "b", "c", "d"];
"a", "b", "c", "d"
];
const list_text = list_items.join("\\n"); const list_text = list_items.join("\\n");
class TestIO extends VMIOStub { class TestIO extends VMIOStub {
constructor() { constructor() {

View File

@ -109,7 +109,6 @@ const ARG_STACK_SLOT_SIZE = 4;
const ARG_STACK_LENGTH = 8; const ARG_STACK_LENGTH = 8;
const STRING_ARG_STORE_ADDRESS = 0x00a92700; const STRING_ARG_STORE_ADDRESS = 0x00a92700;
const STRING_ARG_STORE_SIZE = 1024; // TODO: verify this value const STRING_ARG_STORE_SIZE = 1024; // TODO: verify this value
const FLOAT_EPSILON = 1.19e-7;
const ENTRY_SEGMENT = 0; const ENTRY_SEGMENT = 0;
const LIST_ITEM_DELIMITER = "\n"; const LIST_ITEM_DELIMITER = "\n";
@ -237,7 +236,7 @@ export class VirtualMachine {
} }
} }
private update_source_location(exec: Thread) { private update_source_location(exec: Thread): void {
const inst = this.get_next_instruction_from_thread(exec); const inst = this.get_next_instruction_from_thread(exec);
if (inst.asm && inst.asm.mnemonic) { if (inst.asm && inst.asm.mnemonic) {
@ -299,7 +298,9 @@ export class VirtualMachine {
const inst = this.get_next_instruction_from_thread(exec); const inst = this.get_next_instruction_from_thread(exec);
return this.execute_instruction(auto_advance, exec, inst, srcloc); return this.execute_instruction(auto_advance, exec, inst, srcloc);
} catch (err) { } catch (thrown) {
let err = thrown;
if (!(err instanceof Error)) { if (!(err instanceof Error)) {
err = new Error(String(err)); err = new Error(String(err));
} }

View File

@ -3,7 +3,10 @@ import { AsmToken } from "../instructions";
/** /**
* The virtual machine calls these methods when it requires input. * The virtual machine calls these methods when it requires input.
*/ */
export interface VirtualMachineInput {} // eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface VirtualMachineInput {
// unimplemented
}
/** /**
* The virtual machine calls these methods when it outputs something. * The virtual machine calls these methods when it outputs something.

View File

@ -2,8 +2,7 @@
* @file Implementations of some parts of the Win32 API and the MSVCRT C standard library. * @file Implementations of some parts of the Win32 API and the MSVCRT C standard library.
*/ */
let holdrand = 1;
var holdrand = 1;
export function srand(seed: number): void { export function srand(seed: number): void {
holdrand = seed; holdrand = seed;
@ -12,7 +11,7 @@ export function srand(seed: number): void {
export function rand(): number { export function rand(): number {
const r = (holdrand * 0x343fd + 0x269ec3) >>> 0; const r = (holdrand * 0x343fd + 0x269ec3) >>> 0;
holdrand = r; holdrand = r;
return r >>> 0x10 & 0x7fff; return (r >>> 0x10) & 0x7fff;
} }
export function GetTickCount(): number { export function GetTickCount(): number {

View File

@ -50,16 +50,13 @@ export class QuestEditorStore implements Disposable, MessageLogStore {
*/ */
private readonly log_levels_map = (function<KT extends readonly string[]>(names: KT) { private readonly log_levels_map = (function<KT extends readonly string[]>(names: KT) {
type K = KT[keyof KT & number]; type K = KT[keyof KT & number];
return names.reduce<Record<K, LogLevel>>( return names.reduce<Record<K, LogLevel>>((accum, name: K, idx) => {
(accum, name: K, idx) => { accum[name] = {
accum[name] = { name: name,
name: name, value: idx,
value: idx, };
}; return accum;
return accum; }, {} as Record<K, LogLevel>);
},
{} as Record<K, LogLevel>,
);
})( })(
// Log level names in order of importance // Log level names in order of importance
["Debug", "Info", "Warning", "Error"] as const, ["Debug", "Info", "Warning", "Error"] as const,
@ -127,11 +124,13 @@ export class QuestEditorStore implements Disposable, MessageLogStore {
}), }),
// force refresh // force refresh
/* eslint-disable no-self-assign */
this._log_level.observe(() => (this._log_messages.val = this._log_messages.val)), this._log_level.observe(() => (this._log_messages.val = this._log_messages.val)),
this._log_group.observe(() => (this._log_messages.val = this._log_messages.val)), this._log_group.observe(() => (this._log_messages.val = this._log_messages.val)),
this._show_all_log_groups.observe( this._show_all_log_groups.observe(
() => (this._log_messages.val = this._log_messages.val), () => (this._log_messages.val = this._log_messages.val),
), ),
/* eslint-enable no-self-assign */
); );
this.log_messages = this._log_messages.filtered(this.log_message_predicate); this.log_messages = this._log_messages.filtered(this.log_message_predicate);

View File

@ -72,13 +72,15 @@ export function convert_quest_to_model(quest: Quest): QuestModel {
function build_event_dags(dat_events: readonly DatEvent[]): QuestEventDagModel[] { function build_event_dags(dat_events: readonly DatEvent[]): QuestEventDagModel[] {
// Build up a temporary data structure with partial data. // Build up a temporary data structure with partial data.
// Maps event id and area id to data. // Maps event id and area id to data.
const data_map = new Map<string, const data_map = new Map<
string,
{ {
event?: QuestEventModel; event?: QuestEventModel;
area_id: number; area_id: number;
parents: QuestEventModel[]; parents: QuestEventModel[];
child_ids: number[]; child_ids: number[];
}>(); }
>();
for (const event of dat_events) { for (const event of dat_events) {
const key = `${event.id}-${event.area_id}`; const key = `${event.id}-${event.area_id}`;
@ -122,22 +124,23 @@ function build_event_dags(dat_events: readonly DatEvent[]): QuestEventDagModel[]
case DatEventActionType.Lock: case DatEventActionType.Lock:
event_model.add_action(new QuestEventActionLockModel(action.door_id)); event_model.add_action(new QuestEventActionLockModel(action.door_id));
break; break;
case DatEventActionType.TriggerEvent: { case DatEventActionType.TriggerEvent:
data.child_ids.push(action.event_id); {
data.child_ids.push(action.event_id);
const child_key = `${action.event_id}-${event.area_id}`; const child_key = `${action.event_id}-${event.area_id}`;
const child_data = data_map.get(child_key); const child_data = data_map.get(child_key);
if (child_data) { if (child_data) {
child_data.parents.push(event_model); child_data.parents.push(event_model);
} else { } else {
data_map.set(child_key, { data_map.set(child_key, {
area_id: event.area_id, area_id: event.area_id,
parents: [event_model], parents: [event_model],
child_ids: [], child_ids: [],
}); });
}
} }
}
break; break;
default: default:
logger.warn(`Unknown event action type: ${(action as any).type}.`); logger.warn(`Unknown event action type: ${(action as any).type}.`);
@ -273,7 +276,7 @@ export function convert_quest_from_model(quest: QuestModel): Quest {
pso_roaming: npc.pso_roaming, pso_roaming: npc.pso_roaming,
})), })),
events: convert_quest_events_from_model(quest.event_dags.val), events: convert_quest_events_from_model(quest.event_dags.val),
dat_unknowns: quest.dat_unknowns.map(unk => ({...unk})), dat_unknowns: quest.dat_unknowns.map(unk => ({ ...unk })),
object_code: quest.object_code.map(seg => clone_segment(seg)), object_code: quest.object_code.map(seg => clone_segment(seg)),
shop_items: quest.shop_items.slice(), shop_items: quest.shop_items.slice(),
map_designations: new Map(quest.map_designations.val), map_designations: new Map(quest.map_designations.val),

View File

@ -114,7 +114,10 @@ function create_default_objects(): QuestObjectModel[] {
["property_5", 0], ["property_5", 0],
["property_6", 2365279104], ["property_6", 2365279104],
]), ]),
[[2, 0, 0, 0, 0, 0], [0, 0]], [
[2, 0, 0, 0, 0, 0],
[0, 0],
],
), ),
new QuestObjectModel( new QuestObjectModel(
ObjectType.MenuActivation, ObjectType.MenuActivation,
@ -133,7 +136,10 @@ function create_default_objects(): QuestObjectModel[] {
["property_5", 0], ["property_5", 0],
["property_6", 2365279264], ["property_6", 2365279264],
]), ]),
[[2, 0, 1, 0, 0, 0], [0, 0]], [
[2, 0, 1, 0, 0, 0],
[0, 0],
],
), ),
new QuestObjectModel( new QuestObjectModel(
ObjectType.MenuActivation, ObjectType.MenuActivation,
@ -152,7 +158,10 @@ function create_default_objects(): QuestObjectModel[] {
["property_5", 10], ["property_5", 10],
["property_6", 2365279424], ["property_6", 2365279424],
]), ]),
[[2, 0, 2, 0, 0, 0], [0, 0]], [
[2, 0, 2, 0, 0, 0],
[0, 0],
],
), ),
new QuestObjectModel( new QuestObjectModel(
ObjectType.MenuActivation, ObjectType.MenuActivation,
@ -171,7 +180,10 @@ function create_default_objects(): QuestObjectModel[] {
["property_5", 0], ["property_5", 0],
["property_6", 2365279584], ["property_6", 2365279584],
]), ]),
[[2, 0, 3, 0, 0, 0], [0, 0]], [
[2, 0, 3, 0, 0, 0],
[0, 0],
],
), ),
new QuestObjectModel( new QuestObjectModel(
ObjectType.PlayerSet, ObjectType.PlayerSet,
@ -190,7 +202,10 @@ function create_default_objects(): QuestObjectModel[] {
["property_5", 0], ["property_5", 0],
["property_6", 2365279744], ["property_6", 2365279744],
]), ]),
[[2, 0, 4, 0, 0, 0], [0, 0]], [
[2, 0, 4, 0, 0, 0],
[0, 0],
],
), ),
new QuestObjectModel( new QuestObjectModel(
ObjectType.PlayerSet, ObjectType.PlayerSet,
@ -209,7 +224,10 @@ function create_default_objects(): QuestObjectModel[] {
["property_5", 0], ["property_5", 0],
["property_6", 2365279904], ["property_6", 2365279904],
]), ]),
[[2, 0, 5, 0, 0, 0], [0, 0]], [
[2, 0, 5, 0, 0, 0],
[0, 0],
],
), ),
new QuestObjectModel( new QuestObjectModel(
ObjectType.PlayerSet, ObjectType.PlayerSet,
@ -228,7 +246,10 @@ function create_default_objects(): QuestObjectModel[] {
["property_5", 0], ["property_5", 0],
["property_6", 2365280064], ["property_6", 2365280064],
]), ]),
[[2, 0, 6, 0, 0, 0], [0, 0]], [
[2, 0, 6, 0, 0, 0],
[0, 0],
],
), ),
new QuestObjectModel( new QuestObjectModel(
ObjectType.PlayerSet, ObjectType.PlayerSet,
@ -247,7 +268,10 @@ function create_default_objects(): QuestObjectModel[] {
["property_5", 0], ["property_5", 0],
["property_6", 2365280224], ["property_6", 2365280224],
]), ]),
[[2, 0, 7, 0, 0, 0], [0, 0]], [
[2, 0, 7, 0, 0, 0],
[0, 0],
],
), ),
new QuestObjectModel( new QuestObjectModel(
ObjectType.MainRagolTeleporter, ObjectType.MainRagolTeleporter,
@ -266,7 +290,10 @@ function create_default_objects(): QuestObjectModel[] {
["property_5", 0], ["property_5", 0],
["property_6", 2365227216], ["property_6", 2365227216],
]), ]),
[[0, 0, 87, 7, 0, 0], [0, 0]], [
[0, 0, 87, 7, 0, 0],
[0, 0],
],
), ),
new QuestObjectModel( new QuestObjectModel(
ObjectType.PrincipalWarp, ObjectType.PrincipalWarp,
@ -285,7 +312,10 @@ function create_default_objects(): QuestObjectModel[] {
["property_5", 65536], ["property_5", 65536],
["property_6", 2365280688], ["property_6", 2365280688],
]), ]),
[[2, 0, 9, 0, 0, 0], [0, 0]], [
[2, 0, 9, 0, 0, 0],
[0, 0],
],
), ),
new QuestObjectModel( new QuestObjectModel(
ObjectType.MenuActivation, ObjectType.MenuActivation,
@ -304,7 +334,10 @@ function create_default_objects(): QuestObjectModel[] {
["property_5", 0], ["property_5", 0],
["property_6", 2365280992], ["property_6", 2365280992],
]), ]),
[[2, 0, 10, 0, 0, 0], [1, 0]], [
[2, 0, 10, 0, 0, 0],
[1, 0],
],
), ),
new QuestObjectModel( new QuestObjectModel(
ObjectType.MenuActivation, ObjectType.MenuActivation,
@ -323,7 +356,10 @@ function create_default_objects(): QuestObjectModel[] {
["property_5", 0], ["property_5", 0],
["property_6", 2365281152], ["property_6", 2365281152],
]), ]),
[[2, 0, 11, 0, 0, 0], [0, 0]], [
[2, 0, 11, 0, 0, 0],
[0, 0],
],
), ),
new QuestObjectModel( new QuestObjectModel(
ObjectType.PrincipalWarp, ObjectType.PrincipalWarp,
@ -342,7 +378,10 @@ function create_default_objects(): QuestObjectModel[] {
["property_5", 0], ["property_5", 0],
["property_6", 2365281312], ["property_6", 2365281312],
]), ]),
[[2, 0, 12, 0, 0, 0], [0, 0]], [
[2, 0, 12, 0, 0, 0],
[0, 0],
],
), ),
new QuestObjectModel( new QuestObjectModel(
ObjectType.TelepipeLocation, ObjectType.TelepipeLocation,
@ -361,7 +400,10 @@ function create_default_objects(): QuestObjectModel[] {
["property_5", 0], ["property_5", 0],
["property_6", 2365281616], ["property_6", 2365281616],
]), ]),
[[2, 0, 13, 0, 0, 0], [0, 0]], [
[2, 0, 13, 0, 0, 0],
[0, 0],
],
), ),
new QuestObjectModel( new QuestObjectModel(
ObjectType.TelepipeLocation, ObjectType.TelepipeLocation,
@ -380,7 +422,10 @@ function create_default_objects(): QuestObjectModel[] {
["property_5", 0], ["property_5", 0],
["property_6", 2365281808], ["property_6", 2365281808],
]), ]),
[[2, 0, 14, 0, 0, 0], [0, 0]], [
[2, 0, 14, 0, 0, 0],
[0, 0],
],
), ),
new QuestObjectModel( new QuestObjectModel(
ObjectType.TelepipeLocation, ObjectType.TelepipeLocation,
@ -399,7 +444,10 @@ function create_default_objects(): QuestObjectModel[] {
["property_5", 0], ["property_5", 0],
["property_6", 2365282000], ["property_6", 2365282000],
]), ]),
[[2, 0, 15, 0, 0, 0], [0, 0]], [
[2, 0, 15, 0, 0, 0],
[0, 0],
],
), ),
new QuestObjectModel( new QuestObjectModel(
ObjectType.TelepipeLocation, ObjectType.TelepipeLocation,
@ -418,7 +466,10 @@ function create_default_objects(): QuestObjectModel[] {
["property_5", 10], ["property_5", 10],
["property_6", 2365282192], ["property_6", 2365282192],
]), ]),
[[2, 0, 16, 0, 0, 0], [0, 0]], [
[2, 0, 16, 0, 0, 0],
[0, 0],
],
), ),
new QuestObjectModel( new QuestObjectModel(
ObjectType.MedicalCenterDoor, ObjectType.MedicalCenterDoor,
@ -437,7 +488,10 @@ function create_default_objects(): QuestObjectModel[] {
["property_5", 0], ["property_5", 0],
["property_6", 2365282384], ["property_6", 2365282384],
]), ]),
[[2, 0, 17, 0, 0, 0], [0, 0]], [
[2, 0, 17, 0, 0, 0],
[0, 0],
],
), ),
new QuestObjectModel( new QuestObjectModel(
ObjectType.ShopDoor, ObjectType.ShopDoor,
@ -456,7 +510,10 @@ function create_default_objects(): QuestObjectModel[] {
["property_5", 0], ["property_5", 0],
["property_6", 2365282640], ["property_6", 2365282640],
]), ]),
[[2, 0, 18, 0, 0, 0], [0, 0]], [
[2, 0, 18, 0, 0, 0],
[0, 0],
],
), ),
new QuestObjectModel( new QuestObjectModel(
ObjectType.MenuActivation, ObjectType.MenuActivation,
@ -475,7 +532,10 @@ function create_default_objects(): QuestObjectModel[] {
["property_5", 0], ["property_5", 0],
["property_6", 2365282896], ["property_6", 2365282896],
]), ]),
[[2, 0, 19, 0, 0, 0], [0, 0]], [
[2, 0, 19, 0, 0, 0],
[0, 0],
],
), ),
new QuestObjectModel( new QuestObjectModel(
ObjectType.HuntersGuildDoor, ObjectType.HuntersGuildDoor,
@ -494,7 +554,10 @@ function create_default_objects(): QuestObjectModel[] {
["property_5", 0], ["property_5", 0],
["property_6", 2365283056], ["property_6", 2365283056],
]), ]),
[[2, 0, 20, 0, 0, 0], [0, 0]], [
[2, 0, 20, 0, 0, 0],
[0, 0],
],
), ),
new QuestObjectModel( new QuestObjectModel(
ObjectType.TeleporterDoor, ObjectType.TeleporterDoor,
@ -513,7 +576,10 @@ function create_default_objects(): QuestObjectModel[] {
["property_5", 0], ["property_5", 0],
["property_6", 2365283312], ["property_6", 2365283312],
]), ]),
[[2, 0, 21, 0, 0, 0], [0, 0]], [
[2, 0, 21, 0, 0, 0],
[0, 0],
],
), ),
new QuestObjectModel( new QuestObjectModel(
ObjectType.PlayerSet, ObjectType.PlayerSet,
@ -532,7 +598,10 @@ function create_default_objects(): QuestObjectModel[] {
["property_5", 0], ["property_5", 0],
["property_6", 2365283568], ["property_6", 2365283568],
]), ]),
[[2, 0, 22, 0, 0, 0], [0, 0]], [
[2, 0, 22, 0, 0, 0],
[0, 0],
],
), ),
new QuestObjectModel( new QuestObjectModel(
ObjectType.PlayerSet, ObjectType.PlayerSet,
@ -551,7 +620,10 @@ function create_default_objects(): QuestObjectModel[] {
["property_5", 0], ["property_5", 0],
["property_6", 2365283728], ["property_6", 2365283728],
]), ]),
[[2, 0, 23, 0, 0, 0], [0, 0]], [
[2, 0, 23, 0, 0, 0],
[0, 0],
],
), ),
new QuestObjectModel( new QuestObjectModel(
ObjectType.PlayerSet, ObjectType.PlayerSet,
@ -570,7 +642,10 @@ function create_default_objects(): QuestObjectModel[] {
["property_5", 0], ["property_5", 0],
["property_6", 2365283888], ["property_6", 2365283888],
]), ]),
[[2, 0, 24, 0, 0, 0], [0, 0]], [
[2, 0, 24, 0, 0, 0],
[0, 0],
],
), ),
new QuestObjectModel( new QuestObjectModel(
ObjectType.PlayerSet, ObjectType.PlayerSet,
@ -589,7 +664,10 @@ function create_default_objects(): QuestObjectModel[] {
["property_5", 0], ["property_5", 0],
["property_6", 2365284048], ["property_6", 2365284048],
]), ]),
[[2, 0, 25, 0, 0, 0], [0, 0]], [
[2, 0, 25, 0, 0, 0],
[0, 0],
],
), ),
]; ];
} }
@ -607,7 +685,11 @@ function create_default_npcs(): QuestNpcModel[] {
new Vector3(-49.0010986328125, 0, 50.996429443359375), new Vector3(-49.0010986328125, 0, 50.996429443359375),
new Euler(0, 2.3562304434156633, 0, "ZXY"), new Euler(0, 2.3562304434156633, 0, "ZXY"),
new Vector3(0, 0, 0), new Vector3(0, 0, 0),
[[0, 0, 7, 86, 0, 0, 0, 0, 23, 87], [0, 0, 0, 0, 0, 0], [128, 238, 223, 176]], [
[0, 0, 7, 86, 0, 0, 0, 0, 23, 87],
[0, 0, 0, 0, 0, 0],
[128, 238, 223, 176],
],
), ),
new QuestNpcModel( new QuestNpcModel(
NpcType.FemaleFat, NpcType.FemaleFat,
@ -620,7 +702,11 @@ function create_default_npcs(): QuestNpcModel[] {
new Vector3(167.99769592285156, 0, 83.99686431884766), new Vector3(167.99769592285156, 0, 83.99686431884766),
new Euler(0, 3.927050739026106, 0, "ZXY"), new Euler(0, 3.927050739026106, 0, "ZXY"),
new Vector3(24.000009536743164, 0, 0), new Vector3(24.000009536743164, 0, 0),
[[0, 0, 7, 88, 0, 0, 0, 0, 23, 89], [0, 0, 0, 0, 0, 0], [128, 238, 232, 48]], [
[0, 0, 7, 88, 0, 0, 0, 0, 23, 89],
[0, 0, 0, 0, 0, 0],
[128, 238, 232, 48],
],
), ),
new QuestNpcModel( new QuestNpcModel(
NpcType.MaleDwarf, NpcType.MaleDwarf,
@ -633,7 +719,11 @@ function create_default_npcs(): QuestNpcModel[] {
new Vector3(156.0028839111328, 0, -49.99967575073242), new Vector3(156.0028839111328, 0, -49.99967575073242),
new Euler(0, 5.497871034636549, 0, "ZXY"), new Euler(0, 5.497871034636549, 0, "ZXY"),
new Vector3(30.000009536743164, 0, 0), new Vector3(30.000009536743164, 0, 0),
[[0, 0, 7, 89, 0, 0, 0, 0, 23, 90], [0, 0, 0, 0, 0, 0], [128, 238, 236, 176]], [
[0, 0, 7, 89, 0, 0, 0, 0, 23, 90],
[0, 0, 0, 0, 0, 0],
[128, 238, 236, 176],
],
), ),
new QuestNpcModel( new QuestNpcModel(
NpcType.RedSoldier, NpcType.RedSoldier,
@ -646,7 +736,11 @@ function create_default_npcs(): QuestNpcModel[] {
new Vector3(237.9988250732422, 0, -14.0001220703125), new Vector3(237.9988250732422, 0, -14.0001220703125),
new Euler(0, 5.497871034636549, 0, "ZXY"), new Euler(0, 5.497871034636549, 0, "ZXY"),
new Vector3(0, 0, 0), new Vector3(0, 0, 0),
[[0, 0, 7, 90, 0, 0, 0, 0, 23, 91], [0, 0, 0, 0, 0, 0], [128, 238, 241, 48]], [
[0, 0, 7, 90, 0, 0, 0, 0, 23, 91],
[0, 0, 0, 0, 0, 0],
[128, 238, 241, 48],
],
), ),
new QuestNpcModel( new QuestNpcModel(
NpcType.BlueSoldier, NpcType.BlueSoldier,
@ -659,7 +753,11 @@ function create_default_npcs(): QuestNpcModel[] {
new Vector3(238.00379943847656, 0, 63.00413513183594), new Vector3(238.00379943847656, 0, 63.00413513183594),
new Euler(0, 3.927050739026106, 0, "ZXY"), new Euler(0, 3.927050739026106, 0, "ZXY"),
new Vector3(0, 0, 0), new Vector3(0, 0, 0),
[[0, 0, 7, 91, 0, 0, 0, 0, 23, 92], [0, 0, 0, 0, 0, 0], [128, 238, 245, 176]], [
[0, 0, 7, 91, 0, 0, 0, 0, 23, 92],
[0, 0, 0, 0, 0, 0],
[128, 238, 245, 176],
],
), ),
new QuestNpcModel( new QuestNpcModel(
NpcType.FemaleMacho, NpcType.FemaleMacho,
@ -672,7 +770,11 @@ function create_default_npcs(): QuestNpcModel[] {
new Vector3(-2.001882553100586, 0, 35.0036506652832), new Vector3(-2.001882553100586, 0, 35.0036506652832),
new Euler(0, 3.141640591220885, 0, "ZXY"), new Euler(0, 3.141640591220885, 0, "ZXY"),
new Vector3(26.000009536743164, 0, 0), new Vector3(26.000009536743164, 0, 0),
[[0, 0, 7, 92, 0, 0, 0, 0, 23, 93], [0, 0, 0, 0, 0, 0], [128, 238, 250, 48]], [
[0, 0, 7, 92, 0, 0, 0, 0, 23, 93],
[0, 0, 0, 0, 0, 0],
[128, 238, 250, 48],
],
), ),
new QuestNpcModel( new QuestNpcModel(
NpcType.Scientist, NpcType.Scientist,
@ -685,7 +787,11 @@ function create_default_npcs(): QuestNpcModel[] {
new Vector3(-147.0000457763672, 0, -7.996537208557129), new Vector3(-147.0000457763672, 0, -7.996537208557129),
new Euler(0, 2.577127047485882, 0, "ZXY"), new Euler(0, 2.577127047485882, 0, "ZXY"),
new Vector3(30.000009536743164, 0, 0), new Vector3(30.000009536743164, 0, 0),
[[0, 0, 7, 93, 0, 0, 0, 0, 23, 94], [0, 0, 0, 0, 0, 0], [128, 238, 254, 176]], [
[0, 0, 7, 93, 0, 0, 0, 0, 23, 94],
[0, 0, 0, 0, 0, 0],
[128, 238, 254, 176],
],
), ),
new QuestNpcModel( new QuestNpcModel(
NpcType.MaleOld, NpcType.MaleOld,
@ -698,7 +804,11 @@ function create_default_npcs(): QuestNpcModel[] {
new Vector3(-219.99710083007812, 0, -100.0008316040039), new Vector3(-219.99710083007812, 0, -100.0008316040039),
new Euler(0, 0, 0, "ZXY"), new Euler(0, 0, 0, "ZXY"),
new Vector3(30.000011444091797, 0, 0), new Vector3(30.000011444091797, 0, 0),
[[0, 0, 7, 94, 0, 0, 0, 0, 23, 95], [0, 0, 0, 0, 0, 0], [128, 239, 3, 48]], [
[0, 0, 7, 94, 0, 0, 0, 0, 23, 95],
[0, 0, 0, 0, 0, 0],
[128, 239, 3, 48],
],
), ),
new QuestNpcModel( new QuestNpcModel(
NpcType.GuildLady, NpcType.GuildLady,
@ -711,7 +821,11 @@ function create_default_npcs(): QuestNpcModel[] {
new Vector3(-262.5099792480469, 0, -24.53999900817871), new Vector3(-262.5099792480469, 0, -24.53999900817871),
new Euler(0, 1.963525369513053, 0, "ZXY"), new Euler(0, 1.963525369513053, 0, "ZXY"),
new Vector3(0, 0, 0), new Vector3(0, 0, 0),
[[0, 0, 7, 95, 0, 0, 0, 0, 23, 106], [0, 0, 0, 0, 0, 0], [128, 239, 100, 192]], [
[0, 0, 7, 95, 0, 0, 0, 0, 23, 106],
[0, 0, 0, 0, 0, 0],
[128, 239, 100, 192],
],
), ),
new QuestNpcModel( new QuestNpcModel(
NpcType.Tekker, NpcType.Tekker,
@ -724,7 +838,11 @@ function create_default_npcs(): QuestNpcModel[] {
new Vector3(-43.70983123779297, 2.5999999046325684, -52.78248596191406), new Vector3(-43.70983123779297, 2.5999999046325684, -52.78248596191406),
new Euler(0, 0.7854101478052212, 0, "ZXY"), new Euler(0, 0.7854101478052212, 0, "ZXY"),
new Vector3(0, 0, 0), new Vector3(0, 0, 0),
[[0, 0, 7, 97, 0, 0, 0, 0, 23, 98], [0, 0, 0, 0, 0, 0], [128, 239, 16, 176]], [
[0, 0, 7, 97, 0, 0, 0, 0, 23, 98],
[0, 0, 0, 0, 0, 0],
[128, 239, 16, 176],
],
), ),
new QuestNpcModel( new QuestNpcModel(
NpcType.MaleMacho, NpcType.MaleMacho,
@ -737,7 +855,11 @@ function create_default_npcs(): QuestNpcModel[] {
new Vector3(0.33990478515625, 2.5999999046325684, -84.71995544433594), new Vector3(0.33990478515625, 2.5999999046325684, -84.71995544433594),
new Euler(0, 0, 0, "ZXY"), new Euler(0, 0, 0, "ZXY"),
new Vector3(0, 0, 0), new Vector3(0, 0, 0),
[[0, 0, 7, 98, 0, 0, 0, 0, 23, 99], [0, 0, 0, 0, 0, 0], [128, 239, 21, 48]], [
[0, 0, 7, 98, 0, 0, 0, 0, 23, 99],
[0, 0, 0, 0, 0, 0],
[128, 239, 21, 48],
],
), ),
new QuestNpcModel( new QuestNpcModel(
NpcType.FemaleMacho, NpcType.FemaleMacho,
@ -750,7 +872,11 @@ function create_default_npcs(): QuestNpcModel[] {
new Vector3(43.87113952636719, 2.5999996662139893, -74.80299377441406), new Vector3(43.87113952636719, 2.5999996662139893, -74.80299377441406),
new Euler(0, -0.5645135437350027, 0, "ZXY"), new Euler(0, -0.5645135437350027, 0, "ZXY"),
new Vector3(0, 0, 0), new Vector3(0, 0, 0),
[[0, 0, 7, 99, 0, 0, 0, 0, 23, 100], [0, 0, 0, 0, 0, 0], [128, 239, 25, 176]], [
[0, 0, 7, 99, 0, 0, 0, 0, 23, 100],
[0, 0, 0, 0, 0, 0],
[128, 239, 25, 176],
],
), ),
new QuestNpcModel( new QuestNpcModel(
NpcType.MaleFat, NpcType.MaleFat,
@ -763,7 +889,11 @@ function create_default_npcs(): QuestNpcModel[] {
new Vector3(75.88380432128906, 2.5999996662139893, -42.69328308105469), new Vector3(75.88380432128906, 2.5999996662139893, -42.69328308105469),
new Euler(0, -1.0308508189943528, 0, "ZXY"), new Euler(0, -1.0308508189943528, 0, "ZXY"),
new Vector3(0, 0, 0), new Vector3(0, 0, 0),
[[0, 0, 7, 100, 0, 0, 0, 0, 23, 101], [0, 0, 0, 0, 0, 0], [128, 239, 30, 48]], [
[0, 0, 7, 100, 0, 0, 0, 0, 23, 101],
[0, 0, 0, 0, 0, 0],
[128, 239, 30, 48],
],
), ),
new QuestNpcModel( new QuestNpcModel(
NpcType.FemaleTall, NpcType.FemaleTall,
@ -776,7 +906,11 @@ function create_default_npcs(): QuestNpcModel[] {
new Vector3(16.003997802734375, 0, 5.995697021484375), new Vector3(16.003997802734375, 0, 5.995697021484375),
new Euler(0, -1.1781152217078317, 0, "ZXY"), new Euler(0, -1.1781152217078317, 0, "ZXY"),
new Vector3(22.000009536743164, 0, 0), new Vector3(22.000009536743164, 0, 0),
[[0, 0, 7, 101, 0, 0, 0, 0, 23, 102], [0, 0, 0, 0, 0, 0], [128, 239, 34, 176]], [
[0, 0, 7, 101, 0, 0, 0, 0, 23, 102],
[0, 0, 0, 0, 0, 0],
[128, 239, 34, 176],
],
), ),
new QuestNpcModel( new QuestNpcModel(
NpcType.Nurse, NpcType.Nurse,
@ -789,7 +923,11 @@ function create_default_npcs(): QuestNpcModel[] {
new Vector3(0.3097381591796875, 3, -105.3865966796875), new Vector3(0.3097381591796875, 3, -105.3865966796875),
new Euler(0, 0, 0, "ZXY"), new Euler(0, 0, 0, "ZXY"),
new Vector3(0, 0, 0), new Vector3(0, 0, 0),
[[0, 0, 7, 102, 0, 0, 0, 0, 23, 103], [0, 0, 0, 0, 0, 0], [128, 239, 39, 48]], [
[0, 0, 7, 102, 0, 0, 0, 0, 23, 103],
[0, 0, 0, 0, 0, 0],
[128, 239, 39, 48],
],
), ),
new QuestNpcModel( new QuestNpcModel(
NpcType.Nurse, NpcType.Nurse,
@ -802,7 +940,11 @@ function create_default_npcs(): QuestNpcModel[] {
new Vector3(53.499176025390625, 0, -26.496688842773438), new Vector3(53.499176025390625, 0, -26.496688842773438),
new Euler(0, 5.497871034636549, 0, "ZXY"), new Euler(0, 5.497871034636549, 0, "ZXY"),
new Vector3(18.000009536743164, 0, 0), new Vector3(18.000009536743164, 0, 0),
[[0, 0, 7, 103, 0, 0, 0, 0, 23, 104], [0, 0, 0, 0, 0, 0], [128, 239, 43, 176]], [
[0, 0, 7, 103, 0, 0, 0, 0, 23, 104],
[0, 0, 0, 0, 0, 0],
[128, 239, 43, 176],
],
), ),
]; ];
} }