添加地图自动化模拟和新技能

This commit is contained in:
milimoe 2026-01-05 01:31:05 +08:00
parent f2dad7f1b7
commit 3119b3a4c5
Signed by: milimoe
GPG Key ID: 9554D37E4B8991D0
15 changed files with 319 additions and 24 deletions

View File

@ -1,5 +1,6 @@
using Milimoe.FunGame.Core.Interface.Base; using Milimoe.FunGame.Core.Interface.Base;
using Milimoe.FunGame.Core.Library.Common.Addon; using Milimoe.FunGame.Core.Library.Common.Addon;
using Milimoe.FunGame.Core.Model;
using Oshima.Core.Constant; using Oshima.Core.Constant;
namespace Oshima.FunGame.OshimaMaps namespace Oshima.FunGame.OshimaMaps
@ -14,11 +15,11 @@ namespace Oshima.FunGame.OshimaMaps
public override string Author => OshimaGameModuleConstant.Author; public override string Author => OshimaGameModuleConstant.Author;
public override int Length => 6; public override int Length => 9;
public override int Width => 6; public override int Width => 9;
public override int Height => 3; public override int Height => 1;
public override float Size => 6; public override float Size => 6;
@ -26,7 +27,18 @@ namespace Oshima.FunGame.OshimaMaps
{ {
GameMap map = new FastAutoMap(); GameMap map = new FastAutoMap();
map.Load(); map.Load();
if (queue is GamingQueue gq)
{
gq.WriteLine($"地图 {map.Name} 已加载。");
}
return map; return map;
} }
protected override void AfterTimeElapsed(ref double timeToReduce)
{
}
} }
} }

View File

@ -71,8 +71,13 @@ namespace Oshima.FunGame.OshimaModules.Effects.SkillEffects
e = new (Skill, caster, target, _durative, duration, durationTurn); e = new (Skill, caster, target, _durative, duration, durationTurn);
break; break;
case EffectType.Delay: case EffectType.Delay:
WriteLine($"[ {caster} ] 对 [ {target} ] 造成了迟滞!持续时间:{持续时间}"); double healingReductionPercent = 0.3;
e = new (Skill, caster, _durative, duration, durationTurn); if (_args.Length > 0 && _args[0] is double healingReduce)
{
healingReductionPercent = healingReduce;
}
WriteLine($"[ {caster} ] 对 [ {target} ] 造成了迟滞!普通攻击和技能的硬直时间、当前行动等待时间延长了 {healingReductionPercent * 100:0.##}%!持续时间:{持续时间}");
e = new (Skill, caster, _durative, duration, durationTurn, healingReductionPercent);
break; break;
case EffectType.Stun: case EffectType.Stun:
WriteLine($"[ {caster} ] 对 [ {target} ] 造成了眩晕!持续时间:{持续时间}"); WriteLine($"[ {caster} ] 对 [ {target} ] 造成了眩晕!持续时间:{持续时间}");
@ -166,8 +171,13 @@ namespace Oshima.FunGame.OshimaModules.Effects.SkillEffects
_description = "愤怒:进入行动受限状态,失控并随机行动,行动回合内仅能对嘲讽者发起普通攻击。"; _description = "愤怒:进入行动受限状态,失控并随机行动,行动回合内仅能对嘲讽者发起普通攻击。";
break; break;
case EffectType.Delay: case EffectType.Delay:
double healingReductionPercent = 0.3;
if (_args.Length > 0 && _args[0] is double healingReduce)
{
healingReductionPercent = healingReduce;
}
_dispelledType = DispelledType.Weak; _dispelledType = DispelledType.Weak;
_description = "迟滞:延长普通攻击和技能的硬直时间、当前行动等待时间。"; _description = $"迟滞:普通攻击和技能的硬直时间、当前行动等待时间延长 {healingReductionPercent * 100:0.##}%。";
break; break;
case EffectType.Stun: case EffectType.Stun:
_dispelledType = DispelledType.Strong; _dispelledType = DispelledType.Strong;

View File

