# Conflicts:
#	My project/Assets/Resources/BT/City.asset
#	My project/Assets/Resources/BT/Legion.asset
This commit is contained in:
daixiawu 2025-06-20 03:24:12 +08:00
commit 6e2bea5fbf
11 changed files with 85 additions and 32 deletions

View File

@ -12,7 +12,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 7a686a47eee2fa44cb0a34b5d86e4d5e, type: 3}
m_Name: BT
m_EditorClassIdentifier:
_serializedGraph: '{"type":"NodeCanvas.BehaviourTrees.BehaviourTree","nodes":[{"_position":{"x":216.5371,"y":116.0371},"$type":"NodeCanvas.BehaviourTrees.Selector","$id":"0"},{"_subTree":{"_value":1},"_tag":"\u9632\u5b88\u79d1\u6280","_position":{"x":-225.1669,"y":361.2295},"_comment":"","$type":"NodeCanvas.BehaviourTrees.SubTree","$id":"1"},{"_subTree":{"_value":2},"_tag":"\u57ce\u5e02","_position":{"x":-39.6286,"y":368.0934},"$type":"NodeCanvas.BehaviourTrees.SubTree","$id":"2"},{"_subTree":{"_value":3},"_tag":"\u4e3b\u52a8\u79d1\u6280","_position":{"x":151.7755,"y":366.7513},"$type":"NodeCanvas.BehaviourTrees.SubTree","$id":"3"},{"_subTree":{"_value":4},"_tag":"\u81ea\u7531\u4eba","_position":{"x":338.4889,"y":362.5828},"$type":"NodeCanvas.BehaviourTrees.SubTree","$id":"4"},{"_subTree":{"_value":5},"_tag":"\u519b\u56e2","_position":{"x":516.5888,"y":362.6096},"$type":"NodeCanvas.BehaviourTrees.SubTree","$id":"5"},{"_action":{"$type":"NodeCanvas.Tasks.Actions.AIFinishAction"},"_position":{"x":668.2397,"y":372.3742},"$type":"NodeCanvas.BehaviourTrees.ActionNode","$id":"6"}],"connections":[{"_sourceNode":{"$ref":"0"},"_targetNode":{"$ref":"1"},"$type":"NodeCanvas.BehaviourTrees.BTConnection"},{"_sourceNode":{"$ref":"0"},"_targetNode":{"$ref":"2"},"$type":"NodeCanvas.BehaviourTrees.BTConnection"},{"_sourceNode":{"$ref":"0"},"_targetNode":{"$ref":"3"},"$type":"NodeCanvas.BehaviourTrees.BTConnection"},{"_sourceNode":{"$ref":"0"},"_targetNode":{"$ref":"4"},"$type":"NodeCanvas.BehaviourTrees.BTConnection"},{"_sourceNode":{"$ref":"0"},"_targetNode":{"$ref":"5"},"$type":"NodeCanvas.BehaviourTrees.BTConnection"},{"_sourceNode":{"$ref":"0"},"_targetNode":{"$ref":"6"},"$type":"NodeCanvas.BehaviourTrees.BTConnection"}],"canvasGroups":[],"localBlackboard":{"_variables":{}},"derivedData":{"repeat":true,"$type":"NodeCanvas.BehaviourTrees.BehaviourTree+DerivedSerializationData"}}'
_serializedGraph: '{"type":"NodeCanvas.BehaviourTrees.BehaviourTree","nodes":[{"_position":{"x":216.5371,"y":116.0371},"$type":"NodeCanvas.BehaviourTrees.Selector","$id":"0"},{"_subTree":{"_value":1},"_tag":"\u9632\u5b88\u79d1\u6280","_position":{"x":-223.1669,"y":366.2295},"_comment":"","$type":"NodeCanvas.BehaviourTrees.SubTree","$id":"1"},{"_subTree":{"_value":2},"_tag":"\u57ce\u5e02","_position":{"x":-39.6286,"y":368.0934},"$type":"NodeCanvas.BehaviourTrees.SubTree","$id":"2"},{"_subTree":{"_value":3},"_tag":"\u4e3b\u52a8\u79d1\u6280","_position":{"x":151.7755,"y":366.7513},"$type":"NodeCanvas.BehaviourTrees.SubTree","$id":"3"},{"_subTree":{"_value":4},"_tag":"\u81ea\u7531\u4eba","_position":{"x":338.4889,"y":362.5828},"$type":"NodeCanvas.BehaviourTrees.SubTree","$id":"4"},{"_subTree":{"_value":5},"_tag":"\u519b\u56e2","_position":{"x":516.5888,"y":362.6096},"$type":"NodeCanvas.BehaviourTrees.SubTree","$id":"5"},{"_action":{"$type":"NodeCanvas.Tasks.Actions.AIFinishAction"},"_position":{"x":668.2397,"y":372.3742},"$type":"NodeCanvas.BehaviourTrees.ActionNode","$id":"6"}],"connections":[{"_sourceNode":{"$ref":"0"},"_targetNode":{"$ref":"1"},"$type":"NodeCanvas.BehaviourTrees.BTConnection"},{"_sourceNode":{"$ref":"0"},"_targetNode":{"$ref":"2"},"$type":"NodeCanvas.BehaviourTrees.BTConnection"},{"_sourceNode":{"$ref":"0"},"_targetNode":{"$ref":"3"},"$type":"NodeCanvas.BehaviourTrees.BTConnection"},{"_sourceNode":{"$ref":"0"},"_targetNode":{"$ref":"4"},"$type":"NodeCanvas.BehaviourTrees.BTConnection"},{"_sourceNode":{"$ref":"0"},"_targetNode":{"$ref":"5"},"$type":"NodeCanvas.BehaviourTrees.BTConnection"},{"_sourceNode":{"$ref":"0"},"_targetNode":{"$ref":"6"},"$type":"NodeCanvas.BehaviourTrees.BTConnection"}],"canvasGroups":[],"localBlackboard":{"_variables":{}},"derivedData":{"repeat":true,"$type":"NodeCanvas.BehaviourTrees.BehaviourTree+DerivedSerializationData"}}'
_objectReferences:
- {fileID: 0}
- {fileID: 11400000, guid: 5c2d56f30f0281f4b89ebbbe5f2015e8, type: 2}
@ -24,7 +24,7 @@ MonoBehaviour:
_version: 3.33
_category:
_comments:
_translation: {x: 504, y: 112}
_translation: {x: 667, y: 127}
_zoomFactor: 1
_haltSerialization: 0
_externalSerializationFile: {fileID: 0}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -579,7 +579,7 @@ MonoBehaviour:
Defense: 1
AttackRange: 1
MoveRange: 2
Cost: 0
Cost: 2
Skills: 0b000000070000000d000000
Sprite: {fileID: 0}
SpriteGlow: {fileID: 0}

View File

@ -36,10 +36,6 @@ namespace NodeCanvas.Tasks.Actions
return;
}
if (CalculateTypes[0] == CalculateType.UnitMoveToTargetGrid)
{
Debug.Log(111);
}
data.value.MaxAiAction = AIActionScoreCalculator.CalculateAIActionScore(data.value, CalculateTypes);
if (data.value.MaxAiAction == null)
{

View File

@ -6,11 +6,13 @@
*/
using System.Collections.Generic;
using System.Linq;
using Logic.Action;
using Logic.AI;
using NodeCanvas.Framework;
using ParadoxNotion.Design;
using RuntimeData;
namespace NodeCanvas.Tasks.Actions
@ -43,7 +45,9 @@ namespace NodeCanvas.Tasks.Actions
if (data.value.ForeachUnit.Count == 0 && data.value.ForeachLegion.Count != 0)
{
var legion = data.value.ForeachLegion[0];
foreach (var unit in data.value.Map.UnitMap.UnitList)
var selfUnitList = new HashSet<UnitData>();
data.value.Map.GetUnitDataListByPlayerId(data.value.Player.Id, selfUnitList);
foreach (var unit in selfUnitList)
{
if (unit.LegionId != legion) continue;
data.value.ForeachUnit.Add(unit);

View File

@ -69,6 +69,7 @@ namespace Logic.AI
UnitAttackSelfCityEnemy,
UnitKill,
CityLevelUp,
}
@ -129,6 +130,8 @@ namespace Logic.AI
public Dictionary<uint, GridData> UnitTargetGrid;
// 小兵攻击系数
public Dictionary<uint, int> UnitAttackRatio;
// 军团可达城市
public Dictionary<uint, HashSet<uint>> LegionCanMoveCities;
public List<AIActionBase> AIActions;
@ -180,6 +183,7 @@ namespace Logic.AI
LegionTargetCity = new Dictionary<uint, uint>();
UnitTargetGrid = new Dictionary<uint, GridData>();
UnitAttackRatio = new Dictionary<uint, int>();
LegionCanMoveCities = new Dictionary<uint, HashSet<uint>>();
IsFinish = false;
IsInSight = false;
@ -226,6 +230,7 @@ namespace Logic.AI
LegionTargetCity.Clear();
UnitTargetGrid.Clear();
UnitAttackRatio.Clear();
LegionCanMoveCities.Clear();
// 国家策略
foreach (var playerData in map.PlayerMap.PlayerDataList)
@ -299,6 +304,7 @@ namespace Logic.AI
LegionTargetCity.Clear();
UnitTargetGrid.Clear();
UnitAttackRatio.Clear();
LegionCanMoveCities.Clear();
var selfUnitList = new List<UnitData>();
Map.GetUnitDataListByPlayerId(Player.Id, selfUnitList);
foreach (var unit in selfUnitList)
@ -340,6 +346,20 @@ namespace Logic.AI
LegionGrid[kv.Key] = centerGrid;
}
foreach (var kv in LegionUnits)
{
LegionCanMoveCities[kv.Key] = new HashSet<uint>();
foreach (var city in Map.CityMap.CityList)
{
if (!Map.GetGridDataByCityId(city.Id, out var cityGrid)) continue;
var path = PathFinder.FindPath((int)Map.MapConfig.Width, (int)Map.MapConfig.Height,
new (cityGrid.Pos.X, cityGrid.Pos.Y),
new (LegionGrid[kv.Key].Pos.X, LegionGrid[kv.Key].Pos.Y), Map, Player);
if (!path.found) continue;
LegionCanMoveCities[kv.Key].Add(city.Id);
}
}
foreach (var kv in LegionUnits)
{
var sunDis = 0;
@ -351,6 +371,7 @@ namespace Logic.AI
LegionUnstableScore[kv.Key] = sunDis * kv.Value.Count / 5f;
}
// 自主战略
var selfCity = new HashSet<CityData>();
Map.GetCityDataListByPlayerId(Player.Id, selfCity);
@ -370,6 +391,7 @@ namespace Logic.AI
foreach (var cityPair in CityStrategy)
{
if (cityPair.Value != Strategy.EmergencyDefend) continue;
if (!LegionCanMoveCities[kv.Key].Contains(cityPair.Key.Id)) continue;
LegionTargetCity[kv.Key] = cityPair.Key.Id;
LegionStrategy[kv.Key] = Strategy.Defend;
isFinish = true;
@ -381,6 +403,8 @@ namespace Logic.AI
foreach (var targetCity in citySet)
{
if (selfCity.Contains(targetCity)) continue;
if (!LegionCanMoveCities[kv.Key].Contains(targetCity.Id)) continue;
var score = LegionScore[kv.Key] - CityDefendScore[targetCity.Id];
foreach (var unit in kv.Value)
{
@ -417,6 +441,7 @@ namespace Logic.AI
{
foreach (var city in selfCity)
{
if (!LegionCanMoveCities[legionId].Contains(city.Id)) continue;
if (!Map.GetGridDataByCityId(city.Id, out var cityGrid)) continue;
var score = (LegionScore[legionId] - CityDangerScore[city.Id]) /
(Map.GridMap.CalcDistance(cityGrid, LegionGrid[legionId]) + 1);
@ -451,6 +476,7 @@ namespace Logic.AI
{
foreach (var city in Map.CityMap.CityList)
{
if (!LegionCanMoveCities[legionId].Contains(city.Id)) continue;
if (selfCity.Contains(city)) continue;
if (!Map.GetGridDataByCityId(city.Id, out var cityGrid)) continue;
var score = (2 * LegionScore[legionId] - CityDefendScore[city.Id] - CityRescueScore[city.Id]) /
@ -664,7 +690,7 @@ namespace Logic.AI
{
if (!Map.GetGridDataByCityId(city.Id, out var cityGrid)) continue;
var distance = Map.GridMap.CalcDistance(cityGrid, unitGrid);
if (distance >= minDis) continue;
if (distance <= 2 || distance >= minDis) continue;
minDis = distance;
target = city;
targetGrid = cityGrid;

View File

@ -656,6 +656,30 @@ namespace Logic.AI
if (aiAction.Param.GridData != aiAction.Param.TargetGridData) return false;
return true;
}
if (type == CalculateType.CityLevelUpDefend)
{
if (aiAction.ActionLogic.ActionId.CityLevelUpActionType == CityLevelUpActionType.Workshop)
return true;
if (aiAction.ActionLogic.ActionId.CityLevelUpActionType == CityLevelUpActionType.CityWall)
return true;
if (aiAction.ActionLogic.ActionId.CityLevelUpActionType == CityLevelUpActionType.BigGuy)
return true;
if (aiAction.ActionLogic.ActionId.CityLevelUpActionType == CityLevelUpActionType.Population)
return true;
return false;
}
if (type == CalculateType.CityLevelUp)
{
if (aiAction.ActionLogic.ActionId.CityLevelUpActionType == CityLevelUpActionType.Workshop)
return true;
if (aiAction.ActionLogic.ActionId.CityLevelUpActionType == CityLevelUpActionType.CityWealth)
return true;
if (aiAction.ActionLogic.ActionId.CityLevelUpActionType == CityLevelUpActionType.BigGuy)
return true;
if (aiAction.ActionLogic.ActionId.CityLevelUpActionType == CityLevelUpActionType.Expand)
return true;
return false;
}
}
return false;
}
@ -669,7 +693,6 @@ namespace Logic.AI
if (type == CalculateType.PlayerTechAttack) CalculatePlayerTechDefend(data, param, result);
if (type == CalculateType.PlayerTechScore) CalculatePlayerTechDefend(data, param, result);
if (type == CalculateType.CityLevelUpDefend) CalculateCityLevelUpDefend(data, param, result);
if (type == CalculateType.CityTrainDefend) CalculateCityTrainDefend(data, param, result);
if (type == CalculateType.CityTrainAttack) CalculateCityTrainAttack(data, param, result);
if (type == CalculateType.CityDevelopment) CalculateCityDevelopment(data, param, result);
@ -737,8 +760,11 @@ namespace Logic.AI
{
if (param.UnitData == null || param.TargetGridData == null) return;
if (!param.MapData.GetGridDataByUnitId(param.UnitData.Id, out var unitGrid)) return;
var distance = param.MapData.GridMap.CalcDistance(param.TargetGridData, unitGrid);
result.Score[CalculateType.UnitMoveToTargetGrid] = 1f / (distance + 1);
var path = PathFinder.FindPath((int)param.MapData.MapConfig.Width, (int)param.MapData.MapConfig.Height,
new (unitGrid.Pos.X, unitGrid.Pos.Y), new (param.TargetGridData.Pos.X, param.TargetGridData.Pos.Y),
param.MapData, param.PlayerData);
if (!path.found) return;
result.Score[CalculateType.UnitMoveToTargetGrid] = 1f / (path.length + 1);
}
private static void CalculateLegionDevelopmentAttackUnit(AICalculatorData data, CommonActionParams param, CalculateResult result)
@ -874,7 +900,7 @@ namespace Logic.AI
private static void CalculateCityDevelopment(AICalculatorData data, CommonActionParams param, CalculateResult result)
{
result.Score[CalculateType.CityDevelopment] = param.CityData.Level * 80 + param.CityData.LevelExp * 8 - param.PlayerData.PlayerWealth;
result.Score[CalculateType.CityDevelopment] = param.CityData.Level * 80 + param.CityData.LevelExp * 8 + param.PlayerData.PlayerWealth;
}
private static void CalculateCityTrainAttack(AICalculatorData data, CommonActionParams param, CalculateResult result)
@ -935,13 +961,6 @@ namespace Logic.AI
result.Score[CalculateType.CityTrainDefend] = score;
}
private static void CalculateCityLevelUpDefend(AICalculatorData data, CommonActionParams param, CalculateResult result)
{
result.Score[CalculateType.CityLevelUpDefend] = 0;
if (param.CityData.CityWall) result.Score[CalculateType.CityLevelUpDefend]++;
result.Score[CalculateType.CityLevelUpDefend]+= param.CityData.ParkCount;
}
private static void CalculatePlayerTechDefend(AICalculatorData data, CommonActionParams param, CalculateResult result)
{
result.Score[CalculateType.PlayerTechDefend] = 0;

View File

@ -79,6 +79,8 @@ namespace Logic.AI
_playerData = playerData;
_generator.Init(_mapData, _playerData);
_data.Refresh(mapData, playerData);
_btOwner.StopBehaviour();
_btOwner.StartBehaviour();
MainEditor.Instance.Data = _data;
}
@ -113,7 +115,12 @@ namespace Logic.AI
Debug.Log($"{_generator.ActionType} 耗时:{sw.Elapsed.TotalMilliseconds} ms");
MainEditor.Instance.IsGo = false;
if (index > 20 || _data.IsExcute || _data.IsFinish) break;
if (_data.IsExcute || _data.IsFinish) break;
if (index > 100)
{
Debug.LogWarning($"死循环了");
break;
}
}
if (_data.IsExcute)

View File

@ -92,7 +92,7 @@ namespace Logic.Action
{
UnitData = unit;
}
if (CityId != 0 && MapData.CityMap.GetCityDataByTerritoryGridId(CityId, out var city))
if (CityId != 0 && MapData.CityMap.GetCityById(CityId, out var city))
{
CityData = city;
}
@ -1926,9 +1926,6 @@ namespace Logic.Action
{
if (actionParams.CityData == null) return false;
//如果没有升级行动的点数,退出
//判断钱够不够
if (GetCost() > actionParams.PlayerData.PlayerWealth)
return false;
if (!actionParams.CityData.CityLevelUpPoint)
return false;
if (_actionId.CityLevelUpActionType == CityLevelUpActionType.Explorer)

View File

@ -489,6 +489,10 @@ namespace Logic
playerData.TechTree.LearnTech(TechType.Ramming);
playerData.TechTree.LearnTech(TechType.Riding);
playerData.TechTree.LearnTech(TechType.Archery);
playerData.TechTree.LearnTech(TechType.Spiritualism);
playerData.TechTree.LearnTech(TechType.Construction);
playerData.TechTree.LearnTech(TechType.Meditation);
playerData.TechTree.LearnTech(TechType.Aquatism);
}
}