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,
"",
`
- !game help - Prints this help message
- !game status - Prints information about your character
- !game inventory - Shows your inventory
- !game inventory {index} - Shows information about an item in your inventory
- !game location - Shows information about your current location
- !game nearby - Shows nearby locations
- (WIP) !game travel {location} - Travel to a location
- (WIP) !game talk {entity} - Talk to an entity
- (WIP) !game fight {entity} - Fight an entity
- (WIP) !game work {action} - Start work
`,
);
};
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,
"",
`
- Name: ${player.name}
- Description: ${player.description}
- Race: ${race.name}
- Location: ${location.name}
- Level: ${level.level} - ${level.experienceInLevel}/${level.experienceToNextLevel} exp
- Vitality: ${player.vitality}
- Strength: ${player.strength}
- Endurance: ${player.endurance}
- Agility: ${player.agility}
- Dexterity: ${player.dexterity}
- Intelligence: ${player.intelligence}
- Wisdom: ${player.wisdom}
- Stealth: ${player.stealth}
- Charisma: ${player.charisma}
- Lockpicking: ${player.lockpicking}
`,
);
};
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 `Damage type: ${stat.damageType}Damage: ${stat.damage}`;
};
const mapAbility = (stat: IStat): string => {
return `<${stat.abilityType}`;
};
client.sendHtmlMessage(
roomId,
"",
`${getFullItemName(item)}
- Description: ${item.description}
- Durability: ${item.durability}/100
- Value: ${item.value}
- Type: ${item.type}
- Rarity: ${item.rarity}
- Total damage: ${totalStats.damage}
- Total defence: ${totalStats.defense}
Damage:
${item.stats.map(mapDamage)}
Abilities:
${item.stats.map(mapAbility)}
`,
);
}
const mapItem = (item: IItem, index: number): string => {
const fullName = getFullItemName(item);
return `(${index}) ${fullName}`;
};
client.sendHtmlMessage(
roomId,
"",
`Your inventory (${player.name})
${player.inventory.items.map(mapItem).join(",")}
`,
);
};
const onLocation = (_text: string, roomId: string, sender: string) => {
const player = getPlayerById(sender);
const location = getLocation(player.location);
client.sendHtmlMessage(
roomId,
"",
`
- Player: ${player.name}
- X: ${location.X}
- Y: ${location.Y}
- Location Name: ${location.name}
${location.description}
`,
);
};
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 `${locData.name} - ${distance.toFixed(1)}km - ${locData.description}`;
};
client.sendHtmlMessage(
roomId,
"",
`There are ${location.childLocations.length} locations around you (${player.name})
${location.childLocations.map(mapLocation).join("\n")}
`,
);
};
export { registerModuleGame };