Compare commits

...

4 Commits

Author SHA1 Message Date
hypercross 6984e54bdf refactor: add status cards and rules. 2026-04-15 16:28:18 +08:00
hypercross 7b954bb5a5 refactor: add more effect 2026-04-15 15:41:20 +08:00
hypercross 7472095822 refactor: add team effect 2026-04-15 15:21:44 +08:00
hypercross e5da41c1cb refactor: op -> player 2026-04-15 15:19:58 +08:00
11 changed files with 237 additions and 52 deletions

View File

@ -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

Can't render this file because it has a wrong number of fields in line 12.

View File

@ -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];

View File

@ -7,46 +7,46 @@
# brokenIntent: 防御被打空后改变的意图id多个意图则从中随机
# effects技能效果目标+buff/debuff/攻击/防御+数值/层数
enemy,id,nextIntents,brokenIntent,effects
@enemyDesert,string,@enemyIntentDesert[],@enemyIntentDesert[],['self' | 'opponent';@effectDesert;number][]
@enemyDesert,string,@enemyIntentDesert[],@enemyIntentDesert[],['self' | 'player' | 'team';@effectDesert;number][]
仙人掌怪,boost,boost;defend;defend,,[self;spike;1];[self;defend;4]
仙人掌怪,defend,attack,,[self;defend;8]
仙人掌怪,attack,boost,,[opponent;attack;5]
蛇,poison,attack;attack,,[opponent;venom;1];[opponent;attack;4]
蛇,attack,poison;boost,,[opponent;attack;6]
蛇,boost,poison;attack,,[self;defend;3];[opponent;venom;1]
木乃伊,attack,defend;curse,,[opponent;attack;6]
仙人掌怪,attack,boost,,[player;attack;5]
蛇,poison,attack;attack,,[player;venom;1];[player;attack;4]
蛇,attack,poison;boost,,[player;attack;6]
蛇,boost,poison;attack,,[self;defend;3];[player;venom;1]
木乃伊,attack,defend;curse,,[player;attack;6]
木乃伊,defend,attack,,[self;defend;6]
木乃伊,curse,defend;attack,attack,[opponent;curse;1]
木乃伊,curse,defend;attack,attack,[player;curse;1]
枪手,aim,attack,,[self;aim;2]
枪手,attack,aim;defend,aim,[opponent;attack;8]
枪手,attack,aim;defend,aim,[player;attack;8]
枪手,defend,aim,aim,[self;defend;5]
风卷草,boost,defend;defend;boost,,[self;roll;5];[self;defend;4]
风卷草,defend,boost;attack,,[self;defend;8]
风卷草,attack,boost,,[opponent;rollDamage;0]
秃鹫,attack,defend;defend,,[opponent;attack;6];[opponent;vultureEye;1]
风卷草,attack,boost,,[player;rollDamage;0]
秃鹫,attack,defend;defend,,[player;attack;6];[player;vultureEye;1]
秃鹫,defend,attack;attack,,[self;defend;5]
沙蝎,boost,attack;attack,,[self;tailSting;2]
沙蝎,attack,boost;attack,,[opponent;attack;6]
沙蝎,attack,boost;attack,,[player;attack;6]
幼沙虫,defend,defend;boost,,[self;defend;6]
幼沙虫,boost,attack;defend,,[self;energyDrain;1];[self;defend;4]
幼沙虫,attack,defend;defend,,[opponent;attack;5]
蜥蜴,attack,defend;molt,,[opponent;attack;5]
幼沙虫,attack,defend;defend,,[player;attack;5]
蜥蜴,attack,defend;molt,,[player;attack;5]
蜥蜴,defend,attack;attack,,[self;defend;6]
蜥蜴,molt,defend;attack,,[self;molt;3]
沙匪,attack,attack;heavyAttack,,[opponent;attack;6]
沙匪,heavyAttack,attack;attack;debuff,,[opponent;attack;10]
沙匪,debuff,attack;attack,,[opponent;discard;1]
沙匪,attack,attack;heavyAttack,,[player;attack;6]
沙匪,heavyAttack,attack;attack;debuff,,[player;attack;10]
沙匪,debuff,attack;attack,,[player;discard;1]
风暴之灵,storm,attack;storm,,[self;storm;2];[self;defend;3]
风暴之灵,attack,storm;defend,,[opponent;attack;8];[opponent;static;1]
风暴之灵,attack,storm;defend,,[player;attack;8];[player;static;1]
风暴之灵,defend,storm;attack,,[self;defend;8]
骑马枪手,charge,attack,,[self;charge;2]
骑马枪手,attack,charge;defend,charge,[opponent;attack;6]
骑马枪手,attack,charge;defend,charge,[player;attack;6]
骑马枪手,defend,charge;attack,charge,[self;defend;5]
沙虫王,summon,attack;defend,,[self;summonSandwormLarva;1]
沙虫王,attack,summon;defend,,[opponent;attack;9]
沙虫王,attack,summon;defend,,[player;attack;9]
沙虫王,defend,attack;summon,,[self;defend;6]
沙漠守卫,summon,attack;defend,,[self;summonMummy;1]
沙漠守卫,attack,defend;summon,,[opponent;attack;8]
沙漠守卫,attack,defend;summon,,[player;attack;8]
沙漠守卫,defend,attack;revive,,[self;defend;8]
沙漠守卫,revive,attack;summon,,[self;reviveMummy;1]
1 # 敌人行动状态机,敌人行动时会执行当前的意图,然后将意图变为下一个意图
7 # effects:技能效果,目标+buff/debuff/攻击/防御+数值/层数
8 enemy,id,nextIntents,brokenIntent,effects
9 @enemyDesert,string,@enemyIntentDesert[],@enemyIntentDesert[],['self' | 'opponent';@effectDesert;number][] @enemyDesert,string,@enemyIntentDesert[],@enemyIntentDesert[],['self' | 'player' | 'team';@effectDesert;number][]
10 仙人掌怪,boost,boost;defend;defend,,[self;spike;1];[self;defend;4]
11 仙人掌怪,defend,attack,,[self;defend;8]
12 仙人掌怪,attack,boost,,[opponent;attack;5] 仙人掌怪,attack,boost,,[player;attack;5]
13 蛇,poison,attack;attack,,[opponent;venom;1];[opponent;attack;4] 蛇,poison,attack;attack,,[player;venom;1];[player;attack;4]
14 蛇,attack,poison;boost,,[opponent;attack;6] 蛇,attack,poison;boost,,[player;attack;6]
15 蛇,boost,poison;attack,,[self;defend;3];[opponent;venom;1] 蛇,boost,poison;attack,,[self;defend;3];[player;venom;1]
16 木乃伊,attack,defend;curse,,[opponent;attack;6] 木乃伊,attack,defend;curse,,[player;attack;6]
17 木乃伊,defend,attack,,[self;defend;6]
18 木乃伊,curse,defend;attack,attack,[opponent;curse;1] 木乃伊,curse,defend;attack,attack,[player;curse;1]
19 枪手,aim,attack,,[self;aim;2]
20 枪手,attack,aim;defend,aim,[opponent;attack;8] 枪手,attack,aim;defend,aim,[player;attack;8]
21 枪手,defend,aim,aim,[self;defend;5]
22 风卷草,boost,defend;defend;boost,,[self;roll;5];[self;defend;4]
23 风卷草,defend,boost;attack,,[self;defend;8]
24 风卷草,attack,boost,,[opponent;rollDamage;0] 风卷草,attack,boost,,[player;rollDamage;0]
25 秃鹫,attack,defend;defend,,[opponent;attack;6];[opponent;vultureEye;1] 秃鹫,attack,defend;defend,,[player;attack;6];[player;vultureEye;1]
26 秃鹫,defend,attack;attack,,[self;defend;5]
27 沙蝎,boost,attack;attack,,[self;tailSting;2]
28 沙蝎,attack,boost;attack,,[opponent;attack;6] 沙蝎,attack,boost;attack,,[player;attack;6]
29 幼沙虫,defend,defend;boost,,[self;defend;6]
30 幼沙虫,boost,attack;defend,,[self;energyDrain;1];[self;defend;4]
31 幼沙虫,attack,defend;defend,,[opponent;attack;5] 幼沙虫,attack,defend;defend,,[player;attack;5]
32 蜥蜴,attack,defend;molt,,[opponent;attack;5] 蜥蜴,attack,defend;molt,,[player;attack;5]
33 蜥蜴,defend,attack;attack,,[self;defend;6]
34 蜥蜴,molt,defend;attack,,[self;molt;3]
35 沙匪,attack,attack;heavyAttack,,[opponent;attack;6] 沙匪,attack,attack;heavyAttack,,[player;attack;6]
36 沙匪,heavyAttack,attack;attack;debuff,,[opponent;attack;10] 沙匪,heavyAttack,attack;attack;debuff,,[player;attack;10]
37 沙匪,debuff,attack;attack,,[opponent;discard;1] 沙匪,debuff,attack;attack,,[player;discard;1]
38 风暴之灵,storm,attack;storm,,[self;storm;2];[self;defend;3]
39 风暴之灵,attack,storm;defend,,[opponent;attack;8];[opponent;static;1] 风暴之灵,attack,storm;defend,,[player;attack;8];[player;static;1]
40 风暴之灵,defend,storm;attack,,[self;defend;8]
41 骑马枪手,charge,attack,,[self;charge;2]
42 骑马枪手,attack,charge;defend,charge,[opponent;attack;6] 骑马枪手,attack,charge;defend,charge,[player;attack;6]
43 骑马枪手,defend,charge;attack,charge,[self;defend;5]
44 沙虫王,summon,attack;defend,,[self;summonSandwormLarva;1]
45 沙虫王,attack,summon;defend,,[opponent;attack;9] 沙虫王,attack,summon;defend,,[player;attack;9]
46 沙虫王,defend,attack;summon,,[self;defend;6]
47 沙漠守卫,summon,attack;defend,,[self;summonMummy;1]
48 沙漠守卫,attack,defend;summon,,[opponent;attack;8] 沙漠守卫,attack,defend;summon,,[player;attack;8]
49 沙漠守卫,defend,attack;revive,,[self;defend;8]
50 沙漠守卫,revive,attack;summon,,[self;reviveMummy;1]
51
52

