Add travel

This commit is contained in:
Aslan 2026-01-21 15:42:18 -05:00
parent c9b4f62a59
commit eea6031423
4 changed files with 134 additions and 28 deletions

View file

@ -4,9 +4,13 @@ import { config } from "../../config.js";
import { getPlayerById, getRace } from "../../services/game/entity.js"; import { getPlayerById, getRace } from "../../services/game/entity.js";
import { import {
getLocation, getLocation,
getLocationByName,
getLocationDistance, getLocationDistance,
getParentLocation,
hasLocation,
startTravel,
} from "../../services/game/location.js"; } from "../../services/game/location.js";
import { getLevel } from "../../services/game/game.js"; import { getLevel } from "../../services/game/entity.js";
import { import {
getFullItemName, getFullItemName,
getTotalStats, getTotalStats,
@ -44,6 +48,10 @@ const registerModuleGame = (
startConditions: [`${gamePrefix} nearby`], startConditions: [`${gamePrefix} nearby`],
callbackFunc: onNearby, callbackFunc: onNearby,
}); });
callbackStore.messageCallbacks.push({
startConditions: [`${gamePrefix} travel`],
callbackFunc: onTravel,
});
}; };
const onHelp = (_text: string, roomId: string) => { const onHelp = (_text: string, roomId: string) => {
@ -57,7 +65,7 @@ const onHelp = (_text: string, roomId: string) => {
<li><b>!game inventory {index}</b> - Shows information about an item in your inventory</li> <li><b>!game inventory {index}</b> - Shows information about an item in your inventory</li>
<li><b>!game location</b> - Shows information about your current location</li> <li><b>!game location</b> - Shows information about your current location</li>
<li><b>!game nearby</b> - Shows nearby locations</li> <li><b>!game nearby</b> - Shows nearby locations</li>
<li><b>(WIP) !game travel {location}</b> - Travel to a location</li> <li><b>!game travel {location}</b> - Travel to a location</li>
<li><b>(WIP) !game talk {entity}</b> - Talk to an entity</li> <li><b>(WIP) !game talk {entity}</b> - Talk to an entity</li>
<li><b>(WIP) !game fight {entity}</b> - Fight an entity</li> <li><b>(WIP) !game fight {entity}</b> - Fight an entity</li>
<li><b>(WIP) !game work {action}</b> - Start work</li> <li><b>(WIP) !game work {action}</b> - Start work</li>
@ -193,8 +201,35 @@ const onNearby = (_text: string, roomId: string, sender: string) => {
`<p>There are ${location.childLocations.length} locations around you (${player.name})</p> `<p>There are ${location.childLocations.length} locations around you (${player.name})</p>
<ul> <ul>
${location.childLocations.map(mapLocation).join("\n")} ${location.childLocations.map(mapLocation).join("\n")}
${getParentLocation(player.location).childLocations.map(mapLocation).join("\n")}
</ul>`, </ul>`,
); );
}; };
const onTravel = (text: string, roomId: string, sender: string) => {
const player = getPlayerById(sender);
const locationName = text.replace(`${gamePrefix} travel `, "").trim();
const location = getLocationByName(locationName);
if (!location) {
client.sendTextMessage(roomId, "No such location exists");
return;
}
const currentLocationHasLocation = hasLocation(
player.location,
location.id,
);
const parentLocationHasLocation = hasLocation(
getParentLocation(player.location).id,
location.id,
);
if (!currentLocationHasLocation && !parentLocationHasLocation) {
client.sendTextMessage(roomId, "No such location found nearby");
return;
}
startTravel(player, location.id, client, roomId);
};
export { registerModuleGame }; export { registerModuleGame };

View file

@ -1,9 +1,10 @@
import { getUserNameById } from "../../helpers.js"; import { getUserNameById } from "../../helpers.js";
import { state } from "../../store/store.js"; import { state } from "../../store/store.js";
import type { IPlayer } from "./structures/entities.js"; import type { IEntity, IPlayer } from "./structures/entities.js";
import { itemShortsword } from "./structures/items.js"; import { itemShortsword } from "./structures/items.js";
import { Location } from "./structures/locations.js"; import { Location } from "./structures/locations.js";
import { Race, raceHuman, races, type IRace } from "./structures/races.js"; import { Race, raceHuman, races, type IRace } from "./structures/races.js";
import type { ILevel } from "./types.js";
const createPlayer = (name: string): IPlayer => ({ const createPlayer = (name: string): IPlayer => ({
name: name, name: name,
@ -49,4 +50,27 @@ const getRace = (id: Race): IRace => {
return race ? race : raceHuman; return race ? race : raceHuman;
}; };
export { createPlayer, getPlayerById, getPlayer, getRace }; const getLevel = (experience: number): ILevel => {
let tmpExperience = experience;
let experienceToNextLevel = 50;
let level = 0;
while (tmpExperience >= experienceToNextLevel) {
level++;
tmpExperience -= experienceToNextLevel;
experienceToNextLevel = experienceToNextLevel *= 1.25;
}
return {
level: level,
totalExperience: Math.floor(experience),
experienceInLevel: Math.floor(tmpExperience),
experienceToNextLevel: Math.floor(experienceToNextLevel),
};
};
const getSpeed = (entity: IEntity) => {
return 1 + Math.sqrt(entity.agility + entity.endurance) / 3;
};
export { createPlayer, getPlayerById, getPlayer, getRace, getLevel, getSpeed };

View file

@ -1,22 +0,0 @@
import type { ILevel } from "./types.js";
const getLevel = (experience: number): ILevel => {
let tmpExperience = experience;
let experienceToNextLevel = 50;
let level = 0;
while (tmpExperience >= experienceToNextLevel) {
level++;
tmpExperience -= experienceToNextLevel;
experienceToNextLevel = experienceToNextLevel *= 1.25;
}
return {
level: level,
totalExperience: Math.floor(experience),
experienceInLevel: Math.floor(tmpExperience),
experienceToNextLevel: Math.floor(experienceToNextLevel),
};
};
export { getLevel };

View file

@ -1,9 +1,12 @@
import type { MatrixClient } from "matrix-js-sdk";
import { import {
Location,
locationFarlands, locationFarlands,
locations, locations,
type ILocation, type ILocation,
type Location,
} from "./structures/locations.js"; } from "./structures/locations.js";
import type { IPlayer } from "./structures/entities.js";
import { getSpeed } from "./entity.js";
const getLocation = (id: Location): ILocation => { const getLocation = (id: Location): ILocation => {
const location = locations.find((location) => location.id === id); const location = locations.find((location) => location.id === id);
@ -11,6 +14,14 @@ const getLocation = (id: Location): ILocation => {
return location ? location : locationFarlands; 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 = ( const getLocationDistance = (
locationA: ILocation, locationA: ILocation,
locationB: ILocation, locationB: ILocation,
@ -23,4 +34,62 @@ const getLocationDistance = (
return Math.sqrt(deltaPow); return Math.sqrt(deltaPow);
}; };
export { getLocation, getLocationDistance }; 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 startTravel = (
player: IPlayer,
location: Location,
client: MatrixClient,
roomId: string,
) => {
const currentLocation = getLocation(player.location);
const newLocation = getLocation(location);
const distance = getLocationDistance(currentLocation, newLocation);
setTimeout(
() => {
finishTravel(player, newLocation, client, roomId);
},
(distance / getSpeed(player)) * 3600000,
);
};
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 {
getLocation,
getLocationByName,
getLocationDistance,
getParentLocation,
hasLocation,
startTravel,
finishTravel,
};