@ -107,6 +107,9 @@ namespace Oshima.FunGame.OshimaModules
(long)SkillID. => new (), (long)SkillID. => new (),
(long)SkillID. => new (), (long)SkillID. => new (),
(long)SkillID. => new (), (long)SkillID. => new (),
(long)SkillID. => new (),
(long)SkillID. => new (),
(long)SkillID. => new (),
(long)SuperSkillID. => new (), (long)SuperSkillID. => new (),
(long)SuperSkillID. => new (), (long)SuperSkillID. => new (),
(long)SuperSkillID. => new (), (long)SuperSkillID. => new (),

View File

@ -10,8 +10,8 @@ namespace Oshima.FunGame.OshimaModules.Skills
public override string Description => Effects.Count > 0 ? Effects.First().Description : ""; public override string Description => Effects.Count > 0 ? Effects.First().Description : "";
public override string DispelDescription => Effects.Count > 0 ? Effects.First().DispelDescription : ""; public override string DispelDescription => Effects.Count > 0 ? Effects.First().DispelDescription : "";
public override double EPCost => 100; public override double EPCost => 100;
public override double CD => 45; public override double CD => 55;
public override double HardnessTime { get; set; } = 5; public override double HardnessTime { get; set; } = 7;
public override bool CanSelectSelf => true; public override bool CanSelectSelf => true;
public override bool CanSelectEnemy => false; public override bool CanSelectEnemy => false;

View File

@ -1,5 +1,6 @@
using Milimoe.FunGame.Core.Entity; using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Library.Constant; using Milimoe.FunGame.Core.Library.Constant;
using Milimoe.FunGame.Core.Model;
namespace Oshima.FunGame.OshimaModules.Skills namespace Oshima.FunGame.OshimaModules.Skills
{ {
@ -24,12 +25,12 @@ namespace Oshima.FunGame.OshimaModules.Skills
{ {
public override long Id => Skill.Id; public override long Id => Skill.Id;
public override string Name => Skill.Name; public override string Name => Skill.Name;
public override string Description => $"每释放 {触发硬直次数:0.##} 次魔法才会触发硬直时间,且魔法伤害命中时基于 15% 智力 [ {获得额外能量值:0.##} ] 获得额外能量值,并减少所有技能 2 {GameplayEquilibriumConstant.InGameTime}冷却时间。"; public override string Description => $"每释放 {触发硬直次数:0.##} 次魔法才会触发硬直时间,且魔法伤害命中时基于 8% 智力 [ {获得额外能量值:0.##} ] 获得额外能量值,并减少所有技能 2 {GameplayEquilibriumConstant.InGameTime}冷却时间。";
public bool { get; set; } = false; public bool { get; set; } = false;
public int { get; set; } = 2; public int { get; set; } = 2;
public int { get; set; } = 0; public int { get; set; } = 0;
public double => 0.15 * Skill.Character?.INT ?? 0; public double => 0.08 * Skill.Character?.INT ?? 0;
public override void AfterDamageCalculation(Character character, Character enemy, double damage, double actualDamage, bool isNormalAttack, DamageType damageType, MagicType magicType, DamageResult damageResult) public override void AfterDamageCalculation(Character character, Character enemy, double damage, double actualDamage, bool isNormalAttack, DamageType damageType, MagicType magicType, DamageResult damageResult)
{ {
@ -81,6 +82,11 @@ namespace Oshima.FunGame.OshimaModules.Skills
baseHardnessTime = 0; baseHardnessTime = 0;
isCheckProtected = false; isCheckProtected = false;
WriteLine($"[ {character} ] 发动了灵能反射,消除了硬直时间!!"); WriteLine($"[ {character} ] 发动了灵能反射,消除了硬直时间!!");
if (GamingQueue != null && GamingQueue.CharacterDecisionPoints.TryGetValue(character, out DecisionPoints? dp) && dp != null)
{
dp.ActionsTaken = 1;
dp.ActionsHardnessTime.Clear();
}
} }
else else
{ {
@ -91,6 +97,11 @@ namespace Oshima.FunGame.OshimaModules.Skills
baseHardnessTime = 0; baseHardnessTime = 0;
isCheckProtected = false; isCheckProtected = false;
WriteLine($"[ {character} ] 发动了灵能反射,消除了硬直时间!!"); WriteLine($"[ {character} ] 发动了灵能反射,消除了硬直时间!!");
if (GamingQueue != null && GamingQueue.CharacterDecisionPoints.TryGetValue(character, out DecisionPoints? dp) && dp != null)
{
dp.ActionsTaken = 1;
dp.ActionsHardnessTime.Clear();
}
e.--; e.--;
if (e. == 0) if (e. == 0)
{ {

View File

@ -8,6 +8,7 @@ namespace Oshima.FunGame.OshimaModules.Skills
public override long Id => (long)PassiveID.; public override long Id => (long)PassiveID.;
public override string Name => "敏捷之刃"; public override string Name => "敏捷之刃";
public override string Description => Effects.Count > 0 ? Effects.First().Description : ""; public override string Description => Effects.Count > 0 ? Effects.First().Description : "";
public override double CD => 5;
public (Character? character = null) : base(SkillType.Passive, character) public (Character? character = null) : base(SkillType.Passive, character)
{ {
@ -24,16 +25,18 @@ namespace Oshima.FunGame.OshimaModules.Skills
{ {
public override long Id => Skill.Id; public override long Id => Skill.Id;
public override string Name => Skill.Name; public override string Name => Skill.Name;
public override string Description => $"每次普通攻击都将附带基于 {敏捷系数 * 100:0.##}% 敏捷 [ {敏捷伤害:0.##} ] 点魔法伤害。"; public override string Description => $"普通攻击命中后,附带基于 {敏捷系数 * 100:0.##}% 敏捷 [ {敏捷伤害:0.##} ] 点魔法伤害,可叠加普攻特效。每 {Skill.CD:0.##} {GameplayEquilibriumConstant.InGameTime}仅能触发一次。";
private double => * Skill.Character?.AGI ?? 0; private double => * Skill.Character?.AGI ?? 0;
private readonly double = 2.5;
private readonly double = 2;
private bool = false; private bool = false;
public override void AfterDamageCalculation(Character character, Character enemy, double damage, double actualDamage, bool isNormalAttack, DamageType damageType, MagicType magicType, DamageResult damageResult) public override void AfterDamageCalculation(Character character, Character enemy, double damage, double actualDamage, bool isNormalAttack, DamageType damageType, MagicType magicType, DamageResult damageResult)
{ {
if (character == Skill.Character && isNormalAttack && (damageResult == DamageResult.Normal || damageResult == DamageResult.Critical) && ! && enemy.HP > 0) if (character == Skill.Character && isNormalAttack && (damageResult == DamageResult.Normal || damageResult == DamageResult.Critical) && ! && enemy.HP > 0)
{ {
Skill.CurrentCD = Skill.CD;
WriteLine($"[ {character} ] 发动了敏捷之刃!将造成额外伤害!"); WriteLine($"[ {character} ] 发动了敏捷之刃!将造成额外伤害!");
= true; = true;
DamageToEnemy(character, enemy, DamageType.Magical, magicType, ); DamageToEnemy(character, enemy, DamageType.Magical, magicType, );

View File

@ -25,7 +25,7 @@ namespace Oshima.FunGame.OshimaModules.Skills
{ {
public override long Id => Skill.Id; public override long Id => Skill.Id;
public override string Name => Skill.Name; public override string Name => Skill.Name;
public override string Description => $"进入不可选中状态,获得 100 行动速度,提高 8% 暴击率,持续 {Duration:0.##} {GameplayEquilibriumConstant.InGameTime}。破隐一击:在持续时间内,首次造成伤害会附加 {系数 * 100:0.##}% 敏捷 [ {伤害加成:0.##} ] 的强化伤害,并解除不可选中状态。"; public override string Description => $"进入不可选中状态,获得 100 行动速度,提高 8% 暴击率,持续 {Duration:0.##} {GameplayEquilibriumConstant.InGameTime}。不可选中:无法成为任何目标且免疫场地伤害。破隐一击:在持续时间内,首次造成伤害会附加 {系数 * 100:0.##}% 敏捷 [ {伤害加成:0.##} ] 的强化伤害,并解除不可选中状态。";
public override string DispelDescription => "被驱散性:不可选中状态生效期间,此技能不可驱散,否则可弱驱散"; public override string DispelDescription => "被驱散性:不可选中状态生效期间,此技能不可驱散,否则可弱驱散";
public override EffectType EffectType => EffectType.Unselectable; public override EffectType EffectType => EffectType.Unselectable;
public override bool Durative => true; public override bool Durative => true;

View File

@ -8,15 +8,17 @@ namespace Oshima.FunGame.OshimaModules.Skills
{ {
public override long Id => (long)SkillID.; public override long Id => (long)SkillID.;
public override string Name => "绝影"; public override string Name => "绝影";
public override string Description => Effects.Count > 0 ? Effects.First().Description : ""; public override string Description => string.Join("", Effects.Select(e => e.Description));
public override string DispelDescription => Effects.Count > 0 ? Effects.First().DispelDescription : ""; public override string DispelDescription => Effects.Count > 0 ? Effects.First(e => e is ).DispelDescription : "";
public override double EPCost => 45; public override double EPCost => 60;
public override double CD => 12; public override double CD => 18;
public override double HardnessTime { get; set; } = 7; public override double HardnessTime { get; set; } = 7;
public (Character? character = null) : base(SkillType.Skill, character) public (Character? character = null) : base(SkillType.Skill, character)
{ {
Effects.Add(new _带基础伤害(this, 75, 70, 0.075, 0.055, DamageType.Physical)); CastRange = 6;
Effects.Add(new _带基础伤害(this, 70, 55, 0.095, 0.045, DamageType.Physical));
Effects.Add(new (this, EffectType.Delay, true, 15, 0, 0, 1, 0, 0.3));
} }
} }
} }

View File

@ -0,0 +1,24 @@
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Library.Constant;
using Oshima.FunGame.OshimaModules.Effects.SkillEffects;
namespace Oshima.FunGame.OshimaModules.Skills
{
public class : Skill
{
public override long Id => (long)SkillID.;
public override string Name => "胧";
public override string Description => string.Join("", Effects.Select(e => e.Description));
public override string DispelDescription => Effects.Count > 0 ? Effects.First(e => e is ).DispelDescription : "";
public override double EPCost => 60;
public override double CD => 20;
public override double HardnessTime { get; set; } = 9;
public (Character? character = null) : base(SkillType.Skill, character)
{
CastRange = 4;
Effects.Add(new _带基础伤害(this, 60, 45, 0.065, 0.035, DamageType.Physical));
Effects.Add(new (this, EffectType.Cripple, false, 0, 1, 0, 0.45, 0.05));
}
}
}

View File

@ -0,0 +1,24 @@
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Library.Constant;
using Oshima.FunGame.OshimaModules.Effects.SkillEffects;
namespace Oshima.FunGame.OshimaModules.Skills
{
public class : Skill
{
public override long Id => (long)SkillID.;
public override string Name => "魔眼";
public override string Description => string.Join("", Effects.Select(e => e.Description));
public override string DispelDescription => "被驱散性:迟滞可弱驱散,混乱需强驱散";
public override double EPCost => 65;
public override double CD => 24;
public override double HardnessTime { get; set; } = 8;
public (Character? character = null) : base(SkillType.Skill, character)
{
CastRange = 2;
Effects.Add(new (this, EffectType.Delay, false, 0, 3, 0, 1, 0, 0.5));
Effects.Add(new (this, EffectType.Confusion, false, 0, 2, 0, 0.45, 0.05));
}
}
}

View File

@ -21,6 +21,7 @@
<ProjectReference Include="..\..\FunGame.Core\FunGame.Core.csproj" /> <ProjectReference Include="..\..\FunGame.Core\FunGame.Core.csproj" />
<ProjectReference Include="..\..\FunGame.Extension\FunGame.SQLQueryExtension\FunGame.SQLQueryExtension.csproj" /> <ProjectReference Include="..\..\FunGame.Extension\FunGame.SQLQueryExtension\FunGame.SQLQueryExtension.csproj" />
<ProjectReference Include="..\OshimaCore\OshimaCore.csproj" /> <ProjectReference Include="..\OshimaCore\OshimaCore.csproj" />
<ProjectReference Include="..\OshimaMaps\OshimaMaps.csproj" />
<ProjectReference Include="..\OshimaModules\OshimaModules.csproj" /> <ProjectReference Include="..\OshimaModules\OshimaModules.csproj" />
</ItemGroup> </ItemGroup>

View File

@ -46,7 +46,7 @@ namespace Oshima.FunGame.OshimaServers.Service
FunGameConstant.Characters.Add(new dddovo()); FunGameConstant.Characters.Add(new dddovo());
FunGameConstant.Characters.Add(new Quduoduo()); FunGameConstant.Characters.Add(new Quduoduo());
FunGameConstant.Skills.AddRange([new (), new (), new (), new (), new (), new (), new (), new ()]); FunGameConstant.Skills.AddRange([new (), new (), new (), new (), new (), new (), new (), new (), new (), new (), new ()]);
FunGameConstant.SuperSkills.AddRange([new (), new (), new (), new (), new (), new (), new (), new (), new (), new (), new (), new ()]); FunGameConstant.SuperSkills.AddRange([new (), new (), new (), new (), new (), new (), new (), new (), new (), new (), new (), new ()]);

View File

@ -3,8 +3,10 @@ using System.Text;
using System.Text.Json; using System.Text.Json;
using Milimoe.FunGame.Core.Api.Utility; using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Entity; using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Library.Common.Addon;
using Milimoe.FunGame.Core.Library.Constant; using Milimoe.FunGame.Core.Library.Constant;
using Milimoe.FunGame.Core.Model; using Milimoe.FunGame.Core.Model;
using Oshima.FunGame.OshimaMaps;
using Oshima.FunGame.OshimaModules.Effects.OpenEffects; using Oshima.FunGame.OshimaModules.Effects.OpenEffects;
using Oshima.FunGame.OshimaModules.Models; using Oshima.FunGame.OshimaModules.Models;
using Oshima.FunGame.OshimaModules.Skills; using Oshima.FunGame.OshimaModules.Skills;
@ -18,6 +20,7 @@ namespace Oshima.FunGame.OshimaServers.Service
public static PluginConfig StatsConfig { get; } = new("FunGameSimulation", nameof(CharacterStatistics)); public static PluginConfig StatsConfig { get; } = new("FunGameSimulation", nameof(CharacterStatistics));
public static PluginConfig TeamStatsConfig { get; } = new("FunGameSimulation", nameof(TeamCharacterStatistics)); public static PluginConfig TeamStatsConfig { get; } = new("FunGameSimulation", nameof(TeamCharacterStatistics));
public static PluginConfig LastRecordConfig { get; } = new("FunGameSimulation", "LastRecord"); public static PluginConfig LastRecordConfig { get; } = new("FunGameSimulation", "LastRecord");
public static GameMap Map { get; } = new FastAutoMap();
public static bool IsRuning { get; set; } = false; public static bool IsRuning { get; set; } = false;
public static bool IsWeb { get; set; } = false; public static bool IsWeb { get; set; } = false;
public static bool PrintOut { get; set; } = false; public static bool PrintOut { get; set; } = false;
@ -59,7 +62,7 @@ namespace Oshima.FunGame.OshimaServers.Service
} }
} }
public static async Task<List<string>> StartSimulationGame(bool printout, bool isWeb = false, bool isTeam = false, bool deathMatchRoundDetail = false, int maxRespawnTimesMix = 1, bool useStore = false) public static async Task<List<string>> StartSimulationGame(bool printout, bool isWeb = false, bool isTeam = false, bool deathMatchRoundDetail = false, int maxRespawnTimesMix = 1, bool useStore = false, bool hasMap = false)
{ {
PrintOut = printout; PrintOut = printout;
IsWeb = isWeb; IsWeb = isWeb;
@ -162,6 +165,8 @@ namespace Oshima.FunGame.OshimaServers.Service
}; };
actionQueue = mgq; actionQueue = mgq;
} }
if (hasMap) actionQueue.LoadGameMap(Map);
actionQueue.UseQueueProtected = false;
if (PrintOut) Console.WriteLine(); if (PrintOut) Console.WriteLine();
// 总游戏时长 // 总游戏时长
@ -267,9 +272,48 @@ namespace Oshima.FunGame.OshimaServers.Service
if (PrintOut) Console.WriteLine(); if (PrintOut) Console.WriteLine();
actionQueue.CharacterDeath += ActionQueue_CharacterDeath; actionQueue.CharacterDeath += ActionQueue_CharacterDeath;
if (actionQueue is TeamGamingQueue teamQueue)
// 地图放置角色
if (actionQueue.Map != null)
{ {
//teamQueue.GameEndTeam += TeamQueue_GameEndTeam; GameMap map = actionQueue.Map;
HashSet<Grid> allocated = [];
List<Grid> allGrids = [.. map.Grids.Values];
if (isTeam && tgq != null)
{
Team team1 = tgq.Teams.Values.First();
Team team2 = tgq.Teams.Values.Last();
// 团队模式放置角色
List<Character> team1Members = [.. team1.Members];
List<Character> team2Members = [.. team2.Members];
// 获取地图尺寸
int mapLength = map.Length;
int mapWidth = map.Width;
// 放置队伍一在左下角区域
PlaceTeamInCorner(actionQueue, map, team1Members, allocated, startX: 0, endX: mapLength / 4, startY: mapWidth * 3 / 4, endY: mapWidth - 1);
// 放置队伍二在右上角区域
PlaceTeamInCorner(actionQueue, map, team2Members, allocated, startX: mapLength * 3 / 4, endX: mapLength - 1, startY: 0, endY: mapWidth / 4);
}
else
{
// 非团队模式,随机放置角色
foreach (Character character in characters)
{
character.NormalAttack.GamingQueue = actionQueue;
Grid grid = Grid.Empty;
do
{
grid = allGrids[Random.Shared.Next(allGrids.Count)];
}
while (allocated.Contains(grid));
allocated.Add(grid);
map.SetCharacterCurrentGrid(character, grid);
}
}
} }
// 总回合数 // 总回合数
@ -1157,5 +1201,120 @@ namespace Oshima.FunGame.OshimaServers.Service
if (totalStats.ActionTurn != 0) totalStats.DamagePerTurn = Calculation.Round2Digits(totalStats.TotalDamage / totalStats.ActionTurn); if (totalStats.ActionTurn != 0) totalStats.DamagePerTurn = Calculation.Round2Digits(totalStats.TotalDamage / totalStats.ActionTurn);
if (totalStats.LiveTime != 0) totalStats.DamagePerSecond = Calculation.Round2Digits(totalStats.TotalDamage / totalStats.LiveTime); if (totalStats.LiveTime != 0) totalStats.DamagePerSecond = Calculation.Round2Digits(totalStats.TotalDamage / totalStats.LiveTime);
} }
private static void PlaceTeamInCorner(GamingQueue queue, GameMap map, List<Character> teamMembers, HashSet<Grid> allocated, int startX, int endX, int startY, int endY)
{
// 确保坐标有效
startX = Math.Clamp(startX, 0, map.Length - 1);
endX = Math.Clamp(endX, 0, map.Length - 1);
startY = Math.Clamp(startY, 0, map.Width - 1);
endY = Math.Clamp(endY, 0, map.Width - 1);
// 计算可用空间
int availableWidth = endX - startX + 1;
int availableHeight = endY - startY + 1;
// 计算每行最多角色数保持至少2格间距
int maxPerRow = Math.Min(availableWidth, Math.Max(1, availableWidth / 3));
// 计算起始位置
int currentX = startX;
int currentY = endY; // 从底部开始放置
foreach (Character character in teamMembers)
{
character.NormalAttack.GamingQueue = queue;
Grid? grid = null;
int attempts = 0;
// 尝试在指定区域找到合适位置
do
{
// 获取网格
grid = map[currentX, currentY, 0];
// 如果网格无效或已被占用,尝试下一个位置
if (grid == null || allocated.Contains(grid))
{
// 移动到下一个位置
currentX++;
// 换行处理
if (currentX > endX || currentX - startX >= maxPerRow)
{
currentX = startX;
currentY--; // 向上移动一行
// 如果超出区域,回到底部
if (currentY < startY)
{
currentY = endY;
}
}
}
attempts++;
// 如果尝试次数过多,使用随机位置
if (attempts > teamMembers.Count * 2)
{
grid = GetRandomGridInArea(map, allocated, startX, endX, startY, endY);
break;
}
}
while (grid == null || allocated.Contains(grid));
// 放置角色
if (grid != null)
{
allocated.Add(grid);
map.SetCharacterCurrentGrid(character, grid);
// 移动到下一个位置(保持间距)
currentX += 2; // 水平间距2格
// 换行处理
if (currentX > endX || currentX - startX >= maxPerRow)
{
currentX = startX;
currentY -= 2; // 垂直间距2格
// 如果超出区域,回到底部
if (currentY < startY)
{
currentY = endY;
}
}
}
else
{
// 回退到随机放置
Grid randomGrid = map.Grids.Values.FirstOrDefault(g => !allocated.Contains(g)) ?? Grid.Empty;
allocated.Add(randomGrid);
map.SetCharacterCurrentGrid(character, randomGrid);
}
}
}
private static Grid? GetRandomGridInArea(GameMap map, HashSet<Grid> allocated, int startX, int endX, int startY, int endY)
{
List<Grid> availableGrids = [];
for (int x = startX; x <= endX; x++)
{
for (int y = startY; y <= endY; y++)
{
Grid? grid = map[x, y, 0];
if (grid != null && !allocated.Contains(grid))
{
availableGrids.Add(grid);
}
}
}
return availableGrids.Count > 0 ?
availableGrids[Random.Shared.Next(availableGrids.Count)] :
null;
}
} }
} }

View File

@ -33,9 +33,9 @@ namespace Oshima.FunGame.WebAPI.Controllers
[AllowAnonymous] [AllowAnonymous]
[HttpGet("test")] [HttpGet("test")]
public async Task<List<string>> GetTest([FromQuery] bool? isweb = null, [FromQuery] bool? isteam = null, [FromQuery] bool? showall = null, [FromQuery] int? maxRespawnTimesMix = null) public async Task<List<string>> GetTest([FromQuery] bool? isweb = null, [FromQuery] bool? isteam = null, [FromQuery] bool? showall = null, [FromQuery] int? maxRespawnTimesMix = null, [FromQuery] bool? hasMap = null)
{ {
return await FunGameSimulation.StartSimulationGame(false, isweb ?? true, isteam ?? false, showall ?? false, maxRespawnTimesMix ?? 1); return await FunGameSimulation.StartSimulationGame(false, isweb ?? true, isteam ?? false, showall ?? false, maxRespawnTimesMix ?? 1, false, hasMap ?? false);
} }
[AllowAnonymous] [AllowAnonymous]

View File

@ -397,6 +397,29 @@ namespace Oshima.FunGame.WebAPI.Services
return result; return result;
} }
if (e.Detail.StartsWith("个人地图模拟", StringComparison.CurrentCultureIgnoreCase))
{
e.UseNotice = false;
if (!FunGameSimulation)
{
FunGameSimulation = true;
List<string> msgs = await Controller.GetTest(false, maxRespawnTimesMix: 0, hasMap: true);
List<string> real = MergeMessages(msgs);
int count = 1;
foreach (string msg in real)
{
await SendAsync(e, "筽祀牻", msg.Trim(), msgSeq: count++);
if (count != real.Count) await Task.Delay(5500);
}
FunGameSimulation = false;
}
else
{
await SendAsync(e, "筽祀牻", "游戏正在模拟中,请勿重复请求!");
}
return result;
}
if (e.Detail.StartsWith("混战模拟")) if (e.Detail.StartsWith("混战模拟"))
{ {
e.UseNotice = false; e.UseNotice = false;
@ -456,6 +479,29 @@ namespace Oshima.FunGame.WebAPI.Services
return result; return result;
} }
if (e.Detail.StartsWith("团队地图模拟", StringComparison.CurrentCultureIgnoreCase))
{
e.UseNotice = false;
if (!FunGameSimulation)
{
FunGameSimulation = true;
List<string> msgs = await Controller.GetTest(false, true, hasMap: true);
List<string> real = MergeMessages(msgs);
int count = 1;
foreach (string msg in real)
{
await SendAsync(e, "筽祀牻", msg.Trim(), msgSeq: count++);
if (count != real.Count) await Task.Delay(5500);
}
FunGameSimulation = false;
}
else
{
await SendAsync(e, "筽祀牻", "游戏正在模拟中,请勿重复请求!");
}
return result;
}
if (e.Detail.StartsWith("查数据", StringComparison.CurrentCultureIgnoreCase)) if (e.Detail.StartsWith("查数据", StringComparison.CurrentCultureIgnoreCase))
{ {
e.UseNotice = false; e.UseNotice = false;