koishi-plugin-smmcat-gensokyo 0.0.20 → 0.0.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/battle.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import { Context, Session } from "koishi";
2
2
  import { Config } from ".";
3
3
  import { UserBaseAttribute } from "./users";
4
+ import { UserOccupation } from "./data/skillFn";
5
+ import { MonsterOccupation } from "./data/initMonster";
4
6
  declare module 'koishi' {
5
7
  interface Tables {
6
8
  smm_gensokyo_battle_history: BattleHistory;
@@ -32,6 +34,8 @@ export type BattleAttribute = {
32
34
  userId?: string;
33
35
  /** 类型 */
34
36
  type: '玩家' | '怪物';
37
+ /** 自有类型 */
38
+ selfType: UserOccupation | MonsterOccupation;
35
39
  /** 血量 */
36
40
  hp: number;
37
41
  /** 最大血量 */
@@ -57,33 +61,47 @@ export type BattleAttribute = {
57
61
  /** 出手速度 */
58
62
  speed: number;
59
63
  /** 临时增益状态 */
60
- gain: {
61
- /** 临时增益-最大血量 */
62
- maxHp: number;
63
- /** 临时增益-最大蓝量 */
64
- maxMp: number;
65
- /** 临时增益-攻击力 */
66
- atk: number;
67
- /** 临时增益-防御力 */
68
- def: number;
69
- /** 临时增益-暴击率 */
70
- chr: number;
71
- /** 临时增益-暴击伤害 */
72
- ghd: number;
73
- /** 临时增益-闪避值 */
74
- evasion: number;
75
- /** 临时增益-命中值 */
76
- hit: number;
77
- /** 临时增益-出手速度 */
78
- speed: number;
79
- };
64
+ gain: BuffGain;
80
65
  /** 滞留状态 */
81
66
  buff: {
67
+ [keys: string]: {
68
+ name: string;
69
+ timer: number;
70
+ };
71
+ };
72
+ /** 持有技能 */
73
+ fn?: {
82
74
  name: string;
83
- time: number;
75
+ prob: number;
84
76
  }[];
85
- /** 持有技能 */
86
- fn?: [];
77
+ /** 拓展数据 */
78
+ expand: {
79
+ [keys: string]: any;
80
+ };
81
+ };
82
+ export type BuffGain = {
83
+ /** 临时增益-最大血量 */
84
+ maxHp?: number;
85
+ /** 临时增益-最大蓝量 */
86
+ maxMp?: number;
87
+ /** 临时增益-攻击力 */
88
+ atk?: number;
89
+ /** 临时增益-防御力 */
90
+ def?: number;
91
+ /** 临时增益-暴击率 */
92
+ chr?: number;
93
+ /** 临时增益-暴击伤害 */
94
+ ghd?: number;
95
+ /** 临时增益-闪避值 */
96
+ evasion?: number;
97
+ /** 临时增益-命中值 */
98
+ hit?: number;
99
+ /** 临时增益-出手速度 */
100
+ speed?: number;
101
+ /** 是否眩晕 */
102
+ dizziness?: boolean;
103
+ /** 是否混乱 */
104
+ chaos?: boolean;
87
105
  };
88
106
  /** 最后战斗状态 */
89
107
  type LastPlay = {
@@ -149,4 +167,8 @@ export declare const BattleData: {
149
167
  };
150
168
  /** 获取阵容角色名 */
151
169
  export declare function getLineupName(agent: BattleAttribute): string;
170
+ export declare function getSkillFn(fnList: {
171
+ name: string;
172
+ prob: number;
173
+ }[]): string;
152
174
  export {};
package/lib/damage.d.ts CHANGED
@@ -46,10 +46,17 @@ declare class Damage {
46
46
  beforDef(fn: (config: DamageConfig) => void): this;
47
47
  result(fn?: DamageCallback): DamageConfig;
48
48
  }
49
+ declare class BuffDamage {
50
+ goal: BattleAttribute;
51
+ val: number;
52
+ isRealHarm: boolean;
53
+ constructor(val: number, goal: BattleAttribute, isRealHarm?: boolean);
54
+ giveDamage(): number;
55
+ }
49
56
  /** 给予目标伤害 */
50
57
  declare function giveDamage(self: BattleAttribute, goal: BattleAttribute, damage: DamageConfig): number;
51
58
  /** 治疗目标 */
52
59
  declare function giveCure(goal: BattleAttribute, val: number): number;
53
60
  /** 伤害额外信息 */
54
61
  export declare function moreDamageInfo(damage: DamageConfig): string;
55
- export { Damage, giveDamage, giveCure };
62
+ export { Damage, BuffDamage, giveDamage, giveCure };
@@ -0,0 +1,59 @@
1
+ import { BattleAttribute, BuffGain } from "../battle";
2
+ export declare enum BuffType {
3
+ 增益 = "\u589E\u76CA",
4
+ 减益 = "\u51CF\u76CA",
5
+ 印记 = "\u5370\u8BB0",
6
+ 控制 = "\u63A7\u5236",
7
+ 伤害 = "\u4F24\u5BB3",
8
+ 治疗 = "\u6CBB\u7597"
9
+ }
10
+ interface BuffParams {
11
+ type: BuffType.增益;
12
+ up: BuffGain;
13
+ }
14
+ interface DeBuffParams {
15
+ type: BuffType.减益;
16
+ down: BuffGain;
17
+ }
18
+ interface ImprintBuffParams {
19
+ type: BuffType.印记;
20
+ key: string;
21
+ data: any;
22
+ }
23
+ interface ControlBuffParams {
24
+ type: BuffType.控制;
25
+ name: '晕眩' | '控制';
26
+ }
27
+ interface TreatmentBuffParams {
28
+ type: BuffType.治疗;
29
+ val: number;
30
+ }
31
+ interface HarmBuffParams {
32
+ type: BuffType.伤害;
33
+ val: number;
34
+ isRealHarm?: boolean;
35
+ }
36
+ type BuffItemParams = BuffParams | DeBuffParams | ImprintBuffParams | ControlBuffParams | TreatmentBuffParams | HarmBuffParams;
37
+ interface BuffConfig<T extends BuffType = BuffType> {
38
+ /** 被动名 */
39
+ name: string;
40
+ /** 被动类型 */
41
+ type: T;
42
+ /** 被动说明 */
43
+ info: string;
44
+ /** 被动函数 */
45
+ fn(agent: BattleAttribute, cb?: (val: Extract<BuffItemParams, {
46
+ type: T;
47
+ }>) => void): void;
48
+ }
49
+ type BuffFnList = {
50
+ [key: string]: BuffConfig;
51
+ };
52
+ export declare const BuffFn: BuffFnList;
53
+ /** 为目标添加BUFF */
54
+ export declare function giveBuff(agent: BattleAttribute, buff: {
55
+ name: string;
56
+ timer: number;
57
+ }): string;
58
+ export declare function settlementBuff(agent: BattleAttribute): string;
59
+ export {};
@@ -54,6 +54,12 @@ export type MonsterBaseAttribute = {
54
54
  /** 怪物等级要求? */
55
55
  lv?: number;
56
56
  }[];
57
+ fn?: {
58
+ /** 技能名 */
59
+ name: string;
60
+ /** 触发概率 */
61
+ prob: number;
62
+ }[];
57
63
  };
58
64
  export type MonsterTempData = {
59
65
  [keys: string]: MonsterBaseAttribute;
@@ -0,0 +1,82 @@
1
+ import { BattleAttribute } from "../battle";
2
+ import { DamageConfig } from "../damage";
3
+ export declare enum SkillType {
4
+ 释放失败 = "\u91CA\u653E\u5931\u8D25",
5
+ 伤害技 = "\u4F24\u5BB3\u6280",
6
+ 增益技 = "\u589E\u76CA\u6280",
7
+ 治疗技 = "\u6CBB\u7597\u6280",
8
+ 奥义 = "\u5965\u4E49"
9
+ }
10
+ export declare enum UserOccupation {
11
+ 剑士 = "\u5251\u58EB",
12
+ 法师 = "\u6CD5\u5E08",
13
+ 刺客 = "\u523A\u5BA2"
14
+ }
15
+ interface DamageSkillParams {
16
+ /** 伤害类型 */
17
+ type: SkillType.伤害技;
18
+ /** 伤害信息 */
19
+ damage: DamageConfig;
20
+ /** 释放目标 */
21
+ target: BattleAttribute[];
22
+ /** 是否衔接普攻 */
23
+ isNext: boolean;
24
+ }
25
+ interface HealSkillParams {
26
+ type: SkillType.治疗技;
27
+ /** 是否衔接普攻 */
28
+ isNext: boolean;
29
+ /** 治疗量 */
30
+ value: number;
31
+ target: BattleAttribute[];
32
+ }
33
+ interface BuffSkillParams {
34
+ type: SkillType.增益技;
35
+ /** 是否衔接普攻 */
36
+ isNext: boolean;
37
+ /** 错误提示 */
38
+ err?: string;
39
+ }
40
+ interface UltimateSkillParams {
41
+ type: SkillType.奥义;
42
+ /** 是否衔接普攻 */
43
+ isNext: boolean;
44
+ }
45
+ interface ErrSkillParams {
46
+ type: SkillType.释放失败;
47
+ /** 是否衔接普攻 */
48
+ isNext: boolean;
49
+ /** 错误提示 */
50
+ err?: string;
51
+ }
52
+ type SkillParams = DamageSkillParams | BuffSkillParams | HealSkillParams | UltimateSkillParams | ErrSkillParams;
53
+ interface SkillConfig<T extends SkillType = SkillType> {
54
+ /** 技能名 */
55
+ name: string;
56
+ /** 技能类型 */
57
+ type: T;
58
+ /** 技能说明 */
59
+ info: string;
60
+ /** 等级限制 */
61
+ lv: number;
62
+ /** 消耗MP */
63
+ mp: number;
64
+ /** 职业专属 */
65
+ feature?: UserOccupation[];
66
+ /** 技能函数 */
67
+ fn(agent: {
68
+ self: BattleAttribute;
69
+ goal: BattleAttribute;
70
+ }, agentList: {
71
+ selfList: BattleAttribute[];
72
+ goalList: BattleAttribute[];
73
+ }, cb?: (val: Extract<SkillParams, {
74
+ type: T;
75
+ }>) => void): string;
76
+ }
77
+ type SkillFn = {
78
+ [key: string]: SkillConfig;
79
+ };
80
+ export type UseAtkType = keyof typeof skillFn | '普攻';
81
+ export declare const skillFn: SkillFn;
82
+ export {};
package/lib/index.js CHANGED
@@ -87,7 +87,8 @@ var GensokyoMap = {
87
87
  areaName: "蜘蛛森林三",
88
88
  type: "冒险区" /* 冒险区 */,
89
89
  needLv: 1,
90
- left: "蜘蛛森林一"
90
+ left: "蜘蛛森林一",
91
+ monster: [{ name: "大妖精", lv: 3 }]
91
92
  },
92
93
  "蜘蛛森林通道": {
93
94
  floor: 1,
@@ -218,7 +219,8 @@ var GensokyoMap = {
218
219
  areaName: "野猪巢穴",
219
220
  type: "冒险区" /* 冒险区 */,
220
221
  needLv: 1,
221
- top: "绿野平原四"
222
+ top: "绿野平原四",
223
+ monster: [{ name: "蓬莱山辉夜", lv: 20 }]
222
224
  }
223
225
  }
224
226
  };
@@ -374,7 +376,7 @@ var monsterBenchmark = {
374
376
  def: 1.1,
375
377
  chr: 1.1,
376
378
  evasion: 1.1,
377
- hit: 1.1,
379
+ hit: 1.08,
378
380
  ghd: 1,
379
381
  speed: 1.05
380
382
  },
@@ -387,7 +389,7 @@ var monsterBenchmark = {
387
389
  def: 1.1,
388
390
  chr: 1.08,
389
391
  evasion: 1.08,
390
- hit: 1.08,
392
+ hit: 1.06,
391
393
  ghd: 1,
392
394
  speed: 1.05
393
395
  },
@@ -400,7 +402,7 @@ var monsterBenchmark = {
400
402
  def: 1.05,
401
403
  chr: 1.05,
402
404
  evasion: 1.05,
403
- hit: 1.05,
405
+ hit: 1.04,
404
406
  ghd: 1.05,
405
407
  speed: 1.05
406
408
  }
@@ -470,7 +472,8 @@ var monsterData = {
470
472
  giveMonetary: 2,
471
473
  giveProps: [
472
474
  { name: "红药", val: 3, radomVal: 30 }
473
- ]
475
+ ],
476
+ fn: [{ name: "垂死挣扎", prob: 1 }]
474
477
  },
475
478
  "小蜘蛛": {
476
479
  name: "小蜘蛛",
@@ -502,8 +505,8 @@ var monsterData = {
502
505
  pic: "http://smmcat.cn/run/gensokyo/dora.png",
503
506
  hp: 88,
504
507
  maxHp: 88,
505
- mp: 10,
506
- maxMp: 10,
508
+ mp: 30,
509
+ maxMp: 30,
507
510
  atk: 20,
508
511
  def: 5,
509
512
  chr: 200,
@@ -517,7 +520,8 @@ var monsterData = {
517
520
  giveProps: [
518
521
  { name: "蓝药", val: 3, radomVal: 30 },
519
522
  { name: "初级万能药", val: 2, radomVal: 90, const: true, lv: 5 }
520
- ]
523
+ ],
524
+ fn: [{ name: "治愈之光", prob: 1 }]
521
525
  },
522
526
  "琪露诺": {
523
527
  name: "琪露诺",
@@ -541,6 +545,53 @@ var monsterData = {
541
545
  giveProps: [
542
546
  { name: "初级复活卷轴", val: 1, radomVal: 50 }
543
547
  ]
548
+ },
549
+ "大妖精": {
550
+ name: "大妖精",
551
+ type: "野怪" /* 野怪 */,
552
+ info: "活泼好动且喜欢搞恶作剧的妖怪,常常与琪露诺一起溜达",
553
+ pic: "http://smmcat.cn/run/gensokyo/大妖精.png",
554
+ hp: 120,
555
+ maxHp: 120,
556
+ mp: 40,
557
+ maxMp: 40,
558
+ atk: 18,
559
+ def: 5,
560
+ chr: 100,
561
+ csr: 0,
562
+ evasion: 100,
563
+ hit: -400,
564
+ ghd: 1.2,
565
+ speed: 5,
566
+ giveExp: 15,
567
+ giveMonetary: 3,
568
+ giveProps: [
569
+ { name: "初级复活卷轴", val: 1, radomVal: 50 }
570
+ ]
571
+ },
572
+ "蓬莱山辉夜": {
573
+ name: "蓬莱山辉夜",
574
+ type: "野怪" /* 野怪 */,
575
+ info: "永远与须臾的公主,隐居于永远亭的辉夜姬。 对于拥有无限光阴的蓬莱人而言,过去与未来都是无穷无尽的。",
576
+ pic: "http://smmcat.cn/run/gensokyo/蓬莱山辉夜.png",
577
+ hp: 120,
578
+ maxHp: 120,
579
+ mp: 70,
580
+ maxMp: 70,
581
+ atk: 26,
582
+ def: 2,
583
+ chr: 100,
584
+ csr: 0,
585
+ evasion: 200,
586
+ hit: 1e3,
587
+ ghd: 1.5,
588
+ speed: 6,
589
+ giveExp: 20,
590
+ giveMonetary: 5,
591
+ giveProps: [
592
+ { name: "初级复活卷轴", val: 1, radomVal: 50 }
593
+ ],
594
+ fn: [{ name: "初级治愈", prob: 3 }, { name: "水炮", prob: 1 }]
544
595
  }
545
596
  };
546
597
 
@@ -743,6 +794,31 @@ var Damage = class {
743
794
  return this.config;
744
795
  }
745
796
  };
797
+ var BuffDamage = class {
798
+ static {
799
+ __name(this, "BuffDamage");
800
+ }
801
+ goal;
802
+ val;
803
+ isRealHarm;
804
+ constructor(val, goal, isRealHarm = false) {
805
+ this.goal = goal;
806
+ this.val = val;
807
+ this.isRealHarm = isRealHarm;
808
+ }
809
+ giveDamage() {
810
+ if (this.isRealHarm) {
811
+ const val = this.goal.hp - this.val > 0 ? this.val : this.goal.hp;
812
+ this.goal.hp -= val;
813
+ return val;
814
+ } else {
815
+ const def = this.goal.def + this.goal.gain.def;
816
+ const val = this.goal.hp + def - this.val > 0 ? this.val - def : this.goal.hp;
817
+ this.goal.hp -= val;
818
+ return val;
819
+ }
820
+ }
821
+ };
746
822
  function giveDamage(self, goal, damage) {
747
823
  if (goal.hp - damage.harm > 0) {
748
824
  goal.hp -= damage.harm;
@@ -771,7 +847,185 @@ function moreDamageInfo(damage) {
771
847
  }
772
848
  __name(moreDamageInfo, "moreDamageInfo");
773
849
 
774
- // src/skillFn.ts
850
+ // src/data/buffFn.ts
851
+ var BuffFn = {
852
+ "治愈": {
853
+ name: "治愈",
854
+ type: "治疗" /* 治疗 */,
855
+ info: "每回合回复5%最大血量(最低回复1血)",
856
+ fn: /* @__PURE__ */ __name(function(agent, fn) {
857
+ if (agent.hp <= 0) return;
858
+ const val = Math.floor((agent.maxHp + agent.gain.maxHp) * 0.05) || 1;
859
+ fn && fn({
860
+ type: "治疗" /* 治疗 */,
861
+ val
862
+ });
863
+ }, "fn")
864
+ },
865
+ "中毒": {
866
+ name: "中毒",
867
+ type: "伤害" /* 伤害 */,
868
+ info: "自身每回合受到5%最大血量伤害的真实伤害(最低扣除1血,最高20血)",
869
+ fn: /* @__PURE__ */ __name(function(agent, fn) {
870
+ if (agent.hp <= 0) return;
871
+ const val = Math.min(20, Math.floor((agent.maxHp + agent.gain.maxHp) * 0.05) || 1);
872
+ fn && fn({
873
+ type: "伤害" /* 伤害 */,
874
+ val,
875
+ isRealHarm: true
876
+ });
877
+ }, "fn")
878
+ },
879
+ "晕眩": {
880
+ name: "晕眩",
881
+ type: "控制" /* 控制 */,
882
+ info: "该回合将无法行动",
883
+ fn: /* @__PURE__ */ __name(function(agent, fn) {
884
+ fn && fn({
885
+ type: "控制" /* 控制 */,
886
+ name: this.name
887
+ });
888
+ }, "fn")
889
+ },
890
+ "混乱": {
891
+ name: "混乱",
892
+ type: "控制" /* 控制 */,
893
+ info: "该回合将无法行动",
894
+ fn: /* @__PURE__ */ __name(function(agent, fn) {
895
+ fn && fn({
896
+ type: "控制" /* 控制 */,
897
+ name: this.name
898
+ });
899
+ }, "fn")
900
+ },
901
+ "强壮": {
902
+ name: "强壮",
903
+ type: "增益" /* 增益 */,
904
+ info: "提高基于自身攻击力10%的临时攻击力,最低1点攻击力",
905
+ fn: /* @__PURE__ */ __name(function(agent, fn) {
906
+ const val = Math.floor(agent.atk * 0.1);
907
+ fn && fn({
908
+ type: "增益" /* 增益 */,
909
+ up: {
910
+ atk: val
911
+ }
912
+ });
913
+ }, "fn")
914
+ },
915
+ "弱化": {
916
+ name: "弱化",
917
+ type: "减益" /* 减益 */,
918
+ info: "削弱基于自身攻击力10%,但攻击力最低为1点",
919
+ fn: /* @__PURE__ */ __name(function(agent, fn) {
920
+ const val = Math.floor(agent.atk * 0.1);
921
+ fn && fn({
922
+ type: "减益" /* 减益 */,
923
+ down: {
924
+ atk: val
925
+ }
926
+ });
927
+ }, "fn")
928
+ }
929
+ };
930
+ function giveBuff(agent, buff) {
931
+ const buffInfo = BuffFn[buff.name] || null;
932
+ if (!buffInfo) return;
933
+ let again = false;
934
+ if (agent.buff[buff.name]) again = true;
935
+ agent.buff[buff.name] = buff;
936
+ const dict = { 1: "¹", 2: "²", 3: "³", 4: "⁴", 5: "⁵", 6: "⁶", 7: "⁷", 8: "⁸", 9: "⁹" };
937
+ return `${getLineupName(agent)}被挂上了${buff.name}${dict[buff.timer] || "⁺"}`;
938
+ }
939
+ __name(giveBuff, "giveBuff");
940
+ function settlementBuff(agent) {
941
+ if (agent.hp <= 0) return null;
942
+ agent.gain.atk = 0;
943
+ agent.gain.chr = 0;
944
+ agent.gain.def = 0;
945
+ agent.gain.evasion = 0;
946
+ agent.gain.ghd = 0;
947
+ agent.gain.hit = 0;
948
+ agent.gain.maxHp = 0;
949
+ agent.gain.maxMp = 0;
950
+ agent.gain.maxMp = 0;
951
+ agent.gain.speed = 0;
952
+ agent.gain.dizziness = false;
953
+ agent.gain.chaos = false;
954
+ const msgList = [];
955
+ const gainDict = {
956
+ atk: "攻击",
957
+ def: "防御",
958
+ maxHp: "最大生命值",
959
+ maxMp: "最大魔法值",
960
+ chr: "暴击率",
961
+ ghd: "暴击伤害",
962
+ evasion: "闪避值",
963
+ hit: "命中值",
964
+ speed: "速度"
965
+ };
966
+ Object.keys(agent.buff).forEach((item) => {
967
+ const buffInfo = BuffFn[item] || null;
968
+ if (!buffInfo) return;
969
+ switch (buffInfo.type) {
970
+ case "伤害" /* 伤害 */:
971
+ buffInfo.fn(agent, (val) => {
972
+ const value = new BuffDamage(val.val, agent, val.isRealHarm).giveDamage();
973
+ msgList.push(`${buffInfo.name}-${value}HP`);
974
+ });
975
+ break;
976
+ case "治疗" /* 治疗 */:
977
+ buffInfo.fn(agent, (val) => {
978
+ const value = giveCure(agent, val.val);
979
+ msgList.push(`${buffInfo.name}+${value}HP`);
980
+ });
981
+ break;
982
+ case "增益" /* 增益 */:
983
+ const upMsg = [];
984
+ buffInfo.fn(agent, (val) => {
985
+ Object.keys(val.up).forEach((buffName) => {
986
+ if (agent.gain[buffName]) {
987
+ upMsg.push(
988
+ val.up[buffName] > 0 ? gainDict[buffName] + "↑" + val.up[buffName] : gainDict[buffName] + "↓" + Math.abs(val.up[buffName])
989
+ );
990
+ agent.gain[buffName] += val.up[buffName];
991
+ }
992
+ });
993
+ msgList.push(`${buffInfo.name}:${upMsg.join("、")}`);
994
+ });
995
+ break;
996
+ case "减益" /* 减益 */:
997
+ const downMsg = [];
998
+ buffInfo.fn(agent, (val) => {
999
+ Object.keys(val.down).forEach((buffName) => {
1000
+ if (agent.gain[buffName]) {
1001
+ downMsg.push(
1002
+ val.down[buffName] > 0 ? gainDict[buffName] + "↓" + val.down[buffName] : gainDict[buffName] + "↑" + Math.abs(val.down[buffName])
1003
+ );
1004
+ agent.gain[buffName] -= val.down[buffName];
1005
+ }
1006
+ });
1007
+ msgList.push(`${buffInfo.name}:${upMsg.join("、")}`);
1008
+ });
1009
+ break;
1010
+ case "控制" /* 控制 */:
1011
+ buffInfo.fn(agent, (val) => {
1012
+ const control = { "晕眩": "dizziness", "控制": "chaos" };
1013
+ if (!control[val.name]) return;
1014
+ agent.gain[control[val.name]] = true;
1015
+ return `当前正在${val.name}中...`;
1016
+ });
1017
+ break;
1018
+ default:
1019
+ break;
1020
+ }
1021
+ --agent.buff[item].timer;
1022
+ if (agent.buff[item].timer == 0) delete agent.buff[item];
1023
+ });
1024
+ return msgList.length ? msgList.map((item) => `(${getLineupName(agent)}:${item})`).join("\n") : null;
1025
+ }
1026
+ __name(settlementBuff, "settlementBuff");
1027
+
1028
+ // src/data/skillFn.ts
775
1029
  var skillFn = {
776
1030
  "重砍": {
777
1031
  name: "重砍",
@@ -891,6 +1145,42 @@ var skillFn = {
891
1145
  });
892
1146
  return `${getLineupName(agent.self)}释放初级治愈,${getLineupName(agent.goal)}恢复40HP`;
893
1147
  }, "fn")
1148
+ },
1149
+ "垂死挣扎": {
1150
+ name: "垂死挣扎",
1151
+ type: "伤害技" /* 伤害技 */,
1152
+ info: "对目标造成1.5倍伤害",
1153
+ lv: 1,
1154
+ mp: 20,
1155
+ fn: /* @__PURE__ */ __name(function(agent, agentList, fn) {
1156
+ const damageData = new Damage(agent).result({
1157
+ before: /* @__PURE__ */ __name((val) => {
1158
+ val.default_harm += Math.floor(val.default_harm * 0.5);
1159
+ }, "before")
1160
+ });
1161
+ fn({
1162
+ damage: damageData,
1163
+ type: this.type,
1164
+ target: [agent.goal],
1165
+ isNext: false
1166
+ });
1167
+ return `${getLineupName(agent.self)} 进行垂死挣扎,对 ${getLineupName(agent.goal)} 造成 ${damageData.harm} 伤害。` + moreDamageInfo(damageData);
1168
+ }, "fn")
1169
+ },
1170
+ "治愈之光": {
1171
+ name: "治愈之光",
1172
+ type: "增益技" /* 增益技 */,
1173
+ info: "为目标挂上3回合治愈状态",
1174
+ lv: 1,
1175
+ mp: 20,
1176
+ fn: /* @__PURE__ */ __name(function(agent, agentList, fn) {
1177
+ giveBuff(agent.goal, { name: "治愈", timer: 3 });
1178
+ fn({
1179
+ type: "增益技" /* 增益技 */,
1180
+ isNext: true
1181
+ });
1182
+ return `${getLineupName(agent.self)} 对 ${getLineupName(agent.goal)} 释放治愈之光。`;
1183
+ }, "fn")
894
1184
  }
895
1185
  };
896
1186
 
@@ -1027,9 +1317,16 @@ var BattleData = {
1027
1317
  battleSituationTextFormat(team) {
1028
1318
  const selfTemp = [];
1029
1319
  const goalTemp = [];
1320
+ const getBuffTemplate = /* @__PURE__ */ __name((agent) => {
1321
+ const dict = { 1: "¹", 2: "²", 3: "³", 4: "⁴", 5: "⁵", 6: "⁶", 7: "⁷", 8: "⁸", 9: "⁹" };
1322
+ const buffInfo = Object.keys(agent.buff).map((item) => {
1323
+ return `${agent.buff[item].name}${dict[agent.buff[item].timer] || "⁺"}`;
1324
+ });
1325
+ return buffInfo.length ? "(" + buffInfo.join(" ") + ")" : "";
1326
+ }, "getBuffTemplate");
1030
1327
  team.self.forEach((item) => {
1031
1328
  if (item.hp > 0) {
1032
- selfTemp.push(`lv.${item.lv}[${item.name}]:
1329
+ selfTemp.push(`lv.${item.lv}[${item.name}]${getBuffTemplate(item)}:
1033
1330
  ${generateHealthDisplay(item.hp, item.maxHp + item.gain.maxHp)}(${item.hp}/${item.maxHp + item.gain.maxHp})
1034
1331
  MP:${item.mp}/${item.maxMp + item.gain.maxMp}`);
1035
1332
  } else {
@@ -1038,7 +1335,7 @@ MP:${item.mp}/${item.maxMp + item.gain.maxMp}`);
1038
1335
  });
1039
1336
  team.goal.forEach((item) => {
1040
1337
  if (item.hp > 0) {
1041
- goalTemp.push(`lv.${item.lv}[${item.name}]:
1338
+ goalTemp.push(`lv.${item.lv}[${item.name}]${getBuffTemplate(item)}:
1042
1339
  ${generateHealthDisplay(item.hp, item.maxHp + item.gain.maxHp)}(${item.hp}/${item.maxHp + item.gain.maxHp})
1043
1340
  MP:${item.mp}/${item.maxMp + item.gain.maxMp}`);
1044
1341
  } else {
@@ -1086,6 +1383,8 @@ MP:${item.mp}/${item.maxMp + item.gain.maxMp}`);
1086
1383
  const allAgentList = [...currentBattle.goal, ...currentBattle.self].sort((a, b) => b.speed - a.speed);
1087
1384
  const msgList = [];
1088
1385
  for (const agent of allAgentList) {
1386
+ const buffMsg = settlementBuff(agent);
1387
+ buffMsg && msgList.push(buffMsg);
1089
1388
  if (agent.hp <= 0) {
1090
1389
  if (agent.type == "玩家" && !User.userTempData[agent.userId]?.isDie) {
1091
1390
  User.userTempData[agent.userId].hp = 0;
@@ -1093,78 +1392,93 @@ MP:${item.mp}/${item.maxMp + item.gain.maxMp}`);
1093
1392
  }
1094
1393
  continue;
1095
1394
  }
1096
- let lifeGoalList = [];
1097
- let lifeSelfList = [];
1098
- if (agent.for == "self") {
1099
- lifeGoalList = currentBattle.goal.filter((item) => item.for == "goal" && item.hp > 0);
1100
- lifeSelfList = currentBattle.self.filter((item) => item.for == "self" && item.hp > 0);
1101
- } else {
1102
- lifeGoalList = currentBattle.self.filter((item) => item.for == "self" && item.hp > 0);
1103
- lifeSelfList = currentBattle.goal.filter((item) => item.for == "goal" && item.hp > 0);
1104
- }
1105
- if (!lifeGoalList.length) continue;
1106
- let selectGoal = {};
1107
- let isMy = false;
1108
- let funType = "普攻";
1109
- if (agent.type == "玩家" && agent.userId == session.userId) {
1110
- isMy = true;
1111
- funType = atkType;
1112
- selectGoal = lifeGoalList.find((item) => item.name == select) || lifeGoalList[Math.floor(Math.random() * lifeGoalList.length)];
1113
- } else if (agent.type == "玩家") {
1114
- selectGoal = lifeGoalList[Math.floor(Math.random() * lifeGoalList.length)];
1115
- } else {
1116
- selectGoal = lifeGoalList[Math.floor(Math.random() * lifeGoalList.length)];
1117
- }
1118
- const noralAtk = /* @__PURE__ */ __name(() => {
1119
- const damageInfo = new Damage({ self: agent, goal: selectGoal }).result();
1120
- giveDamage(agent, selectGoal, damageInfo);
1121
- msgList.push(
1122
- `${getLineupName(agent)} 使用普攻攻击了 ${getLineupName(selectGoal)},造成了${damageInfo.harm}伤害。` + moreDamageInfo(damageInfo)
1123
- );
1124
- }, "noralAtk");
1125
- if (funType == "普攻") {
1126
- noralAtk();
1127
- } else {
1128
- if (skillFn[atkType]) {
1129
- if (["治疗技" /* 治疗技 */, "增益技" /* 增益技 */].includes(skillFn[atkType].type)) {
1130
- selectGoal = lifeSelfList.find((item) => item.name == select) || agent;
1395
+ if (!agent.gain.dizziness) {
1396
+ let lifeGoalList = [];
1397
+ let lifeSelfList = [];
1398
+ if (agent.for == "self") {
1399
+ lifeGoalList = currentBattle.goal.filter((item) => item.for == "goal" && item.hp > 0);
1400
+ lifeSelfList = currentBattle.self.filter((item) => item.for == "self" && item.hp > 0);
1401
+ } else {
1402
+ lifeGoalList = currentBattle.self.filter((item) => item.for == "self" && item.hp > 0);
1403
+ lifeSelfList = currentBattle.goal.filter((item) => item.for == "goal" && item.hp > 0);
1404
+ }
1405
+ if (!lifeGoalList.length) continue;
1406
+ let selectGoal = {};
1407
+ let isMy = false;
1408
+ let funType = "普攻";
1409
+ if (!agent.gain.chaos) {
1410
+ if (agent.type == "玩家" && agent.userId == session.userId) {
1411
+ isMy = true;
1412
+ funType = atkType;
1413
+ selectGoal = lifeGoalList.find((item) => item.name == select) || lifeGoalList[Math.floor(Math.random() * lifeGoalList.length)];
1414
+ } else if (agent.type == "玩家") {
1415
+ selectGoal = lifeGoalList[Math.floor(Math.random() * lifeGoalList.length)];
1416
+ } else {
1417
+ selectGoal = lifeGoalList[Math.floor(Math.random() * lifeGoalList.length)];
1418
+ if (random(0, 10) < 4 && agent.fn?.length) {
1419
+ funType = getSkillFn(agent.fn);
1420
+ }
1131
1421
  }
1132
- const selectFn = skillFn[atkType];
1133
- if (selectFn.mp == 0 || agent.mp - selectFn.mp >= 0) {
1134
- agent.mp -= selectFn.mp;
1135
- let isNext = false;
1136
- const fnMsg = selectFn.fn(
1137
- { self: agent, goal: selectGoal },
1138
- { selfList: lifeSelfList, goalList: lifeGoalList },
1139
- (val) => {
1140
- switch (val.type) {
1141
- case "伤害技" /* 伤害技 */:
1142
- val.target.map((goal) => {
1143
- giveDamage(agent, goal, val.damage);
1144
- });
1145
- break;
1146
- case "治疗技" /* 治疗技 */:
1147
- val.target.map((goal) => {
1148
- giveCure(goal, val.value);
1149
- });
1150
- break;
1151
- case "释放失败" /* 释放失败 */:
1152
- val.err && session.send(val.err);
1153
- default:
1154
- break;
1422
+ } else {
1423
+ const fliteMyList = allAgentList.filter((item) => item.name !== agent.name && item.hp > 0);
1424
+ if (!fliteMyList.length) continue;
1425
+ selectGoal = fliteMyList[Math.random() * fliteMyList.length];
1426
+ }
1427
+ const noralAtk = /* @__PURE__ */ __name(() => {
1428
+ const damageInfo = new Damage({ self: agent, goal: selectGoal }).result();
1429
+ giveDamage(agent, selectGoal, damageInfo);
1430
+ msgList.push(
1431
+ `${getLineupName(agent)} 使用普攻攻击了 ${getLineupName(selectGoal)},造成了${damageInfo.harm}伤害。` + moreDamageInfo(damageInfo)
1432
+ );
1433
+ }, "noralAtk");
1434
+ if (funType == "普攻") {
1435
+ noralAtk();
1436
+ } else {
1437
+ if (skillFn[funType]) {
1438
+ let _selectGoal = selectGoal;
1439
+ if (["治疗技" /* 治疗技 */, "增益技" /* 增益技 */].includes(skillFn[funType].type)) {
1440
+ _selectGoal = lifeSelfList.find((item) => item.name == select) || agent;
1441
+ }
1442
+ const selectFn = skillFn[funType];
1443
+ if (selectFn.mp == 0 || agent.mp - selectFn.mp >= 0) {
1444
+ agent.mp -= selectFn.mp;
1445
+ let isNext = false;
1446
+ const fnMsg = selectFn.fn(
1447
+ { self: agent, goal: _selectGoal },
1448
+ { selfList: lifeSelfList, goalList: lifeGoalList },
1449
+ (val) => {
1450
+ switch (val.type) {
1451
+ case "伤害技" /* 伤害技 */:
1452
+ val.target.map((goal) => {
1453
+ giveDamage(agent, goal, val.damage);
1454
+ });
1455
+ break;
1456
+ case "治疗技" /* 治疗技 */:
1457
+ val.target.map((goal) => {
1458
+ giveCure(goal, val.value);
1459
+ });
1460
+ break;
1461
+ case "增益技" /* 增益技 */:
1462
+ isMy && val.err && session.send(val.err);
1463
+ break;
1464
+ case "释放失败" /* 释放失败 */:
1465
+ isMy && val.err && session.send(val.err);
1466
+ default:
1467
+ break;
1468
+ }
1469
+ isNext = val.isNext;
1155
1470
  }
1156
- isNext = val.isNext;
1157
- }
1158
- );
1159
- fnMsg && msgList.push(fnMsg);
1160
- isNext && noralAtk();
1471
+ );
1472
+ fnMsg && msgList.push(fnMsg);
1473
+ isNext && noralAtk();
1474
+ } else {
1475
+ isMy && await session.send(`MP不足,释放失败!`);
1476
+ noralAtk();
1477
+ }
1161
1478
  } else {
1162
- await session.send(`MP不足,释放失败!`);
1479
+ isMy && await session.send(`未持有该技能或者该技能不存在,释放失败!`);
1163
1480
  noralAtk();
1164
1481
  }
1165
- } else {
1166
- await session.send(`未持有该技能或者该技能不存在,释放失败!`);
1167
- noralAtk();
1168
1482
  }
1169
1483
  }
1170
1484
  }
@@ -1264,6 +1578,19 @@ function getLineupName(agent) {
1264
1578
  return `[${agent.type}]${agent.name}`;
1265
1579
  }
1266
1580
  __name(getLineupName, "getLineupName");
1581
+ function getSkillFn(fnList) {
1582
+ const totalProb = fnList.reduce((sum, item) => sum + item.prob, 0);
1583
+ const random2 = Math.random() * totalProb;
1584
+ let currentProb = 0;
1585
+ for (const item of fnList) {
1586
+ currentProb += item.prob;
1587
+ if (random2 < currentProb) {
1588
+ return item.name;
1589
+ }
1590
+ }
1591
+ return fnList[fnList.length - 1].name;
1592
+ }
1593
+ __name(getSkillFn, "getSkillFn");
1267
1594
  function initBattleAttribute(data) {
1268
1595
  if ("playName" in data) {
1269
1596
  const userData = data;
@@ -1272,6 +1599,7 @@ function initBattleAttribute(data) {
1272
1599
  name: userData.playName,
1273
1600
  lv: userData.lv,
1274
1601
  type: "玩家",
1602
+ selfType: userData.type,
1275
1603
  hp: userData.hp,
1276
1604
  maxHp: userData.maxHp,
1277
1605
  mp: userData.mp,
@@ -1293,10 +1621,13 @@ function initBattleAttribute(data) {
1293
1621
  ghd: 0,
1294
1622
  evasion: 0,
1295
1623
  hit: 0,
1296
- speed: 0
1624
+ speed: 0,
1625
+ chaos: false,
1626
+ dizziness: false
1297
1627
  },
1298
- buff: [],
1299
- fn: []
1628
+ buff: {},
1629
+ fn: [],
1630
+ expand: {}
1300
1631
  };
1301
1632
  return temp;
1302
1633
  } else {
@@ -1304,6 +1635,7 @@ function initBattleAttribute(data) {
1304
1635
  const temp = {
1305
1636
  name: monsterData2.name,
1306
1637
  type: "怪物",
1638
+ selfType: monsterData2.type,
1307
1639
  lv: monsterData2.lv,
1308
1640
  hp: monsterData2.hp,
1309
1641
  maxHp: monsterData2.maxHp,
@@ -1326,10 +1658,13 @@ function initBattleAttribute(data) {
1326
1658
  ghd: 0,
1327
1659
  evasion: 0,
1328
1660
  hit: 0,
1329
- speed: 0
1661
+ speed: 0,
1662
+ chaos: false,
1663
+ dizziness: false
1330
1664
  },
1331
- buff: [],
1332
- fn: []
1665
+ buff: {},
1666
+ fn: monsterData2.fn ? JSON.parse(JSON.stringify(monsterData2.fn)) : [],
1667
+ expand: {}
1333
1668
  };
1334
1669
  return temp;
1335
1670
  }
@@ -1669,7 +2004,11 @@ var User = {
1669
2004
  await session.send("名字重复,请更换一个名字。");
1670
2005
  return;
1671
2006
  }
1672
- if (playname.trim().length > 6 || playname.trim().length < 1) {
2007
+ if (Object.keys(monsterData).includes(playname?.trim())) {
2008
+ await session.send("请不要设置怪物的名字!");
2009
+ return;
2010
+ }
2011
+ if (playname.trim().length < 6 || playname.trim().length > 1) {
1673
2012
  await session.send("名字长度有问题,要求小于 6个字,大于 1个字");
1674
2013
  return;
1675
2014
  }
package/lib/test.d.ts CHANGED
@@ -1,13 +1,8 @@
1
- declare const nameList: {
2
- readonly 张三: {
3
- readonly age: 25;
4
- };
5
- readonly 李四: {
6
- readonly age: 30;
7
- };
8
- };
9
- declare const fn: (name: keyof typeof nameList) => {
10
- readonly age: 25;
11
- } | {
12
- readonly age: 30;
13
- };
1
+ declare const fn: {
2
+ name: string;
3
+ prob: number;
4
+ }[];
5
+ declare function useAtkFn(fnList: {
6
+ name: string;
7
+ prob: number;
8
+ }[]): string;
package/lib/users.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Context, Session } from "koishi";
2
2
  import { Config } from ".";
3
- import { UserOccupation } from "./skillFn";
3
+ import { UserOccupation } from "./data/skillFn";
4
4
  declare module 'koishi' {
5
5
  interface Tables {
6
6
  smm_gensokyo_user_attribute: DatabaseUserAttribute;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-smmcat-gensokyo",
3
3
  "description": "名为《幻想乡》的文字冒险游戏",
4
- "version": "0.0.20",
4
+ "version": "0.0.22",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [