aslobot-matrix/src/services/game/location.ts
2026-01-23 08:57:00 -05:00

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,
};