-
Notifications
You must be signed in to change notification settings - Fork 86
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #259 from rune-js/feature/player-region-changed-hook
Adding player_region_changed action hook and removed old scenery spawns
- Loading branch information
Showing
11 changed files
with
509 additions
and
863 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,36 @@ | ||
import { logger } from '@runejs/core'; | ||
import { Player } from '@server/world/actor/player/player'; | ||
import { musicRegionMap, musicRegions } from '@server/config'; | ||
import { songs } from '@server/world/config/songs'; | ||
import { playerRegionChangedHook } from '@server/world/action/player-region-changed'; | ||
import { playerInitAction } from '@server/world/actor/player/player'; | ||
|
||
musicRegions.forEach(song => song.regionIds.forEach(region => musicRegionMap.set(region, song.songId))); | ||
|
||
export function playSongForRegion(player: Player): void { | ||
const regionId = ((player.position.x >> 6) * 256) + (player.position.y >> 6); | ||
const songId: number = musicRegionMap.get(regionId); | ||
logger.info('Playing: ' + getByValue(songs, songId) + ' (Song ID: ' + songId + ' Region ID: ' + regionId + ')'); | ||
|
||
player.playSong(songId); | ||
player.metadata['updateMusic'] = false; | ||
} | ||
musicRegions.forEach(song => song.regionIds.forEach(region => musicRegionMap.set(region, song.songId))); | ||
|
||
function getByValue(map, searchValue) { | ||
for (const [key, value] of map.entries()) { | ||
if (value === searchValue) | ||
return key; | ||
} | ||
} | ||
|
||
const regionChangedHandler = ({ player, currentMapRegionId }): void => { | ||
const songId: number = musicRegionMap.get(currentMapRegionId); | ||
player.sendMessage(`Playing ${songId}:${getByValue(songs, songId)} at region ${currentMapRegionId}`); | ||
player.playSong(songId); | ||
player.metadata['updateMusic'] = false; | ||
}; | ||
|
||
const playerInitHandler: playerInitAction = ({ player }): void => { | ||
// Plays the appropriate location's song on player init | ||
regionChangedHandler({ player, | ||
currentMapRegionId: ((player.position.x >> 6) << 8) + (player.position.y >> 6) }); | ||
}; | ||
|
||
export default [{ | ||
type: 'player_region_changed', | ||
regionType: 'map', | ||
handler: regionChangedHandler | ||
}, { | ||
type: 'player_init', | ||
action: playerInitHandler | ||
}]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
import { Player } from '@server/world/actor/player/player'; | ||
import { Coords, Position } from '@server/world/position'; | ||
import { Action, getActionList } from '@server/world/action/index'; | ||
import { RegionType } from '@server/world/map/region'; | ||
|
||
|
||
/** | ||
* The definition for a player action function. | ||
*/ | ||
export type playerRegionChangedHook = (playerActionData: PlayerRegionChangedData) => void; | ||
|
||
/** | ||
* Details about a player being interacted with. | ||
*/ | ||
export interface PlayerRegionChangedData { | ||
// The player performing the action. | ||
player: Player; | ||
// Whether or not the player is teleporting to their new location | ||
teleporting: boolean; | ||
// The original position that the player was at before moving to the new region. | ||
originalPosition: Position; | ||
// The position that the player ended up at in the new region. | ||
currentPosition: Position; | ||
// The player's original chunk coordinates | ||
originalChunkCoords: Coords; | ||
// The player's current chunk coordinates | ||
currentChunkCoords: Coords; | ||
// The player's original map region coordinates | ||
originalMapRegionCoords: Coords; | ||
// The player's current map region coordinates | ||
currentMapRegionCoords: Coords; | ||
// The player's original map region id | ||
originalMapRegionId: number; | ||
// The player's current map region id | ||
currentMapRegionId: number; | ||
// The region types that changed for the player. | ||
regionTypes: RegionType[]; | ||
} | ||
|
||
/** | ||
* Defines a player region changed action. | ||
*/ | ||
export interface PlayerRegionChangedAction extends Action { | ||
// The action function to be performed. | ||
handler: playerRegionChangedHook; | ||
// Optional single region type for the action hook to apply to. | ||
regionType?: RegionType; | ||
// Optional multiple region types for the action hook to apply to. | ||
regionTypes?: RegionType[]; | ||
// Optional teleporting requirement | ||
teleporting?: boolean; | ||
} | ||
|
||
/** | ||
* Creates a PlayerRegionChangedData object from the given inputs. | ||
* @param player The player. | ||
* @param originalPosition The player's original position. | ||
* @param currentPosition The player's current position. | ||
* @param teleporting Whether or not the player is teleporting; defaults to false. | ||
*/ | ||
export const regionChangedDataFactory = (player: Player, | ||
originalPosition: Position, currentPosition: Position, | ||
teleporting: boolean = false): PlayerRegionChangedData => { | ||
const regionTypes: RegionType[] = []; | ||
const originalMapRegionId: number = ((originalPosition.x >> 6) << 8) + (originalPosition.y >> 6); | ||
const currentMapRegionId: number = ((currentPosition.x >> 6) << 8) + (currentPosition.y >> 6); | ||
const originalChunkCoords: Coords = { | ||
x: originalPosition.chunkX, | ||
y: originalPosition.chunkY, | ||
level: originalPosition.level | ||
}; | ||
const currentChunkCoords: Coords = { | ||
x: currentPosition.chunkX, | ||
y: currentPosition.chunkY, | ||
level: currentPosition.level | ||
}; | ||
|
||
if(originalMapRegionId !== currentMapRegionId) { | ||
regionTypes.push('map'); | ||
} | ||
|
||
if(!Coords.equals(originalChunkCoords, currentChunkCoords)) { | ||
regionTypes.push('chunk'); | ||
} | ||
|
||
if(regionTypes.length === 0) { | ||
return null; | ||
} | ||
|
||
return { | ||
player, regionTypes, teleporting, | ||
|
||
originalPosition, | ||
originalChunkCoords, | ||
originalMapRegionCoords: { | ||
x: originalPosition.x >> 6, | ||
y: originalPosition.y >> 6, | ||
level: originalPosition.level | ||
}, | ||
originalMapRegionId, | ||
|
||
currentPosition: player.position, | ||
currentChunkCoords, | ||
currentMapRegionCoords: { | ||
x: currentPosition.x >> 6, | ||
y: currentPosition.y >> 6, | ||
level: currentPosition.level | ||
}, | ||
currentMapRegionId | ||
}; | ||
}; | ||
|
||
const playerRegionChangedHandler = (actionData: PlayerRegionChangedData): void => { | ||
if(!actionData) { | ||
return; | ||
} | ||
|
||
const { regionTypes } = actionData; | ||
|
||
if(!regionTypes || regionTypes.length === 0) { | ||
return; | ||
} | ||
|
||
// Find all action hooks that match the provided input | ||
const actionList = getActionList('player_region_changed')?.filter((actionHook: PlayerRegionChangedAction) => { | ||
if(actionHook.teleporting && !actionData.teleporting) { | ||
return false; | ||
} | ||
|
||
if(actionHook.regionType) { | ||
return regionTypes.indexOf(actionHook.regionType) !== -1; | ||
} else if(actionHook.regionTypes && actionHook.regionTypes.length !== 0) { | ||
let valid = false; | ||
for(const type of actionHook.regionTypes) { | ||
if(regionTypes.indexOf(type) !== -1) { | ||
valid = true; | ||
break; | ||
} | ||
} | ||
|
||
return valid; | ||
} | ||
|
||
return false; | ||
}) || null; | ||
|
||
if(!actionList || actionList.length === 0) { | ||
// No matching actions found | ||
return; | ||
} | ||
|
||
actionList.forEach(async actionHook => | ||
new Promise<void>(resolve => { | ||
actionHook.handler(actionData); | ||
resolve(); | ||
})); | ||
}; | ||
|
||
export default { | ||
action: 'player_region_changed', | ||
handler: playerRegionChangedHandler | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.