View File

@ -6,7 +6,7 @@ type EnemyIntentDesertTable = readonly {
readonly id: string;
readonly nextIntents: readonly EnemyIntentDesert[];
readonly brokenIntent: readonly EnemyIntentDesert[];
readonly effects: readonly ["self" | "opponent", EffectDesert, number];
readonly effects: readonly ["self" | "player" | "team", EffectDesert, number];
}[];
export type EnemyIntentDesert = EnemyIntentDesertTable[number];

View File

@ -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]

1 # type can be one of: weapon, armor, consumable, tool
8 #
9 # targetType can be one of: single, none
10 type,name,shape,costType,costCount,targetType,price,desc type,name,shape,costType,costCount,targetType,price,desc,effects
11 string,string,string,'energy'|'uses',int,'single'|'none',int,string string,string,string,'energy'|'uses',int,'single'|'none',int,string,['self'|'target'|'all'|'random'; @effectDesert; number][]
12 weapon,剑,oee,energy,1,single,50,【攻击2】【攻击2】 weapon,剑,oee,energy,1,single,50,【攻击2】【攻击2】,[target;attack;2];[target;attack;2]
13 weapon,长斧,oees,energy,2,none,80,对全体【攻击5】 weapon,长斧,oees,energy,2,none,80,对全体【攻击5】,[all;attack;5]
14 weapon,长枪,oeee,energy,1,single,75,【攻击2】【攻击2】【攻击2】 weapon,长枪,oeee,energy,1,single,75,【攻击2】【攻击2】【攻击2】,[target;attack;2];[target;attack;2];[target;attack;2]
15 weapon,短刀,oe,energy,1,single,40,【攻击3】【攻击3】 weapon,短刀,oe,energy,1,single,40,【攻击3】【攻击3】,[target;attack;3];[target;attack;3]
16 weapon,飞镖,o,energy,0,single,30,【攻击1】,抓一张牌 weapon,飞镖,o,energy,0,single,30,【攻击1】,抓一张牌,[target;attack;1];[self;draw;1]
17 weapon,十字弩,onrersrw,energy,2,single,120,【攻击6】。对同一目标打出其他十字弩 weapon,十字弩,onrersrw,energy,2,single,120,【攻击6】。对同一目标打出其他十字弩,[target;attack;6];[self;crossbow;0]
18 armor,盾,oesw,energy,1,none,50,【防御3】 armor,盾,oesw,energy,1,none,50,【防御3】,[self;defend;3]
19 armor,斗笠,oerwrn,energy,2,none,90,【防御8】 armor,斗笠,oerwrn,energy,2,none,90,【防御8】,[self;defend;8]
20 armor,披风,oers,energy,1,none,45,【防御2】,下回合【防御2】 armor,披风,oers,energy,1,none,45,【防御2】,下回合【防御2】,[self;defend;2];[self;defendNext;2]
21 armor,护腕,o,energy,0,none,25,【防御1】,抓1张牌 armor,护腕,o,energy,0,none,25,【防御1】,抓1张牌,[self;defend;1];[self;draw;1]
22 armor,大盾,oesswn,energy,1,none,70,【防御5】 armor,大盾,oesswn,energy,1,none,70,【防御5】,[self;defend;5]
23 armor,锁子甲,oers,energy,1,none,60,本回合受到伤害-3 armor,锁子甲,oers,energy,1,none,60,本回合受到伤害-3,[self;damageReduce;3]
24 consumable,绷带,o,uses,3,none,20,从牌堆或弃牌堆随机移除1张伤口 consumable,绷带,o,uses,3,none,20,从牌堆或弃牌堆随机移除1张伤口,[self;removeWound;1]
25 consumable,淬毒药剂,o,uses,3,none,30,周围物品的【攻击】+2 consumable,淬毒药剂,o,uses,3,none,30,周围物品的【攻击】+2,[self;attackBuff;2]
26 consumable,强固药剂,o,uses,3,none,30,周围物品的【防御】+2 consumable,强固药剂,o,uses,3,none,30,周围物品的【防御】+2,[self;defendBuff;2]
27 consumable,活力药剂,o,uses,3,none,25,获得1点能量 consumable,活力药剂,o,uses,3,none,25,获得1点能量,[self;gainEnergy;1]
28 consumable,集中药剂,o,uses,3,none,25,抓2张牌 consumable,集中药剂,o,uses,3,none,25,抓2张牌,[self;draw;2]
29 consumable,治疗药剂,o,uses,3,none,35,从牌堆或弃牌堆移除3张伤口 consumable,治疗药剂,o,uses,3,none,35,从牌堆或弃牌堆移除3张伤口,[self;removeWound;3]
30 tool,水袋,os,energy,1,none,35,下回合开始时,获得1能量,抓2张牌 tool,水袋,os,energy,1,none,35,下回合开始时,获得1能量,抓2张牌,[self;energyNext;1];[self;drawNext;2]
31 tool,绳索,ose,energy,1,none,30,周围物品的牌【防御】+2直到打出 tool,绳索,ose,energy,1,none,30,周围物品的牌【防御】+2直到打出,[self;defendBuffUntilPlay;2]
32 tool,腰带,owre,energy,0,none,40,从牌堆周围物品的牌当中选择一张加入手牌 tool,腰带,owre,energy,0,none,40,从牌堆周围物品的牌当中选择一张加入手牌,[self;drawChoice;1]
33 tool,火把,on,energy,1,none,25,下次打出周围物品的牌时,将其消耗并获得1能量 tool,火把,on,energy,1,none,25,下次打出周围物品的牌时,将其消耗并获得1能量,[self;burnForEnergy;1]
34 tool,磨刀石,o,energy,1,none,30,周围物品的牌【攻击】+3直到打出 tool,磨刀石,o,energy,1,none,30,周围物品的牌【攻击】+3直到打出,[self;attackBuffUntilPlay;3]
35 tool,铁匠锤,oers,energy,1,none,45,从牌堆/弃牌堆选择一张牌,随机变为一张周围物品的牌 tool,铁匠锤,oers,energy,1,none,45,从牌堆/弃牌堆选择一张牌,随机变为一张周围物品的牌,[self;transformRandom;1]
36

