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