koishi-plugin-maple-warriors 0.0.2 → 0.0.3

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.
Files changed (2) hide show
  1. package/lib/index.js +57 -53
  2. package/package.json +1 -1
package/lib/index.js CHANGED
@@ -34,13 +34,13 @@ var DEFAULT_PREY_DATA = [
34
34
  "野兔 1 3-5 2-4 2-4 1-3 5-50"
35
35
  ];
36
36
  var Config = import_koishi.Schema.object({
37
- preyData: import_koishi.Schema.array(import_koishi.Schema.string()).role("table").default(DEFAULT_PREY_DATA).description("猎物数据,每行格式:猎物名 权重 体质 攻击 韧性 暴击 敏捷(权重是固定数值,属性可以是固定数值或范围,如1-10)"),
37
+ preyData: import_koishi.Schema.array(import_koishi.Schema.string()).role("table").default(DEFAULT_PREY_DATA).description("猎物数据,每行格式:猎物名 权重 体质 攻击 防御 暴击 敏捷(权重是固定数值,属性可以是固定数值或范围,如1-10)"),
38
38
  battleMessageInterval: import_koishi.Schema.number().min(1).max(5).default(2).description("战斗消息发送间隔(秒)")
39
39
  });
40
40
  function calculateRates(character) {
41
41
  const resistance = (character.toughness / (character.toughness + 90)).toFixed(4);
42
42
  const critRate = (character.crit / (character.crit + 90)).toFixed(4);
43
- const chargeTime = (1 + 280 / (character.agility + 70)).toFixed(2);
43
+ const chargeTime = (1 + 720 / (character.agility + 80)).toFixed(2);
44
44
  const dodgeRate = (0.2 * character.agility / (character.agility + 90)).toFixed(4);
45
45
  return { resistance, critRate, chargeTime, dodgeRate };
46
46
  }
@@ -233,7 +233,7 @@ function apply(ctx, config) {
233
233
  等级: ${character.level}
234
234
  体质: ${character.constitution} (HP: ${character.currentHp}/${character.maxHp})
235
235
  攻击: ${character.attack}
236
- 韧性: ${character.toughness} (抗性: ${(parseFloat(rates.resistance) * 100).toFixed(2)}%)
236
+ 防御: ${character.toughness} (韧性: ${(parseFloat(rates.resistance) * 100).toFixed(2)}%)
237
237
  暴击: ${character.crit} (暴击率: ${(parseFloat(rates.critRate) * 100).toFixed(2)}%)
238
238
  敏捷: ${character.agility} (蓄力: ${rates.chargeTime}s 闪避率: ${(parseFloat(rates.dodgeRate) * 100).toFixed(2)}%)
239
239
  状态: ${character.status}${character.statusEndTime ? " 剩余" + formatRemainingTime(character.statusEndTime) : ""}
@@ -300,7 +300,7 @@ ${itemsText || "空空如也"}`;
300
300
  }
301
301
  __name(checkCharacterStatus, "checkCharacterStatus");
302
302
  ctx.command("猫武士", "猫武士插件 - 帮助菜单");
303
- ctx.command("猫武士/修改名字 <name>", "修改角色名字").example("修改名字 火焰猫").example("修改名字 闪电虎").action(async ({ session }, name2) => {
303
+ ctx.command("猫武士/修改名字 <name>", "修改角色名字").example("修改名字 火星").action(async ({ session }, name2) => {
304
304
  if (!name2 || name2.trim().length === 0) {
305
305
  return "格式错误!正确格式:修改名字 角色名";
306
306
  }
@@ -343,27 +343,26 @@ ${itemsText || "空空如也"}`;
343
343
  let character = await getOrCreateCharacter(userId);
344
344
  return await formatCharacterInfo(character);
345
345
  });