View File

@ -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];

View File

@ -3,14 +3,17 @@ import encounterDesertCsv from './encounterDesert.csv';
import enemyDesertCsv from './enemyDesert.csv';
import enemyIntentDesertCsv from './enemyIntentDesert.csv';
import effectDesertCsv from './effectDesert.csv';
import statusCardDesertCsv from './statusCardDesert.csv';
export const heroItemFighter1Data = heroItemFighter1Csv();
export const encounterDesertData = encounterDesertCsv();
export const enemyDesertData = enemyDesertCsv();
export const enemyIntentDesertData = enemyIntentDesertCsv();
export const effectDesertData = effectDesertCsv();
export const statusCardDesertData = statusCardDesertCsv();
export { default as encounterDesertCsv, type EncounterDesert } from './encounterDesert.csv';
export { default as enemyDesertCsv, type EnemyDesert } from './enemyDesert.csv';
export { default as enemyIntentDesertCsv, type EnemyIntentDesert } from './enemyIntentDesert.csv';
export { default as effectDesertCsv, type EffectDesert } from './effectDesert.csv';
export { default as statusCardDesertCsv, type StatusCardDesert } from './statusCardDesert.csv';

View File

@ -0,0 +1,72 @@
# 战斗规则
## 战斗状态
角色表:
- 敌方角色表
- 我方角色表
角色状态:
- hp/最大hp
- buff表名称->层数同名buff合并叠加
战利品表:
- 类型
- 数量
触发规则表:
- 类型
- 层数
## 战斗开始
战斗开始时,首先进行敌方角色的战斗开始结算,然后进行玩家的战斗开始结算。
战斗开始会让玩家抓5张起始手牌让敌方角色初始化意图。
## 回合
进行一个玩家回合,然后进行一个敌方回合,以此重复,直到不存在玩家或敌方角色存活。
玩家回合包含以下阶段:
- buff更新temporary buff清空lingering buff层数-1。
- 回合开始:触发回合开始结算的效果。
- 玩家行动:玩家可以花费能量打出手牌。点结束来结束行动。
- 回合结束:触发回合结束结算的效果。
- 重置手牌弃掉剩余的手牌重新抓5张手牌。
- 重置能量重置到3点能量。
敌人回合包含以下阶段:
- buff更新每个敌人的temporary buff清空lingering buff层数-1。
- 回合开始:触发回合开始结算的效果。
- 敌人行动:每个敌人的意图依次生效,然后更新下一个意图。
- 回合结束:触发回合结束结算的效果。
## 效果
效果结算时,具有以下上下文:
- name: 效果名称
- stacks: 层数
- target: 目标角色,如果有
- source来源角色如果有
- card来源卡牌如果有
效果有以下类型:
- Instant: 立即结算。
- Buff: 施加为buff持续整场战斗。
- BuffTemporary: 施加为buff下次buff更新时清空。
- BuffLingering: 施加为buff下次buff更新时层数-1。
- BuffPosture: 施加为buff受到伤害时扣除等量层数。
- Item: 施加为物品buff对来源卡牌对应的物品周围的物品生效。
- ItemUntilPlayed施加为物品buff对来源卡牌对应的物品生效生效一次后失效。
- ItemTemporary: 施加为物品buff对来源卡牌对应的物品生效下次buff更新时清空。
- ItemPermanent: 施加为物品buff对来源卡牌对应的物品生效战斗结束后依然有效。
- Card: 施加为状态卡牌,洗入玩家弃牌堆。对敌人无效。
- CardDraw洗入抓牌堆。
- CardHand加入手牌。

