@@ -6,18 +6,26 @@ import { clamp } from "../util/MathUtil";
66import { MapManager , MapSquare } from "../renderer/MapManager" ;
77import { MapViewer } from "./MapViewer" ;
88import { 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
1016export 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}
0 commit comments