148 lines
3.6 KiB
TypeScript
148 lines
3.6 KiB
TypeScript
import type { MatrixClient } from "matrix-js-sdk";
|
|
import {
|
|
Location,
|
|
locationFarlands,
|
|
locations,
|
|
type ILocation,
|
|
} from "./structures/locations.js";
|
|
import type { IEntity, IPlayer } from "./structures/entities.js";
|
|
import { getSpeed } from "./entity.js";
|
|
|
|
const existsLocation = (name: string): boolean => {
|
|
return (
|
|
locations.find(
|
|
(location) => location.name.toLowerCase() === name.toLowerCase(),
|
|
) !== undefined
|
|
);
|
|
};
|
|
|
|
const getLocation = (id: Location): ILocation => {
|
|
const location = locations.find((location) => location.id === id);
|
|
|
|
return location ? location : locationFarlands;
|
|
};
|
|
|
|
const getLocationByName = (name: string): ILocation => {
|
|
const location = locations.find(
|
|
(location) => location.name.toLowerCase() === name.toLowerCase(),
|
|
);
|
|
|
|
return location ? location : locationFarlands;
|
|
};
|
|
|
|
const getLocationDistance = (
|
|
locationA: ILocation,
|
|
locationB: ILocation,
|
|
): number => {
|
|
const parentOfA = getParentLocation(locationA.id);
|
|
const parentOfB = getParentLocation(locationB.id);
|
|
|
|
let locAX = locationA.X;
|
|
let locAY = locationA.Y;
|
|
let locBX = locationB.X;
|
|
let locBY = locationB.Y;
|
|
|
|
if (locationA.id === parentOfB.id) {
|
|
locBX += locAX;
|
|
locBY += locAY;
|
|
} else if (locationB.id === parentOfA.id) {
|
|
locAX += locBX;
|
|
locAY += locBY;
|
|
}
|
|
|
|
const deltaX = Math.abs(locAX - locBX);
|
|
const deltaY = Math.abs(locAY - locBY);
|
|
|
|
const deltaPow = Math.pow(deltaX, 2) + Math.pow(deltaY, 2);
|
|
|
|
return Math.sqrt(deltaPow);
|
|
};
|
|
|
|
const getParentLocation = (childLocation: Location): ILocation => {
|
|
const parentLocation = locations.find((location) =>
|
|
location.childLocations.includes(childLocation),
|
|
);
|
|
|
|
return parentLocation ? parentLocation : locationFarlands;
|
|
};
|
|
|
|
const hasLocation = (
|
|
locationParent: Location,
|
|
locationChild: Location,
|
|
): boolean => {
|
|
const childLocations = getLocation(locationParent).childLocations;
|
|
|
|
return childLocations.includes(locationChild);
|
|
};
|
|
|
|
const entitiesShareLocation = (entityA: IEntity, entityB: IEntity): boolean => {
|
|
const locationA = getLocation(entityA.location);
|
|
const locationB = getLocation(entityB.location);
|
|
console.log(locationA.id);
|
|
console.log(locationB.id);
|
|
|
|
return locationA.id === locationB.id;
|
|
};
|
|
|
|
const getTravelTimeInHours = (
|
|
player: IPlayer,
|
|
locationA: ILocation,
|
|
locationB: ILocation,
|
|
) => {
|
|
const distance = getLocationDistance(locationA, locationB);
|
|
|
|
return distance / getSpeed(player);
|
|
};
|
|
|
|
const getTravelTimeInMilliseconds = (
|
|
player: IPlayer,
|
|
locationA: ILocation,
|
|
locationB: ILocation,
|
|
) => {
|
|
return getTravelTimeInHours(player, locationA, locationB) * 3600000;
|
|
};
|
|
|
|
const startTravel = (
|
|
player: IPlayer,
|
|
location: Location,
|
|
client: MatrixClient,
|
|
roomId: string,
|
|
) => {
|
|
const currentLocation = getLocation(player.location);
|
|
const newLocation = getLocation(location);
|
|
|
|
setTimeout(
|
|
() => {
|
|
finishTravel(player, newLocation, client, roomId);
|
|
},
|
|
getTravelTimeInMilliseconds(player, currentLocation, newLocation),
|
|
);
|
|
};
|
|
|
|
const finishTravel = (
|
|
player: IPlayer,
|
|
location: ILocation,
|
|
client: MatrixClient,
|
|
roomId: string,
|
|
) => {
|
|
player.location = location.id;
|
|
|
|
client.sendTextMessage(
|
|
roomId,
|
|
`${player.name} has arrived to ${location.name}`,
|
|
);
|
|
};
|
|
|
|
export {
|
|
existsLocation,
|
|
getLocation,
|
|
getLocationByName,
|
|
getLocationDistance,
|
|
getParentLocation,
|
|
hasLocation,
|
|
entitiesShareLocation,
|
|
getTravelTimeInHours,
|
|
getTravelTimeInMilliseconds,
|
|
startTravel,
|
|
finishTravel,
|
|
};
|