import { GameObjectRegister } from "." import { CardType, type Card } from "./Card" import type { GameObjectNetcode } from "./GameObject" export enum CardEffects { GOLD = "gold", DAMAGE = "damage", HEAL = "heal", PREPARE = "prepare", STUN = "stun", SACRIFICE = "sacrifice", DRAW = "draw", DRAW_AND_DISCARD = "draw_and_discard", MAKE_DISCARD = "make_discard", RESTACK_DISCARDED_CHAMPION = "restack_discarded_champion", RESTACK_DISCARDED_CARD = "restack_discarded_card", STACK_NEXT_ACTION_BOUGHT = "stack_next_action_bought", STACK_NEXT_CARD_BOUGHT = "stack_next_card_bought", PLAY_NEXT_CARD_BOUGHT = "play_next_card_bought" } export enum EffectTimes { PER_CHAMPION = "per_champion", PER_OTHER_CHAMPION = "per_other_champion", PER_OTHER_GUARD = "per_other_guard", PER_CARD_OF_SAME_FACTION = "per_card_of_same_faction", PER_OTHER_CARD_OF_SAME_FACTION = "per_other_card_of_same_faction" } export enum EffectType { CHAMPION_ACTION = "champion_action", SUICIDE = "suicide", FACTION_COMBO = "faction_combo" } export interface EffectNetcode extends GameObjectNetcode { effect: CardEffects amount: number sub_effects: Array mutex: Array card: string effect_type?: EffectType times?: EffectTimes } export type Effect = Omit & { sub_effects: { [key: string]: Effect } mutex: { [key: string]: Effect } card: Card usable: boolean } export function create_effect(input: EffectNetcode, register: GameObjectRegister) { const effect = new Proxy(input, { get(target: EffectNetcode, prop, reciever) { if (prop == "sub_effects") { return Object.fromEntries(Object.entries(register.effects).filter(([i, v]) => i in target.sub_effects)) } if (prop == "mutex") { return Object.fromEntries(Object.entries(register.effects).filter(([i, v]) => i in target.mutex)) } if (prop == "usable") { // ugly bastard if (!register.self) { return false } let cardLocked = register.self.value?.turn?.cards_locked if (!cardLocked) { return false } let cardList = Object.values(cardLocked) const card = cardList.find(c => c.effects.map(e => e.uuid).includes(effect.uuid)) if (!card) { return false } if (target.effect_type === EffectType.FACTION_COMBO) { if (!cardList.some(c => c !== card && c.faction === card.faction)) { return false } } if (target.times === EffectTimes.PER_OTHER_CARD_OF_SAME_FACTION) { if (!cardList.some(c => c !== card && c.faction === card.faction)) { return false } } else if (target.times === EffectTimes.PER_OTHER_CHAMPION) { if (!cardList.some(c => c !== card && c.card_type === CardType.CHAMPION)) { return false } } else if (target.times === EffectTimes.PER_OTHER_GUARD) { if (!cardList.some(c => c !== card && c.guard)) { return false } } return true } if (prop == "card") { return register.cards.get(target.card) } return Reflect.get(target, prop, reciever); }, set(target, prop, val, receiver) { return Reflect.set(target, prop, val, receiver); } }) as Effect return effect }