198 lines
6.6 KiB
TypeScript
198 lines
6.6 KiB
TypeScript
import { MatrixClient } from "matrix-js-sdk";
|
|
import type { ICallbackStore } from "../types.js";
|
|
import { config } from "../../config.js";
|
|
import { getPlayerById, getRace } from "../../services/game/entity.js";
|
|
import {
|
|
getLocation,
|
|
getLocationDistance,
|
|
} from "../../services/game/location.js";
|
|
import { getLevel } from "../../services/game/game.js";
|
|
import {
|
|
getFullItemName,
|
|
getTotalStats,
|
|
type IItem,
|
|
type IStat,
|
|
type Location,
|
|
} from "../../services/game/index.js";
|
|
let client: MatrixClient;
|
|
|
|
const gamePrefix = `${config.app.triggerPrefix}game`;
|
|
|
|
const registerModuleGame = (
|
|
matrixClient: MatrixClient,
|
|
callbackStore: ICallbackStore,
|
|
) => {
|
|
client = matrixClient;
|
|
|
|
callbackStore.messageCallbacks.push({
|
|
startConditions: [`${gamePrefix} help`],
|
|
callbackFunc: onHelp,
|
|
});
|
|
callbackStore.messageCallbacks.push({
|
|
startConditions: [`${gamePrefix} status`],
|
|
callbackFunc: onStatus,
|
|
});
|
|
callbackStore.messageCallbacks.push({
|
|
startConditions: [`${gamePrefix} inventory`],
|
|
callbackFunc: onInventory,
|
|
});
|
|
callbackStore.messageCallbacks.push({
|
|
startConditions: [`${gamePrefix} location`],
|
|
callbackFunc: onLocation,
|
|
});
|
|
callbackStore.messageCallbacks.push({
|
|
startConditions: [`${gamePrefix} nearby`],
|
|
callbackFunc: onNearby,
|
|
});
|
|
};
|
|
|
|
const onHelp = (_text: string, roomId: string) => {
|
|
client.sendHtmlMessage(
|
|
roomId,
|
|
"",
|
|
`<ul>
|
|
<li><b>!game help</b> - Prints this help message</li>
|
|
<li><b>!game status</b> - Prints information about your character</li>
|
|
<li><b>!game inventory</b> - Shows 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 nearby</b> - Shows nearby locations</li>
|
|
<li><b>(WIP) !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 fight {entity}</b> - Fight an entity</li>
|
|
<li><b>(WIP) !game work {action}</b> - Start work</li>
|
|
</ul>`,
|
|
);
|
|
};
|
|
|
|
const onStatus = (_text: string, roomId: string, sender: string) => {
|
|
const player = getPlayerById(sender);
|
|
const race = getRace(player.race);
|
|
const location = getLocation(player.location);
|
|
|
|
const level = getLevel(player.experience);
|
|
|
|
client.sendHtmlMessage(
|
|
roomId,
|
|
"",
|
|
`<ul>
|
|
<li><b>Name:</b> ${player.name}</li>
|
|
<li><b>Description:</b> ${player.description}</li>
|
|
<li><b>Race:</b> ${race.name}</li>
|
|
<li><b>Location:</b> ${location.name}</li>
|
|
<li><b>Level:</b> ${level.level} - ${level.experienceInLevel}/${level.experienceToNextLevel} exp</li>
|
|
<li><b>Vitality:</b> ${player.vitality}</li>
|
|
<li><b>Strength:</b> ${player.strength}</li>
|
|
<li><b>Endurance:</b> ${player.endurance}</li>
|
|
<li><b>Agility:</b> ${player.agility}</li>
|
|
<li><b>Dexterity:</b> ${player.dexterity}</li>
|
|
<li><b>Intelligence:</b> ${player.intelligence}</li>
|
|
<li><b>Wisdom:</b> ${player.wisdom}</li>
|
|
<li><b>Stealth:</b> ${player.stealth}</li>
|
|
<li><b>Charisma:</b> ${player.charisma}</li>
|
|
<li><b>Lockpicking:</b> ${player.lockpicking}</li>
|
|
</ul>`,
|
|
);
|
|
};
|
|
|
|
const onInventory = (text: string, roomId: string, sender: string) => {
|
|
const player = getPlayerById(sender);
|
|
|
|
const itemIndex = text.replace(`${gamePrefix} location `, "").trim();
|
|
const itemIndexInt = Number(itemIndex);
|
|
if (!isNaN(itemIndexInt)) {
|
|
const item = player.inventory.items[itemIndexInt];
|
|
if (!item) {
|
|
client.sendTextMessage(roomId, "No item with that index found");
|
|
return;
|
|
}
|
|
|
|
const totalStats = getTotalStats(item);
|
|
|
|
const mapDamage = (stat: IStat): string => {
|
|
return `<li><b>Damage type:</b> ${stat.damageType}</li><li><b>Damage:</b> ${stat.damage}</li>`;
|
|
};
|
|
|
|
const mapAbility = (stat: IStat): string => {
|
|
return `<li><${stat.abilityType}</li>`;
|
|
};
|
|
|
|
client.sendHtmlMessage(
|
|
roomId,
|
|
"",
|
|
`<p>${getFullItemName(item)}</p>
|
|
<ul>
|
|
<li><b>Description:</b> ${item.description}</li>
|
|
<li><b>Durability:</b> ${item.durability}/100</li>
|
|
<li><b>Value:</b> ${item.value}</li>
|
|
<li><b>Type:</b> ${item.type}</li>
|
|
<li><b>Rarity:</b> ${item.rarity}</li>
|
|
<li><b>Total damage:</b> ${totalStats.damage}</li>
|
|
<li><b>Total defence:</b> ${totalStats.defense}</li>
|
|
</ul>
|
|
<p>Damage:</p>
|
|
<ul>
|
|
${item.stats.map(mapDamage)}
|
|
</ul>
|
|
<p>Abilities:</p>
|
|
<ul>
|
|
${item.stats.map(mapAbility)}
|
|
</ul>`,
|
|
);
|
|
}
|
|
|
|
const mapItem = (item: IItem, index: number): string => {
|
|
const fullName = getFullItemName(item);
|
|
|
|
return `<b>(${index})</b> ${fullName}`;
|
|
};
|
|
|
|
client.sendHtmlMessage(
|
|
roomId,
|
|
"",
|
|
`<p>Your inventory (${player.name})</p>
|
|
<ul>
|
|
${player.inventory.items.map(mapItem).join(",")}
|
|
</ul>`,
|
|
);
|
|
};
|
|
|
|
const onLocation = (_text: string, roomId: string, sender: string) => {
|
|
const player = getPlayerById(sender);
|
|
const location = getLocation(player.location);
|
|
|
|
client.sendHtmlMessage(
|
|
roomId,
|
|
"",
|
|
`<ul>
|
|
<li><b>Player:</b> ${player.name}</li>
|
|
<li><b>X:</b> ${location.X}</li>
|
|
<li><b>Y:</b> ${location.Y}</li>
|
|
<li><b>Location Name:</b> ${location.name}</li>
|
|
</ul>
|
|
<p>${location.description}</p>`,
|
|
);
|
|
};
|
|
|
|
const onNearby = (_text: string, roomId: string, sender: string) => {
|
|
const player = getPlayerById(sender);
|
|
const location = getLocation(player.location);
|
|
|
|
const mapLocation = (locId: Location): string => {
|
|
const locData = getLocation(locId);
|
|
const distance = getLocationDistance(location, locData);
|
|
|
|
return `<li><b>${locData.name}</b> - ${distance.toFixed(1)}km - <i>${locData.description}</i></li>`;
|
|
};
|
|
|
|
client.sendHtmlMessage(
|
|
roomId,
|
|
"",
|
|
`<p>There are ${location.childLocations.length} locations around you (${player.name})</p>
|
|
<ul>
|
|
${location.childLocations.map(mapLocation).join("\n")}
|
|
</ul>`,
|
|
);
|
|
};
|
|
|
|
export { registerModuleGame };
|