View File

@ -0,0 +1,10 @@
# 状态牌:由某些效果创建,洗入玩家牌堆或手牌
# unplayable: 是否不可打出
# effects: 状态牌在场时施加的效果
id, name, desc, unplayable, effects
string, string, string, boolean, ['self'; @effectDesert; number][]
wound, 伤口, 无效果,占用手牌和牌堆, true,
venom, 蛇毒, 弃掉超过1张蛇毒时受到6伤害, true, [self; venom; 1]
curse, 诅咒, 受攻击时物品攻击-1直到弃掉一张该物品的牌, true, [self; curse; 1]
static, 静电, 在手里时受电击伤害+1, true, [self; static; 1]
1 # 状态牌:由某些效果创建,洗入玩家牌堆或手牌
2 # unplayable: 是否不可打出
3 # effects: 状态牌在场时施加的效果
4 id, name, desc, unplayable, effects
5 string, string, string, boolean, ['self'; @effectDesert; number][]
6 wound, 伤口, 无效果,占用手牌和牌堆, true,
7 venom, 蛇毒, 弃掉超过1张蛇毒时受到6伤害, true, [self; venom; 1]
8 curse, 诅咒, 受攻击时物品攻击-1,直到弃掉一张该物品的牌, true, [self; curse; 1]
9 static, 静电, 在手里时受电击伤害+1, true, [self; static; 1]

View File

@ -0,0 +1,14 @@
import type { EffectDesert } from './effectDesert.csv';
type StatusCardDesertTable = readonly {
readonly id: string;
readonly name: string;
readonly desc: string;
readonly unplayable: boolean;
readonly effects: readonly ["self", EffectDesert, number];
}[];
export type StatusCardDesert = StatusCardDesertTable[number];
declare function getData(): StatusCardDesertTable;
export default getData;

View File

@ -5,6 +5,7 @@ import {
enemyDesertData,
enemyIntentDesertData,
effectDesertData,
statusCardDesertData,
} from '@/samples/slay-the-spire-like/data';
describe('heroItemFighter1.csv import', () => {
@ -26,6 +27,7 @@ describe('heroItemFighter1.csv import', () => {
expect(item).toHaveProperty('costCount');
expect(item).toHaveProperty('targetType');
expect(item).toHaveProperty('desc');
expect(item).toHaveProperty('effects');
}
});
@ -75,6 +77,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 +148,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 +161,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 +173,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');
});
});
@ -231,7 +247,7 @@ describe('enemyIntentDesert.csv import', () => {
it('should have effects with target, effect ref, and value', () => {
for (const intent of enemyIntentDesertData) {
for (const [target, effect, value] of intent.effects) {
expect(target === 'self' || target === 'opponent').toBe(true);
expect(target === 'self' || target === 'player' || target === 'team').toBe(true);
expect(typeof effect === 'string' || typeof effect === 'object').toBe(true);
expect(typeof value).toBe('number');
}
@ -243,3 +259,53 @@ describe('enemyIntentDesert.csv import', () => {
expect(enemyIds.size).toBe(14);
});
});
describe('statusCardDesert.csv import', () => {
it('should import data as an array', () => {
expect(Array.isArray(statusCardDesertData)).toBe(true);
expect(statusCardDesertData.length).toBeGreaterThan(0);
});
it('should have expected number of status cards', () => {
expect(statusCardDesertData.length).toBe(4);
});
it('should have correct fields for each status card', () => {
for (const card of statusCardDesertData) {
expect(card).toHaveProperty('id');
expect(card).toHaveProperty('name');
expect(card).toHaveProperty('desc');
expect(card).toHaveProperty('unplayable');
expect(card).toHaveProperty('effects');
expect(typeof card.id).toBe('string');
expect(typeof card.name).toBe('string');
expect(typeof card.desc).toBe('string');
expect(typeof card.unplayable).toBe('boolean');
}
});
it('should have all cards unplayable', () => {
for (const card of statusCardDesertData) {
expect(card.unplayable).toBe(true);
}
});
it('should have effects with target, effect ref, and value', () => {
for (const card of statusCardDesertData) {
expect(Array.isArray(card.effects)).toBe(true);
for (const [target, effect, value] of card.effects) {
expect(target).toBe('self');
expect(typeof effect === 'string' || typeof effect === 'object').toBe(true);
expect(typeof value).toBe('number');
}
}
});
it('should contain expected status cards by id', () => {
const ids = statusCardDesertData.map(c => c.id);
expect(ids).toContain('wound');
expect(ids).toContain('venom');
expect(ids).toContain('curse');
expect(ids).toContain('static');
});
});