346
- ctx.command("猫武士/训练 <attrs>", "训练提升属性").example("训练 体质 体质 攻击").example("训练 体质").example("训练 随机").action(async ({ session }, attrs) => {
346
+ ctx.command("猫武士/训练 <...args>", "训练提升属性").example("训练 体质 体质 攻击").example("训练 体质").example("训练 随机").action(async ({ session }, ...args) => {
347
347
  const userId = session.userId;
348
348
  let character = await getOrCreateCharacter(userId);
349
- const statusCheck = checkCharacterStatus(character);
350
- if (!statusCheck.canAct) {
351
- return statusCheck.message;
352
- }
353
349
  const today = getTodayDateString();
354
350
  if (character.lastTrainDate && isSameDay(character.lastTrainDate, today)) {
355
351
  return "今天已经训练过了,要注意劳逸结合哦!";
356
352
  }
357
- if (!attrs) {
353
+ const statusCheck = checkCharacterStatus(character);
354
+ if (!statusCheck.canAct) {
355
+ return statusCheck.message;
356
+ }
357
+ if (args.length === 0) {
358
358
  return "格式错误!正确格式:训练 属性1 属性2 属性3(可重复,若只指定一项,则其余两项随机提升)或 训练 随机";
359
359
  }
360
- const attrList = attrs.trim().split(/\s+/);
361
- if (attrList.length === 1 && attrList[0] === "随机") {
362
- const validAttrs2 = ["体质", "攻击", "韧性", "暴击", "敏捷"];
360
+ if (args.length === 1 && args[0] === "随机") {
361
+ const validAttrs2 = ["体质", "攻击", "防御", "暴击", "敏捷"];
363
362
  const attrMap2 = {
364
363
  "体质": "constitution",
365
364
  "攻击": "attack",
366
- "韧性": "toughness",
365
+ "防御": "toughness",
367
366
  "暴击": "crit",
368
367
  "敏捷": "agility"
369
368
  };
@@ -385,30 +384,30 @@ ${itemsText || "空空如也"}`;
385
384
  return `训练成功!你好像领悟了什么……
386
385
  ${changes2.join(" ")}`;
387
386
  }
388
- if (attrList.length > 3) {
387
+ if (args.length > 3) {
389
388
  return "只能指定3个属性(可以重复),不要太贪心哦!";
390
389
  }
391
- const validAttrs = ["体质", "攻击", "韧性", "暴击", "敏捷"];
390
+ const validAttrs = ["体质", "攻击", "防御", "暴击", "敏捷"];
392
391
  const attrMap = {
393
392
  "体质": "constitution",
394
393
  "攻击": "attack",
395
- "韧性": "toughness",
394
+ "防御": "toughness",
396
395
  "暴击": "crit",
397
396
  "敏捷": "agility"
398
397
  };
399
- for (const attr of attrList) {
398
+ for (const attr of args) {
400
399
  if (!validAttrs.includes(attr)) {
401
400
  return `属性名错误!有效的属性有:${validAttrs.join("、")}`;
402
401
  }
403
402
  }
404
403
  const updates = {};
405
404
  const attributeCounts = {};
406
- for (const attr of attrList) {
405
+ for (const attr of args) {
407
406
  const field = attrMap[attr];
408
407
  updates[field] = (updates[field] || character[field] || 0) + 1;
409
408
  attributeCounts[attr] = (attributeCounts[attr] || 0) + 1;
410
409
  }
411
- for (let i = 0; i < 3 - attrList.length; i++) {
410
+ for (let i = 0; i < 3 - args.length; i++) {
412
411
  const randomAttr = validAttrs[Math.floor(Math.random() * validAttrs.length)];
413
412
  const field = attrMap[randomAttr];
414
413
  updates[field] = (updates[field] || character[field] || 0) + 1;
@@ -450,7 +449,7 @@ ${changes.join(" ")}`;
450
449
  const crit = parseAttributeRange(selectedPrey.crit);
451
450
  const agility = parseAttributeRange(selectedPrey.agility);
452
451
  const preyHp = constitution * 5;
453
- const chargeTime = parseFloat((1 + 280 / (agility + 70)).toFixed(2));
452
+ const chargeTime = parseFloat((1 + 720 / (agility + 80)).toFixed(2));
454
453
  const prey = {
455
454
  name: selectedPrey.name,
456
455
  constitution,
@@ -474,7 +473,7 @@ ${changes.join(" ")}`;
474
473
  await session.send(`发现猎物: ${prey.name}
475
474
  体质: ${prey.constitution} (HP: ${prey.hp})
476
475
  攻击: ${prey.attack}
477
- 韧性: ${prey.toughness} (抗性: ${(parseFloat(preyRates.resistance) * 100).toFixed(2)}%)
476
+ 防御: ${prey.toughness} (韧性: ${(parseFloat(preyRates.resistance) * 100).toFixed(2)}%)
478
477
  暴击: ${prey.crit} (暴击率: ${(parseFloat(preyRates.critRate) * 100).toFixed(2)}%)
479
478
  敏捷: ${prey.agility} (蓄力: ${preyRates.chargeTime}s 闪避率: ${(parseFloat(preyRates.dodgeRate) * 100).toFixed(2)}%)`);
480
479
  await new Promise((resolve) => setTimeout(resolve, 2e3));
@@ -489,7 +488,7 @@ ${changes.join(" ")}`;
489
488
  agility: character.agility,
490
489
  hp: character.currentHp,
491
490
  maxHp: character.maxHp,
492
- chargeTime: parseFloat((1 + 280 / (character.agility + 70)).toFixed(2)),
491
+ chargeTime: parseFloat((1 + 720 / (character.agility + 80)).toFixed(2)),
493
492
  nextAttackTime: 0
494
493
  };
495
494
  await executeBattle(
@@ -517,6 +516,7 @@ ${changes.join(" ")}`;
517
516
  const items = parseItemsString(character.items);
518
517
  items[selectedPrey.name] = (items[selectedPrey.name] || 0) + 1;
519
518
  updates.items = serializeItems(items);
519
+ await session.send(`捕猎成功!获得物品 ${selectedPrey.name}*1`);
520
520
  }
521
521
  }
522
522
  await ctx.database.set("maple_warriors", { userId }, updates);
@@ -593,7 +593,7 @@ ${changes.join(" ")}`;
593
593
  }
594
594
  if (item.toughnessBonus) {
595
595
  updates.toughness = character.toughness + item.toughnessBonus * count;
596
- changes.push(`韧性+${item.toughnessBonus * count}`);
596
+ changes.push(`防御+${item.toughnessBonus * count}`);
597
597
  }
598
598
  if (item.critBonus) {
599
599
  updates.crit = character.crit + item.critBonus * count;
@@ -663,6 +663,7 @@ ${changes.join(" ")}`;
663
663
  });
664
664
  }
665
665
  battleManager.endBattle(channelId);
666
+ return;
666
667
  } else {
667
668
  return "当前没有正在进行的战斗。";
668
669
  }
@@ -697,7 +698,7 @@ ${changes.join(" ")}`;
697
698
  if (item.hpBonus) bonuses.push(`HP+${item.hpBonus}`);
698
699
  if (item.constitutionBonus) bonuses.push(`体质+${item.constitutionBonus}`);
699
700
  if (item.attackBonus) bonuses.push(`攻击+${item.attackBonus}`);
700
- if (item.toughnessBonus) bonuses.push(`韧性+${item.toughnessBonus}`);
701
+ if (item.toughnessBonus) bonuses.push(`防御+${item.toughnessBonus}`);
701
702
  if (item.critBonus) bonuses.push(`暴击+${item.critBonus}`);
702
703
  if (item.agilityBonus) bonuses.push(`敏捷+${item.agilityBonus}`);
703
704
  let result = `物品: ${item.name}
@@ -710,7 +711,7 @@ ${changes.join(" ")}`;
710
711
  }
711
712
  return result.trim();
712
713
  });
713
- ctx.command("猫武士/添加物品 <...args>", "添加或修改物品").example("添加物品 老鼠 体质 1 很常见的老鼠").example("添加物品 治疗药水 hp 10 恢复生命值").action(async ({ session }, ...args) => {
714
+ ctx.command("猫武士/添加物品 <...args>", "添加或修改物品").example("添加物品 老鼠 hp 1 很常见的老鼠").example("添加物品 治疗药水 hp 10 恢复生命值").action(async ({ session }, ...args) => {
714
715
  if (args.length < 1) {
715
716
  return "格式错误!正确格式:添加物品 物品名 [属性 增加数 ...] [介绍]";
716
717
  }
@@ -725,13 +726,13 @@ ${changes.join(" ")}`;
725
726
  agilityBonus: 0
726
727
  };
727
728
  let i = 1;
728
- const validAttrs = ["HP", "hp", "体质", "攻击", "韧性", "暴击", "敏捷"];
729
+ const validAttrs = ["HP", "hp", "体质", "攻击", "防御", "暴击", "敏捷"];
729
730
  const attrMap = {
730
731
  "HP": "hpBonus",
731
732
  "hp": "hpBonus",
732
733
  "体质": "constitutionBonus",
733
734
  "攻击": "attackBonus",
734
- "韧性": "toughnessBonus",
735
+ "防御": "toughnessBonus",
735
736
  "暴击": "critBonus",
736
737
  "敏捷": "agilityBonus"
737
738
  };
@@ -760,7 +761,7 @@ ${changes.join(" ")}`;
760
761
  if (fieldName) {
761
762
  updates[fieldName] = value;
762
763
  } else {
763
- return `属性名错误!有效的属性有:${["HP", "体质", "攻击", "韧性", "暴击", "敏捷"].join("、")}`;
764
+ return `属性名错误!有效的属性有:${["HP", "体质", "攻击", "防御", "暴击", "敏捷"].join("、")}`;
764
765
  }
765
766
  i += 2;
766
767
  }
@@ -771,7 +772,7 @@ ${changes.join(" ")}`;
771
772
  description,
772
773
  createdAt: /* @__PURE__ */ new Date()
773
774
  });
774
- return `修改${itemName}成功!`;
775
+ return `修改物品成功!`;
775
776
  } else {
776
777
  await ctx.database.create("maple_warriors_items", {
777
778
  name: itemName,
@@ -779,7 +780,7 @@ ${changes.join(" ")}`;
779
780
  description,
780
781
  createdAt: /* @__PURE__ */ new Date()
781
782
  });
782
- return `添加${itemName}成功!`;
783
+ return `添加物品成功!`;
783
784
  }
784
785
  });
785
786
  ctx.command("猫武士/物品列表 [page]", "查看物品列表").example("物品列表").example("物品列表 2").action(async ({ session }, page = "1") => {
@@ -819,13 +820,18 @@ ${changes.join(" ")}`;
819
820
  ctx.command("猫武士/战斗训练 <target:user>", "与指定用户的角色进行训练战斗(不消耗HP)").example("战斗训练 @火星").action(async ({ session }, target) => {
820
821
  const channelId = session.channelId;
821
822
  const userId = session.userId;
823
+ let targetUserId = target;
824
+ if (target.includes(":")) {
825
+ const parts = target.split(":");
826
+ targetUserId = parts[parts.length - 1];
827
+ }
822
828
  if (battleManager.isBattling(channelId)) {
823
829
  return "请等待当前战斗结束!";
824
830
  }
825
- if (!target) {
831
+ if (!targetUserId) {
826
832
  return "请指定训练对手!正确格式:战斗训练 @用户名";
827
833
  }
828
- if (target === userId) {
834
+ if (targetUserId === userId) {
829
835
  return "不能和自己进行战斗训练哦!";
830
836
  }
831
837
  let player1 = await getOrCreateCharacter(userId);
@@ -833,7 +839,11 @@ ${changes.join(" ")}`;
833
839
  if (!statusCheck.canAct) {
834
840
  return statusCheck.message;
835
841
  }
836
- let player2 = await getOrCreateCharacter(target);
842
+ let player2Characters = await ctx.database.get("maple_warriors", { userId: targetUserId });
843
+ if (player2Characters.length === 0) {
844
+ return "战斗失败!对方尚未生成角色";
845
+ }
846
+ let player2 = player2Characters[0];
837
847
  const opponentStatusCheck = checkCharacterStatus(player2);
838
848
  if (!opponentStatusCheck.canAct) {
839
849
  return `对手目前状态不佳,无法进行战斗训练:${opponentStatusCheck.message}`;
@@ -851,7 +861,7 @@ ${changes.join(" ")}`;
851
861
  hp: player1.currentHp,
852
862
  // 使用当前HP
853
863
  maxHp: player1.maxHp,
854
- chargeTime: parseFloat((1 + 280 / (player1.agility + 70)).toFixed(2)),
864
+ chargeTime: parseFloat((1 + 720 / (player1.agility + 80)).toFixed(2)),
855
865
  nextAttackTime: 0
856
866
  };
857
867
  const player2Char = {
@@ -864,7 +874,7 @@ ${changes.join(" ")}`;
864
874
  hp: player2.currentHp,
865
875
  // 使用当前HP
866
876
  maxHp: player2.maxHp,
867
- chargeTime: parseFloat((1 + 280 / (player2.agility + 70)).toFixed(2)),
877
+ chargeTime: parseFloat((1 + 720 / (player2.agility + 80)).toFixed(2)),
868
878
  nextAttackTime: 0
869
879
  };
870
880
  const abortController = battleManager.getAbortController(channelId);
@@ -911,8 +921,8 @@ ${changes.join(" ")}`;
911
921
  }
912
922
  __name(apply, "apply");
913
923
  async function executeBattle(session, player1, player2, battleMessageInterval, isTraining = false, abortController) {
914
- const originalHp1 = player1.hp;
915
- const originalHp2 = player2.hp;
924
+ const initialHp1 = player1.hp;
925
+ const initialHp2 = player2.hp;
916
926
  const rates1 = calculateRates({
917
927
  toughness: player1.toughness,
918
928
  crit: player1.crit,
@@ -966,21 +976,18 @@ async function executeBattle(session, player1, player2, battleMessageInterval, i
966
976
  }
967
977
  const baseDamage = attacker.attack * (0.5 + Math.random());
968
978
  let initialDamage = Math.ceil(baseDamage);
969
- let totalDamage = initialDamage;
970
979
  const attackerCritRate = attacker === player1 ? critRate1 : critRate2;
971
980
  let isCritical = false;
972
981
  if (Math.random() < attackerCritRate) {
973
- totalDamage *= 2;
982
+ initialDamage *= 2;
974
983
  isCritical = true;
975
984
  battleMessage += ` 暴击!`;
976
985
  }
986
+ battleMessage += ` 造成了${initialDamage}点伤害。`;
977
987
  const reduceAmount = defender.toughness * Math.random();
978
- const reducedDamage = Math.min(Math.ceil(reduceAmount), totalDamage);
979
- const finalDamage = totalDamage - reducedDamage;
988
+ const reducedDamage = Math.min(Math.ceil(reduceAmount), initialDamage);
989
+ const finalDamage = initialDamage - reducedDamage;
980
990
  if (finalDamage <= 0) {
981
- if (isCritical) {
982
- battleMessage += ` 造成了${totalDamage}点伤害。`;
983
- }
984
991
  battleMessage += ` 被${defender.name}抵挡住了!`;
985
992
  await session.send(battleMessage);
986
993
  currentTime = attackTime;
@@ -988,11 +995,6 @@ async function executeBattle(session, player1, player2, battleMessageInterval, i
988
995
  }
989
996
  defender.hp -= finalDamage;
990
997
  if (defender.hp < 0) defender.hp = 0;
991
- if (isCritical) {
992
- battleMessage += ` 造成了${totalDamage}点伤害。`;
993
- } else {
994
- battleMessage += ` 造成了${initialDamage}点伤害。`;
995
- }
996
998
  battleMessage += ` ${defender.name}抵挡了${reducedDamage}点伤害,实际造成${finalDamage}点伤害。${defender.name} HP: ${defender.hp}`;
997
999
  await session.send(battleMessage);
998
1000
  if (defender.hp <= 0) {
@@ -1002,10 +1004,12 @@ async function executeBattle(session, player1, player2, battleMessageInterval, i
1002
1004
  currentTime = attackTime;
1003
1005
  }
1004
1006
  if (currentTime > maxBattleTime && player1.hp > 0 && player2.hp > 0) {
1005
- if (player1.hp > player2.hp) {
1006
- await session.send(`战斗超时!${player1.name} 剩余HP更高,获得胜利!`);
1007
+ const player1Loss = initialHp1 - player1.hp;
1008
+ const player2Loss = initialHp2 - player2.hp;
1009
+ if (player1Loss < player2Loss) {
1010
+ await session.send(`战斗超时!${player1.name} 损失HP较少,获得胜利!`);
1007
1011
  } else if (player2.hp > player1.hp) {
1008
- await session.send(`战斗超时!${player2.name} 剩余HP更高,获得胜利!`);
1012
+ await session.send(`战斗超时!${player2.name} 损失HP较少,获得胜利!`);
1009
1013
  } else {
1010
1014
  await session.send(`战斗超时!双方平局!`);
1011
1015
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-maple-warriors",
3
3
  "description": "-",
4
- "version": "0.0.2",
4
+ "version": "0.0.3",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [