Compare commits
4 Commits
509e121275
...
6984e54bdf
| Author | SHA1 | Date |
|---|---|---|
|
|
6984e54bdf | |
|
|
7b954bb5a5 | |
|
|
7472095822 | |
|
|
e5da41c1cb |
|
|
@ -6,9 +6,11 @@
|
||||||
# card: 不施加buff,对玩家时在玩家弃牌堆创建同名卡牌,对敌人无效(敌人没有牌堆)
|
# card: 不施加buff,对玩家时在玩家弃牌堆创建同名卡牌,对敌人无效(敌人没有牌堆)
|
||||||
# cardDraw: 不施加buff,在抓牌堆洗入同名卡牌
|
# cardDraw: 不施加buff,在抓牌堆洗入同名卡牌
|
||||||
# cardHand:不施加buff,在玩家手牌中创建同名卡牌
|
# cardHand:不施加buff,在玩家手牌中创建同名卡牌
|
||||||
|
# item: 施加buff到周围物品,永久生效
|
||||||
|
# itemUntilPlayed: 施加buff到周围物品,物品被打出后失效
|
||||||
|
|
||||||
id, name, description, timing
|
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
|
attack, 攻击, 对对手造成伤害, instant
|
||||||
defend, 防御, 抵消下次行动前受到的伤害, posture
|
defend, 防御, 抵消下次行动前受到的伤害, posture
|
||||||
spike, 尖刺, 对攻击者造成X点伤害, lingering
|
spike, 尖刺, 对攻击者造成X点伤害, lingering
|
||||||
|
|
@ -28,3 +30,18 @@ charge, 冲锋, 受到或造成的伤害翻倍并消耗等量冲锋, lingering
|
||||||
summonMummy, 召唤木乃伊, 召唤1个木乃伊, instant
|
summonMummy, 召唤木乃伊, 召唤1个木乃伊, instant
|
||||||
summonSandwormLarva, 召唤幼沙虫, 召唤1个幼沙虫, instant
|
summonSandwormLarva, 召唤幼沙虫, 召唤1个幼沙虫, instant
|
||||||
reviveMummy, 复活木乃伊, 复活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.
|
|
|
@ -2,7 +2,7 @@ type EffectDesertTable = readonly {
|
||||||
readonly id: string;
|
readonly id: string;
|
||||||
readonly name: string;
|
readonly name: string;
|
||||||
readonly description: 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];
|
export type EffectDesert = EffectDesertTable[number];
|
||||||
|
|
|
||||||
|
|
@ -7,46 +7,46 @@
|
||||||
# brokenIntent: 防御被打空后改变的意图id,多个意图则从中随机
|
# brokenIntent: 防御被打空后改变的意图id,多个意图则从中随机
|
||||||
# effects:技能效果,目标+buff/debuff/攻击/防御+数值/层数
|
# effects:技能效果,目标+buff/debuff/攻击/防御+数值/层数
|
||||||
enemy,id,nextIntents,brokenIntent,effects
|
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]
|
仙人掌怪,boost,boost;defend;defend,,[self;spike;1];[self;defend;4]
|
||||||
仙人掌怪,defend,attack,,[self;defend;8]
|
仙人掌怪,defend,attack,,[self;defend;8]
|
||||||
仙人掌怪,attack,boost,,[opponent;attack;5]
|
仙人掌怪,attack,boost,,[player;attack;5]
|
||||||
蛇,poison,attack;attack,,[opponent;venom;1];[opponent;attack;4]
|
蛇,poison,attack;attack,,[player;venom;1];[player;attack;4]
|
||||||
蛇,attack,poison;boost,,[opponent;attack;6]
|
蛇,attack,poison;boost,,[player;attack;6]
|
||||||
蛇,boost,poison;attack,,[self;defend;3];[opponent;venom;1]
|
蛇,boost,poison;attack,,[self;defend;3];[player;venom;1]
|
||||||
木乃伊,attack,defend;curse,,[opponent;attack;6]
|
木乃伊,attack,defend;curse,,[player;attack;6]
|
||||||
木乃伊,defend,attack,,[self;defend;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]
|
枪手,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]
|
枪手,defend,aim,aim,[self;defend;5]
|
||||||
风卷草,boost,defend;defend;boost,,[self;roll;5];[self;defend;4]
|
风卷草,boost,defend;defend;boost,,[self;roll;5];[self;defend;4]
|
||||||
风卷草,defend,boost;attack,,[self;defend;8]
|
风卷草,defend,boost;attack,,[self;defend;8]
|
||||||
风卷草,attack,boost,,[opponent;rollDamage;0]
|
风卷草,attack,boost,,[player;rollDamage;0]
|
||||||
秃鹫,attack,defend;defend,,[opponent;attack;6];[opponent;vultureEye;1]
|
秃鹫,attack,defend;defend,,[player;attack;6];[player;vultureEye;1]
|
||||||
秃鹫,defend,attack;attack,,[self;defend;5]
|
秃鹫,defend,attack;attack,,[self;defend;5]
|
||||||
沙蝎,boost,attack;attack,,[self;tailSting;2]
|
沙蝎,boost,attack;attack,,[self;tailSting;2]
|
||||||
沙蝎,attack,boost;attack,,[opponent;attack;6]
|
沙蝎,attack,boost;attack,,[player;attack;6]
|
||||||
幼沙虫,defend,defend;boost,,[self;defend;6]
|
幼沙虫,defend,defend;boost,,[self;defend;6]
|
||||||
幼沙虫,boost,attack;defend,,[self;energyDrain;1];[self;defend;4]
|
幼沙虫,boost,attack;defend,,[self;energyDrain;1];[self;defend;4]
|
||||||
幼沙虫,attack,defend;defend,,[opponent;attack;5]
|
幼沙虫,attack,defend;defend,,[player;attack;5]
|
||||||
蜥蜴,attack,defend;molt,,[opponent;attack;5]
|
蜥蜴,attack,defend;molt,,[player;attack;5]
|
||||||
蜥蜴,defend,attack;attack,,[self;defend;6]
|
蜥蜴,defend,attack;attack,,[self;defend;6]
|
||||||
蜥蜴,molt,defend;attack,,[self;molt;3]
|
蜥蜴,molt,defend;attack,,[self;molt;3]
|
||||||
沙匪,attack,attack;heavyAttack,,[opponent;attack;6]
|
沙匪,attack,attack;heavyAttack,,[player;attack;6]
|
||||||
沙匪,heavyAttack,attack;attack;debuff,,[opponent;attack;10]
|
沙匪,heavyAttack,attack;attack;debuff,,[player;attack;10]
|
||||||
沙匪,debuff,attack;attack,,[opponent;discard;1]
|
沙匪,debuff,attack;attack,,[player;discard;1]
|
||||||
风暴之灵,storm,attack;storm,,[self;storm;2];[self;defend;3]
|
风暴之灵,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]
|
风暴之灵,defend,storm;attack,,[self;defend;8]
|
||||||
骑马枪手,charge,attack,,[self;charge;2]
|
骑马枪手,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]
|
骑马枪手,defend,charge;attack,charge,[self;defend;5]
|
||||||
沙虫王,summon,attack;defend,,[self;summonSandwormLarva;1]
|
沙虫王,summon,attack;defend,,[self;summonSandwormLarva;1]
|
||||||
沙虫王,attack,summon;defend,,[opponent;attack;9]
|
沙虫王,attack,summon;defend,,[player;attack;9]
|
||||||
沙虫王,defend,attack;summon,,[self;defend;6]
|
沙虫王,defend,attack;summon,,[self;defend;6]
|
||||||
沙漠守卫,summon,attack;defend,,[self;summonMummy;1]
|
沙漠守卫,summon,attack;defend,,[self;summonMummy;1]
|
||||||
沙漠守卫,attack,defend;summon,,[opponent;attack;8]
|
沙漠守卫,attack,defend;summon,,[player;attack;8]
|
||||||
沙漠守卫,defend,attack;revive,,[self;defend;8]
|
沙漠守卫,defend,attack;revive,,[self;defend;8]
|
||||||
沙漠守卫,revive,attack;summon,,[self;reviveMummy;1]
|
沙漠守卫,revive,attack;summon,,[self;reviveMummy;1]
|
||||||
|
|
|
@ -6,7 +6,7 @@ type EnemyIntentDesertTable = readonly {
|
||||||
readonly id: string;
|
readonly id: string;
|
||||||
readonly nextIntents: readonly EnemyIntentDesert[];
|
readonly nextIntents: readonly EnemyIntentDesert[];
|
||||||
readonly brokenIntent: 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];
|
export type EnemyIntentDesert = EnemyIntentDesertTable[number];
|
||||||
|
|
|
||||||
|
|
@ -8,29 +8,29 @@
|
||||||
#
|
#
|
||||||
# targetType can be one of: single, none
|
# targetType can be one of: single, none
|
||||||
|
|
||||||
type,name,shape,costType,costCount,targetType,price,desc
|
type,name,shape,costType,costCount,targetType,price,desc,effects
|
||||||
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][]
|
||||||
weapon,剑,oee,energy,1,single,50,【攻击2】【攻击2】
|
weapon,剑,oee,energy,1,single,50,【攻击2】【攻击2】,[target;attack;2];[target;attack;2]
|
||||||
weapon,长斧,oees,energy,2,none,80,对全体【攻击5】
|
weapon,长斧,oees,energy,2,none,80,对全体【攻击5】,[all;attack;5]
|
||||||
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]
|
||||||
weapon,短刀,oe,energy,1,single,40,【攻击3】【攻击3】
|
weapon,短刀,oe,energy,1,single,40,【攻击3】【攻击3】,[target;attack;3];[target;attack;3]
|
||||||
weapon,飞镖,o,energy,0,single,30,【攻击1】,抓一张牌
|
weapon,飞镖,o,energy,0,single,30,【攻击1】,抓一张牌,[target;attack;1];[self;draw;1]
|
||||||
weapon,十字弩,onrersrw,energy,2,single,120,【攻击6】。对同一目标打出其他十字弩
|
weapon,十字弩,onrersrw,energy,2,single,120,【攻击6】。对同一目标打出其他十字弩,[target;attack;6];[self;crossbow;0]
|
||||||
armor,盾,oesw,energy,1,none,50,【防御3】
|
armor,盾,oesw,energy,1,none,50,【防御3】,[self;defend;3]
|
||||||
armor,斗笠,oerwrn,energy,2,none,90,【防御8】
|
armor,斗笠,oerwrn,energy,2,none,90,【防御8】,[self;defend;8]
|
||||||
armor,披风,oers,energy,1,none,45,【防御2】,下回合【防御2】
|
armor,披风,oers,energy,1,none,45,【防御2】,下回合【防御2】,[self;defend;2];[self;defendNext;2]
|
||||||
armor,护腕,o,energy,0,none,25,【防御1】,抓1张牌
|
armor,护腕,o,energy,0,none,25,【防御1】,抓1张牌,[self;defend;1];[self;draw;1]
|
||||||
armor,大盾,oesswn,energy,1,none,70,【防御5】
|
armor,大盾,oesswn,energy,1,none,70,【防御5】,[self;defend;5]
|
||||||
armor,锁子甲,oers,energy,1,none,60,本回合受到伤害-3
|
armor,锁子甲,oers,energy,1,none,60,本回合受到伤害-3,[self;damageReduce;3]
|
||||||
consumable,绷带,o,uses,3,none,20,从牌堆或弃牌堆随机移除1张伤口
|
consumable,绷带,o,uses,3,none,20,从牌堆或弃牌堆随机移除1张伤口,[self;removeWound;1]
|
||||||
consumable,淬毒药剂,o,uses,3,none,30,周围物品的【攻击】+2
|
consumable,淬毒药剂,o,uses,3,none,30,周围物品的【攻击】+2,[self;attackBuff;2]
|
||||||
consumable,强固药剂,o,uses,3,none,30,周围物品的【防御】+2
|
consumable,强固药剂,o,uses,3,none,30,周围物品的【防御】+2,[self;defendBuff;2]
|
||||||
consumable,活力药剂,o,uses,3,none,25,获得1点能量
|
consumable,活力药剂,o,uses,3,none,25,获得1点能量,[self;gainEnergy;1]
|
||||||
consumable,集中药剂,o,uses,3,none,25,抓2张牌
|
consumable,集中药剂,o,uses,3,none,25,抓2张牌,[self;draw;2]
|
||||||
consumable,治疗药剂,o,uses,3,none,35,从牌堆或弃牌堆移除3张伤口
|
consumable,治疗药剂,o,uses,3,none,35,从牌堆或弃牌堆移除3张伤口,[self;removeWound;3]
|
||||||
tool,水袋,os,energy,1,none,35,下回合开始时,获得1能量,抓2张牌
|
tool,水袋,os,energy,1,none,35,下回合开始时,获得1能量,抓2张牌,[self;energyNext;1];[self;drawNext;2]
|
||||||
tool,绳索,ose,energy,1,none,30,周围物品的牌【防御】+2直到打出
|
tool,绳索,ose,energy,1,none,30,周围物品的牌【防御】+2直到打出,[self;defendBuffUntilPlay;2]
|
||||||
tool,腰带,owre,energy,0,none,40,从牌堆周围物品的牌当中选择一张加入手牌
|
tool,腰带,owre,energy,0,none,40,从牌堆周围物品的牌当中选择一张加入手牌,[self;drawChoice;1]
|
||||||
tool,火把,on,energy,1,none,25,下次打出周围物品的牌时,将其消耗并获得1能量
|
tool,火把,on,energy,1,none,25,下次打出周围物品的牌时,将其消耗并获得1能量,[self;burnForEnergy;1]
|
||||||
tool,磨刀石,o,energy,1,none,30,周围物品的牌【攻击】+3直到打出
|
tool,磨刀石,o,energy,1,none,30,周围物品的牌【攻击】+3直到打出,[self;attackBuffUntilPlay;3]
|
||||||
tool,铁匠锤,oers,energy,1,none,45,从牌堆/弃牌堆选择一张牌,随机变为一张周围物品的牌
|
tool,铁匠锤,oers,energy,1,none,45,从牌堆/弃牌堆选择一张牌,随机变为一张周围物品的牌,[self;transformRandom;1]
|
||||||
|
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import type { EffectDesert } from './effectDesert.csv';
|
||||||
|
|
||||||
type HeroItemFighter1Table = readonly {
|
type HeroItemFighter1Table = readonly {
|
||||||
readonly type: string;
|
readonly type: string;
|
||||||
readonly name: string;
|
readonly name: string;
|
||||||
|
|
@ -7,6 +9,7 @@ type HeroItemFighter1Table = readonly {
|
||||||
readonly targetType: "single" | "none";
|
readonly targetType: "single" | "none";
|
||||||
readonly price: number;
|
readonly price: number;
|
||||||
readonly desc: string;
|
readonly desc: string;
|
||||||
|
readonly effects: readonly ["self" | "target" | "all" | "random", EffectDesert, number];
|
||||||
}[];
|
}[];
|
||||||
|
|
||||||
export type HeroItemFighter1 = HeroItemFighter1Table[number];
|
export type HeroItemFighter1 = HeroItemFighter1Table[number];
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,17 @@ import encounterDesertCsv from './encounterDesert.csv';
|
||||||
import enemyDesertCsv from './enemyDesert.csv';
|
import enemyDesertCsv from './enemyDesert.csv';
|
||||||
import enemyIntentDesertCsv from './enemyIntentDesert.csv';
|
import enemyIntentDesertCsv from './enemyIntentDesert.csv';
|
||||||
import effectDesertCsv from './effectDesert.csv';
|
import effectDesertCsv from './effectDesert.csv';
|
||||||
|
import statusCardDesertCsv from './statusCardDesert.csv';
|
||||||
|
|
||||||
export const heroItemFighter1Data = heroItemFighter1Csv();
|
export const heroItemFighter1Data = heroItemFighter1Csv();
|
||||||
export const encounterDesertData = encounterDesertCsv();
|
export const encounterDesertData = encounterDesertCsv();
|
||||||
export const enemyDesertData = enemyDesertCsv();
|
export const enemyDesertData = enemyDesertCsv();
|
||||||
export const enemyIntentDesertData = enemyIntentDesertCsv();
|
export const enemyIntentDesertData = enemyIntentDesertCsv();
|
||||||
export const effectDesertData = effectDesertCsv();
|
export const effectDesertData = effectDesertCsv();
|
||||||
|
export const statusCardDesertData = statusCardDesertCsv();
|
||||||
|
|
||||||
export { default as encounterDesertCsv, type EncounterDesert } from './encounterDesert.csv';
|
export { default as encounterDesertCsv, type EncounterDesert } from './encounterDesert.csv';
|
||||||
export { default as enemyDesertCsv, type EnemyDesert } from './enemyDesert.csv';
|
export { default as enemyDesertCsv, type EnemyDesert } from './enemyDesert.csv';
|
||||||
export { default as enemyIntentDesertCsv, type EnemyIntentDesert } from './enemyIntentDesert.csv';
|
export { default as enemyIntentDesertCsv, type EnemyIntentDesert } from './enemyIntentDesert.csv';
|
||||||
export { default as effectDesertCsv, type EffectDesert } from './effectDesert.csv';
|
export { default as effectDesertCsv, type EffectDesert } from './effectDesert.csv';
|
||||||
|
export { default as statusCardDesertCsv, type StatusCardDesert } from './statusCardDesert.csv';
|
||||||
|
|
|
||||||
|
|
@ -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:加入手牌。
|
||||||
|
|
@ -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]
|
||||||
|
|
|
@ -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;
|
||||||
|
|
@ -5,6 +5,7 @@ import {
|
||||||
enemyDesertData,
|
enemyDesertData,
|
||||||
enemyIntentDesertData,
|
enemyIntentDesertData,
|
||||||
effectDesertData,
|
effectDesertData,
|
||||||
|
statusCardDesertData,
|
||||||
} from '@/samples/slay-the-spire-like/data';
|
} from '@/samples/slay-the-spire-like/data';
|
||||||
|
|
||||||
describe('heroItemFighter1.csv import', () => {
|
describe('heroItemFighter1.csv import', () => {
|
||||||
|
|
@ -26,6 +27,7 @@ describe('heroItemFighter1.csv import', () => {
|
||||||
expect(item).toHaveProperty('costCount');
|
expect(item).toHaveProperty('costCount');
|
||||||
expect(item).toHaveProperty('targetType');
|
expect(item).toHaveProperty('targetType');
|
||||||
expect(item).toHaveProperty('desc');
|
expect(item).toHaveProperty('desc');
|
||||||
|
expect(item).toHaveProperty('effects');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -75,6 +77,17 @@ describe('heroItemFighter1.csv import', () => {
|
||||||
expect(typeCounts['consumable']).toBe(6);
|
expect(typeCounts['consumable']).toBe(6);
|
||||||
expect(typeCounts['tool']).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', () => {
|
describe('encounterDesert.csv import', () => {
|
||||||
|
|
@ -135,7 +148,7 @@ describe('effectDesert.csv import', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have expected number of effects', () => {
|
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', () => {
|
it('should have correct fields for each effect', () => {
|
||||||
|
|
@ -148,7 +161,7 @@ describe('effectDesert.csv import', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have valid timing values', () => {
|
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) {
|
for (const effect of effectDesertData) {
|
||||||
expect(validTimings).toContain(effect.timing);
|
expect(validTimings).toContain(effect.timing);
|
||||||
}
|
}
|
||||||
|
|
@ -160,6 +173,9 @@ describe('effectDesert.csv import', () => {
|
||||||
expect(ids).toContain('defend');
|
expect(ids).toContain('defend');
|
||||||
expect(ids).toContain('spike');
|
expect(ids).toContain('spike');
|
||||||
expect(ids).toContain('venom');
|
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', () => {
|
it('should have effects with target, effect ref, and value', () => {
|
||||||
for (const intent of enemyIntentDesertData) {
|
for (const intent of enemyIntentDesertData) {
|
||||||
for (const [target, effect, value] of intent.effects) {
|
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 effect === 'string' || typeof effect === 'object').toBe(true);
|
||||||
expect(typeof value).toBe('number');
|
expect(typeof value).toBe('number');
|
||||||
}
|
}
|
||||||
|
|
@ -243,3 +259,53 @@ describe('enemyIntentDesert.csv import', () => {
|
||||||
expect(enemyIds.size).toBe(14);
|
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');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue