feat: more effects
This commit is contained in:
parent
131af2c0bb
commit
90ca8fa761
|
|
@ -7,6 +7,8 @@ import { moveToRegion } from "@/core/region";
|
||||||
import { CombatGameContext } from "@/samples/slay-the-spire-like/system/combat/types";
|
import { CombatGameContext } from "@/samples/slay-the-spire-like/system/combat/types";
|
||||||
import { EffectData } from "@/samples/slay-the-spire-like/system/types";
|
import { EffectData } from "@/samples/slay-the-spire-like/system/types";
|
||||||
import { GameCard } from "@/samples/slay-the-spire-like/system/deck";
|
import { GameCard } from "@/samples/slay-the-spire-like/system/deck";
|
||||||
|
import { getAdjacentItems } from "@/samples/slay-the-spire-like/system/grid-inventory";
|
||||||
|
import { GameItemMeta } from "@/samples/slay-the-spire-like/system/progress";
|
||||||
|
|
||||||
export function addEffectTriggers(triggers: Triggers) {
|
export function addEffectTriggers(triggers: Triggers) {
|
||||||
// ========== instant effects ==========
|
// ========== instant effects ==========
|
||||||
|
|
@ -430,6 +432,91 @@ export function addEffectTriggers(triggers: Triggers) {
|
||||||
|
|
||||||
await next();
|
await next();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ========== crossbow: replay other crossbows on same target ==========
|
||||||
|
triggers.onEffectApplied.use(async (ctx, next) => {
|
||||||
|
await next();
|
||||||
|
|
||||||
|
if (ctx.effect.id !== "crossbow" || !ctx.cardId || !ctx.targetId) return;
|
||||||
|
|
||||||
|
const { cards, regions } = ctx.game.value.player.deck;
|
||||||
|
const handIds = [...regions.hand.childIds];
|
||||||
|
for (const id of handIds) {
|
||||||
|
const card = cards[id];
|
||||||
|
if (card && card.itemId === "crossbow" && id !== ctx.cardId) {
|
||||||
|
await triggers.onCardPlayed.execute(ctx.game, {
|
||||||
|
cardId: id,
|
||||||
|
targetId: ctx.targetId,
|
||||||
|
sourceEntityKey: "player",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// ========== burnForEnergy: consume adjacent item, gain energy when its card is played ==========
|
||||||
|
triggers.onCardPlayed.use(async (ctx, next) => {
|
||||||
|
await next();
|
||||||
|
|
||||||
|
const card = ctx.game.value.player.deck.cards[ctx.cardId];
|
||||||
|
if (!card) return;
|
||||||
|
const playedItemId = card.itemId;
|
||||||
|
|
||||||
|
const adjacent = getAdjacentItems<GameItemMeta>(ctx.game.value.inventory, playedItemId);
|
||||||
|
for (const [adjItemId] of adjacent) {
|
||||||
|
const adjEffects = ctx.game.value.player.itemEffects[adjItemId];
|
||||||
|
if (!adjEffects) continue;
|
||||||
|
const burn = adjEffects.burnForEnergy;
|
||||||
|
if (!burn || burn.stacks <= 0) continue;
|
||||||
|
|
||||||
|
await ctx.game.produceAsync(draft => {
|
||||||
|
const item = draft.inventory.items.get(adjItemId);
|
||||||
|
if (item) {
|
||||||
|
draft.inventory.items.delete(adjItemId);
|
||||||
|
}
|
||||||
|
draft.player.energy += burn.stacks;
|
||||||
|
delete draft.player.itemEffects[adjItemId];
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// ========== sandwormKing: heal 10 hp when player discards fatigue ==========
|
||||||
|
triggers.onCardDiscarded.use(async (ctx, next) => {
|
||||||
|
await next();
|
||||||
|
|
||||||
|
const card = ctx.game.value.player.deck.cards[ctx.cardId];
|
||||||
|
if (!card || card.cardData.id !== "fatigue") return;
|
||||||
|
|
||||||
|
const sandwormKing = ctx.game.value.enemies.find(
|
||||||
|
e => e.enemy.id === "沙虫王" && e.isAlive
|
||||||
|
);
|
||||||
|
if (!sandwormKing) return;
|
||||||
|
|
||||||
|
await ctx.game.produceAsync(draft => {
|
||||||
|
const king = draft.enemies.find(e => e.id === sandwormKing.id);
|
||||||
|
if (king) {
|
||||||
|
king.hp = Math.min(king.hp + 10, king.maxHp);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// ========== vulture: give vultureEye when vulture deals damage ==========
|
||||||
|
triggers.onDamage.use(async (ctx, next) => {
|
||||||
|
await next();
|
||||||
|
|
||||||
|
const dealt = ctx.amount - (ctx.prevented ?? 0);
|
||||||
|
if (dealt <= 0 || !ctx.sourceEntityKey) return;
|
||||||
|
|
||||||
|
const attacker = getCombatEntity(ctx.game.value, ctx.sourceEntityKey);
|
||||||
|
if (!attacker || !("enemy" in attacker) || attacker.enemy.id !== "秃鹫") return;
|
||||||
|
|
||||||
|
await triggers.onEffectApplied.execute(ctx.game, {
|
||||||
|
effect: findEffect(ctx.game, "vultureEye"),
|
||||||
|
entityKey: "player",
|
||||||
|
stacks: 1,
|
||||||
|
sourceEntityKey: ctx.sourceEntityKey,
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAllEnemyData(game: CombatGameContext) {
|
function getAllEnemyData(game: CombatGameContext) {
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ type TriggerTypes = {
|
||||||
onCardDiscarded: { cardId: string, sourceEntityKey?: "player" | string },
|
onCardDiscarded: { cardId: string, sourceEntityKey?: "player" | string },
|
||||||
onCardDrawn: { cardId: string, sourceEntityKey?: "player" | string },
|
onCardDrawn: { cardId: string, sourceEntityKey?: "player" | string },
|
||||||
onDraw: {count: number},
|
onDraw: {count: number},
|
||||||
onEffectApplied: { effect: EffectData, entityKey: "player" | string, stacks: number, cardId?: string, sourceEntityKey?: "player" | string },
|
onEffectApplied: { effect: EffectData, entityKey: "player" | string, stacks: number, cardId?: string, sourceEntityKey?: "player" | string, targetId?: string },
|
||||||
onHpChange: { entityKey: "player" | string, amount: number},
|
onHpChange: { entityKey: "player" | string, amount: number},
|
||||||
onDamage: { entityKey: "player" | string, amount: number, prevented?: number, sourceEntityKey?: "player" | string},
|
onDamage: { entityKey: "player" | string, amount: number, prevented?: number, sourceEntityKey?: "player" | string},
|
||||||
onEnemyIntent: { enemyId: string, sourceEntityKey?: "player" | string },
|
onEnemyIntent: { enemyId: string, sourceEntityKey?: "player" | string },
|
||||||
|
|
@ -71,7 +71,7 @@ function createTriggers(){
|
||||||
for(const [trigger, target, effect, stacks] of card.cardData.effects){
|
for(const [trigger, target, effect, stacks] of card.cardData.effects){
|
||||||
if(trigger !== 'onPlay') continue;
|
if(trigger !== 'onPlay') continue;
|
||||||
for(const entity of getEffectTargets(target, ctx.game, ctx.targetId))
|
for(const entity of getEffectTargets(target, ctx.game, ctx.targetId))
|
||||||
await triggers.onEffectApplied.execute(ctx.game,{effect, entityKey: entity.id, stacks, cardId: ctx.cardId, sourceEntityKey: source});
|
await triggers.onEffectApplied.execute(ctx.game,{effect, entityKey: entity.id, stacks, cardId: ctx.cardId, sourceEntityKey: source, targetId: ctx.targetId});
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
onCardDiscarded: createTrigger("onCardDiscarded", async ctx => {
|
onCardDiscarded: createTrigger("onCardDiscarded", async ctx => {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue