From 7b954bb5a540a27990aa3a471dab93e15b41bbbb Mon Sep 17 00:00:00 2001 From: hypercross Date: Wed, 15 Apr 2026 15:41:20 +0800 Subject: [PATCH] refactor: add more effect --- .../slay-the-spire-like/data/effectDesert.csv | 19 ++++++- .../data/effectDesert.csv.d.ts | 2 +- .../data/heroItemFighter1.csv | 52 +++++++++---------- .../data/heroItemFighter1.csv.d.ts | 3 ++ .../slay-the-spire-like/data/index.test.ts | 19 ++++++- 5 files changed, 65 insertions(+), 30 deletions(-) diff --git a/src/samples/slay-the-spire-like/data/effectDesert.csv b/src/samples/slay-the-spire-like/data/effectDesert.csv index f678beb..858fff0 100644 --- a/src/samples/slay-the-spire-like/data/effectDesert.csv +++ b/src/samples/slay-the-spire-like/data/effectDesert.csv @@ -6,9 +6,11 @@ # card: 不施加buff,对玩家时在玩家弃牌堆创建同名卡牌,对敌人无效(敌人没有牌堆) # cardDraw: 不施加buff,在抓牌堆洗入同名卡牌 # cardHand:不施加buff,在玩家手牌中创建同名卡牌 +# item: 施加buff到周围物品,永久生效 +# itemUntilPlayed: 施加buff到周围物品,物品被打出后失效 id, name, description, timing -string, string, string, 'instant'|'temporary'|'lingering'|'permanent'|'posture'|'card'|'cardDraw'|'cardHand' +string, string, string, 'instant'|'temporary'|'lingering'|'permanent'|'posture'|'card'|'cardDraw'|'cardHand'|'item'|'itemUntilPlayed' attack, 攻击, 对对手造成伤害, instant defend, 防御, 抵消下次行动前受到的伤害, posture spike, 尖刺, 对攻击者造成X点伤害, lingering @@ -28,3 +30,18 @@ charge, 冲锋, 受到或造成的伤害翻倍并消耗等量冲锋, lingering summonMummy, 召唤木乃伊, 召唤1个木乃伊, instant summonSandwormLarva, 召唤幼沙虫, 召唤1个幼沙虫, instant reviveMummy, 复活木乃伊, 复活1个已死亡的木乃伊, instant +draw, 抓牌, 抓X张牌, instant +crossbow, 十字弩连击, 对同一目标打出其他十字弩, instant +defendNext, 下回合防御, 下回合开始时获得防御, temporary +damageReduce, 减伤, 本回合受到的伤害减少X, temporary +removeWound, 移除伤口, 从牌堆或弃牌堆移除X张伤口, instant +attackBuff, 攻击增益, 周围物品的攻击+X, itemUntilPlayed +defendBuff, 防御增益, 周围物品的防御+X, itemUntilPlayed +gainEnergy, 获得能量, 获得X点能量, instant +energyNext, 下回合获能量, 下回合开始时获得X点能量, temporary +drawNext, 下回合抓牌, 下回合开始时抓X张牌, temporary +defendBuffUntilPlay, 防御增益直到打出, 周围物品的牌防御+X直到打出, itemUntilPlayed +drawChoice, 选择抓牌, 从牌堆周围物品的牌中选择一张加入手牌, instant +burnForEnergy, 消耗获能量, 打出周围物品的牌时消耗并获得X能量, itemUntilPlayed +attackBuffUntilPlay, 攻击增益直到打出, 周围物品的牌攻击+X直到打出, itemUntilPlayed +transformRandom, 随机变牌, 选择一张牌随机变为周围物品的牌, instant diff --git a/src/samples/slay-the-spire-like/data/effectDesert.csv.d.ts b/src/samples/slay-the-spire-like/data/effectDesert.csv.d.ts index f55b6f8..1847600 100644 --- a/src/samples/slay-the-spire-like/data/effectDesert.csv.d.ts +++ b/src/samples/slay-the-spire-like/data/effectDesert.csv.d.ts @@ -2,7 +2,7 @@ type EffectDesertTable = readonly { readonly id: string; readonly name: string; readonly description: string; - readonly timing: "instant" | "temporary" | "lingering" | "permanent" | "posture" | "card" | "cardDraw" | "cardHand"; + readonly timing: "instant" | "temporary" | "lingering" | "permanent" | "posture" | "card" | "cardDraw" | "cardHand" | "item" | "itemUntilPlayed"; }[]; export type EffectDesert = EffectDesertTable[number]; diff --git a/src/samples/slay-the-spire-like/data/heroItemFighter1.csv b/src/samples/slay-the-spire-like/data/heroItemFighter1.csv index 8616263..983fc31 100644 --- a/src/samples/slay-the-spire-like/data/heroItemFighter1.csv +++ b/src/samples/slay-the-spire-like/data/heroItemFighter1.csv @@ -8,29 +8,29 @@ # # targetType can be one of: single, none -type,name,shape,costType,costCount,targetType,price,desc -string,string,string,'energy'|'uses',int,'single'|'none',int,string -weapon,剑,oee,energy,1,single,50,【攻击2】【攻击2】 -weapon,长斧,oees,energy,2,none,80,对全体【攻击5】 -weapon,长枪,oeee,energy,1,single,75,【攻击2】【攻击2】【攻击2】 -weapon,短刀,oe,energy,1,single,40,【攻击3】【攻击3】 -weapon,飞镖,o,energy,0,single,30,【攻击1】,抓一张牌 -weapon,十字弩,onrersrw,energy,2,single,120,【攻击6】。对同一目标打出其他十字弩 -armor,盾,oesw,energy,1,none,50,【防御3】 -armor,斗笠,oerwrn,energy,2,none,90,【防御8】 -armor,披风,oers,energy,1,none,45,【防御2】,下回合【防御2】 -armor,护腕,o,energy,0,none,25,【防御1】,抓1张牌 -armor,大盾,oesswn,energy,1,none,70,【防御5】 -armor,锁子甲,oers,energy,1,none,60,本回合受到伤害-3 -consumable,绷带,o,uses,3,none,20,从牌堆或弃牌堆随机移除1张伤口 -consumable,淬毒药剂,o,uses,3,none,30,周围物品的【攻击】+2 -consumable,强固药剂,o,uses,3,none,30,周围物品的【防御】+2 -consumable,活力药剂,o,uses,3,none,25,获得1点能量 -consumable,集中药剂,o,uses,3,none,25,抓2张牌 -consumable,治疗药剂,o,uses,3,none,35,从牌堆或弃牌堆移除3张伤口 -tool,水袋,os,energy,1,none,35,下回合开始时,获得1能量,抓2张牌 -tool,绳索,ose,energy,1,none,30,周围物品的牌【防御】+2直到打出 -tool,腰带,owre,energy,0,none,40,从牌堆周围物品的牌当中选择一张加入手牌 -tool,火把,on,energy,1,none,25,下次打出周围物品的牌时,将其消耗并获得1能量 -tool,磨刀石,o,energy,1,none,30,周围物品的牌【攻击】+3直到打出 -tool,铁匠锤,oers,energy,1,none,45,从牌堆/弃牌堆选择一张牌,随机变为一张周围物品的牌 +type,name,shape,costType,costCount,targetType,price,desc,effects +string,string,string,'energy'|'uses',int,'single'|'none',int,string,['self'|'target'|'all'|'random'; @effectDesert; number][] +weapon,剑,oee,energy,1,single,50,【攻击2】【攻击2】,[target;attack;2];[target;attack;2] +weapon,长斧,oees,energy,2,none,80,对全体【攻击5】,[all;attack;5] +weapon,长枪,oeee,energy,1,single,75,【攻击2】【攻击2】【攻击2】,[target;attack;2];[target;attack;2];[target;attack;2] +weapon,短刀,oe,energy,1,single,40,【攻击3】【攻击3】,[target;attack;3];[target;attack;3] +weapon,飞镖,o,energy,0,single,30,【攻击1】,抓一张牌,[target;attack;1];[self;draw;1] +weapon,十字弩,onrersrw,energy,2,single,120,【攻击6】。对同一目标打出其他十字弩,[target;attack;6];[self;crossbow;0] +armor,盾,oesw,energy,1,none,50,【防御3】,[self;defend;3] +armor,斗笠,oerwrn,energy,2,none,90,【防御8】,[self;defend;8] +armor,披风,oers,energy,1,none,45,【防御2】,下回合【防御2】,[self;defend;2];[self;defendNext;2] +armor,护腕,o,energy,0,none,25,【防御1】,抓1张牌,[self;defend;1];[self;draw;1] +armor,大盾,oesswn,energy,1,none,70,【防御5】,[self;defend;5] +armor,锁子甲,oers,energy,1,none,60,本回合受到伤害-3,[self;damageReduce;3] +consumable,绷带,o,uses,3,none,20,从牌堆或弃牌堆随机移除1张伤口,[self;removeWound;1] +consumable,淬毒药剂,o,uses,3,none,30,周围物品的【攻击】+2,[self;attackBuff;2] +consumable,强固药剂,o,uses,3,none,30,周围物品的【防御】+2,[self;defendBuff;2] +consumable,活力药剂,o,uses,3,none,25,获得1点能量,[self;gainEnergy;1] +consumable,集中药剂,o,uses,3,none,25,抓2张牌,[self;draw;2] +consumable,治疗药剂,o,uses,3,none,35,从牌堆或弃牌堆移除3张伤口,[self;removeWound;3] +tool,水袋,os,energy,1,none,35,下回合开始时,获得1能量,抓2张牌,[self;energyNext;1];[self;drawNext;2] +tool,绳索,ose,energy,1,none,30,周围物品的牌【防御】+2直到打出,[self;defendBuffUntilPlay;2] +tool,腰带,owre,energy,0,none,40,从牌堆周围物品的牌当中选择一张加入手牌,[self;drawChoice;1] +tool,火把,on,energy,1,none,25,下次打出周围物品的牌时,将其消耗并获得1能量,[self;burnForEnergy;1] +tool,磨刀石,o,energy,1,none,30,周围物品的牌【攻击】+3直到打出,[self;attackBuffUntilPlay;3] +tool,铁匠锤,oers,energy,1,none,45,从牌堆/弃牌堆选择一张牌,随机变为一张周围物品的牌,[self;transformRandom;1] diff --git a/src/samples/slay-the-spire-like/data/heroItemFighter1.csv.d.ts b/src/samples/slay-the-spire-like/data/heroItemFighter1.csv.d.ts index 5ff6eb0..de4efd2 100644 --- a/src/samples/slay-the-spire-like/data/heroItemFighter1.csv.d.ts +++ b/src/samples/slay-the-spire-like/data/heroItemFighter1.csv.d.ts @@ -1,3 +1,5 @@ +import type { EffectDesert } from './effectDesert.csv'; + type HeroItemFighter1Table = readonly { readonly type: string; readonly name: string; @@ -7,6 +9,7 @@ type HeroItemFighter1Table = readonly { readonly targetType: "single" | "none"; readonly price: number; readonly desc: string; + readonly effects: readonly ["self" | "target" | "all" | "random", EffectDesert, number]; }[]; export type HeroItemFighter1 = HeroItemFighter1Table[number]; diff --git a/tests/samples/slay-the-spire-like/data/index.test.ts b/tests/samples/slay-the-spire-like/data/index.test.ts index becc534..30e77ef 100644 --- a/tests/samples/slay-the-spire-like/data/index.test.ts +++ b/tests/samples/slay-the-spire-like/data/index.test.ts @@ -26,6 +26,7 @@ describe('heroItemFighter1.csv import', () => { expect(item).toHaveProperty('costCount'); expect(item).toHaveProperty('targetType'); expect(item).toHaveProperty('desc'); + expect(item).toHaveProperty('effects'); } }); @@ -75,6 +76,17 @@ describe('heroItemFighter1.csv import', () => { expect(typeCounts['consumable']).toBe(6); expect(typeCounts['tool']).toBe(6); }); + + it('should have effects with target, effect ref, and value', () => { + for (const item of heroItemFighter1Data) { + expect(Array.isArray(item.effects)).toBe(true); + for (const [target, effect, value] of item.effects) { + expect(target === 'self' || target === 'target' || target === 'all' || target === 'random').toBe(true); + expect(typeof effect === 'string' || typeof effect === 'object').toBe(true); + expect(typeof value).toBe('number'); + } + } + }); }); describe('encounterDesert.csv import', () => { @@ -135,7 +147,7 @@ describe('effectDesert.csv import', () => { }); it('should have expected number of effects', () => { - expect(effectDesertData.length).toBe(19); + expect(effectDesertData.length).toBe(34); }); it('should have correct fields for each effect', () => { @@ -148,7 +160,7 @@ describe('effectDesert.csv import', () => { }); it('should have valid timing values', () => { - const validTimings = ['instant', 'temporary', 'lingering', 'permanent', 'posture', 'card', 'cardDraw', 'cardHand']; + const validTimings = ['instant', 'temporary', 'lingering', 'permanent', 'posture', 'card', 'cardDraw', 'cardHand', 'item', 'itemUntilPlayed']; for (const effect of effectDesertData) { expect(validTimings).toContain(effect.timing); } @@ -160,6 +172,9 @@ describe('effectDesert.csv import', () => { expect(ids).toContain('defend'); expect(ids).toContain('spike'); expect(ids).toContain('venom'); + expect(ids).toContain('draw'); + expect(ids).toContain('removeWound'); + expect(ids).toContain('gainEnergy'); }); });