aslobot-matrix/src/services/game/entity.ts

216 lines
5.1 KiB
TypeScript

import { getUserNameById } from "../../helpers.js";
import { state } from "../../store/store.js";
import {
Attack,
attackPunch,
attacks,
type IAttack,
} from "./structures/attacks.js";
import {
npcBecky,
npcs,
type IEntity,
type INPC,
type INPCData,
type IPlayer,
type NPC,
type TFullNPC,
} from "./structures/entities.js";
import { itemShortsword } from "./structures/items.js";
import { Location } from "./structures/locations.js";
import { Race, raceHuman, races, type IRace } from "./structures/races.js";
import type { ILevel } from "./types.js";
const createPlayer = (name: string): IPlayer => ({
isPlayer: true,
name: name,
description: "",
race: Race.HUMAN,
location: Location.FARLANDS,
inventory: {
items: [itemShortsword],
},
experience: 0,
health: 100,
vitality: 0,
strength: 0,
endurance: 0,
agility: 0,
dexterity: 0,
intelligence: 0,
wisdom: 0,
stealth: 0,
charisma: 0,
lockpicking: 0,
attacks: [Attack.PUNCH, Attack.KICK],
});
const createNpcData = (npc: INPC): INPCData => ({
id: npc.id,
health: getMaxHealth(npc),
dead: false,
});
const isPlayer = (entity: IEntity): boolean => {
return "isPlayer" in entity;
};
const existsPlayer = (name: string): boolean => {
return (
state.game.players.find(
(player) => player.name.toLowerCase() === name.toLowerCase(),
) !== undefined
);
};
const existsNpc = (name: string): boolean => {
return (
npcs.find((npc) => npc.name.toLowerCase() === name.toLowerCase()) !==
undefined
);
};
const existsEntity = (name: string): boolean => {
return existsPlayer(name) || existsNpc(name);
};
const getAttack = (id: Attack): IAttack => {
const attack = attacks.find((attack) => attack.id === id);
return attack ? attack : attackPunch;
};
const getPlayer = (userId: string): IPlayer => {
return getPlayerByName(getUserNameById(userId));
};
const getPlayerByName = (name: string): IPlayer => {
const player = state.game.players.find(
(player) => player.name.toLowerCase() === name.toLowerCase(),
);
if (player) {
return player;
}
const newPlayer = createPlayer(name);
state.game.players.push(newPlayer);
return newPlayer;
};
const getEntityByName = (name: string): IPlayer | TFullNPC => {
if (existsPlayer(name)) {
return getPlayerByName(name);
}
const npc = getNpcByName(name);
return { ...npc, ...getNpcData(npc.id) };
};
const getNpc = (id: NPC): INPC => {
const npc = npcs.find((npc) => npc.id === id);
return npc ? npc : npcBecky;
};
const getNpcByName = (name: string): INPC => {
const npc = npcs.find(
(npc) => npc.name.toLowerCase() === name.toLowerCase(),
);
return npc ? npc : npcBecky;
};
const getNpcData = (id: NPC): INPCData => {
const npcData = state.game.npcs.find((npcData) => npcData.id === id);
if (npcData) {
return npcData;
}
const newNpcData = createNpcData(getNpc(id));
state.game.npcs.push(newNpcData);
return newNpcData;
};
const getNpcsAtLocation = (id: Location): INPC[] => {
return npcs.filter((npc) => npc.location === id);
};
const getPlayersAtLocation = (id: Location): IPlayer[] => {
return state.game.players.filter((player) => player.location === id);
};
const getEntitiesAtLocation = (id: Location): IEntity[] => {
const npcsAtLocation = getNpcsAtLocation(id);
const playersAtLocation = getPlayersAtLocation(id);
return [...npcsAtLocation, ...playersAtLocation];
};
const getRace = (id: Race): IRace => {
const race = races.find((race) => race.id === id);
return race ? race : raceHuman;
};
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 getMaxHealth = (entity: IEntity): number => {
return 100 + entity.vitality * 10;
};
const getHealthPercentage = (entity: IPlayer | INPC): number => {
if ("health" in entity) {
return (entity.health / getMaxHealth(entity)) * 100;
}
const npcData = getNpcData(entity.id);
return (npcData.health / getMaxHealth(entity)) * 100;
};
const getSpeed = (entity: IEntity) => {
return 60 + 3 + Math.sqrt(entity.agility + entity.endurance) / 2;
};
export {
createPlayer,
createNpcData,
isPlayer,
existsPlayer,
existsNpc,
existsEntity,
getAttack,
getPlayer,
getPlayerByName,
getEntityByName,
getNpc,
getNpcByName,
getNpcData,
getNpcsAtLocation,
getPlayersAtLocation,
getEntitiesAtLocation,
getRace,
getLevel,
getMaxHealth,
getHealthPercentage,
getSpeed,
};