Skip to content

Commit 79bd4fb

Browse files
committed
Move high-level interaction-related code out of the renderer.
1 parent 0081a06 commit 79bd4fb

File tree

3 files changed

+198
-189
lines changed

3 files changed

+198
-189
lines changed

src/mapviewer/MapViewerRenderer.ts

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,26 @@ import { clamp } from "../util/MathUtil";
66
import { MapManager, MapSquare } from "../renderer/MapManager";
77
import { MapViewer } from "./MapViewer";
88
import { RendererType } from "../renderer/Renderers";
9+
import { OsrsMenuEntry } from "../components/rs/menu/OsrsMenu";
10+
import { InteractType } from "../renderer/InteractType";
11+
import { INTERACTION_RADIUS } from "../renderer/Interactions";
12+
import { MenuTargetType } from "../rs/MenuEntry";
13+
import { isTouchDevice } from "../util/DeviceUtil";
14+
import { InputManager } from "../util/InputManager";
915

1016
export abstract class MapViewerRenderer<T extends MapSquare = MapSquare> extends Renderer {
1117
abstract type: RendererType;
1218

1319
mapManager: MapManager<T>;
20+
inputManager: InputManager;
1421

1522
constructor(public mapViewer: MapViewer) {
1623
super();
1724
this.mapManager = new MapManager(
1825
mapViewer.workerPool.size * 2,
1926
this.queueLoadMap.bind(this),
2027
);
28+
this.inputManager = mapViewer.inputManager;
2129
}
2230

2331
override async init() {
@@ -200,4 +208,186 @@ export abstract class MapViewerRenderer<T extends MapSquare = MapSquare> extends
200208

201209
// this.mapViewer.debugText = `Frame Time Js: ${this.stats.frameTimeJs.toFixed(3)}`;
202210
}
211+
212+
checkInteractions(interactReady: boolean, interactBuffer: Float32Array,
213+
closestInteractIndices: Map<number, number[]>): void {
214+
const frameCount = this.stats.frameCount;
215+
216+
const isMouseDown = this.inputManager.dragX !== -1 || this.inputManager.dragY !== -1;
217+
const picked = this.inputManager.pickX !== -1 && this.inputManager.pickY !== -1;
218+
219+
if (!interactReady && !picked)
220+
return;
221+
222+
const menuCooldown = isTouchDevice ? 50 : 10;
223+
224+
if (
225+
this.inputManager.mouseX === -1 ||
226+
this.inputManager.mouseY === -1 ||
227+
frameCount - this.mapViewer.menuOpenedFrame < menuCooldown
228+
) {
229+
return;
230+
}
231+
232+
// Don't auto close menu on touch devices
233+
if (this.mapViewer.menuOpen && !picked && !isMouseDown && isTouchDevice) {
234+
return;
235+
}
236+
237+
if (!picked && !this.mapViewer.tooltips) {
238+
this.mapViewer.closeMenu();
239+
return;
240+
}
241+
242+
const menuEntries: OsrsMenuEntry[] = [];
243+
const examineEntries: OsrsMenuEntry[] = [];
244+
245+
const locIds = new Set<number>();
246+
const objIds = new Set<number>();
247+
const npcIds = new Set<number>();
248+
249+
for (let i = 0; i < INTERACTION_RADIUS + 1; i++) {
250+
const indices = closestInteractIndices.get(i);
251+
if (!indices) {
252+
continue;
253+
}
254+
for (const index of indices) {
255+
const interactId = interactBuffer[index];
256+
const interactType = interactBuffer[index + 2];
257+
if (interactType === InteractType.LOC) {
258+
const locType = this.mapViewer.cacheLoaders.locTypeLoader.load(interactId);
259+
if (locType.name === "null" && !this.mapViewer.debugId) {
260+
continue;
261+
}
262+
if (locIds.has(interactId)) {
263+
continue;
264+
}
265+
locIds.add(interactId);
266+
267+
for (const option of locType.actions) {
268+
if (!option) {
269+
continue;
270+
}
271+
menuEntries.push({
272+
option,
273+
targetId: locType.id,
274+
targetType: MenuTargetType.LOC,
275+
targetName: locType.name,
276+
targetLevel: -1,
277+
onClick: this.mapViewer.closeMenu,
278+
});
279+
}
280+
281+
examineEntries.push({
282+
option: "Examine",
283+
targetId: locType.id,
284+
targetType: MenuTargetType.LOC,
285+
targetName: locType.name,
286+
targetLevel: -1,
287+
onClick: this.mapViewer.onExamine,
288+
});
289+
} else if (interactType === InteractType.OBJ) {
290+
const objType = this.mapViewer.cacheLoaders.objTypeLoader.load(interactId);
291+
if (objType.name === "null" && !this.mapViewer.debugId) {
292+
continue;
293+
}
294+
if (objIds.has(interactId)) {
295+
continue;
296+
}
297+
objIds.add(interactId);
298+
299+
for (const option of objType.groundActions) {
300+
if (!option) {
301+
continue;
302+
}
303+
menuEntries.push({
304+
option,
305+
targetId: objType.id,
306+
targetType: MenuTargetType.OBJ,
307+
targetName: objType.name,
308+
targetLevel: -1,
309+
onClick: this.mapViewer.closeMenu,
310+
});
311+
}
312+
313+
examineEntries.push({
314+
option: "Examine",
315+
targetId: objType.id,
316+
targetType: MenuTargetType.OBJ,
317+
targetName: objType.name,
318+
targetLevel: -1,
319+
onClick: this.mapViewer.onExamine,
320+
});
321+
} else if (interactType === InteractType.NPC) {
322+
let npcType = this.mapViewer.cacheLoaders.npcTypeLoader.load(interactId);
323+
if (npcType.transforms) {
324+
const transformed = npcType.transform(
325+
this.mapViewer.cacheLoaders.varManager,
326+
this.mapViewer.cacheLoaders.npcTypeLoader,
327+
);
328+
if (!transformed) {
329+
continue;
330+
}
331+
npcType = transformed;
332+
}
333+
if (npcType.name === "null" && !this.mapViewer.debugId) {
334+
continue;
335+
}
336+
if (npcIds.has(interactId)) {
337+
continue;
338+
}
339+
npcIds.add(interactId);
340+
341+
for (const option of npcType.actions) {
342+
if (!option) {
343+
continue;
344+
}
345+
menuEntries.push({
346+
option,
347+
targetId: npcType.id,
348+
targetType: MenuTargetType.NPC,
349+
targetName: npcType.name,
350+
targetLevel: npcType.combatLevel,
351+
onClick: this.mapViewer.closeMenu,
352+
});
353+
}
354+
355+
examineEntries.push({
356+
option: "Examine",
357+
targetId: npcType.id,
358+
targetType: MenuTargetType.NPC,
359+
targetName: npcType.name,
360+
targetLevel: npcType.combatLevel,
361+
onClick: this.mapViewer.onExamine,
362+
});
363+
}
364+
}
365+
}
366+
367+
menuEntries.push({
368+
option: "Walk here",
369+
targetId: -1,
370+
targetType: MenuTargetType.NONE,
371+
targetName: "",
372+
targetLevel: -1,
373+
onClick: this.mapViewer.closeMenu,
374+
});
375+
menuEntries.push(...examineEntries);
376+
menuEntries.push({
377+
option: "Cancel",
378+
targetId: -1,
379+
targetType: MenuTargetType.NONE,
380+
targetName: "",
381+
targetLevel: -1,
382+
onClick: this.mapViewer.closeMenu,
383+
});
384+
385+
this.mapViewer.menuOpen = picked;
386+
if (picked) {
387+
this.mapViewer.menuOpenedFrame = frameCount;
388+
}
389+
this.mapViewer.menuX = this.inputManager.mouseX;
390+
this.mapViewer.menuY = this.inputManager.mouseY;
391+
this.mapViewer.menuEntries = menuEntries;
392+
}
203393
}

src/renderer/Interactions.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import PicoGL from "picogl";
22

3+
export const INTERACT_BUFFER_COUNT = 2;
4+
export const INTERACTION_RADIUS = 5;
5+
36
export class Interactions {
47
interactSize: number;
58

0 commit comments

Comments
 (0)