koishi-plugin-smmcat-gensokyo 0.0.3 → 0.0.5

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,5 +1,6 @@
1
1
  import { Context, Session } from "koishi";
2
2
  import { Config } from ".";
3
+ import { UserBaseAttribute } from "./users";
3
4
  declare module 'koishi' {
4
5
  interface Tables {
5
6
  smm_gensokyo_battle_history: BattleHistory;
@@ -81,12 +82,15 @@ export type BattleAttribute = {
81
82
  name: string;
82
83
  time: number;
83
84
  }[];
85
+ /** 持有技能 */
86
+ fn?: [];
84
87
  };
85
88
  /** 最后战斗状态 */
86
89
  type LastPlay = {
87
90
  [keys: string]: {
88
91
  self: BattleAttribute[];
89
92
  goal: BattleAttribute[];
93
+ isPK?: boolean;
90
94
  };
91
95
  };
92
96
  export declare const BattleData: {
@@ -98,28 +102,40 @@ export declare const BattleData: {
98
102
  init(config: Config, ctx: Context): void;
99
103
  /** 玩家是否正在战斗 */
100
104
  isBattle(session: Session): boolean;
105
+ /** 玩家是否正在战斗 */
106
+ isBattleByUserId(userId: string): boolean;
101
107
  /** 玩家是否在队伍中 */
102
108
  isTeam(session: Session): boolean;
109
+ isTeamByUserId(userId: string): boolean;
110
+ teamListByUser(userId: string): UserBaseAttribute[];
103
111
  /** 创建战斗-与怪物 */
104
112
  createBattleByMonster(session: Session, goal: {
105
113
  name: string;
106
114
  lv: number;
107
115
  }[]): Promise<void>;
116
+ /** 创建战斗-与玩家 */
117
+ createBattleByUser(session: Session, goal: {
118
+ userId: string;
119
+ }[]): Promise<void>;
108
120
  /** 文本化当前战况 */
109
121
  battleSituationTextFormat(team: {
110
122
  self: BattleAttribute[];
111
123
  goal: BattleAttribute[];
124
+ isPK?: boolean;
112
125
  }): string;
113
126
  /** 判断输赢 */
114
127
  playOver(team: {
115
128
  self: BattleAttribute[];
116
129
  goal: BattleAttribute[];
130
+ isPK?: boolean;
117
131
  }): {
118
132
  over: boolean;
119
133
  type: string;
120
134
  };
121
135
  /** 清理战场 */
122
136
  clearBattleData(session: Session): void;
123
- play(session: Session, atkType: "\u666E\u653B", select?: string): Promise<void>;
137
+ play(session: Session, atkType: string, select?: string): Promise<void>;
124
138
  };
139
+ /** 获取阵容角色名 */
140
+ export declare function getLineupName(agent: BattleAttribute): string;
125
141
  export {};
package/lib/damage.d.ts CHANGED
@@ -10,7 +10,7 @@ type DamageCallback = {
10
10
  interface Callback {
11
11
  (data: DamageConfig): void;
12
12
  }
13
- type DamageConfig = {
13
+ export type DamageConfig = {
14
14
  agent: {
15
15
  self: BattleAttribute;
16
16
  goal: BattleAttribute;
@@ -48,4 +48,6 @@ declare class Damage {
48
48
  }
49
49
  /** 给予目标伤害 */
50
50
  declare function giveDamage(self: BattleAttribute, goal: BattleAttribute, damage: DamageConfig): number;
51
+ /** 伤害额外信息 */
52
+ export declare function moreDamageInfo(damage: DamageConfig): string;
51
53
  export { Damage, giveDamage };
package/lib/index.js CHANGED
@@ -308,10 +308,24 @@ var GensokyoMap = {
308
308
  };
309
309
  fn && await fn(areaInfo);
310
310
  await delay(3e3);
311
- GensokyoMap.setLocalStoragePoistionData(session.userId);
312
311
  userCurrentArea.moveing = false;
312
+ GensokyoMap.setLocalStoragePoistionData(session.userId);
313
313
  return;
314
314
  },
315
+ /** 查询附近玩家 */
316
+ nearbyPlayersByUserId(userId) {
317
+ const areaData = GensokyoMap.getUserCurrentArea(userId);
318
+ const liveUser = [];
319
+ Object.keys(GensokyoMap.userCurrentLoal).forEach((_userId) => {
320
+ const userItem = GensokyoMap.userCurrentLoal[_userId];
321
+ if (userItem.areaName == areaData.areaName && userItem.floor == areaData.floor) {
322
+ if (userId !== userItem.userId) {
323
+ liveUser.push({ userId: userItem.userId, playName: userItem.playName });
324
+ }
325
+ }
326
+ });
327
+ return liveUser;
328
+ },
315
329
  /** 区域信息格式化 */
316
330
  userAreaTextFormat(gameName, data) {
317
331
  const liveUser = [];
@@ -786,7 +800,7 @@ var Damage = class {
786
800
  this.config = {
787
801
  agent: { self: { ...agent.self }, goal: { ...agent.goal } },
788
802
  harm: 0,
789
- default_harm: agent.self.atk + agent.self.gain.atk,
803
+ default_harm: 0,
790
804
  isRealHarm: realHarm,
791
805
  isEvasion: false,
792
806
  isCsp: false,
@@ -795,13 +809,14 @@ var Damage = class {
795
809
  }
796
810
  /** 伤害判定前 */
797
811
  before(fn) {
812
+ this.config.default_harm = this.config.agent.self.atk + this.config.agent.self.gain.atk;
798
813
  fn && fn(this.config);
799
814
  return this;
800
815
  }
801
816
  /** 真实伤害判定 */
802
817
  beforRealHarm(fn) {
803
818
  fn && fn(this.config);
804
- if (this.config.isEvasion) {
819
+ if (this.config.isRealHarm) {
805
820
  this.config.harm = this.config.default_harm;
806
821
  }
807
822
  return this;
@@ -877,6 +892,65 @@ function giveDamage(self, goal, damage) {
877
892
  }
878
893
  }
879
894
  __name(giveDamage, "giveDamage");
895
+ function moreDamageInfo(damage) {
896
+ return (damage.isCsp ? `(暴击!)` : "") + (damage.isEvasion ? `(闪避成功!)` : "") + (damage.isBadDef ? `(未破防!)` : "");
897
+ }
898
+ __name(moreDamageInfo, "moreDamageInfo");
899
+
900
+ // src/skillFn.ts
901
+ var skillFn = {
902
+ "重砍": {
903
+ name: "重砍",
904
+ type: "伤害技" /* 伤害技 */,
905
+ info: "[伤害技]消耗10MP,对敌方一个单位造成基于攻击力1.2倍伤害。该次伤害无视敌方30%防御!(最低无视1防御)",
906
+ mp: 10,
907
+ fn: /* @__PURE__ */ __name(function(agent, agentList, fn) {
908
+ const damageData = new Damage(agent).result({
909
+ before: /* @__PURE__ */ __name((val) => {
910
+ val.default_harm += Math.floor(val.default_harm * 0.2);
911
+ val.agent.goal.def -= Math.floor(val.agent.goal.def * 0.3) || 1;
912
+ }, "before")
913
+ });
914
+ fn({
915
+ damage: damageData,
916
+ type: this.type,
917
+ target: [agent.goal],
918
+ isNext: false
919
+ });
920
+ return `${getLineupName(agent.self)} 释放重砍,对 ${getLineupName(agent.goal)} 造成 ${damageData.harm} 伤害。` + moreDamageInfo(damageData);
921
+ }, "fn")
922
+ },
923
+ "濒死一击": {
924
+ name: "濒死一击",
925
+ type: "伤害技" /* 伤害技 */,
926
+ info: "[伤害技]血量低于40%可释放,消耗20MP,对敌方一个单位造成基于攻击力2倍伤害。该次伤害暴击率提高20%",
927
+ mp: 20,
928
+ fn: /* @__PURE__ */ __name(function(agent, agentList, fn) {
929
+ if (agent.self.hp / (agent.self.maxHp + agent.self.gain.maxHp) < 0.4) {
930
+ const damageData = new Damage(agent).result({
931
+ before: /* @__PURE__ */ __name((val) => {
932
+ val.default_harm += val.default_harm;
933
+ val.agent.self.chr += 200;
934
+ }, "before")
935
+ });
936
+ fn({
937
+ damage: damageData,
938
+ type: this.type,
939
+ target: [agent.goal],
940
+ isNext: false
941
+ });
942
+ return `${getLineupName(agent.self)} 释放濒死一击,对 ${getLineupName(agent.goal)} 造成 ${damageData.harm} 伤害。` + moreDamageInfo(damageData);
943
+ } else {
944
+ fn({
945
+ type: "释放失败" /* 释放失败 */,
946
+ isNext: true,
947
+ err: "释放失败,未达成条件。"
948
+ });
949
+ return ``;
950
+ }
951
+ }, "fn")
952
+ }
953
+ };
880
954
 
881
955
  // src/battle.ts
882
956
  var BattleData = {
@@ -893,10 +967,31 @@ var BattleData = {
893
967
  isBattle(session) {
894
968
  return !!BattleData.lastPlay[session.userId];
895
969
  },
970
+ /** 玩家是否正在战斗 */
971
+ isBattleByUserId(userId) {
972
+ return !!BattleData.lastPlay[userId];
973
+ },
896
974
  /** 玩家是否在队伍中 */
897
975
  isTeam(session) {
898
976
  return !!BattleData.teamTemp[session.userId];
899
977
  },
978
+ isTeamByUserId(userId) {
979
+ return !!BattleData.teamTemp[userId];
980
+ },
981
+ // 返回队伍信息
982
+ teamListByUser(userId) {
983
+ const teamList = [];
984
+ if (!BattleData.teamTemp[userId]) {
985
+ return [];
986
+ }
987
+ const _userId = BattleData.teamTemp[userId].for;
988
+ Object.keys(BattleData.teamTemp).forEach((item) => {
989
+ if (BattleData.teamTemp[item].for == _userId) {
990
+ teamList.push(User.getUserAttributeByUserId(item));
991
+ }
992
+ });
993
+ return teamList;
994
+ },
900
995
  /** 创建战斗-与怪物 */
901
996
  async createBattleByMonster(session, goal) {
902
997
  if (BattleData.isBattle(session)) {
@@ -923,14 +1018,69 @@ var BattleData = {
923
1018
  goal.forEach((item) => {
924
1019
  battle_monsterList.push(initBattleAttribute(Monster.getMonsterAttributeData(item.name, item.lv)));
925
1020
  });
1021
+ const temp = {
1022
+ self: battle_user.map((i) => ({ ...i, for: "self" })),
1023
+ goal: battle_monsterList.map((i) => ({ ...i, for: "goal" }))
1024
+ };
926
1025
  playUser.forEach((userId) => {
927
- BattleData.lastPlay[userId] = {
928
- self: battle_user.map((i) => ({ ...i, for: "self" })),
929
- goal: battle_monsterList.map((i) => ({ ...i, for: "goal" }))
930
- };
1026
+ BattleData.lastPlay[userId] = temp;
931
1027
  });
932
1028
  await session.send(`开始与 ${goal.map((i) => i.name).join("、")} 进行战斗`);
933
1029
  },
1030
+ /** 创建战斗-与玩家 */
1031
+ async createBattleByUser(session, goal) {
1032
+ if (BattleData.isBattle(session)) {
1033
+ await session.send("当前正在战斗,还不能逃脱!");
1034
+ return;
1035
+ }
1036
+ const battle_self = [];
1037
+ const battle_goal = [];
1038
+ const playUser = [];
1039
+ const lostMsg = [];
1040
+ goal = goal.filter((item) => {
1041
+ const isBattle = BattleData.isBattleByUserId(item.userId);
1042
+ const pyUser = User.userTempData[item.userId];
1043
+ if (isBattle) {
1044
+ lostMsg.push(`${pyUser.playName}正在参与着一场战斗,无法被PK选中。`);
1045
+ return false;
1046
+ }
1047
+ return true;
1048
+ });
1049
+ if (lostMsg.length) {
1050
+ await session.send(lostMsg.join("\n"));
1051
+ }
1052
+ if (!goal.length) {
1053
+ lostMsg.push(`PK失败,无任何目标进行PK`);
1054
+ return;
1055
+ }
1056
+ if (BattleData.isTeam(session) && BattleData.teamTemp[session.userId].identity == "队员") {
1057
+ await session.send("你不是队伍的队长,无法主动操作战斗!");
1058
+ return;
1059
+ } else if (BattleData.isTeam(session)) {
1060
+ Object.keys(BattleData.teamTemp).forEach((item) => {
1061
+ if (BattleData.teamTemp[item].for == session.userId) {
1062
+ playUser.push(item);
1063
+ battle_self.push(initBattleAttribute(User.getUserAttributeByUserId(item)));
1064
+ }
1065
+ });
1066
+ } else {
1067
+ playUser.push(session.userId);
1068
+ battle_self.push(initBattleAttribute(User.getUserAttributeByUserId(session.userId)));
1069
+ }
1070
+ goal.forEach((item) => {
1071
+ playUser.push(item.userId);
1072
+ battle_goal.push(initBattleAttribute(User.getUserAttributeByUserId(item.userId)));
1073
+ });
1074
+ const pkTemp = {
1075
+ self: battle_self.map((i) => ({ ...i, for: "self" })),
1076
+ goal: battle_goal.map((i) => ({ ...i, for: "goal" })),
1077
+ isPK: true
1078
+ };
1079
+ playUser.forEach((userId) => {
1080
+ BattleData.lastPlay[userId] = pkTemp;
1081
+ });
1082
+ await session.send(`开始与玩家 ${battle_goal.map((i) => i.name).join("、")} 进行PK战斗`);
1083
+ },
934
1084
  /** 文本化当前战况 */
935
1085
  battleSituationTextFormat(team) {
936
1086
  const selfTemp = [];
@@ -938,7 +1088,8 @@ var BattleData = {
938
1088
  team.self.forEach((item) => {
939
1089
  if (item.hp > 0) {
940
1090
  selfTemp.push(`lv.${item.lv}[${item.name}]:
941
- ${generateHealthDisplay(item.hp, item.maxHp + item.gain.maxHp)}(${item.hp}/${item.maxHp + item.gain.maxHp})`);
1091
+ ${generateHealthDisplay(item.hp, item.maxHp + item.gain.maxHp)}(${item.hp}/${item.maxHp + item.gain.maxHp})
1092
+ MP:${item.mp}/${item.maxMp + item.gain.maxMp}`);
942
1093
  } else {
943
1094
  selfTemp.push(`lv.${item.lv}[${item.name}]:已阵亡`);
944
1095
  }
@@ -946,11 +1097,17 @@ ${generateHealthDisplay(item.hp, item.maxHp + item.gain.maxHp)}(${item.hp}/${ite
946
1097
  team.goal.forEach((item) => {
947
1098
  if (item.hp > 0) {
948
1099
  goalTemp.push(`lv.${item.lv}[${item.name}]:
949
- ${generateHealthDisplay(item.hp, item.maxHp + item.gain.maxHp)}(${item.hp}/${item.maxHp + item.gain.maxHp})`);
1100
+ ${generateHealthDisplay(item.hp, item.maxHp + item.gain.maxHp)}(${item.hp}/${item.maxHp + item.gain.maxHp})
1101
+ MP:${item.mp}/${item.maxMp + item.gain.maxMp}`);
950
1102
  } else {
951
1103
  goalTemp.push(`lv.${item.lv}[${item.name}]:已阵亡`);
952
1104
  }
953
1105
  });
1106
+ if (team.isPK) {
1107
+ return `[当前战况]
1108
+ 攻击方:
1109
+ ` + selfTemp.join("\n") + "\n\n防御方:\n" + goalTemp.join("\n");
1110
+ }
954
1111
  return `[当前战况]
955
1112
  我方阵容:
956
1113
  ` + selfTemp.join("\n") + "\n\n敌方阵容:\n" + goalTemp.join("\n");
@@ -962,19 +1119,20 @@ ${generateHealthDisplay(item.hp, item.maxHp + item.gain.maxHp)}(${item.hp}/${ite
962
1119
  if (self && goal) {
963
1120
  return { over: true, type: "平局" };
964
1121
  } else if (self) {
965
- return { over: true, type: "敌方赢" };
1122
+ return { over: true, type: team.isPK ? "防御方赢" : "敌方赢" };
966
1123
  } else if (goal) {
967
- return { over: true, type: "我方赢" };
1124
+ return { over: true, type: team.isPK ? "攻击方赢" : "我方赢" };
968
1125
  }
969
1126
  return { over: false, type: "未结束" };
970
1127
  },
971
1128
  /** 清理战场 */
972
1129
  clearBattleData(session) {
973
1130
  if (BattleData.isTeam(session)) {
974
- const userId = BattleData.teamTemp[session.userId].for;
975
- Object.keys(BattleData.teamTemp).forEach((item) => {
976
- if (BattleData.teamTemp[item].for == userId) {
977
- delete BattleData.lastPlay[item];
1131
+ const currentBattle = BattleData.lastPlay[session.userId];
1132
+ const allAgentList = [...currentBattle.goal, ...currentBattle.self].sort((a, b) => b.speed - a.speed);
1133
+ allAgentList.forEach((item) => {
1134
+ if (item.type == "玩家") {
1135
+ delete BattleData.lastPlay[item.userId];
978
1136
  }
979
1137
  });
980
1138
  } else {
@@ -992,25 +1150,71 @@ ${generateHealthDisplay(item.hp, item.maxHp + item.gain.maxHp)}(${item.hp}/${ite
992
1150
  for (const agent of allAgentList) {
993
1151
  if (agent.hp <= 0) continue;
994
1152
  let lifeGoalList = [];
1153
+ let lifeSelfList = [];
995
1154
  if (agent.for == "self") {
996
1155
  lifeGoalList = currentBattle.goal.filter((item) => item.for == "goal" && item.hp > 0);
1156
+ lifeSelfList = currentBattle.self.filter((item) => item.for == "self" && item.hp > 0);
997
1157
  } else {
998
1158
  lifeGoalList = currentBattle.self.filter((item) => item.for == "self" && item.hp > 0);
1159
+ lifeSelfList = currentBattle.goal.filter((item) => item.for == "goal" && item.hp > 0);
999
1160
  }
1000
1161
  if (!lifeGoalList.length) continue;
1001
1162
  let selectGoal = {};
1002
1163
  let isMy = false;
1164
+ let funType = "普攻";
1003
1165
  if (agent.type == "玩家" && agent.userId == session.userId) {
1004
1166
  isMy = true;
1167
+ funType = atkType;
1005
1168
  selectGoal = lifeGoalList.find((item) => item.name == select) || lifeGoalList[Math.floor(Math.random() * lifeGoalList.length)];
1169
+ } else if (agent.type == "玩家") {
1170
+ selectGoal = lifeGoalList[Math.floor(Math.random() * lifeGoalList.length)];
1006
1171
  } else {
1007
1172
  selectGoal = lifeGoalList[Math.floor(Math.random() * lifeGoalList.length)];
1008
1173
  }
1009
- const damageInfo = new Damage({ self: agent, goal: selectGoal }).result();
1010
- giveDamage(agent, selectGoal, damageInfo);
1011
- msgList.push(
1012
- `[${agent.type}]${agent.name} 使用普攻攻击了 [${selectGoal.type}]${selectGoal.name},造成了${damageInfo.harm}伤害。` + (damageInfo.isCsp ? `(暴击!)` : "") + (damageInfo.isEvasion ? `(闪避成功!)` : "") + (damageInfo.isBadDef ? `(未破防!)` : "")
1013
- );
1174
+ const noralAtk = /* @__PURE__ */ __name(() => {
1175
+ const damageInfo = new Damage({ self: agent, goal: selectGoal }).result();
1176
+ giveDamage(agent, selectGoal, damageInfo);
1177
+ msgList.push(
1178
+ `${getLineupName(agent)} 使用普攻攻击了 ${getLineupName(selectGoal)},造成了${damageInfo.harm}伤害。` + moreDamageInfo(damageInfo)
1179
+ );
1180
+ }, "noralAtk");
1181
+ if (funType == "普攻") {
1182
+ noralAtk();
1183
+ } else {
1184
+ if (skillFn[atkType]) {
1185
+ const selectFn = skillFn[atkType];
1186
+ if (selectFn.mp == 0 || agent.mp - selectFn.mp >= 0) {
1187
+ agent.mp -= selectFn.mp;
1188
+ let isNext = false;
1189
+ const fnMsg = selectFn.fn(
1190
+ { self: agent, goal: selectGoal },
1191
+ { selfList: lifeSelfList, goalList: lifeGoalList },
1192
+ (val) => {
1193
+ switch (val.type) {
1194
+ case "伤害技" /* 伤害技 */:
1195
+ val.target.map((goal) => {
1196
+ giveDamage(agent, goal, val.damage);
1197
+ });
1198
+ break;
1199
+ case "释放失败" /* 释放失败 */:
1200
+ val.err && session.send(val.err);
1201
+ default:
1202
+ break;
1203
+ }
1204
+ isNext = val.isNext;
1205
+ }
1206
+ );
1207
+ fnMsg && msgList.push(fnMsg);
1208
+ isNext && noralAtk();
1209
+ } else {
1210
+ await session.send(`MP不足,释放失败!`);
1211
+ noralAtk();
1212
+ }
1213
+ } else {
1214
+ await session.send(`未持有该技能或者该技能不存在,释放失败!`);
1215
+ noralAtk();
1216
+ }
1217
+ }
1014
1218
  }
1015
1219
  await session.send(msgList.length ? `战斗记录:
1016
1220
  ` + msgList.join("\n") : "");
@@ -1022,6 +1226,10 @@ ${generateHealthDisplay(item.hp, item.maxHp + item.gain.maxHp)}(${item.hp}/${ite
1022
1226
  }
1023
1227
  }
1024
1228
  };
1229
+ function getLineupName(agent) {
1230
+ return `[${agent.type}]${agent.name}`;
1231
+ }
1232
+ __name(getLineupName, "getLineupName");
1025
1233
  function initBattleAttribute(data) {
1026
1234
  if ("playName" in data) {
1027
1235
  const userData = data;
@@ -1053,7 +1261,8 @@ function initBattleAttribute(data) {
1053
1261
  hit: 0,
1054
1262
  speed: 0
1055
1263
  },
1056
- buff: []
1264
+ buff: [],
1265
+ fn: []
1057
1266
  };
1058
1267
  return temp;
1059
1268
  } else {
@@ -1085,7 +1294,8 @@ function initBattleAttribute(data) {
1085
1294
  hit: 0,
1086
1295
  speed: 0
1087
1296
  },
1088
- buff: []
1297
+ buff: [],
1298
+ fn: []
1089
1299
  };
1090
1300
  return temp;
1091
1301
  }
@@ -1219,7 +1429,7 @@ function apply(ctx, config) {
1219
1429
  GensokyoMap.initUserPoistion(session, userData);
1220
1430
  const areaInfo = GensokyoMap.getUserCurrentArea(session.userId);
1221
1431
  if (goal) {
1222
- if (!areaInfo.monster.map((i) => i.name).includes(goal)) {
1432
+ if (!areaInfo.monster?.map((i) => i.name).includes(goal)) {
1223
1433
  return `没有在该区域找到该怪物。`;
1224
1434
  }
1225
1435
  const selectMonster = areaInfo.monster.find((i) => i.name == goal);
@@ -1234,6 +1444,40 @@ function apply(ctx, config) {
1234
1444
  if (!userData) return;
1235
1445
  BattleData.play(session, "普攻", goal);
1236
1446
  });
1447
+ ctx.command("幻想乡/打怪技能 <skill> <goal>").action(async ({ session }, skill, goal) => {
1448
+ const userData = await User.getUserAttribute(session);
1449
+ if (!userData) return;
1450
+ BattleData.play(session, skill, goal);
1451
+ });
1452
+ ctx.command("打怪pk <goal>").action(async ({ session }, goal) => {
1453
+ const userData = await User.getUserAttribute(session);
1454
+ if (!userData) return;
1455
+ GensokyoMap.initUserPoistion(session, userData);
1456
+ if (!goal) {
1457
+ await session.send("请选择PK目标!");
1458
+ return;
1459
+ }
1460
+ const nearUserItem = GensokyoMap.nearbyPlayersByUserId(session.userId);
1461
+ const exist = nearUserItem.find((item) => item.playName == goal.trim());
1462
+ if (!exist) {
1463
+ await session.send(`PK失败,当前区域未存在【${goal}】玩家`);
1464
+ return;
1465
+ }
1466
+ if (BattleData.isTeamByUserId(exist.userId)) {
1467
+ const teamItem = BattleData.teamListByUser(exist.userId);
1468
+ await session.send(`对方有组队,您将扮演攻击方与对方队伍进行战斗。`);
1469
+ await BattleData.createBattleByUser(session, teamItem.map((item) => ({ userId: item.userId })));
1470
+ } else {
1471
+ await session.send(`您将扮演攻击方与对方进行战斗。`);
1472
+ await BattleData.createBattleByUser(session, [{ userId: exist.userId }]);
1473
+ }
1474
+ });
1475
+ ctx.command("技能查询 <goal>").action(async ({ session }, goal) => {
1476
+ if (!goal) return `请输入技能名,例如 /技能查询 重砍`;
1477
+ if (!skillFn[goal]) return `没有存在 ${goal} 技能!`;
1478
+ return `[${goal}]信息如下:
1479
+ ` + skillFn[goal].info;
1480
+ });
1237
1481
  }
1238
1482
  __name(apply, "apply");
1239
1483
  // Annotate the CommonJS export names for ESM import in node:
package/lib/map.d.ts CHANGED
@@ -98,6 +98,11 @@ export declare const GensokyoMap: {
98
98
  setLocalStoragePoistionData(userId: string): Promise<void>;
99
99
  /** 用户移动 */
100
100
  move(session: Session, type: MoveType, fn?: (area: AreaCallbackData) => Promise<void>): Promise<void>;
101
+ /** 查询附近玩家 */
102
+ nearbyPlayersByUserId(userId: string): {
103
+ userId: string;
104
+ playName: string;
105
+ }[];
101
106
  /** 区域信息格式化 */
102
107
  userAreaTextFormat(gameName: string, data: AreaCallbackData): string;
103
108
  };
@@ -0,0 +1,74 @@
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
+ interface DamageSkillParams {
11
+ /** 伤害类型 */
12
+ type: SkillType.伤害技;
13
+ /** 伤害信息 */
14
+ damage: DamageConfig;
15
+ /** 释放目标 */
16
+ target: BattleAttribute[];
17
+ /** 是否衔接普攻 */
18
+ isNext: boolean;
19
+ }
20
+ interface BuffSkillParams {
21
+ type: SkillType.增益技;
22
+ buffs: {
23
+ val: number;
24
+ time: number;
25
+ name: number;
26
+ }[];
27
+ target: BattleAttribute | BattleAttribute[];
28
+ /** 是否衔接普攻 */
29
+ isNext: boolean;
30
+ }
31
+ interface HealSkillParams {
32
+ type: SkillType.治疗技;
33
+ /** 是否衔接普攻 */
34
+ isNext: boolean;
35
+ }
36
+ interface UltimateSkillParams {
37
+ type: SkillType.奥义;
38
+ /** 是否衔接普攻 */
39
+ isNext: boolean;
40
+ }
41
+ interface ErrSkillParams {
42
+ type: SkillType.释放失败;
43
+ /** 是否衔接普攻 */
44
+ isNext: boolean;
45
+ /** 错误提示 */
46
+ err?: string;
47
+ }
48
+ type SkillParams = DamageSkillParams | BuffSkillParams | HealSkillParams | UltimateSkillParams | ErrSkillParams;
49
+ interface SkillConfig<T extends SkillType = SkillType> {
50
+ /** 技能名 */
51
+ name: string;
52
+ /** 技能类型 */
53
+ type: T;
54
+ /** 技能说明 */
55
+ info: string;
56
+ /** 消耗MP */
57
+ mp: number;
58
+ /** 技能函数 */
59
+ fn(agent: {
60
+ self: BattleAttribute;
61
+ goal: BattleAttribute;
62
+ }, agentList: {
63
+ selfList: BattleAttribute[];
64
+ goalList: BattleAttribute[];
65
+ }, cb?: (val: Extract<SkillParams, {
66
+ type: T;
67
+ }>) => void): string;
68
+ }
69
+ type SkillFn = {
70
+ [key: string]: SkillConfig;
71
+ };
72
+ export type UseAtkType = keyof typeof skillFn | '普攻';
73
+ export declare const skillFn: SkillFn;
74
+ export {};
package/lib/test.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ declare const nameList: {
2
+ 张三: {};
3
+ 李四: {};
4
+ };
5
+ declare const fn: (name: any) => any;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-smmcat-gensokyo",
3
3
  "description": "名为《幻想乡》的文字冒险游戏",
4
- "version": "0.0.3",
4
+ "version": "0.0.5",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [