diff --git a/src/samples/slay-the-spire-like/data/desert/cardEffect.csv b/src/samples/slay-the-spire-like/data/desert/cardEffect.csv index b8cad23..a5193d4 100644 --- a/src/samples/slay-the-spire-like/data/desert/cardEffect.csv +++ b/src/samples/slay-the-spire-like/data/desert/cardEffect.csv @@ -1,5 +1,5 @@ # type CardEffectTrigger = 'onPlay' | 'onDraw' | 'onDiscard' -# type CardEffectTarget = 'user' | 'eachTarget' | 'eachEnemy' | 'randomEnemy' | 'player' +# type CardEffectTarget = 'source' | 'eachTarget' | 'eachEnemy' | 'randomEnemy' | 'player' # type CardEffectList = [effect: @effect; stacks: number][] id,card,trigger,target,effects @@ -9,28 +9,28 @@ greataxe,greataxe,onPlay,eachTarget,[attack;5] spear,spear,onPlay,eachTarget,[attack;2];[attack;2];[attack;2] dagger,dagger,onPlay,eachTarget,[attack;3];[attack;3] dart,dart,onPlay,eachTarget,[attack;1] -dart-draw,dart,onPlay,user,[draw;1] +dart-draw,dart,onPlay,source,[draw;1] crossbow,crossbow,onPlay,eachTarget,[attack;6] -crossbow-combo,crossbow,onPlay,user,[crossbow;0] -shield,shield,onPlay,user,[defend;3] -hat,hat,onPlay,user,[defend;8] -cape,cape,onPlay,user,[defend;2];[defendNext;2] -bracer,bracer,onPlay,user,[defend;1];[draw;1] -greatshield,greatshield,onPlay,user,[defend;5] -chainmail,chainmail,onPlay,user,[damageReduce;3] -bandage,bandage,onPlay,user,[removeWound;1] -poisonPotion,poisonPotion,onPlay,user,[attackBuff;2] -fortifyPotion,fortifyPotion,onPlay,user,[defendBuff;2] -vitalityPotion,vitalityPotion,onPlay,user,[gainEnergy;1] -focusPotion,focusPotion,onPlay,user,[draw;2] -healingPotion,healingPotion,onPlay,user,[removeWound;3] -waterBag,waterBag,onPlay,user,[energyNext;1];[drawNext;2] -rope,rope,onPlay,user,[defendBuffUntilPlay;2] -belt,belt,onPlay,user,[drawChoice;1] -torch,torch,onPlay,user,[burnForEnergy;1] -whetstone,whetstone,onPlay,user,[attackBuffUntilPlay;3] -blacksmithHammer,blacksmithHammer,onPlay,user,[transformRandom;1] -venom,venom,onDiscard,user,[attack;3] -curse,curse,onDraw,user,[curse;1] -static,static,onDraw,user,[static;1] -vultureEye,vultureEye,onDraw,user,[expose;3] +crossbow-combo,crossbow,onPlay,source,[crossbow;0] +shield,shield,onPlay,source,[defend;3] +hat,hat,onPlay,source,[defend;8] +cape,cape,onPlay,source,[defend;2];[defendNext;2] +bracer,bracer,onPlay,source,[defend;1];[draw;1] +greatshield,greatshield,onPlay,source,[defend;5] +chainmail,chainmail,onPlay,source,[damageReduce;3] +bandage,bandage,onPlay,source,[removeWound;1] +poisonPotion,poisonPotion,onPlay,source,[attackBuff;2] +fortifyPotion,fortifyPotion,onPlay,source,[defendBuff;2] +vitalityPotion,vitalityPotion,onPlay,source,[gainEnergy;1] +focusPotion,focusPotion,onPlay,source,[draw;2] +healingPotion,healingPotion,onPlay,source,[removeWound;3] +waterBag,waterBag,onPlay,source,[energyNext;1];[drawNext;2] +rope,rope,onPlay,source,[defendBuffUntilPlay;2] +belt,belt,onPlay,source,[drawChoice;1] +torch,torch,onPlay,source,[burnForEnergy;1] +whetstone,whetstone,onPlay,source,[attackBuffUntilPlay;3] +blacksmithHammer,blacksmithHammer,onPlay,source,[transformRandom;1] +venom,venom,onDiscard,source,[attack;3] +curse,curse,onDraw,source,[curse;1] +static,static,onDraw,source,[static;1] +vultureEye,vultureEye,onDraw,source,[expose;3] diff --git a/src/samples/slay-the-spire-like/data/desert/cardEffect.csv.d.ts b/src/samples/slay-the-spire-like/data/desert/cardEffect.csv.d.ts index 72f7e92..19a7794 100644 --- a/src/samples/slay-the-spire-like/data/desert/cardEffect.csv.d.ts +++ b/src/samples/slay-the-spire-like/data/desert/cardEffect.csv.d.ts @@ -2,7 +2,7 @@ import type { Card } from './card.csv'; import type { Effect } from './effect.csv'; export type CardEffectTrigger = 'onPlay' | 'onDraw' | 'onDiscard'; -export type CardEffectTarget = 'user' | 'eachTarget' | 'eachEnemy' | 'randomEnemy' | 'player'; +export type CardEffectTarget = 'source' | 'eachTarget' | 'eachEnemy' | 'randomEnemy' | 'player'; export type CardEffectList = [effect: Effect, stacks: number][]; type CardEffectTable = readonly { diff --git a/src/samples/slay-the-spire-like/data/desert/intent.csv b/src/samples/slay-the-spire-like/data/desert/intent.csv index 422ac3c..f3bd4ec 100644 --- a/src/samples/slay-the-spire-like/data/desert/intent.csv +++ b/src/samples/slay-the-spire-like/data/desert/intent.csv @@ -6,50 +6,50 @@ # initBuffs: initial buffs for this intent (applied when intent becomes active) # effects: effects executed when this intent is active -# type IntentEffectTarget = 'user' | 'eachEnemy' | 'randomEnemy' | 'player' +# type IntentEffectTarget = 'source' | 'eachEnemy' | 'randomEnemy' | 'player' # type IntentEffect = [IntentEffectTarget;@effect;number] # type IntentEffectList = IntentEffect[] id,enemy,initialIntent,nextIntents,brokenIntent,effects string,@enemy,boolean,@intent[],@intent[],IntentEffectList -仙人掌怪-boost,仙人掌怪,true,仙人掌怪-boost;仙人掌怪-defend,,[user;spike;1];[user;defend;4] -仙人掌怪-defend,仙人掌怪,false,仙人掌怪-attack,,[user;defend;8] +仙人掌怪-boost,仙人掌怪,true,仙人掌怪-boost;仙人掌怪-defend,,[source;spike;1];[source;defend;4] +仙人掌怪-defend,仙人掌怪,false,仙人掌怪-attack,,[source;defend;8] 仙人掌怪-attack,仙人掌怪,false,仙人掌怪-boost,,[player;attack;5] 蛇-poison,蛇,true,蛇-attack;蛇-attack,,[player;venom;1];[player;attack;4] 蛇-attack,蛇,false,蛇-poison;蛇-boost,,[player;attack;6] -蛇-boost,蛇,false,蛇-poison;蛇-attack,,[user;defend;3];[player;venom;1] +蛇-boost,蛇,false,蛇-poison;蛇-attack,,[source;defend;3];[player;venom;1] 木乃伊-attack,木乃伊,true,木乃伊-defend;木乃伊-curse,,[player;attack;6] -木乃伊-defend,木乃伊,false,木乃伊-attack,,[user;defend;6] +木乃伊-defend,木乃伊,false,木乃伊-attack,,[source;defend;6] 木乃伊-curse,木乃伊,false,木乃伊-defend;木乃伊-attack,木乃伊-attack,[player;curse;1] -枪手-aim,枪手,true,枪手-attack,,[user;aim;2] +枪手-aim,枪手,true,枪手-attack,,[source;aim;2] 枪手-attack,枪手,false,枪手-aim;枪手-defend,枪手-aim,[player;attack;8] -枪手-defend,枪手,false,枪手-aim,枪手-aim,[user;defend;5] -风卷草-boost,风卷草,true,风卷草-defend;风卷草-defend;风卷草-boost,,[user;roll;5];[user;defend;4] -风卷草-defend,风卷草,false,风卷草-boost;风卷草-attack,,[user;defend;8] +枪手-defend,枪手,false,枪手-aim,枪手-aim,[source;defend;5] +风卷草-boost,风卷草,true,风卷草-defend;风卷草-defend;风卷草-boost,,[source;roll;5];[source;defend;4] +风卷草-defend,风卷草,false,风卷草-boost;风卷草-attack,,[source;defend;8] 风卷草-attack,风卷草,false,风卷草-boost,,[player;rollDamage;0] 秃鹫-attack,秃鹫,true,秃鹫-defend;秃鹫-defend,,[player;attack;6];[player;vultureEye;1] -秃鹫-defend,秃鹫,false,秃鹫-attack;秃鹫-attack,,[user;defend;5] -沙蝎-boost,沙蝎,true,沙蝎-attack;沙蝎-attack,,[user;tailSting;2] +秃鹫-defend,秃鹫,false,秃鹫-attack;秃鹫-attack,,[source;defend;5] +沙蝎-boost,沙蝎,true,沙蝎-attack;沙蝎-attack,,[source;tailSting;2] 沙蝎-attack,沙蝎,false,沙蝎-boost;沙蝎-attack,,[player;attack;6] -幼沙虫-defend,幼沙虫,true,幼沙虫-defend;幼沙虫-boost,,[user;defend;6] -幼沙虫-boost,幼沙虫,false,幼沙虫-attack;幼沙虫-defend,,[user;energyDrain;1];[user;defend;4] +幼沙虫-defend,幼沙虫,true,幼沙虫-defend;幼沙虫-boost,,[source;defend;6] +幼沙虫-boost,幼沙虫,false,幼沙虫-attack;幼沙虫-defend,,[source;energyDrain;1];[source;defend;4] 幼沙虫-attack,幼沙虫,false,幼沙虫-defend;幼沙虫-defend,,[player;attack;5] 蜥蜴-attack,蜥蜴,true,蜥蜴-defend;蜥蜴-molt,,[player;attack;5] -蜥蜴-defend,蜥蜴,false,蜥蜴-attack;蜥蜴-attack,,[user;defend;6] -蜥蜴-molt,蜥蜴,false,蜥蜴-defend;蜥蜴-attack,,[user;molt;3] +蜥蜴-defend,蜥蜴,false,蜥蜴-attack;蜥蜴-attack,,[source;defend;6] +蜥蜴-molt,蜥蜴,false,蜥蜴-defend;蜥蜴-attack,,[source;molt;3] 沙匪-attack,沙匪,true,沙匪-attack;沙匪-heavyAttack,,[player;attack;6] 沙匪-heavyAttack,沙匪,false,沙匪-attack;沙匪-attack;沙匪-debuff,,[player;attack;10] 沙匪-debuff,沙匪,false,沙匪-attack;沙匪-attack,,[player;discard;1] -风暴之灵-storm,风暴之灵,true,风暴之灵-attack;风暴之灵-storm,,[user;storm;2];[user;defend;3] +风暴之灵-storm,风暴之灵,true,风暴之灵-attack;风暴之灵-storm,,[source;storm;2];[source;defend;3] 风暴之灵-attack,风暴之灵,false,风暴之灵-storm;风暴之灵-defend,,[player;attack;8];[player;static;1] -风暴之灵-defend,风暴之灵,false,风暴之灵-storm;风暴之灵-attack,,[user;defend;8] -骑马枪手-charge,骑马枪手,true,骑马枪手-attack,,[user;charge;2] +风暴之灵-defend,风暴之灵,false,风暴之灵-storm;风暴之灵-attack,,[source;defend;8] +骑马枪手-charge,骑马枪手,true,骑马枪手-attack,,[source;charge;2] 骑马枪手-attack,骑马枪手,false,骑马枪手-charge;骑马枪手-defend,骑马枪手-charge,[player;attack;6] -骑马枪手-defend,骑马枪手,false,骑马枪手-charge;骑马枪手-attack,骑马枪手-charge,[user;defend;5] -沙虫王-summon,沙虫王,true,沙虫王-attack;沙虫王-defend,,[user;summonSandwormLarva;18] +骑马枪手-defend,骑马枪手,false,骑马枪手-charge;骑马枪手-attack,骑马枪手-charge,[source;defend;5] +沙虫王-summon,沙虫王,true,沙虫王-attack;沙虫王-defend,,[source;summonSandwormLarva;18] 沙虫王-attack,沙虫王,false,沙虫王-summon;沙虫王-defend,,[player;attack;9] -沙虫王-defend,沙虫王,false,沙虫王-attack;沙虫王-summon,,[user;defend;6] -沙漠守卫-summon,沙漠守卫,true,沙漠守卫-attack;沙漠守卫-defend,,[user;summonMummy;14] +沙虫王-defend,沙虫王,false,沙虫王-attack;沙虫王-summon,,[source;defend;6] +沙漠守卫-summon,沙漠守卫,true,沙漠守卫-attack;沙漠守卫-defend,,[source;summonMummy;14] 沙漠守卫-attack,沙漠守卫,false,沙漠守卫-defend;沙漠守卫-summon,,[player;attack;8] -沙漠守卫-defend,沙漠守卫,false,沙漠守卫-attack;沙漠守卫-revive,,[user;defend;8] -沙漠守卫-revive,沙漠守卫,false,沙漠守卫-attack;沙漠守卫-summon,,[user;reviveMummy;1] +沙漠守卫-defend,沙漠守卫,false,沙漠守卫-attack;沙漠守卫-revive,,[source;defend;8] +沙漠守卫-revive,沙漠守卫,false,沙漠守卫-attack;沙漠守卫-summon,,[source;reviveMummy;1] diff --git a/src/samples/slay-the-spire-like/data/desert/intent.csv.d.ts b/src/samples/slay-the-spire-like/data/desert/intent.csv.d.ts index 52143e0..a0b4c77 100644 --- a/src/samples/slay-the-spire-like/data/desert/intent.csv.d.ts +++ b/src/samples/slay-the-spire-like/data/desert/intent.csv.d.ts @@ -1,7 +1,7 @@ import type { Enemy } from './enemy.csv'; import type { Effect } from './effect.csv'; -export type IntentEffectTarget = 'user' | 'eachEnemy' | 'randomEnemy' | 'player'; +export type IntentEffectTarget = 'source' | 'eachEnemy' | 'randomEnemy' | 'player'; export type IntentEffect = [IntentEffectTarget, Effect, number]; export type IntentEffectList = IntentEffect[]; diff --git a/src/samples/slay-the-spire-like/system/combat/effects.ts b/src/samples/slay-the-spire-like/system/combat/effects.ts index dc98a8d..574cc60 100644 --- a/src/samples/slay-the-spire-like/system/combat/effects.ts +++ b/src/samples/slay-the-spire-like/system/combat/effects.ts @@ -112,7 +112,7 @@ export function* getEffectTargets( for (const enemy of getAliveEnemies(game.value)) { yield enemy; } - } else if (target === "user") { + } else if (target === "source") { const entity = getCombatEntity(game.value, sourceEntityKey); if (entity) yield entity; } else if (target === "player") { diff --git a/tests/utils/command.test.ts b/tests/utils/command.test.ts index 9037e2d..3ef1ea2 100644 --- a/tests/utils/command.test.ts +++ b/tests/utils/command.test.ts @@ -1,174 +1,176 @@ -import { describe, it, expect } from 'vitest'; -import { parseCommand, type Command } from '@/utils/command'; +import { describe, it, expect } from "vitest"; +import { parseCommand, type Command } from "@/utils/command"; -describe('parseCommand', () => { - it('should parse empty string', () => { - const result = parseCommand(''); - expect(result).toEqual({ - name: '', - flags: {}, - options: {}, - params: [] - }); +describe("parseCommand", () => { + it("should parse empty string", () => { + const result = parseCommand(""); + expect(result).toEqual({ + name: "", + flags: {}, + options: {}, + params: [], }); + }); - it('should parse command name only', () => { - const result = parseCommand('move'); - expect(result).toEqual({ - name: 'move', - flags: {}, - options: {}, - params: [] - }); + it("should parse command name only", () => { + const result = parseCommand("move"); + expect(result).toEqual({ + name: "move", + flags: {}, + options: {}, + params: [], }); + }); - it('should parse command with params', () => { - const result = parseCommand('move meeple1 region1'); - expect(result).toEqual({ - name: 'move', - flags: {}, - options: {}, - params: ['meeple1', 'region1'] - }); + it("should parse command with params", () => { + const result = parseCommand("move meeple1 region1"); + expect(result).toEqual({ + name: "move", + flags: {}, + options: {}, + params: ["meeple1", "region1"], }); + }); - it('should parse command with long flags', () => { - const result = parseCommand('move meeple1 --force --quiet'); - expect(result).toEqual({ - name: 'move', - flags: { force: true, quiet: true }, - options: {}, - params: ['meeple1'] - }); + it("should parse command with long flags", () => { + const result = parseCommand("move meeple1 --force --quiet"); + expect(result).toEqual({ + name: "move", + flags: { force: true, quiet: true }, + options: {}, + params: ["meeple1"], }); + }); - it('should parse command with short flags', () => { - const result = parseCommand('move meeple1 -f -q'); - expect(result).toEqual({ - name: 'move', - flags: { f: true, q: true }, - options: {}, - params: ['meeple1'] - }); + it("should parse command with short flags", () => { + const result = parseCommand("move meeple1 -f -q"); + expect(result).toEqual({ + name: "move", + flags: { f: true, q: true }, + options: {}, + params: ["meeple1"], }); + }); - it('should parse command with long options', () => { - const result = parseCommand('move meeple1 --x 10 --y 20'); - expect(result).toEqual({ - name: 'move', - flags: {}, - options: { x: '10', y: '20' }, - params: ['meeple1'] - }); + it("should parse command with long options", () => { + const result = parseCommand("move meeple1 --x 10 --y 20"); + expect(result).toEqual({ + name: "move", + flags: {}, + options: { x: "10", y: "20" }, + params: ["meeple1"], }); + }); - it('should parse command with short options', () => { - const result = parseCommand('move meeple1 -x 10 -y 20'); - expect(result).toEqual({ - name: 'move', - flags: {}, - options: { x: '10', y: '20' }, - params: ['meeple1'] - }); + it("should parse command with short options", () => { + const result = parseCommand("move meeple1 -x 10 -y 20"); + expect(result).toEqual({ + name: "move", + flags: {}, + options: { x: "10", y: "20" }, + params: ["meeple1"], }); + }); - it('should parse command with mixed flags和选项', () => { - const result = parseCommand('move meeple1 region1 --force -x 10 -q'); - expect(result).toEqual({ - name: 'move', - flags: { force: true, q: true }, - options: { x: '10' }, - params: ['meeple1', 'region1'] - }); + it("should parse command with mixed flags和选项", () => { + const result = parseCommand("move meeple1 region1 --force -x 10 -q"); + expect(result).toEqual({ + name: "move", + flags: { force: true, q: true }, + options: { x: "10" }, + params: ["meeple1", "region1"], }); + }); - it('should handle extra whitespace', () => { - const result = parseCommand(' move meeple1 --force '); - expect(result).toEqual({ - name: 'move', - flags: { force: true }, - options: {}, - params: ['meeple1'] - }); + it("should handle extra whitespace", () => { + const result = parseCommand(" move meeple1 --force "); + expect(result).toEqual({ + name: "move", + flags: { force: true }, + options: {}, + params: ["meeple1"], }); + }); - it('should parse complex command', () => { - const result = parseCommand('place meeple1 board --x 5 --y 3 --rotate 90 --force'); - expect(result).toEqual({ - name: 'place', - flags: { force: true }, - options: { x: '5', y: '3', rotate: '90' }, - params: ['meeple1', 'board'] - }); + it("should parse complex command", () => { + const result = parseCommand( + "place meeple1 board --x 5 --y 3 --rotate 90 --force", + ); + expect(result).toEqual({ + name: "place", + flags: { force: true }, + options: { x: "5", y: "3", rotate: "90" }, + params: ["meeple1", "board"], }); + }); - it('should treat negative number as option value', () => { - const result = parseCommand('set --value -10'); - expect(result).toEqual({ - name: 'set', - flags: {}, - options: { value: '-10' }, - params: [] - }); + it("should treat negative number as option value", () => { + const result = parseCommand("set --value -10"); + expect(result).toEqual({ + name: "set", + flags: {}, + options: { value: "-10" }, + params: [], }); + }); - it('should parse quoted string with double quotes', () => { - const result = parseCommand('place tile "large castle" --x 5'); - expect(result).toEqual({ - name: 'place', - flags: {}, - options: { x: '5' }, - params: ['tile', 'large castle'] - }); + it("should parse quoted string with double quotes", () => { + const result = parseCommand('place tile "large castle" --x 5'); + expect(result).toEqual({ + name: "place", + flags: {}, + options: { x: "5" }, + params: ["tile", "large castle"], }); + }); - it('should parse quoted string with single quotes', () => { - const result = parseCommand("place tile 'large castle' --x 5"); - expect(result).toEqual({ - name: 'place', - flags: {}, - options: { x: '5' }, - params: ['tile', 'large castle'] - }); + it("should parse quoted string with single quotes", () => { + const result = parseCommand("place tile 'large castle' --x 5"); + expect(result).toEqual({ + name: "place", + flags: {}, + options: { x: "5" }, + params: ["tile", "large castle"], }); + }); - it('should handle escaped quotes', () => { - const result = parseCommand('say "hello \\"world\\""'); - expect(result).toEqual({ - name: 'say', - flags: {}, - options: {}, - params: ['hello "world"'] - }); + it("should handle escaped quotes", () => { + const result = parseCommand('say "hello \\"world\\""'); + expect(result).toEqual({ + name: "say", + flags: {}, + options: {}, + params: ['hello "world"'], }); + }); - it('should handle escaped backslash', () => { - const result = parseCommand('set path "C:\\\\Users"'); - expect(result).toEqual({ - name: 'set', - flags: {}, - options: {}, - params: ['path', 'C:\\Users'] - }); + it("should handle escaped backslash", () => { + const result = parseCommand('set path "C:\\\\Users"'); + expect(result).toEqual({ + name: "set", + flags: {}, + options: {}, + params: ["path", "C:\\Users"], }); + }); - it('should handle mixed quotes', () => { - const result = parseCommand('cmd "hello world" \'foo bar\' --flag'); - expect(result).toEqual({ - name: 'cmd', - flags: { flag: true }, - options: {}, - params: ['hello world', 'foo bar'] - }); + it("should handle mixed quotes", () => { + const result = parseCommand("cmd \"hello world\" 'foo bar' --flag"); + expect(result).toEqual({ + name: "cmd", + flags: { flag: true }, + options: {}, + params: ["hello world", "foo bar"], }); + }); - it('should handle quote in middle of argument', () => { - const result = parseCommand('cmd "hello\'s world"'); - expect(result).toEqual({ - name: 'cmd', - flags: {}, - options: {}, - params: ["hello's world"] - }); + it("should handle quote in middle of argument", () => { + const result = parseCommand('cmd "hello\'s world"'); + expect(result).toEqual({ + name: "cmd", + flags: {}, + options: {}, + params: ["hello's world"], }); + }); });