UNPKG

programming-game

Version:

The client for programming game, an mmorpg that you interact with entirely through code.

337 lines (331 loc) 9.72 kB
import { Items, UsableItems, Equipments } from "./items"; import { recipes } from "./recipes"; import { Spells, CastIntent } from "./spells"; import { ClientSidePlayer, ROLES, SetRoleIntent, IntentType, ClientSideUnit, AttackIntent, Tree, MiningNode, HarvestIntent, MoveIntent, RespawnIntent, SummonManaIntent, EatIntent, SellItemsIntent, BuyItemsIntent, UseIntent, SeekPartyIntent, InviteToPartyIntent, LeavePartyIntent, AcceptPartyInviteIntent, DeclinePartyInviteIntent, PlayerEquipment, EquipIntent, UnequipIntent, CraftIntent, WeaponSkillIntent, DropIntent, NewTrades, SetTradeIntent, ClientSideNPC, AcceptQuestIntent, AbandonQuestIntent, TurnInQuestIntent, Inventory, WithdrawIntent, DepositIntent, EquipSpellIntent, UnequipSpellIntent, Position, } from "./types"; import { entries } from "./utils"; import { WeaponSkill, WeaponSkillSpecifics } from "./weapon-skills"; export const getHandlers = (player: ClientSidePlayer) => { const handlers = { /** * Update the role that you intend to play when grouping with other players. */ setRole: (role: ROLES): SetRoleIntent => { return { type: IntentType.setRole, role }; }, /** * Move to and attack a unit. */ attack: (target: ClientSideUnit): AttackIntent => { return { type: IntentType.attack, target: target.id }; }, /** * Attempt to harvest resources from a tree or mining node. */ harvest: (target: Tree | MiningNode): HarvestIntent => { return { type: IntentType.harvest, target: target.id, }; }, /** * Move to the specified position. * @param position {Position} The position to move to. */ move: (position: Position): MoveIntent => { return { type: IntentType.move, position }; }, /** * Respawn a your character after death. * * Respawning will place your character at the nearest respawn point, but you'll lose all your items and equipment. */ respawn: (): RespawnIntent => { return { type: IntentType.respawn } as RespawnIntent; }, /** * Concentrate and restore your mana more quickly than normal. */ summonMana: (): SummonManaIntent => { return { type: IntentType.summonMana }; }, /** * Attempt to eat an item from your inventory. */ eat: (item: Items): EatIntent => { return { type: IntentType.eat, item: item, save: (player.inventory[item] || 0) - 1, }; }, /** * Cast a spell at an optional target. * * Spells require that the appropriate spell stone is equipped in your spellbook AND that you have enough spell slots in your equipment. */ cast: (spell: Spells, target?: ClientSideUnit): CastIntent => { return { type: IntentType.cast, spell, target: target?.id }; }, /** * Sell items from your inventory to an NPC or player. */ sell: (opt: { items: { [key in Items]?: number }; to: ClientSideUnit; }): SellItemsIntent => { return { type: IntentType.sellItems, items: entries(opt.items).reduce((acc, [item, amount]) => { const until = (player.inventory[item] || 0) - (amount || 0); acc[item] = until; return acc; }, {} as { [key in Items]: number }), to: opt.to.id, }; }, /** * Buy items from an NPC or player. * * The target unit must have the items available to sell, and listed in their trades. */ buy: (opts: { items: { [key in Items]?: number }; from: ClientSideUnit; }): BuyItemsIntent => { return { type: IntentType.buyItems, items: entries(opts.items).reduce((acc, [item, amount]) => { if (!amount) return acc; const until = amount + (player.inventory[item] || 0); if (amount) { acc[item] = until; } return acc; }, {} as { [key in Items]: number }), from: opts.from.id, }; }, /** * Use an item from your inventory, optionally you can use the item on a target unit instead of yourself. */ use: (item: UsableItems, target?: ClientSideUnit): UseIntent => { return { type: IntentType.use, item, until: (player.inventory[item] || 0) - 1, target: target?.id, }; }, /** * Announce to the world that you are seeking a party. */ seekParty: (): SeekPartyIntent => { return { type: IntentType.seekParty }; }, /** * Invite the specified player id to join your party. */ inviteToParty: (playerId: string): InviteToPartyIntent => { return { type: IntentType.inviteToParty, playerId }; }, /** * Leave your current party. */ leaveParty: (): LeavePartyIntent => { return { type: IntentType.leaveParty }; }, /** * Accept a party invitation from the specified player id. * * This is a noop if the player hasn't invited you to a party. */ acceptPartyInvite: (playerId: string): AcceptPartyInviteIntent => { return { type: IntentType.acceptPartyInvite, playerId }; }, /** * Decline a party invitation from the specified player id. */ declinePartyInvite: (playerId: string): DeclinePartyInviteIntent => { return { type: IntentType.declinePartyInvite, playerId }; }, /** * Equip a piece of equipment into the specified slot. * * The item must be in your inventory. */ equip: (item: Equipments, slot: keyof PlayerEquipment): EquipIntent => { return { type: IntentType.equip, item, slot }; }, /** * Return a piece of equipment from your equipment back into your inventory. */ unequip: (slot: keyof PlayerEquipment): UnequipIntent => { return { type: IntentType.unequip, slot }; }, /** * Attempt to craft an item using materials from your inventory. */ craft: ( item: keyof typeof recipes, from: Partial<Record<Items, number>> ): CraftIntent => { return { type: IntentType.craft, item, from }; }, /** * Consumes TP to use a weapon skill on a target. * * Some weapon skills may require additional options. */ useWeaponSkill: <T extends WeaponSkill>( specifics: WeaponSkillSpecifics[T]["client"] ): WeaponSkillIntent<T> => { if (specifics.skill === "misdirectingShot") { return { type: IntentType.weaponSkill, skill: specifics.skill, target: specifics.target.id, options: { to: specifics.target.id, }, }; } return { type: IntentType.weaponSkill, skill: specifics.skill, target: specifics.target.id, }; }, /** * Drop items from your inventory onto the ground. */ drop: ({ item, amount }: { item: Items; amount: number }): DropIntent => { return { type: IntentType.drop, item, until: (player.inventory[item] || 0) - amount, }; }, /** * Update the list of items that you are buying an selling as well as their prices. */ setTrade: (trades: NewTrades): SetTradeIntent => { return { type: IntentType.setTrade, trades, }; }, /** * Accept a quest from an NPC. */ acceptQuest: (npc: ClientSideNPC, questId: string): AcceptQuestIntent => { return { type: IntentType.acceptQuest, npcId: npc.id, questId }; }, /** * Remove a quest from your active quests and free up a slot in your quest log. */ abandonQuest: (questId: string): AbandonQuestIntent => { return { type: IntentType.abandonQuest, questId }; }, /** * Turn in a completed quest to an NPC. */ turnInQuest: (npc: ClientSideNPC, questId: string): TurnInQuestIntent => { return { type: IntentType.turnInQuest, npcId: npc.id, questId }; }, /** * Withdraw items from a storage NPC to your inventory. * * The specified NPC MUST be a banker. */ withdraw: (npc: ClientSideNPC, items: Inventory): WithdrawIntent => { const until: Inventory = {}; entries(items).forEach(([item, amount = 0]) => { const charAmount = player.storage[item] || 0; until[item] = charAmount - amount; }); return { type: IntentType.withdraw, npcId: npc.id, until, }; }, /** * Deposit items from your inventory into a storage NPC. * * The specified NPC MUST be a banker. */ deposit: (npc: ClientSideNPC, items: Inventory): DepositIntent => { const until: Inventory = {}; entries(items).forEach(([item, amount = 0]) => { const charAmount = player.inventory[item] || 0; until[item] = charAmount - amount; }); return { type: IntentType.deposit, npcId: npc.id, until, }; }, /** * Equips the specified spell stone from your inventory into your spellbook. * * You MUST have an open slot if your spellbook, and the spell stone must be in your inventory. */ equipSpell: (spell: Spells): EquipSpellIntent => { return { type: IntentType.equipSpell, spell, }; }, /** * Unequips the first spell in the player's spellbook, and returns it to your inventory. */ unequipSpell: (): UnequipSpellIntent => { return { type: IntentType.unequipSpell, }; }, }; return handlers; }; export type Handlers = ReturnType<typeof getHandlers>;