UNPKG

programming-game

Version:

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

238 lines (230 loc) 5.23 kB
import { OffhandEquipmentType, WeaponType } from "./items"; import { AppliesMechanics, ClientSideUnit, StatusEffectName } from "./types"; export type WeaponSkill = // 1h sword skills | "doubleSlash" // bow skills | "pinningShot" | "misdirectingShot" // unarmed skills | "combo" | "haymaker" | "headbutt" // 2h sword skills | "charge" | "powerSlash" // shield skills | "shieldCharge" // generic skills | "threaten"; type Exchange<T extends ClientSideUnit> = T["id"]; // exchange any fields of T that extend ClientSideUnit with their 'id' field type ClientSideUnitExchange<T> = { [K in keyof T]: T[K] extends ClientSideUnit ? Exchange<T[K]> : T[K]; }; type T = ClientSideUnitExchange<{ to: ClientSideUnit; }>; type WeaponSkillOptions<S extends WeaponSkill, ClientOptions, ServerOptions> = { client: { skill: S; target: ClientSideUnit; options?: ClientOptions; } & (ClientOptions extends undefined ? { options?: undefined; } : { options: ClientOptions; }); server: { skill: S; target: string; options?: ServerOptions; } & (ServerOptions extends undefined ? { options?: undefined; } : { options: ServerOptions; }); }; export type WeaponSkillSpecifics = { misdirectingShot: WeaponSkillOptions< "misdirectingShot", { to: ClientSideUnit; }, { to: string; } >; doubleSlash: WeaponSkillOptions<"doubleSlash", undefined, undefined>; powerSlash: WeaponSkillOptions<"powerSlash", undefined, undefined>; pinningShot: WeaponSkillOptions<"pinningShot", undefined, undefined>; combo: WeaponSkillOptions<"combo", undefined, undefined>; haymaker: WeaponSkillOptions<"haymaker", undefined, undefined>; headbutt: WeaponSkillOptions<"headbutt", undefined, undefined>; charge: WeaponSkillOptions<"charge", undefined, undefined>; shieldCharge: WeaponSkillOptions<"shieldCharge", undefined, undefined>; threaten: WeaponSkillOptions<"threaten", undefined, undefined>; }; type t = WeaponSkillSpecifics["misdirectingShot"]["server"]; export type WeaponSkillDefinition = { id: WeaponSkill; name: string; tpCost: number; weaponType?: WeaponType | OffhandEquipmentType | "unarmed"; target?: string; minRange?: number; maxRange?: number; mechanics?: { damageMultiplier?: number; attackMultiplier?: number; threat?: number; }; selfEffects?: { duration: number; effect: StatusEffectName; mechanics: AppliesMechanics; }; targetEffects?: { duration: number; effect: StatusEffectName; mechanics: AppliesMechanics; }; }; export const weaponSkills: Record<WeaponSkill, WeaponSkillDefinition> = { doubleSlash: { id: "doubleSlash", name: "Double Slash", tpCost: 10, weaponType: "oneHandedSword", mechanics: { damageMultiplier: 1, attackMultiplier: 2, }, }, misdirectingShot: { id: "misdirectingShot", name: "Misdirecting Shot", tpCost: 15, weaponType: "bow", mechanics: {}, }, pinningShot: { id: "pinningShot", name: "Pinning Shot", tpCost: 30, weaponType: "bow", mechanics: { damageMultiplier: 1, attackMultiplier: 1, }, targetEffects: { duration: 3_000, effect: "pinningShot", mechanics: { snare: true, }, }, }, // unarmed skills combo: { id: "combo", name: "Combo", tpCost: 30, weaponType: "unarmed", mechanics: { damageMultiplier: 1, attackMultiplier: 3, }, }, haymaker: { id: "haymaker", name: "Haymaker", tpCost: 30, weaponType: "unarmed", mechanics: { damageMultiplier: 5, attackMultiplier: 1, }, }, headbutt: { id: "headbutt", name: "Headbutt", tpCost: 40, weaponType: "unarmed", targetEffects: { duration: 500, effect: "headbutt", mechanics: { stun: true, }, }, }, // two handed sword skills charge: { id: "charge", name: "Charge", tpCost: 20, weaponType: "twoHandedSword", maxRange: 7, mechanics: { damageMultiplier: 1.5, }, selfEffects: { duration: 3_000, effect: "charge", mechanics: { movementMultiplier: 2.5, }, }, }, powerSlash: { id: "powerSlash", name: "Power Slash", tpCost: 20, weaponType: "twoHandedSword", mechanics: { damageMultiplier: 2, attackMultiplier: 1, }, }, // shield skills shieldCharge: { id: "shieldCharge", name: "Shield Charge", tpCost: 20, weaponType: "shield", maxRange: 7, mechanics: { damageMultiplier: 1.5, }, selfEffects: { duration: 3_000, effect: "shieldCharge", mechanics: { movementMultiplier: 2.5, stats: {}, }, }, targetEffects: { duration: 3_000, effect: "stunned", mechanics: { stun: true, }, }, }, threaten: { name: "Threaten", id: "threaten", tpCost: 15, weaponType: undefined, mechanics: { attackMultiplier: 0, // threaten does not attack, it just applies threat threat: 30, }, }, };