feat: add posture damage & item effect update trigger

This commit is contained in:
hypercross 2026-04-17 11:57:07 +08:00
parent 65afe6dc8f
commit 1d749f59a6
2 changed files with 43 additions and 9 deletions

View File

@ -34,6 +34,14 @@ export function onEntityEffectUpkeep(entity: CombatEntity){
}
}
export function onEntityPostureDamage(entity: CombatEntity, damage: number){
for(const effect of Object.values(entity.effects)){
const lifecycle = effect.data.lifecycle;
if(lifecycle === 'posture')
addEntityEffect(entity, effect.data, -Math.min(damage, effect.stacks));
}
}
export function onPlayerItemEffectUpkeep(entity: PlayerEntity){
for(const [itemKey, itemEffects] of Object.entries(entity.itemEffects)){
for(const effect of Object.values(itemEffects)){
@ -44,6 +52,26 @@ export function onPlayerItemEffectUpkeep(entity: PlayerEntity){
}
}
export function onItemPlay(entity: PlayerEntity, itemKey: string){
const effects = entity.itemEffects[itemKey];
if(!effects)return;
for(const effect of Object.values(effects)){
if(effect.data.lifecycle === 'itemUntilPlay'){
addItemEffect(entity, itemKey, effect.data, -effect.stacks);
}
}
}
export function onItemDiscard(entity: PlayerEntity, itemKey: string){
const effects = entity.itemEffects[itemKey];
if(!effects)return;
for(const effect of Object.values(effects)){
if(effect.data.lifecycle === 'itemUntilDiscard'){
addItemEffect(entity, itemKey, effect.data, -effect.stacks);
}
}
}
export function* getAliveEnemies(state: CombatState) {
for (let enemy of state.enemies) {
if (enemy.isAlive) {

View File

@ -2,9 +2,9 @@ import {CombatGameContext} from "./types";
import {
addEntityEffect,
addItemEffect,
getAliveEnemies,
getAliveEnemies, onEntityPostureDamage,
onEntityEffectUpkeep,
onPlayerItemEffectUpkeep
onPlayerItemEffectUpkeep, onItemDiscard, onItemPlay
} 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";
@ -24,6 +24,7 @@ type TriggerTypes = {
onDraw: {count: number},
onEffectApplied: { effect: EffectData, entityKey: "player" | string, stacks: number, cardId?: string },
onHpChange: { entityKey: "player" | string, amount: number},
onDamage: { entityKey: "player" | string, amount: number, dealt?: number, prevented?: number},
}
function createTriggers(){
@ -58,12 +59,14 @@ function createTriggers(){
await ctx.game.produceAsync(draft => {
const {cards, regions} = draft.player.deck;
moveToRegion(cards[ctx.cardId], regions.hand, regions.discardPile);
onItemPlay(draft.player, cards[ctx.cardId].itemId);
});
}),
onCardDiscarded: createTrigger("onCardDiscarded", async ctx => {
await ctx.game.produceAsync(draft => {
const {cards, regions} = draft.player.deck;
moveToRegion(cards[ctx.cardId], regions.hand, regions.discardPile);
onItemDiscard(draft.player, cards[ctx.cardId].itemId);
});
}),
onCardDrawn: createTrigger("onCardDrawn", async ctx => {
@ -103,13 +106,6 @@ function createTriggers(){
return;
}
if(ctx.effect.lifecycle.startsWith('card')){
await ctx.game.produceAsync(draft => {
// TODO
});
return;
}
await ctx.game.produceAsync(draft => {
const entity = ctx.entityKey === "player" ? draft.player : draft.enemies.find(e => e.id === ctx.entityKey);
if(entity) addEntityEffect(entity, ctx.effect, ctx.stacks);
@ -125,6 +121,16 @@ function createTriggers(){
});
if(ctx.game.value.result) throw ctx.game.value;
}),
onDamage: createTrigger("onDamage", async ctx => {
const entity = ctx.entityKey === "player" ? ctx.game.value.player : ctx.game.value.enemies.find(e => e.id === ctx.entityKey);
if(!entity || !entity.isAlive) return;
const dealt = ctx.dealt = Math.min(Math.max(0,entity.hp), ctx.amount);
ctx.prevented = ctx.amount - ctx.dealt;
await ctx.game.produceAsync(draft => {
onEntityPostureDamage(entity, dealt);
});
await triggers.onHpChange.execute(ctx.game,{entityKey: ctx.entityKey, amount: -ctx.amount});
}),
}
return triggers;
}