fix: add effect triggering fixes
This commit is contained in:
parent
aedf82d264
commit
af0906561c
|
|
@ -1,5 +1,11 @@
|
|||
import {CombatEntity, CombatState, EffectTable, PlayerEntity} from "./types";
|
||||
import {CardData, EffectData} from "@/samples/slay-the-spire-like/system/types";
|
||||
import {CombatEntity, CombatGameContext, CombatState, EffectTable, PlayerEntity} from "./types";
|
||||
import {
|
||||
CardData,
|
||||
CardEffectTarget,
|
||||
CardTargetType,
|
||||
EffectData,
|
||||
EffectTarget
|
||||
} from "@/samples/slay-the-spire-like/system/types";
|
||||
import {GameItemMeta} from "@/samples/slay-the-spire-like/system/progress/types";
|
||||
import {GridInventory} from "@/samples/slay-the-spire-like/system/grid-inventory/types";
|
||||
|
||||
|
|
@ -80,6 +86,25 @@ export function* getAliveEnemies(state: CombatState) {
|
|||
}
|
||||
}
|
||||
|
||||
export function* getEffectTargets(target: CardEffectTarget | EffectTarget, game: CombatGameContext, targetId?: string){
|
||||
if(target === 'all' || target === 'team'){
|
||||
for(const enemy of getAliveEnemies(game.value)){
|
||||
yield enemy;
|
||||
}
|
||||
} else if(target === 'self') {
|
||||
yield game.value.player;
|
||||
} else if(target === 'target'){
|
||||
if(!targetId) return;
|
||||
const entity = getCombatEntity(game.value, targetId);
|
||||
if(entity) yield entity;
|
||||
} else if(target === 'random'){
|
||||
const aliveEnemies = [...getAliveEnemies(game.value)];
|
||||
if(aliveEnemies.length === 0) return;
|
||||
const index = game.rng.nextInt(aliveEnemies.length);
|
||||
yield aliveEnemies[index];
|
||||
}
|
||||
}
|
||||
|
||||
export function getCombatEntity(state: CombatState, entityKey: string){
|
||||
return entityKey === 'player' ? state.player : state.enemies.find(e => e.id === entityKey);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import {
|
|||
addItemEffect,
|
||||
getAliveEnemies, onEntityPostureDamage,
|
||||
onEntityEffectUpkeep,
|
||||
onPlayerItemEffectUpkeep, onItemDiscard, onItemPlay, payCardCost
|
||||
onPlayerItemEffectUpkeep, onItemDiscard, onItemPlay, payCardCost, getCombatEntity, getEffectTargets
|
||||
} from "@/samples/slay-the-spire-like/system/combat/effects";
|
||||
import {promptMainAction} from "@/samples/slay-the-spire-like/system/combat/prompts";
|
||||
import {moveToRegion, shuffle} from "@/core/region";
|
||||
|
|
@ -34,7 +34,7 @@ function createTriggers(){
|
|||
onCombatStart: createTrigger("onCombatStart"),
|
||||
onTurnStart: createTrigger("onTurnStart", async ctx => {
|
||||
await ctx.game.produceAsync(draft => {
|
||||
const entity = ctx.entityKey === "player" ? draft.player : draft.enemies.find(e => e.id === ctx.entityKey);
|
||||
const entity = getCombatEntity(draft, ctx.entityKey);
|
||||
if(entity) onEntityEffectUpkeep(entity);
|
||||
if(entity === draft.player)
|
||||
onPlayerItemEffectUpkeep(draft.player);
|
||||
|
|
@ -65,6 +65,13 @@ function createTriggers(){
|
|||
moveToRegion(card, regions.hand, regions.discardPile);
|
||||
onItemPlay(draft.player, card.itemId);
|
||||
});
|
||||
const {cards, regions} = ctx.game.value.player.deck;
|
||||
const card = cards[ctx.cardId];
|
||||
for(const [trigger, target, effect, stacks] of card.cardData.effects){
|
||||
if(trigger !== 'onPlay') continue;
|
||||
for(const entity of getEffectTargets(target, ctx.game, ctx.targetId))
|
||||
await triggers.onEffectApplied.execute(ctx.game,{effect, entityKey: entity.id, stacks, cardId: ctx.cardId});
|
||||
}
|
||||
}),
|
||||
onCardDiscarded: createTrigger("onCardDiscarded", async ctx => {
|
||||
await ctx.game.produceAsync(draft => {
|
||||
|
|
@ -72,12 +79,26 @@ function createTriggers(){
|
|||
moveToRegion(cards[ctx.cardId], regions.hand, regions.discardPile);
|
||||
onItemDiscard(draft.player, cards[ctx.cardId].itemId);
|
||||
});
|
||||
const {cards, regions} = ctx.game.value.player.deck;
|
||||
const card = cards[ctx.cardId];
|
||||
for(const [trigger, target, effect, stacks] of card.cardData.effects){
|
||||
if(trigger !== 'onDiscard') continue;
|
||||
for(const entity of getEffectTargets(target, ctx.game))
|
||||
await triggers.onEffectApplied.execute(ctx.game,{effect, entityKey: entity.id, stacks, cardId: ctx.cardId});
|
||||
}
|
||||
}),
|
||||
onCardDrawn: createTrigger("onCardDrawn", async ctx => {
|
||||
await ctx.game.produceAsync(draft => {
|
||||
const {cards, regions} = draft.player.deck;
|
||||
moveToRegion(cards[ctx.cardId], regions.drawPile, regions.hand);
|
||||
});
|
||||
const {cards, regions} = ctx.game.value.player.deck;
|
||||
const card = cards[ctx.cardId];
|
||||
for(const [trigger, target, effect, stacks] of card.cardData.effects){
|
||||
if(trigger !== 'onDraw') continue;
|
||||
for(const entity of getEffectTargets(target, ctx.game))
|
||||
await triggers.onEffectApplied.execute(ctx.game,{effect, entityKey: entity.id, stacks, cardId: ctx.cardId});
|
||||
}
|
||||
}),
|
||||
onDraw: createTrigger("onDraw", async ctx => {
|
||||
let toDraw = ctx.count;
|
||||
|
|
@ -138,26 +159,12 @@ function createTriggers(){
|
|||
const enemy = ctx.game.value.enemies.find(e => e.id === ctx.enemyId);
|
||||
if(!enemy || !enemy.isAlive) return;
|
||||
|
||||
const intent = enemy.intents[enemy.currentIntentId];
|
||||
const intent = enemy.currentIntent;
|
||||
if(!intent) return;
|
||||
|
||||
for(const [target, effect, stacks] of intent.effects){
|
||||
if(target === 'team'){
|
||||
for(const enemy of getAliveEnemies(ctx.game.value)){
|
||||
await triggers.onEffectApplied.execute(ctx.game, {
|
||||
effect,
|
||||
entityKey: enemy.id,
|
||||
stacks,
|
||||
});
|
||||
}
|
||||
}else {
|
||||
const entityKey = target === 'self' ? ctx.enemyId : 'player';
|
||||
await triggers.onEffectApplied.execute(ctx.game, {
|
||||
effect,
|
||||
entityKey,
|
||||
stacks,
|
||||
});
|
||||
}
|
||||
for(const entity of getEffectTargets(target, ctx.game))
|
||||
await triggers.onEffectApplied.execute(ctx.game, { effect, entityKey: entity.id, stacks, });
|
||||
}
|
||||
}),
|
||||
onIntentUpdate: createTrigger("onIntentUpdate", async ctx => {
|
||||
|
|
@ -165,13 +172,13 @@ function createTriggers(){
|
|||
const enemy = draft.enemies.find(e => e.id === ctx.enemyId);
|
||||
if(!enemy) return;
|
||||
|
||||
const intent = enemy.intents[enemy.currentIntentId];
|
||||
const intent = enemy.currentIntent;
|
||||
if(!intent) return;
|
||||
|
||||
const nextIntents = intent.nextIntents;
|
||||
if(nextIntents.length > 0){
|
||||
const nextIndex = ctx.game.rng.nextInt(nextIntents.length);
|
||||
enemy.currentIntentId = nextIntents[nextIndex];
|
||||
enemy.currentIntent = nextIntents[nextIndex];
|
||||
}
|
||||
});
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import {GameItemMeta} from "@/samples/slay-the-spire-like/system/progress";
|
|||
export type EffectTable = Record<string, {data: EffectData, stacks: number}>;
|
||||
|
||||
export type CombatEntity = {
|
||||
id: string; // player is just "player"
|
||||
effects: EffectTable;
|
||||
hp: number;
|
||||
maxHp: number;
|
||||
|
|
@ -21,10 +22,9 @@ export type PlayerEntity = CombatEntity & {
|
|||
}
|
||||
|
||||
export type EnemyEntity = CombatEntity & {
|
||||
id: string;
|
||||
enemy: EnemyData;
|
||||
intents: Record<string, IntentData>;
|
||||
currentIntentId: string;
|
||||
currentIntent: IntentData;
|
||||
};
|
||||
|
||||
export type CombatPhase = "playerTurn" | "enemyTurn" | "combatEnd";
|
||||
|
|
|
|||
Loading…
Reference in New Issue