192 lines
4.5 KiB
TypeScript
192 lines
4.5 KiB
TypeScript
import { getUserNameById } from "../../helpers.js";
|
|
import { state } from "../../store/store.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 => ({
|
|
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,
|
|
});
|
|
|
|
const createNpcData = (npc: INPC): INPCData => ({
|
|
id: npc.id,
|
|
health: getMaxHealth(npc),
|
|
dead: false,
|
|
});
|
|
|
|
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 getPlayer = (userId: string): IPlayer => {
|
|
return getPlayerByName(getUserNameById(userId));
|
|
};
|
|
|
|
const getPlayerByName = (name: string): IPlayer => {
|
|
const player = state.game.players.find((player) => player.name === name);
|
|
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.id === name);
|
|
|
|
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 entity.vitality * 10;
|
|
};
|
|
|
|
const getHealthPercentage = (entity: IPlayer | INPC): number => {
|
|
if ("health" in entity) {
|
|
return entity.health / getMaxHealth(entity);
|
|
}
|
|
|
|
const npcData = getNpcData(entity.id);
|
|
return npcData.health / getMaxHealth(entity);
|
|
};
|
|
|
|
const getSpeed = (entity: IEntity) => {
|
|
return 60 + 3 + Math.sqrt(entity.agility + entity.endurance) / 2;
|
|
};
|
|
|
|
export {
|
|
createPlayer,
|
|
createNpcData,
|
|
existsPlayer,
|
|
existsNpc,
|
|
existsEntity,
|
|
getPlayer,
|
|
getPlayerByName,
|
|
getEntityByName,
|
|
getNpc,
|
|
getNpcByName,
|
|
getNpcData,
|
|
getNpcsAtLocation,
|
|
getPlayersAtLocation,
|
|
getEntitiesAtLocation,
|
|
getRace,
|
|
getLevel,
|
|
getMaxHealth,
|
|
getHealthPercentage,
|
|
getSpeed,
|
|
};
|