Merge branch 'main' of http://10.27.16.144:3000/kawagiri/TH1
This commit is contained in:
commit
6c114fc6fc
File diff suppressed because one or more lines are too long
@ -12,7 +12,7 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: ee4fa5caed5fb2b43b903ef7859c9bf9, type: 3}
|
||||
m_Name: BlackBoard
|
||||
m_EditorClassIdentifier:
|
||||
_serializedBlackboard: '{"_variables":{"AIData":{"_value":{},"_name":"AIData","_id":"84e6dedf-2cb5-4be6-b2d0-55291cb78d97","$type":"NodeCanvas.Framework.Variable`1[[Logic.AI.AICalculatorData,
|
||||
_serializedBlackboard: '{"_variables":{"Data":{"_value":{"StrategyCity":[{"Key":0,"Value":[]},{"Key":1,"Value":[]},{"Key":2,"Value":[]},{"Key":3,"Value":[]},{"Key":4,"Value":[]},{"Key":5,"Value":[]}],"StrategyUnit":[{"Key":0,"Value":[]},{"Key":1,"Value":[]},{"Key":2,"Value":[]},{"Key":3,"Value":[]},{"Key":4,"Value":[]},{"Key":5,"Value":[]}],"StrategyLegion":[{"Key":0,"Value":[]},{"Key":1,"Value":[]},{"Key":2,"Value":[]},{"Key":3,"Value":[]},{"Key":4,"Value":[]},{"Key":5,"Value":[]}],"MilitaryScore":{},"DevelopmentScore":{},"ThreatScore":{},"MilitaryGapScore":{},"GeographicalDistance":{},"CityDefendScore":{},"CityRescueScore":{},"CityEnemyScore":{},"CityDangerScore":{},"CityBorderDistance":{},"LegionUnits":{},"FreeUnits":[],"LegionScore":{},"LegionGrid":{},"LegionGapScore":{},"LegionUnstableScore":{},"AIActions":[],"TargetParam":{},"Marks":{}},"_name":"Data","_id":"84e6dedf-2cb5-4be6-b2d0-55291cb78d97","$type":"NodeCanvas.Framework.Variable`1[[Logic.AI.AICalculatorData,
|
||||
Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]"}}}'
|
||||
_objectReferences: []
|
||||
_UID: 741313d3-f9b0-425b-9848-f246bb07a9cb
|
||||
|
||||
24
My project/Assets/Resources/BT/City.asset
Normal file
24
My project/Assets/Resources/BT/City.asset
Normal file
File diff suppressed because one or more lines are too long
8
My project/Assets/Resources/BT/City.asset.meta
Normal file
8
My project/Assets/Resources/BT/City.asset.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 49c0da9bda6079b4084856c777257077
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
24
My project/Assets/Resources/BT/DefendTech.asset
Normal file
24
My project/Assets/Resources/BT/DefendTech.asset
Normal file
@ -0,0 +1,24 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 7a686a47eee2fa44cb0a34b5d86e4d5e, type: 3}
|
||||
m_Name: DefendTech
|
||||
m_EditorClassIdentifier:
|
||||
_serializedGraph: '{"type":"NodeCanvas.BehaviourTrees.BehaviourTree","nodes":[{"_tag":"","_position":{"x":-4057.796,"y":495.8528},"$type":"NodeCanvas.BehaviourTrees.Sequencer","$id":"0"},{"_action":{"MarkStr":"DefendTech","CheckNotHave":true,"$type":"NodeCanvas.Tasks.Actions.MarkAction"},"_position":{"x":-4346.097,"y":657.5146},"$type":"NodeCanvas.BehaviourTrees.ActionNode","$id":"1"},{"_tag":"","_position":{"x":-3859.394,"y":652.2503},"$type":"NodeCanvas.BehaviourTrees.Selector","$id":"2"},{"_tag":"","_position":{"x":-3980.755,"y":761.3211},"$type":"NodeCanvas.BehaviourTrees.Sequencer","$id":"3"},{"_condition":{"CountryStrategy":1,"$type":"NodeCanvas.Tasks.Actions.CountryStrategyCondition"},"_tag":"","_position":{"x":-4438.908,"y":944.6642},"$type":"NodeCanvas.BehaviourTrees.ConditionNode","$id":"4"},{"_action":{"Strategy":1,"IsPlayer":true,"$type":"NodeCanvas.Tasks.Actions.AIParamAction"},"_tag":"","_position":{"x":-4328.108,"y":1030.32},"$type":"NodeCanvas.BehaviourTrees.ActionNode","$id":"5"},{"_action":{"ActionTypes":[9],"$type":"NodeCanvas.Tasks.Actions.AIGeneratorAction"},"_tag":"","_position":{"x":-4135.428,"y":1028.843},"$type":"NodeCanvas.BehaviourTrees.ActionNode","$id":"6"},{"_action":{"CalculateTypes":[0],"$type":"NodeCanvas.Tasks.Actions.AICalculateAction"},"_tag":"","_position":{"x":-4088.958,"y":1108.48},"$type":"NodeCanvas.BehaviourTrees.ActionNode","$id":"7"},{"_action":{"$type":"NodeCanvas.Tasks.Actions.AIExecuteAction"},"_tag":"","_position":{"x":-3920.547,"y":1026.896},"$type":"NodeCanvas.BehaviourTrees.ActionNode","$id":"8"},{"_action":{"MarkStr":"DefendTech","$type":"NodeCanvas.Tasks.Actions.MarkAction"},"_position":{"x":-3854.173,"y":854.0856},"$type":"NodeCanvas.BehaviourTrees.ActionNode","$id":"9"}],"connections":[{"_sourceNode":{"$ref":"0"},"_targetNode":{"$ref":"1"},"$type":"NodeCanvas.BehaviourTrees.BTConnection"},{"_sourceNode":{"$ref":"0"},"_targetNode":{"$ref":"2"},"$type":"NodeCanvas.BehaviourTrees.BTConnection"},{"_sourceNode":{"$ref":"2"},"_targetNode":{"$ref":"3"},"$type":"NodeCanvas.BehaviourTrees.BTConnection"},{"_sourceNode":{"$ref":"2"},"_targetNode":{"$ref":"9"},"$type":"NodeCanvas.BehaviourTrees.BTConnection"},{"_sourceNode":{"$ref":"3"},"_targetNode":{"$ref":"4"},"$type":"NodeCanvas.BehaviourTrees.BTConnection"},{"_sourceNode":{"$ref":"3"},"_targetNode":{"$ref":"5"},"$type":"NodeCanvas.BehaviourTrees.BTConnection"},{"_sourceNode":{"$ref":"3"},"_targetNode":{"$ref":"6"},"$type":"NodeCanvas.BehaviourTrees.BTConnection"},{"_sourceNode":{"$ref":"3"},"_targetNode":{"$ref":"7"},"$type":"NodeCanvas.BehaviourTrees.BTConnection"},{"_sourceNode":{"$ref":"3"},"_targetNode":{"$ref":"8"},"$type":"NodeCanvas.BehaviourTrees.BTConnection"}],"canvasGroups":[],"localBlackboard":{"_variables":{}},"derivedData":{"repeat":true,"$type":"NodeCanvas.BehaviourTrees.BehaviourTree+DerivedSerializationData"}}'
|
||||
_objectReferences: []
|
||||
_graphSource:
|
||||
_version: 3.33
|
||||
_category:
|
||||
_comments:
|
||||
_translation: {x: 4836, y: -298}
|
||||
_zoomFactor: 0.9998963
|
||||
_haltSerialization: 0
|
||||
_externalSerializationFile: {fileID: 0}
|
||||
8
My project/Assets/Resources/BT/DefendTech.asset.meta
Normal file
8
My project/Assets/Resources/BT/DefendTech.asset.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5c2d56f30f0281f4b89ebbbe5f2015e8
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
24
My project/Assets/Resources/BT/Legion.asset
Normal file
24
My project/Assets/Resources/BT/Legion.asset
Normal file
File diff suppressed because one or more lines are too long
8
My project/Assets/Resources/BT/Legion.asset.meta
Normal file
8
My project/Assets/Resources/BT/Legion.asset.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cf5354f0e5a794a4688155a6dc1354f9
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
24
My project/Assets/Resources/BT/Tech.asset
Normal file
24
My project/Assets/Resources/BT/Tech.asset
Normal file
File diff suppressed because one or more lines are too long
8
My project/Assets/Resources/BT/Tech.asset.meta
Normal file
8
My project/Assets/Resources/BT/Tech.asset.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6b1eeef55a4e73d42b4d25f9e0794b53
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
24
My project/Assets/Resources/BT/Unit.asset
Normal file
24
My project/Assets/Resources/BT/Unit.asset
Normal file
File diff suppressed because one or more lines are too long
8
My project/Assets/Resources/BT/Unit.asset.meta
Normal file
8
My project/Assets/Resources/BT/Unit.asset.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c172427e55805814c9b171c0d4a91cb1
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -38,6 +38,7 @@ RenderSettings:
|
||||
m_ReflectionIntensity: 1
|
||||
m_CustomReflection: {fileID: 0}
|
||||
m_Sun: {fileID: 0}
|
||||
m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
m_UseRadianceAmbientProbe: 0
|
||||
--- !u!157 &3
|
||||
LightmapSettings:
|
||||
@ -12269,10 +12270,10 @@ RectTransform:
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1243696580}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 112.445, y: -35}
|
||||
m_SizeDelta: {x: 84.89, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &85187974
|
||||
MonoBehaviour:
|
||||
@ -60895,6 +60896,84 @@ CanvasRenderer:
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 394711511}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!1 &395918545
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 395918548}
|
||||
- component: {fileID: 395918547}
|
||||
- component: {fileID: 395918546}
|
||||
m_Layer: 0
|
||||
m_Name: AIBT
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!114 &395918546
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 395918545}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: b98a6db0b653f764eac834f85857a9dd, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
_parentBlackboard: {fileID: 11400000, guid: 54af86fc7df8ad84ba30333205e32a2c, type: 2}
|
||||
_serializedBlackboard: '{"_variables":{}}'
|
||||
_objectReferences: []
|
||||
_serializedVariables: []
|
||||
--- !u!114 &395918547
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 395918545}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: aad115aca74ce3c4891b3f6de0b4aae8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
_serializedExposedParameters: []
|
||||
_boundGraphSerialization:
|
||||
_boundGraphObjectReferences: []
|
||||
_boundGraphSource:
|
||||
_version: 0
|
||||
_category:
|
||||
_comments:
|
||||
_translation: {x: 0, y: 0}
|
||||
_zoomFactor: 1
|
||||
_firstActivation: 2
|
||||
_enableAction: 0
|
||||
_disableAction: 0
|
||||
_lockBoundGraphPrefabOverrides: 1
|
||||
_preInitializeSubGraphs: 0
|
||||
_updateMode: 3
|
||||
_graph: {fileID: 11400000, guid: be76ba4e003c482489c2bb30da007cb8, type: 2}
|
||||
_blackboard: {fileID: 395918546}
|
||||
--- !u!4 &395918548
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 395918545}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 1268.7635, y: 605.7429, z: 7.64894}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &397028032
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -322673,3 +322752,4 @@ SceneRoots:
|
||||
- {fileID: 727821838}
|
||||
- {fileID: 656929328}
|
||||
- {fileID: 1136548652}
|
||||
- {fileID: 395918548}
|
||||
|
||||
@ -23,7 +23,7 @@ namespace NodeCanvas.Tasks.Actions
|
||||
|
||||
protected override string info
|
||||
{
|
||||
get { return string.Format($"Calculate Action"); }
|
||||
get { return string.Format($"对行为评分,评分策略为 {CalculateTypes[0]}"); }
|
||||
}
|
||||
|
||||
protected override void OnExecute()
|
||||
@ -36,10 +36,13 @@ namespace NodeCanvas.Tasks.Actions
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var calculateType in CalculateTypes)
|
||||
AIActionScoreCalculator.CalculateAIActionScore(data.value, calculateType);
|
||||
|
||||
data.value.AIActions = data.value.AIActions.OrderBy(a => a.Result.GetAllScore()).ToList();
|
||||
data.value.MaxAiAction = AIActionScoreCalculator.CalculateAIActionScore(data.value, CalculateTypes);
|
||||
if (data.value.MaxAiAction == null)
|
||||
{
|
||||
EndAction(false);
|
||||
return;
|
||||
}
|
||||
|
||||
EndAction(true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,21 +18,25 @@ namespace NodeCanvas.Tasks.Actions
|
||||
{
|
||||
protected override string info
|
||||
{
|
||||
get { return string.Format($"AI Execute Action"); }
|
||||
get { return string.Format($"执行"); }
|
||||
}
|
||||
|
||||
protected override void OnExecute()
|
||||
{
|
||||
// 直接从Blackboard获取AICalculatorData
|
||||
var data = blackboard.GetVariable<AICalculatorData>("Data");
|
||||
if (data?.value == null || data.value.AIActions.Count == 0)
|
||||
if (data?.value == null)
|
||||
{
|
||||
EndAction(false);
|
||||
return;
|
||||
}
|
||||
|
||||
var aiAction = data.value.AIActions[0];
|
||||
aiAction.ActionLogic.Execute(aiAction.Param);
|
||||
|
||||
data.value.MaxAiAction.Param.MapData = data.value.Map;
|
||||
data.value.MaxAiAction.Param.RefreshParams();
|
||||
data.value.MaxAiAction.ActionLogic.Execute(data.value.MaxAiAction.Param);
|
||||
data.value.IsExcute = true;
|
||||
data.value.MaxAiAction.CheckIsActionInPlayerSight();
|
||||
data.value.IsInSight = data.value.MaxAiAction.IsInSight;
|
||||
EndAction(true);
|
||||
}
|
||||
}
|
||||
|
||||
38
My project/Assets/Scripts/AINodeCanvas/AIFinishAction.cs
Normal file
38
My project/Assets/Scripts/AINodeCanvas/AIFinishAction.cs
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* @Author: 白哉
|
||||
* @Description:
|
||||
* @Date: 2025年06月06日 星期五 19:06:16
|
||||
* @Modify:
|
||||
*/
|
||||
|
||||
|
||||
using Logic.AI;
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
|
||||
|
||||
namespace NodeCanvas.Tasks.Actions
|
||||
{
|
||||
[Category("AIAction")]
|
||||
public class AIFinishAction : ActionTask
|
||||
{
|
||||
protected override string info
|
||||
{
|
||||
get { return string.Format($"行为树执行结束"); }
|
||||
}
|
||||
|
||||
protected override void OnExecute()
|
||||
{
|
||||
// 直接从Blackboard获取AICalculatorData
|
||||
var data = blackboard.GetVariable<AICalculatorData>("Data");
|
||||
if (data?.value == null)
|
||||
{
|
||||
EndAction(false);
|
||||
return;
|
||||
}
|
||||
|
||||
data.value.IsFinish = true;
|
||||
EndAction(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c80b7d7ac0524f64bb60c9aefbad0475
|
||||
timeCreated: 1750228853
|
||||
@ -59,9 +59,9 @@ namespace NodeCanvas.Tasks.Actions
|
||||
if (data.value.StrategyLegion.ContainsKey(strategy) && data.value.StrategyLegion[strategy].Count != 0)
|
||||
{
|
||||
var legion = data.value.StrategyLegion[strategy][0];
|
||||
if (data.value.LegionUnit.ContainsKey(legion) && data.value.LegionUnit[legion].Count != 0)
|
||||
if (data.value.LegionUnits.ContainsKey(legion) && data.value.LegionUnits[legion].Count != 0)
|
||||
{
|
||||
data.value.LegionUnit[legion].RemoveAt(0);
|
||||
data.value.LegionUnits[legion].RemoveAt(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -46,6 +46,7 @@ namespace NodeCanvas.Tasks.Actions
|
||||
|
||||
data.value.TargetParam.MapData = data.value.Map;
|
||||
data.value.TargetParam.PlayerData = data.value.Player;
|
||||
data.value.TargetParam.OnParamChanged();
|
||||
if (IsPlayer) EndAction(true);
|
||||
|
||||
if (IsCity)
|
||||
@ -53,6 +54,7 @@ namespace NodeCanvas.Tasks.Actions
|
||||
if (data.value.StrategyCity.ContainsKey(Strategy) && data.value.StrategyCity[Strategy].Count != 0)
|
||||
{
|
||||
data.value.TargetParam.CityData = data.value.StrategyCity[Strategy][0];
|
||||
data.value.TargetParam.OnParamChanged();
|
||||
EndAction(true);
|
||||
return;
|
||||
}
|
||||
@ -63,6 +65,7 @@ namespace NodeCanvas.Tasks.Actions
|
||||
if (data.value.StrategyUnit.ContainsKey(Strategy) && data.value.StrategyUnit[Strategy].Count != 0)
|
||||
{
|
||||
data.value.TargetParam.UnitData = data.value.StrategyUnit[Strategy][0];
|
||||
data.value.TargetParam.OnParamChanged();
|
||||
EndAction(true);
|
||||
return;
|
||||
}
|
||||
@ -73,9 +76,10 @@ namespace NodeCanvas.Tasks.Actions
|
||||
if (data.value.StrategyLegion.ContainsKey(Strategy) && data.value.StrategyLegion[Strategy].Count != 0)
|
||||
{
|
||||
var legion = data.value.StrategyLegion[Strategy][0];
|
||||
if (data.value.LegionUnit.ContainsKey(legion) && data.value.LegionUnit[legion].Count != 0)
|
||||
if (data.value.LegionUnits.ContainsKey(legion) && data.value.LegionUnits[legion].Count != 0)
|
||||
{
|
||||
data.value.TargetParam.UnitData = data.value.LegionUnit[legion][0];
|
||||
data.value.TargetParam.UnitData = data.value.LegionUnits[legion][0];
|
||||
data.value.TargetParam.OnParamChanged();
|
||||
EndAction(true);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* @Author: 白哉
|
||||
* @Description:
|
||||
* @Date: 2025年06月06日 星期五 19:06:16
|
||||
* @Modify:
|
||||
*/
|
||||
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Logic.AI;
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
using RuntimeData;
|
||||
|
||||
|
||||
namespace NodeCanvas.Tasks.Actions
|
||||
{
|
||||
[Category("AIAction")]
|
||||
public class AIParamAroundNoUnitCity : ActionTask
|
||||
{
|
||||
public int Offset;
|
||||
|
||||
protected override string info
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format($"周围 {Offset} 格内存在无人驻守的我方城市");
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnExecute()
|
||||
{
|
||||
// 直接从Blackboard获取AICalculatorData
|
||||
var data = blackboard.GetVariable<AICalculatorData>("Data");
|
||||
if (data?.value?.TargetParam.UnitData == null)
|
||||
{
|
||||
EndAction(false);
|
||||
return;
|
||||
}
|
||||
|
||||
var param = data.value.TargetParam;
|
||||
var unit = data.value.TargetParam.UnitData;
|
||||
if (!param.MapData.GetGridDataByUnitId(unit.Id, out var unitGrid))
|
||||
{
|
||||
EndAction(false);
|
||||
return;
|
||||
}
|
||||
|
||||
var selfCity = new HashSet<CityData>();
|
||||
param.MapData.GetCityDataListByPlayerId(param.PlayerData.Id, selfCity);
|
||||
var aroundGrid = param.MapData.GridMap.GetAroundGridData(Offset, Offset, unitGrid);
|
||||
foreach (var grid in aroundGrid)
|
||||
{
|
||||
if (!param.MapData.GetCityDataByGid(grid.Id, out var city)) continue;
|
||||
if (param.MapData.GetUnitDataByGid(grid.Id, out var cityUnit)) continue;
|
||||
if (!selfCity.Contains(city)) continue;
|
||||
data.value.TargetParam.GridData = grid;
|
||||
data.value.TargetParam.CityData = city;
|
||||
data.value.TargetParam.OnParamChanged();
|
||||
EndAction(true);
|
||||
return;
|
||||
}
|
||||
|
||||
EndAction(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e16fa8844b264801bb7df58c5be25c29
|
||||
timeCreated: 1750218255
|
||||
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* @Author: 白哉
|
||||
* @Description:
|
||||
* @Date: 2025年06月06日 星期五 19:06:16
|
||||
* @Modify:
|
||||
*/
|
||||
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Logic.AI;
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
using RuntimeData;
|
||||
|
||||
|
||||
namespace NodeCanvas.Tasks.Actions
|
||||
{
|
||||
[Category("AIAction")]
|
||||
public class AIParamEnemyCityTarget : ActionTask
|
||||
{
|
||||
protected override string info
|
||||
{
|
||||
get { return string.Format($"将可达最近的地方城市中心设为目标点"); }
|
||||
}
|
||||
|
||||
protected override void OnExecute()
|
||||
{
|
||||
// 直接从Blackboard获取AICalculatorData
|
||||
var data = blackboard.GetVariable<AICalculatorData>("Data");
|
||||
if (data?.value?.TargetParam.UnitData == null)
|
||||
{
|
||||
EndAction(false);
|
||||
return;
|
||||
}
|
||||
|
||||
var param = data.value.TargetParam;
|
||||
if (!param.MapData.GetGridDataByUnitId(param.UnitData.Id, out var unitGrid))
|
||||
{
|
||||
EndAction(false);
|
||||
return;
|
||||
}
|
||||
|
||||
var selfCity = new HashSet<CityData>();
|
||||
param.MapData.GetCityDataListByPlayerId(param.PlayerData.Id, selfCity);
|
||||
var length = int.MaxValue;
|
||||
GridData minTarget = null;
|
||||
foreach (var city in param.MapData.CityMap.CityList)
|
||||
{
|
||||
if (selfCity.Contains(city)) continue;
|
||||
if (!param.MapData.GetGridDataByCityId(city.Id, out var cityGrid)) continue;
|
||||
var path = PathFinder.FindPath((int)param.MapData.MapConfig.Width, (int)param.MapData.MapConfig.Height,
|
||||
new (unitGrid.Pos.X, unitGrid.Pos.Y), new (cityGrid.Pos.X, cityGrid.Pos.Y), param.MapData, param.PlayerData);
|
||||
if (!path.found) continue;
|
||||
if (path.length < length)
|
||||
{
|
||||
length = path.length;
|
||||
minTarget = cityGrid;
|
||||
}
|
||||
}
|
||||
if (minTarget != null)
|
||||
{
|
||||
data.value.TargetParam.GridData = minTarget;
|
||||
data.value.TargetParam.OnParamChanged();
|
||||
EndAction(true);
|
||||
return;
|
||||
}
|
||||
|
||||
EndAction(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: db30b01ea10348129709429852518f2b
|
||||
timeCreated: 1750244250
|
||||
98
My project/Assets/Scripts/AINodeCanvas/AIParamExplore.cs
Normal file
98
My project/Assets/Scripts/AINodeCanvas/AIParamExplore.cs
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* @Author: 白哉
|
||||
* @Description:
|
||||
* @Date: 2025年06月06日 星期五 19:06:16
|
||||
* @Modify:
|
||||
*/
|
||||
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Logic.AI;
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
using RuntimeData;
|
||||
|
||||
|
||||
namespace NodeCanvas.Tasks.Actions
|
||||
{
|
||||
[Category("AIAction")]
|
||||
public class AIParamExplore : ActionTask
|
||||
{
|
||||
public int Offset = 1;
|
||||
|
||||
protected override string info
|
||||
{
|
||||
get { return string.Format($"查找周围 {Offset} 格内可抵达的探索目标"); }
|
||||
}
|
||||
|
||||
protected override void OnExecute()
|
||||
{
|
||||
// 直接从Blackboard获取AICalculatorData
|
||||
var data = blackboard.GetVariable<AICalculatorData>("Data");
|
||||
if (data?.value?.TargetParam.UnitData == null)
|
||||
{
|
||||
EndAction(false);
|
||||
return;
|
||||
}
|
||||
|
||||
var param = data.value.TargetParam;
|
||||
if (!param.MapData.GetGridDataByUnitId(param.UnitData.Id, out var unitGrid))
|
||||
{
|
||||
EndAction(false);
|
||||
return;
|
||||
}
|
||||
|
||||
var selfCity = new HashSet<CityData>();
|
||||
param.MapData.GetCityDataListByPlayerId(param.PlayerData.Id, selfCity);
|
||||
var aroundGrids = param.MapData.GridMap.GetAroundGridData(Offset, Offset, unitGrid);
|
||||
var targetGrids = new List<List<GridData>>();
|
||||
for (int i = 0; i < 3; i++) targetGrids.Add(new List<GridData>());
|
||||
foreach (var grid in aroundGrids)
|
||||
{
|
||||
if (grid == unitGrid) continue;
|
||||
if (grid.Resource == ResourceType.CityCenter && !param.MapData.GetCityDataByGid(grid.Id, out _))
|
||||
{
|
||||
targetGrids[0].Add(grid);
|
||||
continue;
|
||||
}
|
||||
if (grid.Resource == ResourceType.Treasure)
|
||||
{
|
||||
targetGrids[1].Add(grid);
|
||||
continue;
|
||||
}
|
||||
if (grid.Resource == ResourceType.Starfish)
|
||||
{
|
||||
targetGrids[2].Add(grid);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
var length = int.MaxValue;
|
||||
GridData minTarget = null;
|
||||
foreach (var list in targetGrids)
|
||||
{
|
||||
foreach (var target in list)
|
||||
{
|
||||
var path = PathFinder.FindPath((int)param.MapData.MapConfig.Width, (int)param.MapData.MapConfig.Height,
|
||||
new (unitGrid.Pos.X, unitGrid.Pos.Y), new (target.Pos.X, target.Pos.Y), param.MapData, param.PlayerData);
|
||||
if (!path.found) continue;
|
||||
if (path.length < length)
|
||||
{
|
||||
length = path.length;
|
||||
minTarget = target;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (minTarget != null)
|
||||
{
|
||||
data.value.TargetParam.GridData = minTarget;
|
||||
data.value.TargetParam.OnParamChanged();
|
||||
EndAction(true);
|
||||
return;
|
||||
}
|
||||
|
||||
EndAction(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f94528ce5a934593b2d384da2aa304fd
|
||||
timeCreated: 1750156321
|
||||
54
My project/Assets/Scripts/AINodeCanvas/AIParamHealth.cs
Normal file
54
My project/Assets/Scripts/AINodeCanvas/AIParamHealth.cs
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* @Author: 白哉
|
||||
* @Description:
|
||||
* @Date: 2025年06月06日 星期五 19:06:16
|
||||
* @Modify:
|
||||
*/
|
||||
|
||||
|
||||
using Logic.AI;
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
|
||||
|
||||
namespace NodeCanvas.Tasks.Actions
|
||||
{
|
||||
[Category("AIAction")]
|
||||
public class AIParamHealth : ActionTask
|
||||
{
|
||||
public bool GreaterThan = true;
|
||||
public float Ratio = 0.6f;
|
||||
|
||||
|
||||
protected override string info
|
||||
{
|
||||
get
|
||||
{
|
||||
if (GreaterThan) return string.Format($"血量大于等于");
|
||||
return string.Format($"血量小于等于");
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnExecute()
|
||||
{
|
||||
// 直接从Blackboard获取AICalculatorData
|
||||
var data = blackboard.GetVariable<AICalculatorData>("Data");
|
||||
if (data?.value?.TargetParam.UnitData == null)
|
||||
{
|
||||
EndAction(false);
|
||||
return;
|
||||
}
|
||||
|
||||
var unit = data.value.TargetParam.UnitData;
|
||||
if (!Table.Instance.UnitTypeDataAssets.GetUnitTypeInfo(unit.UnitType, unit.GiantType, out var info))
|
||||
{
|
||||
EndAction(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (GreaterThan && unit.Health >= info.MaxHealth * Ratio) EndAction(true);
|
||||
else if (!GreaterThan && unit.Health <= info.MaxHealth * Ratio) EndAction(true);
|
||||
else EndAction(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 912e15e2957c415a83cf667e56b94677
|
||||
timeCreated: 1750216920
|
||||
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* @Author: 白哉
|
||||
* @Description:
|
||||
* @Date: 2025年06月06日 星期五 19:06:16
|
||||
* @Modify:
|
||||
*/
|
||||
|
||||
|
||||
using Logic.AI;
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
|
||||
|
||||
namespace NodeCanvas.Tasks.Actions
|
||||
{
|
||||
[Category("AIAction")]
|
||||
public class AIParamSelfTerritory : ActionTask
|
||||
{
|
||||
public bool IsIn = true;
|
||||
|
||||
|
||||
protected override string info
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsIn) return string.Format($"在我方领土");
|
||||
return string.Format($"不在我方领土");
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnExecute()
|
||||
{
|
||||
// 直接从Blackboard获取AICalculatorData
|
||||
var data = blackboard.GetVariable<AICalculatorData>("Data");
|
||||
if (data?.value?.TargetParam.UnitData == null)
|
||||
{
|
||||
EndAction(false);
|
||||
return;
|
||||
}
|
||||
|
||||
var unit = data.value.TargetParam.UnitData;
|
||||
var set = data.value.TargetParam.MapData.GetPlayerTerritoryGridIdSet(data.value.TargetParam.PlayerData.Id);
|
||||
if (data.value.TargetParam.MapData.GetGridDataByUnitId(unit.Id, out var grid))
|
||||
{
|
||||
if (IsIn && set.Contains(grid.Id))
|
||||
{
|
||||
EndAction(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsIn && !set.Contains(grid.Id))
|
||||
{
|
||||
EndAction(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
EndAction(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 36fb2cbde3fa43b888e9b54a6c53d832
|
||||
timeCreated: 1750217595
|
||||
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* @Author: 白哉
|
||||
* @Description:
|
||||
* @Date: 2025年06月06日 星期五 19:06:16
|
||||
* @Modify:
|
||||
*/
|
||||
|
||||
|
||||
using Logic.AI;
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
|
||||
|
||||
namespace NodeCanvas.Tasks.Actions
|
||||
{
|
||||
[Category("AIAction")]
|
||||
public class AIParamTargetCityHaveUnit : ActionTask
|
||||
{
|
||||
public bool CheckHaveUnit = true;
|
||||
|
||||
|
||||
protected override string info
|
||||
{
|
||||
get
|
||||
{
|
||||
if (CheckHaveUnit) return string.Format($"目标城市上有单位");
|
||||
return string.Format($"目标城市上没有单位");
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnExecute()
|
||||
{
|
||||
// 直接从Blackboard获取AICalculatorData
|
||||
var data = blackboard.GetVariable<AICalculatorData>("Data");
|
||||
if (data?.value?.TargetParam.UnitData == null)
|
||||
{
|
||||
EndAction(false);
|
||||
return;
|
||||
}
|
||||
|
||||
var param = data.value.TargetParam;
|
||||
var legion = param.UnitData.LegionId;
|
||||
var targetCity = data.value.LegionTargetCity[legion];
|
||||
if (targetCity == 0)
|
||||
{
|
||||
EndAction(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (param.MapData.GetGridDataByCityId(targetCity, out var gridData))
|
||||
{
|
||||
if (param.MapData.GetUnitDataByGid(gridData.Id, out var unitData))
|
||||
{
|
||||
EndAction(CheckHaveUnit);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
EndAction(!CheckHaveUnit);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5e827c6d3dd340c28c48224d17641397
|
||||
timeCreated: 1750164921
|
||||
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* @Author: 白哉
|
||||
* @Description:
|
||||
* @Date: 2025年06月06日 星期五 19:06:16
|
||||
* @Modify:
|
||||
*/
|
||||
|
||||
|
||||
using Logic.AI;
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
|
||||
|
||||
namespace NodeCanvas.Tasks.Actions
|
||||
{
|
||||
[Category("AIAction")]
|
||||
public class AIParamTrainUnitType : ActionTask
|
||||
{
|
||||
public UnitType UnitType;
|
||||
|
||||
|
||||
protected override string info
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format($"只能建 {UnitType} 小兵");
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnExecute()
|
||||
{
|
||||
// 直接从Blackboard获取AICalculatorData
|
||||
var data = blackboard.GetVariable<AICalculatorData>("Data");
|
||||
if (data?.value?.TargetParam == null)
|
||||
{
|
||||
EndAction(false);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = data.value.AIActions.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (data.value.AIActions[i].ActionLogic.ActionId.UnitType == UnitType) continue;
|
||||
data.value.AIActions.RemoveAt(i);
|
||||
}
|
||||
|
||||
EndAction(data.value.AIActions.Count > 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bf0540198eaf409094a3eb834578f27b
|
||||
timeCreated: 1750246584
|
||||
@ -18,6 +18,10 @@ namespace NodeCanvas.Tasks.Actions
|
||||
{
|
||||
public Strategy CountryStrategy;
|
||||
|
||||
protected override string info
|
||||
{
|
||||
get { return string.Format($"当国家战略为: {CountryStrategy} 时"); }
|
||||
}
|
||||
|
||||
protected override bool OnCheck()
|
||||
{
|
||||
|
||||
@ -17,18 +17,35 @@ namespace NodeCanvas.Tasks.Actions
|
||||
public class MarkAction : ActionTask
|
||||
{
|
||||
public string MarkStr;
|
||||
public bool CheckNotHave;
|
||||
|
||||
|
||||
protected override string info
|
||||
{
|
||||
get { return string.Format($"Add {MarkStr}"); }
|
||||
get
|
||||
{
|
||||
if (CheckNotHave) return string.Format($"检查没有 {MarkStr} 标记");
|
||||
else return string.Format($"添加 {MarkStr} 标记");
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnExecute()
|
||||
{
|
||||
// 直接从Blackboard获取AICalculatorData
|
||||
var data = blackboard.GetVariable<AICalculatorData>("Data");
|
||||
if (data?.value != null) data.value.Marks.Add(MarkStr);
|
||||
if (data?.value == null)
|
||||
{
|
||||
EndAction(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (CheckNotHave)
|
||||
{
|
||||
EndAction(!data.value.Marks.Contains(MarkStr));
|
||||
return;
|
||||
}
|
||||
|
||||
data.value.Marks.Add(MarkStr);
|
||||
EndAction(true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -142,6 +142,18 @@ namespace RuntimeData
|
||||
}
|
||||
}
|
||||
|
||||
// 通过玩家 ID 找城市Set
|
||||
public void GetCityDataListByPlayerId(uint pid, HashSet<CityData> cityDataList=null)
|
||||
{
|
||||
if (cityDataList == null) cityDataList = new HashSet<CityData>();
|
||||
foreach (var kv in CityToPlayerDict)
|
||||
{
|
||||
if (kv.Value != pid) continue;
|
||||
if (!CityMap.GetCityById(kv.Key, out var cityData)) continue;
|
||||
cityDataList.Add(cityData);
|
||||
}
|
||||
}
|
||||
|
||||
// 通过玩家 ID 找城市 Set
|
||||
public HashSet<CityData> GetCityDataSetByPlayerId(uint pid)
|
||||
{
|
||||
|
||||
@ -192,7 +192,6 @@ namespace RuntimeData
|
||||
public uint PlayerCivId;
|
||||
public uint PlayerForceId;
|
||||
public uint CradleCityId;
|
||||
|
||||
|
||||
// 是否存活
|
||||
public bool Alive;
|
||||
@ -213,7 +212,9 @@ namespace RuntimeData
|
||||
// 用于记录累计击杀多少 unit
|
||||
public int TotalKill;
|
||||
|
||||
public List<uint> MeetPlayerSet;
|
||||
public List<uint> MeetPlayers;
|
||||
public List<uint> CurAttackPlayers;
|
||||
public List<uint> LastAttackPlayers;
|
||||
|
||||
//用于记录是否死亡,是否要centMessage来宣告死亡信息
|
||||
public bool DieMark = false;
|
||||
@ -224,7 +225,9 @@ namespace RuntimeData
|
||||
Sight = new MapSightData();
|
||||
TechTree = new TechTreeData();
|
||||
Wonder = new WonderData();
|
||||
MeetPlayerSet = new List<uint>();
|
||||
MeetPlayers = new List<uint>();
|
||||
CurAttackPlayers = new List<uint>();
|
||||
LastAttackPlayers = new List<uint>();
|
||||
//InitData();
|
||||
}
|
||||
|
||||
@ -240,8 +243,10 @@ namespace RuntimeData
|
||||
Sight = new MapSightData();
|
||||
|
||||
Wonder = new WonderData();
|
||||
MeetPlayerSet = new List<uint>();
|
||||
MeetPlayerSet.Add(Id);
|
||||
CurAttackPlayers = new List<uint>();
|
||||
LastAttackPlayers = new List<uint>();
|
||||
MeetPlayers = new List<uint>();
|
||||
MeetPlayers.Add(Id);
|
||||
InitData(civId,forceId);
|
||||
}
|
||||
|
||||
@ -259,6 +264,14 @@ namespace RuntimeData
|
||||
TechTree = new TechTreeData(copyData.TechTree);
|
||||
Wonder = new WonderData(copyData.Wonder);
|
||||
|
||||
CurAttackPlayers = new List<uint>();
|
||||
foreach (var id in copyData.CurAttackPlayers) CurAttackPlayers.Add(id);
|
||||
LastAttackPlayers = new List<uint>();
|
||||
foreach (var id in copyData.LastAttackPlayers) LastAttackPlayers.Add(id);
|
||||
|
||||
MeetPlayers = new List<uint>();
|
||||
foreach (var id in copyData.MeetPlayers) MeetPlayers.Add(id);
|
||||
|
||||
TurnNoAttack = copyData.TurnNoAttack;
|
||||
TotalKill = copyData.TotalKill;
|
||||
|
||||
@ -278,6 +291,13 @@ namespace RuntimeData
|
||||
Sight.DeepCopy(copyData.Sight);
|
||||
TechTree.DeepCopy(copyData.TechTree);
|
||||
Wonder.DeepCopy(copyData.Wonder);
|
||||
|
||||
CurAttackPlayers.Clear();
|
||||
foreach (var id in copyData.CurAttackPlayers) CurAttackPlayers.Add(id);
|
||||
LastAttackPlayers.Clear();
|
||||
foreach (var id in copyData.LastAttackPlayers) LastAttackPlayers.Add(id);
|
||||
MeetPlayers.Clear();
|
||||
foreach (var id in copyData.MeetPlayers) MeetPlayers.Add(id);
|
||||
|
||||
TurnNoAttack = copyData.TurnNoAttack;
|
||||
TotalKill = copyData.TotalKill;
|
||||
@ -310,6 +330,9 @@ namespace RuntimeData
|
||||
public void OnTurnStart(MapData map)
|
||||
{
|
||||
Turn++;
|
||||
LastAttackPlayers.Clear();
|
||||
foreach (var id in CurAttackPlayers)LastAttackPlayers.Add(id);
|
||||
CurAttackPlayers.Clear();
|
||||
for (int i = Skills.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var skill = Skills[i];
|
||||
|
||||
@ -290,6 +290,7 @@ namespace RuntimeData
|
||||
//MoveRange = Table.Instance.QueryUnitMoveRange(UnitType);
|
||||
Exp = 0;
|
||||
Veteran = false;
|
||||
LegionId = 0;
|
||||
}
|
||||
|
||||
// 全局通知调用
|
||||
|
||||
@ -9,14 +9,14 @@ public enum UnitType
|
||||
{
|
||||
None,
|
||||
Warrior, // 战士
|
||||
Rider, // 骑兵
|
||||
Archer, // 弓箭手
|
||||
Defender, // 盾兵
|
||||
Knights, // 骑士们
|
||||
Catapult, // 投石车
|
||||
Swordsman, // 剑士
|
||||
Cloak, // 间谍
|
||||
Minder, // 脑控
|
||||
Rider, // 骑兵 Riding
|
||||
Archer, // 弓箭手 Archery
|
||||
Defender, // 盾兵 Strategy
|
||||
Knights, // 重骑兵 Chivalry
|
||||
Catapult, // 投石车 Mathematics
|
||||
Swordsman, // 剑士 Smithery
|
||||
Cloak, // 间谍 Diplomacy
|
||||
Minder, // 脑控 Philosophy
|
||||
Boat, // 小艇
|
||||
Ship, // 远战船
|
||||
RammerShip, // 近战船
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -9,6 +9,7 @@
|
||||
using System.Collections.Generic;
|
||||
using Logic.Action;
|
||||
using RuntimeData;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Logic.AI
|
||||
{
|
||||
@ -276,6 +277,7 @@ namespace Logic.AI
|
||||
{
|
||||
if (!data.Map.GridMap.GetGridDataByGid(gridId, out var grid)) continue;
|
||||
data.TargetParam.GridData = grid;
|
||||
data.TargetParam.OnParamChanged();
|
||||
foreach (var action in actions)
|
||||
{
|
||||
if (!action.CheckCan(data.TargetParam)) continue;
|
||||
@ -326,10 +328,10 @@ namespace Logic.AI
|
||||
foreach (var grid in data.Map.GridMap.GridList)
|
||||
{
|
||||
var result = Main.UnitLogic.CheckUnitCanMoveOrAttack(data.Map, data.TargetParam.UnitData, grid);
|
||||
if (result != MoveAttackType.Move) continue;
|
||||
if (result != MoveAttackType.Move && result != MoveAttackType.MoveToPort && result != MoveAttackType.MoveAshore) continue;
|
||||
if (data.TargetParam.UnitData.MP <= 0) continue;
|
||||
data.TargetParam.GridData = grid;
|
||||
|
||||
data.TargetParam.OnParamChanged();
|
||||
foreach (var action in actions)
|
||||
{
|
||||
if (!action.CheckCan(data.TargetParam)) continue;
|
||||
@ -342,6 +344,7 @@ namespace Logic.AI
|
||||
{
|
||||
if (data.TargetParam.UnitData == null) return;
|
||||
if (!data.TargetParam.UnitData.Alive) return;
|
||||
if (data.TargetParam.UnitData.AP <= 0) return;
|
||||
data.TargetParam.MainObjectType = ActionLogicFactory.GetMainObjectType(type);
|
||||
|
||||
Main.UnitLogic.CalcUnitMoveInfo(data.Map, data.TargetParam.UnitData.Id);
|
||||
@ -353,6 +356,7 @@ namespace Logic.AI
|
||||
|
||||
data.TargetParam.GridData = grid;
|
||||
data.TargetParam.TargetUnitData = targetUnit;
|
||||
data.TargetParam.OnParamChanged();
|
||||
|
||||
foreach (var action in actions)
|
||||
{
|
||||
|
||||
@ -557,31 +557,523 @@ namespace Logic.AI
|
||||
}
|
||||
|
||||
// 这里的得分是和当前情况的差值
|
||||
public static void CalculateAIActionScore(AICalculatorData data, CalculateType type)
|
||||
public static AIActionBase CalculateAIActionScore(AICalculatorData data, List<CalculateType> types)
|
||||
{
|
||||
if (type == CalculateType.PlayerTechDefend)
|
||||
AIActionBase maxAction = null;
|
||||
var calMap = data.Map.GetDeepCopyMapData();
|
||||
var startResult = CalculateAIActionScore(data, data.TargetParam, types);
|
||||
var maxScoreOffset = 0f;
|
||||
|
||||
foreach (var aiAction in data.AIActions)
|
||||
{
|
||||
foreach (var aiAction in data.AIActions)
|
||||
if (CalculateAIActionIsTrue(data, aiAction, types)) return aiAction;
|
||||
|
||||
calMap.DeepCopy(data.Map);
|
||||
aiAction.Param.MapData = calMap;
|
||||
aiAction.Param.RefreshParams();
|
||||
aiAction.ActionLogic.Execute(aiAction.Param);
|
||||
aiAction.Result = CalculateAIActionScore(data, aiAction.Param, types);
|
||||
|
||||
var scoreOffset = aiAction.Result.GetAllScore() - startResult.GetAllScore();
|
||||
if (scoreOffset <= 0) continue;
|
||||
if (maxAction == null || scoreOffset > maxScoreOffset)
|
||||
{
|
||||
aiAction.Result = new CalculateResult();
|
||||
if (aiAction.ActionLogic.ActionId.ActionType == CommonActionType.LearnTech &&
|
||||
aiAction.ActionLogic.ActionId.TechType == TechType.Strategy)
|
||||
{
|
||||
aiAction.Result.Score[type] = 2;
|
||||
}
|
||||
if (aiAction.ActionLogic.ActionId.ActionType == CommonActionType.LearnTech &&
|
||||
aiAction.ActionLogic.ActionId.TechType == TechType.Organization)
|
||||
{
|
||||
aiAction.Result.Score[type] = 1;
|
||||
}
|
||||
maxAction = aiAction;
|
||||
maxScoreOffset = scoreOffset;
|
||||
}
|
||||
}
|
||||
|
||||
return maxAction;
|
||||
}
|
||||
|
||||
private static bool CalculateAIActionIsTrue(AICalculatorData data, AIActionBase aiAction, List<CalculateType> types)
|
||||
{
|
||||
foreach (var type in types)
|
||||
{
|
||||
if (type == CalculateType.UnitCollect)
|
||||
{
|
||||
if (aiAction.ActionLogic.ActionId.UnitActionType == UnitActionType.Capture) return true;
|
||||
if (aiAction.ActionLogic.ActionId.UnitActionType == UnitActionType.Gather) return true;
|
||||
if (aiAction.ActionLogic.ActionId.UnitActionType == UnitActionType.Examine) return true;
|
||||
}
|
||||
if (type == CalculateType.UnitUpgrade)
|
||||
{
|
||||
if (aiAction.ActionLogic.ActionId.UnitActionType == UnitActionType.Upgrade) return true;
|
||||
}
|
||||
if (type == CalculateType.LegionDefendAttack)
|
||||
{
|
||||
if (aiAction.Param.UnitData == null || aiAction.Param.TargetUnitData == null) return false;
|
||||
if (aiAction.Param.UnitData.GetAttackValue(aiAction.Param.MapData) <
|
||||
aiAction.Param.TargetUnitData.GetAttackValue(aiAction.Param.MapData)) return false;
|
||||
return true;
|
||||
}
|
||||
if (type == CalculateType.UnitAttack)
|
||||
{
|
||||
if (aiAction.Param.UnitData == null || aiAction.Param.TargetUnitData == null) return false;
|
||||
if (aiAction.Param.UnitData.GetAttackValue(aiAction.Param.MapData) <
|
||||
aiAction.Param.TargetUnitData.GetAttackValue(aiAction.Param.MapData)) return false;
|
||||
return true;
|
||||
}
|
||||
if (type == CalculateType.UnitAuto)
|
||||
{
|
||||
return Random.value > 0.5f;
|
||||
}
|
||||
if (type == CalculateType.CityOK)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (type == CalculateType.LegionAttackCityUnit)
|
||||
{
|
||||
if (aiAction.Param.UnitData == null || aiAction.Param.TargetUnitData == null) return false;
|
||||
if (aiAction.Param.UnitData.LegionId == 0) return false;
|
||||
if (!data.LegionTargetCity.TryGetValue(aiAction.Param.UnitData.LegionId, out var cityId)) return false;
|
||||
if (!aiAction.Param.MapData.GetGridDataByCityId(cityId, out var cityGrid)) return false;
|
||||
if (!aiAction.Param.MapData.GetGridDataByUnitId(aiAction.Param.TargetUnitData.Id, out var unitGrid)) return false;
|
||||
if (unitGrid != cityGrid) return false;
|
||||
|
||||
var selfDmg = Table.Instance.CalcDamage(aiAction.Param.MapData, aiAction.Param.UnitData, aiAction.Param.TargetUnitData);
|
||||
var otherDmg = Table.Instance.CalcDamage(aiAction.Param.MapData, aiAction.Param.TargetUnitData, aiAction.Param.UnitData);
|
||||
if (selfDmg * 3 < otherDmg) return false;
|
||||
return true;
|
||||
}
|
||||
if (type == CalculateType.LegionAttackCityTerritoryUnit)
|
||||
{
|
||||
if (aiAction.Param.UnitData == null || aiAction.Param.TargetUnitData == null) return false;
|
||||
if (aiAction.Param.UnitData.LegionId == 0) return false;
|
||||
if (!data.LegionTargetCity.TryGetValue(aiAction.Param.UnitData.LegionId, out var cityId)) return false;
|
||||
if (!aiAction.Param.MapData.GetGridDataByCityId(cityId, out var cityGrid)) return false;
|
||||
if (!aiAction.Param.MapData.GetUnitDataByGid(cityGrid.Id, out var unitData)) return false;
|
||||
var selfDmg = Table.Instance.CalcDamage(aiAction.Param.MapData, aiAction.Param.UnitData, aiAction.Param.TargetUnitData);
|
||||
var otherDmg = Table.Instance.CalcDamage(aiAction.Param.MapData, aiAction.Param.TargetUnitData, aiAction.Param.UnitData);
|
||||
if (selfDmg * 3 < otherDmg) return false;
|
||||
return true;
|
||||
}
|
||||
if (type == CalculateType.LegionAttackUnit)
|
||||
{
|
||||
if (aiAction.Param.UnitData == null || aiAction.Param.TargetUnitData == null) return false;
|
||||
var selfDmg = Table.Instance.CalcDamage(aiAction.Param.MapData, aiAction.Param.UnitData, aiAction.Param.TargetUnitData);
|
||||
var otherDmg = Table.Instance.CalcDamage(aiAction.Param.MapData, aiAction.Param.TargetUnitData, aiAction.Param.UnitData);
|
||||
if (selfDmg * 3 < otherDmg) return false;
|
||||
return true;
|
||||
}
|
||||
if (type == CalculateType.LegionDevelopmentAttackUnit)
|
||||
{
|
||||
if (aiAction.Param.UnitData == null || aiAction.Param.TargetUnitData == null) return false;
|
||||
var selfDmg = Table.Instance.CalcDamage(aiAction.Param.MapData, aiAction.Param.UnitData, aiAction.Param.TargetUnitData);
|
||||
var otherDmg = Table.Instance.CalcDamage(aiAction.Param.MapData, aiAction.Param.TargetUnitData, aiAction.Param.UnitData);
|
||||
if (selfDmg * 2 < otherDmg) return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static CalculateResult CalculateAIActionScore(AICalculatorData data, CommonActionParams param, List<CalculateType> types)
|
||||
{
|
||||
var result = new CalculateResult();
|
||||
foreach (var type in types)
|
||||
{
|
||||
if (type == CalculateType.PlayerTechDefend) CalculatePlayerTechDefend(data, data.TargetParam, result);
|
||||
if (type == CalculateType.PlayerTechAttack) CalculatePlayerTechDefend(data, data.TargetParam, result);
|
||||
if (type == CalculateType.PlayerTechScore) CalculatePlayerTechDefend(data, data.TargetParam, result);
|
||||
|
||||
if (type == CalculateType.CityLevelUpDefend) CalculateCityLevelUpDefend(data, data.TargetParam, result);
|
||||
if (type == CalculateType.CityTrainDefend) CalculateCityTrainDefend(data, data.TargetParam, result);
|
||||
if (type == CalculateType.CityTrainAttack) CalculateCityTrainAttack(data, data.TargetParam, result);
|
||||
if (type == CalculateType.CityDevelopment) CalculateCityDevelopment(data, data.TargetParam, result);
|
||||
|
||||
if (type == CalculateType.LegionDefendKill) CalculateLegionDefendKill(data, data.TargetParam, result);
|
||||
if (type == CalculateType.LegionDefendMove) CalculateLegionDefendMove(data, data.TargetParam, result);
|
||||
if (type == CalculateType.LegionDefendAttack) CalculateLegionDefendAttack(data, data.TargetParam, result);
|
||||
if (type == CalculateType.LegionDefendMoveForTrain) CalculateLegionDefendMoveForTrain(data, data.TargetParam, result);
|
||||
|
||||
if (type == CalculateType.UnitRecovery) CalculateUnitRecovery(data, data.TargetParam, result);
|
||||
if (type == CalculateType.UnitAttackCityCenter) CalculateUnitAttackCityCenter(data, data.TargetParam, result);
|
||||
if (type == CalculateType.UnitExplore) CalculateExplore(data, data.TargetParam, result);
|
||||
if (type == CalculateType.UnitRetreat) CalculateUnitRetreat(data, data.TargetParam, result);
|
||||
if (type == CalculateType.UnitMoveToTargetGrid) CalculateUnitMoveToTargetGrid(data, data.TargetParam, result);
|
||||
|
||||
if (type == CalculateType.LegionAttackMoveInCity) CalculateLegionAttackMoveInCity(data, data.TargetParam, result);
|
||||
if (type == CalculateType.LegionAttackMoveToCity) CalculateLegionAttackMoveToCity(data, data.TargetParam, result);
|
||||
if (type == CalculateType.LegionAttackCityUnit) CalculateLegionAttackCityUnit(data, data.TargetParam, result);
|
||||
if (type == CalculateType.LegionAttackCityTerritoryUnit) CalculateLegionAttackCityTerritoryUnit(data, data.TargetParam, result);
|
||||
if (type == CalculateType.LegionAttackUnit) CalculateLegionAttackUnit(data, data.TargetParam, result);
|
||||
|
||||
if (type == CalculateType.LegionDevelopmentMoveToCityTerritory) CalculateLegionDevelopmentMoveToCityTerritory(data, data.TargetParam, result);
|
||||
if (type == CalculateType.LegionDevelopmentKill) CalculateLegionDevelopmentKill(data, data.TargetParam, result);
|
||||
if (type == CalculateType.LegionDevelopmentMoveToCity) CalculateLegionDevelopmentMoveToCity(data, data.TargetParam, result);
|
||||
if (type == CalculateType.LegionDevelopmentAttackUnit) CalculateLegionDevelopmentAttackUnit(data, data.TargetParam, result);
|
||||
if (type == CalculateType.LegionDevelopmentMoveToOtherCity) CalculateLegionDevelopmentMoveToOtherCity(data, data.TargetParam, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void CalculateUnitAttackCityCenter(AICalculatorData data, CommonActionParams param, CalculateResult result)
|
||||
{
|
||||
if (param.UnitData == null || param.TargetUnitData == null) return;
|
||||
if (!param.MapData.GetGridDataByUnitId(param.TargetUnitData.Id, out var unitGrid)) return;
|
||||
if (!param.MapData.GetCityDataByGid(unitGrid.Id, out var cityData)) return;
|
||||
var selfCities = param.MapData.GetCityDataSetByPlayerId(param.PlayerData.Id);
|
||||
if (!selfCities.Contains(cityData)) return;
|
||||
|
||||
result.Score[CalculateType.UnitAttackCityCenter] = 1f;
|
||||
}
|
||||
|
||||
private static void CalculateLegionDevelopmentMoveToOtherCity(AICalculatorData data, CommonActionParams param, CalculateResult result)
|
||||
{
|
||||
if (param.UnitData == null || param.GridData == null) return;
|
||||
if (!param.MapData.GetGridDataByUnitId(param.UnitData.Id, out var unitGrid)) return;
|
||||
var distance = param.MapData.GridMap.CalcDistance(param.GridData, unitGrid);
|
||||
result.Score[CalculateType.LegionDevelopmentMoveToOtherCity] = 1f / (distance + 1);
|
||||
}
|
||||
|
||||
private static void CalculateUnitRetreat(AICalculatorData data, CommonActionParams param, CalculateResult result)
|
||||
{
|
||||
if (param.UnitData == null) return;
|
||||
if (!data.UnitTargetGrid.ContainsKey(param.UnitData.Id)) return;
|
||||
if (!param.MapData.GetGridDataByUnitId(param.UnitData.Id, out var unitGrid)) return;
|
||||
var distance = param.MapData.GridMap.CalcDistance(data.UnitTargetGrid[param.UnitData.Id], unitGrid);
|
||||
result.Score[CalculateType.UnitRetreat] = 1f / (distance + 1);
|
||||
}
|
||||
|
||||
private static void CalculateExplore(AICalculatorData data, CommonActionParams param, CalculateResult result)
|
||||
{
|
||||
if (param.UnitData == null || param.GridData == null) return;
|
||||
if (!param.MapData.GetGridDataByUnitId(param.UnitData.Id, out var unitGrid)) return;
|
||||
var distance = param.MapData.GridMap.CalcDistance(param.GridData, unitGrid);
|
||||
result.Score[CalculateType.UnitExplore] = 1f / (distance + 1);
|
||||
}
|
||||
|
||||
private static void CalculateUnitMoveToTargetGrid(AICalculatorData data, CommonActionParams param, CalculateResult result)
|
||||
{
|
||||
if (param.UnitData == null || param.GridData == null) return;
|
||||
if (!param.MapData.GetGridDataByUnitId(param.UnitData.Id, out var unitGrid)) return;
|
||||
var distance = param.MapData.GridMap.CalcDistance(param.GridData, unitGrid);
|
||||
result.Score[CalculateType.UnitMoveToTargetGrid] = 1f / (distance + 1);
|
||||
}
|
||||
|
||||
private static void CalculateLegionDevelopmentAttackUnit(AICalculatorData data, CommonActionParams param, CalculateResult result)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private static void CalculateLegionDevelopmentMoveToCity(AICalculatorData data, CommonActionParams param, CalculateResult result)
|
||||
{
|
||||
if (param.UnitData == null || param.CityData == null) return;
|
||||
if (!param.MapData.GetGridDataByUnitId(param.UnitData.Id, out var unitGrid)) return;
|
||||
if (!param.MapData.GetGridDataByCityId(param.CityData.Id, out var cityGrid)) return;
|
||||
var distance = param.MapData.GridMap.CalcDistance(cityGrid, unitGrid);
|
||||
result.Score[CalculateType.LegionDevelopmentMoveToCity] = 1f / (distance + 1);
|
||||
}
|
||||
|
||||
private static void CalculateLegionDevelopmentKill(AICalculatorData data, CommonActionParams param, CalculateResult result)
|
||||
{
|
||||
var score = 0;
|
||||
var selfUnits = new HashSet<UnitData>();
|
||||
param.MapData.GetUnitDataListByPlayerId(param.PlayerData.Id, selfUnits);
|
||||
foreach (var unit in param.MapData.UnitMap.UnitList)
|
||||
{
|
||||
if (selfUnits.Contains(unit)) continue;
|
||||
if (!Table.Instance.UnitTypeDataAssets.GetUnitTypeInfo(unit.UnitType, unit.GiantType, out var info)) continue;
|
||||
score += info.Cost;
|
||||
}
|
||||
result.Score[CalculateType.LegionDevelopmentKill] = 1f / (score + 1);
|
||||
}
|
||||
|
||||
private static void CalculateLegionDevelopmentMoveToCityTerritory(AICalculatorData data, CommonActionParams param, CalculateResult result)
|
||||
{
|
||||
if (param.UnitData == null) return;
|
||||
if (!param.MapData.GetGridDataByUnitId(param.UnitData.Id, out var grid)) return;
|
||||
var set = param.MapData.GetPlayerTerritoryGridIdSet(param.PlayerData.Id);
|
||||
if (!set.Contains(grid.Id)) return;
|
||||
result.Score[CalculateType.LegionDevelopmentMoveToCityTerritory] = 1f;
|
||||
}
|
||||
|
||||
private static void CalculateLegionAttackUnit(AICalculatorData data, CommonActionParams param, CalculateResult result)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private static void CalculateLegionAttackOccupation(AICalculatorData data, CommonActionParams param, CalculateResult result)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private static void CalculateLegionAttackCityTerritoryUnit(AICalculatorData data, CommonActionParams param, CalculateResult result)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private static void CalculateLegionAttackCityUnit(AICalculatorData data, CommonActionParams param, CalculateResult result)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private static void CalculateLegionAttackMoveToCity(AICalculatorData data, CommonActionParams param, CalculateResult result)
|
||||
{
|
||||
if (param.UnitData.LegionId == 0) return;
|
||||
if (!data.LegionTargetCity.TryGetValue(param.UnitData.LegionId, out var cityId)) return;
|
||||
if (!param.MapData.GetGridDataByCityId(cityId, out var cityGrid)) return;
|
||||
if (!param.MapData.GetGridDataByUnitId(param.UnitData.Id, out var unitGrid)) return;
|
||||
if (param.MapData.GetUnitDataByGid(cityGrid.Id, out var cityUnit)) return;
|
||||
var path = PathFinder.FindPath((int)param.MapData.MapConfig.Width, (int)param.MapData.MapConfig.Height,
|
||||
new (unitGrid.Pos.X, unitGrid.Pos.Y), new (cityGrid.Pos.X, cityGrid.Pos.Y), param.MapData, param.PlayerData);
|
||||
result.Score[CalculateType.UnitRecovery] = 1f / (path.length + 1);
|
||||
}
|
||||
|
||||
private static void CalculateLegionAttackMoveInCity(AICalculatorData data, CommonActionParams param, CalculateResult result)
|
||||
{
|
||||
if (param.UnitData.LegionId == 0) return;
|
||||
if (!data.LegionTargetCity.TryGetValue(param.UnitData.LegionId, out var cityId)) return;
|
||||
if (!param.MapData.GetGridDataByCityId(cityId, out var cityGrid)) return;
|
||||
if (!param.MapData.GetGridDataByUnitId(param.UnitData.Id, out var unitGrid)) return;
|
||||
if (cityGrid != unitGrid) return;
|
||||
result.Score[CalculateType.LegionAttackMoveInCity] = 1f;
|
||||
|
||||
// if (param.UnitData.LegionId == 0) return;
|
||||
// if (!data.LegionTargetCity.TryGetValue(param.UnitData.LegionId, out var cityId)) return;
|
||||
// if (!param.MapData.CityMap.GetCityById(cityId, out var city)) return;
|
||||
// if (!param.MapData.GetGridDataByUnitId(param.UnitData.Id, out var unitGrid)) return;
|
||||
// if (!param.MapData.GetGridDataByUnitId(city.Id, out var cityGrid)) return;
|
||||
// var path = PathFinder.FindPath((int)param.MapData.MapConfig.Width, (int)param.MapData.MapConfig.Height,
|
||||
// new (unitGrid.Pos.X, unitGrid.Pos.Y), new (cityGrid.Pos.X, cityGrid.Pos.Y), param.MapData, param.PlayerData);
|
||||
// result.Score[CalculateType.UnitRecovery] = 1f / (path.length + 1);
|
||||
}
|
||||
|
||||
private static void CalculateLegionDefendMoveForTrain(AICalculatorData data, CommonActionParams param, CalculateResult result)
|
||||
{
|
||||
if (param.UnitData.LegionId == 0) return;
|
||||
if (!data.LegionTargetCity.TryGetValue(param.UnitData.LegionId, out var cityId)) return;
|
||||
if (!param.MapData.CityMap.GetCityById(cityId, out var city)) return;
|
||||
if (!param.MapData.GetGridDataByCityId(cityId, out var grid)) return;
|
||||
|
||||
if (param.MapData.GetUnitDataByGid(grid.Id, out var unit))
|
||||
{
|
||||
if (!Table.Instance.UnitTypeDataAssets.GetUnitTypeInfo(unit.UnitType, unit.GiantType, out var info)) return;
|
||||
result.Score[CalculateType.UnitRecovery] = info.Defense;
|
||||
}
|
||||
else
|
||||
{
|
||||
var actions = ActionLogicFactory.GetActionLogicByType(CommonActionType.TrainUnit);
|
||||
if (actions == null || actions.Count == 0) return;
|
||||
|
||||
var newParam = new CommonActionParams();
|
||||
newParam.MainObjectType = MainObjectType.City;
|
||||
newParam.MapData = param.MapData;
|
||||
newParam.PlayerData = param.PlayerData;
|
||||
newParam.CityData = city;
|
||||
foreach (var action in actions)
|
||||
{
|
||||
if (!action.CheckCan(newParam)) continue;
|
||||
if (!Table.Instance.UnitTypeDataAssets.GetUnitTypeInfo(action.ActionId.UnitType, action.ActionId.GiantType, out var info)) return;
|
||||
if (info.Defense > result.Score[CalculateType.UnitRecovery])
|
||||
result.Score[CalculateType.UnitRecovery] = info.Defense;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void CalculateUnitRecovery(AICalculatorData data, CommonActionParams param, CalculateResult result)
|
||||
{
|
||||
result.Score[CalculateType.UnitRecovery] = param.UnitData.Health;
|
||||
}
|
||||
|
||||
private static void CalculateLegionDefendAttack(AICalculatorData data, CommonActionParams param, CalculateResult result)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private static void CalculateLegionDefendMove(AICalculatorData data, CommonActionParams param, CalculateResult result)
|
||||
{
|
||||
if (param.UnitData.LegionId == 0) return;
|
||||
var targetCityId = data.LegionTargetCity[param.UnitData.LegionId];
|
||||
if (!param.MapData.GetGridDataByCityId(targetCityId, out var targetGrid)) return;
|
||||
if (!param.MapData.GetGridDataByUnitId(param.UnitData.Id, out var unitGrid)) return;
|
||||
var path = PathFinder.FindPath((int)param.MapData.MapConfig.Width, (int)param.MapData.MapConfig.Height,
|
||||
new (unitGrid.Pos.X, unitGrid.Pos.Y), new (targetGrid.Pos.X, targetGrid.Pos.Y), param.MapData, param.PlayerData);
|
||||
|
||||
var selfUnits = new HashSet<UnitData>();
|
||||
param.MapData.GetUnitDataListByPlayerId(param.PlayerData.Id, selfUnits);
|
||||
var around = param.MapData.GridMap.GetAroundGridData(1, 1, unitGrid);
|
||||
var score = 0;
|
||||
foreach (var aroundGrid in around)
|
||||
{
|
||||
if (!param.MapData.GetUnitDataByGid(aroundGrid.Id, out var aroundUnit)) continue;
|
||||
if (!selfUnits.Contains(aroundUnit)) continue;
|
||||
if (!Table.Instance.UnitTypeDataAssets.GetUnitTypeInfo(aroundUnit.UnitType, aroundUnit.GiantType, out var info)) continue;
|
||||
score += info.Cost;
|
||||
}
|
||||
result.Score[CalculateType.LegionDefendMove] = 1 / ((float)path.length + 1) * 1000 + score / 1000f;
|
||||
}
|
||||
|
||||
private static void CalculateLegionDefendKill(AICalculatorData data, CommonActionParams param, CalculateResult result)
|
||||
{
|
||||
if (param.TargetUnitData == null) return;
|
||||
if (param.TargetUnitData.Alive) return;
|
||||
result.Score[CalculateType.LegionDefendKill] = 1;
|
||||
}
|
||||
|
||||
private static void CalculateUnitCollect(AICalculatorData data, CommonActionParams param, CalculateResult result)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private static void CalculateCityDevelopment(AICalculatorData data, CommonActionParams param, CalculateResult result)
|
||||
{
|
||||
result.Score[CalculateType.CityDevelopment] = param.CityData.Level * 50 + param.CityData.LevelExp * 5 - param.PlayerData.PlayerWealth * 5;
|
||||
}
|
||||
|
||||
private static void CalculateCityTrainAttack(AICalculatorData data, CommonActionParams param, CalculateResult result)
|
||||
{
|
||||
float score = 0;
|
||||
var selfUnits = new HashSet<UnitData>();
|
||||
param.MapData.GetUnitDataListByPlayerId(param.PlayerData.Id, selfUnits);
|
||||
if (!param.MapData.GetGridDataByCityId(param.CityData.Id, out var cityGrid)) return;
|
||||
|
||||
var units = new HashSet<UnitData>();
|
||||
var targets = new HashSet<UnitData>();
|
||||
var selfScore = 0;
|
||||
var targetScore = 0;
|
||||
foreach (var unit in param.MapData.UnitMap.UnitList)
|
||||
{
|
||||
if (!param.MapData.GetGridDataByUnitId(unit.Id, out var unitGrid)) continue;
|
||||
if (param.MapData.GridMap.CalcDistance(cityGrid, unitGrid) > 3) continue;
|
||||
if (!Table.Instance.UnitTypeDataAssets.GetUnitTypeInfo(unit.UnitType, unit.GiantType, out var info))
|
||||
continue;
|
||||
if (selfUnits.Contains(unit))
|
||||
{
|
||||
units.Add(unit);
|
||||
selfScore += info.Cost;
|
||||
}
|
||||
else
|
||||
{
|
||||
targets.Add(unit);
|
||||
targetScore += info.Cost;
|
||||
}
|
||||
}
|
||||
|
||||
score = selfScore - targetScore;
|
||||
foreach (var selfUnit in units)
|
||||
{
|
||||
foreach (var target in targets)
|
||||
{
|
||||
score += data.CalUnitCounterScore(selfUnit, target);
|
||||
score -= data.CalUnitCounterScore(target, selfUnit);
|
||||
}
|
||||
}
|
||||
|
||||
result.Score[CalculateType.CityTrainAttack] = score;
|
||||
}
|
||||
|
||||
public static void CalculatePlayerTechDefend(AICalculatorData data)
|
||||
private static void CalculateCityTrainDefend(AICalculatorData data, CommonActionParams param, CalculateResult result)
|
||||
{
|
||||
float score = 0;
|
||||
var selfUnits = new HashSet<UnitData>();
|
||||
param.MapData.GetUnitDataListByPlayerId(param.PlayerData.Id, selfUnits);
|
||||
if (!param.MapData.GetGridDataByCityId(param.CityData.Id, out var cityGrid)) return;
|
||||
|
||||
foreach (var unit in selfUnits)
|
||||
{
|
||||
if (!param.MapData.GetGridDataByUnitId(unit.Id, out var unitGrid)) continue;
|
||||
if (param.MapData.GridMap.CalcDistance(cityGrid, unitGrid) > 3) continue;
|
||||
score += unit.GetDefenseValue(param.MapData) + unit.Health;
|
||||
}
|
||||
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;
|
||||
if (param.PlayerData.TechTree.CheckIfHasTech(TechType.Strategy))
|
||||
result.Score[CalculateType.PlayerTechDefend] += 2;
|
||||
if (param.PlayerData.TechTree.CheckIfHasTech(TechType.Organization))
|
||||
result.Score[CalculateType.PlayerTechDefend] += 1;
|
||||
}
|
||||
|
||||
private static void CalculatePlayerTechAttack(AICalculatorData data, CommonActionParams param, CalculateResult result)
|
||||
{
|
||||
var score = 0;
|
||||
foreach (var playerId in param.PlayerData.LastAttackPlayers)
|
||||
{
|
||||
if (!param.MapData.PlayerMap.GetPlayerDataByPlayerID(playerId, out var target)) continue;
|
||||
score += CalculatePlayerTechGapScore(param.PlayerData, target);
|
||||
}
|
||||
|
||||
result.Score[CalculateType.PlayerTechAttack] = score;
|
||||
}
|
||||
|
||||
private static void CalculatePlayerTechScore(AICalculatorData data, CommonActionParams param, CalculateResult result)
|
||||
{
|
||||
var score = 0;
|
||||
foreach (var target in param.MapData.PlayerMap.PlayerDataList)
|
||||
{
|
||||
if (target == param.PlayerData) continue;
|
||||
score += CalculatePlayerTechGapScore(param.PlayerData, target);
|
||||
}
|
||||
|
||||
result.Score[CalculateType.PlayerTechScore] = score;
|
||||
}
|
||||
|
||||
private static int CalculatePlayerTechGapScore(PlayerData player1, PlayerData player2)
|
||||
{
|
||||
int player1Score = 0;
|
||||
int player2Score = 0;
|
||||
int gapScore = 0;
|
||||
foreach (var tech in player1.TechTree.TechList)
|
||||
{
|
||||
var techInfo = Table.Instance.TechDataAssets.GetTechInfo(tech);
|
||||
player1Score += techInfo.CostLevel;
|
||||
}
|
||||
foreach (var tech in player2.TechTree.TechList)
|
||||
{
|
||||
var techInfo = Table.Instance.TechDataAssets.GetTechInfo(tech);
|
||||
player2Score += techInfo.CostLevel;
|
||||
}
|
||||
|
||||
foreach (var tech1 in player1.TechTree.TechList)
|
||||
{
|
||||
foreach (var tech2 in player2.TechTree.TechList)
|
||||
{
|
||||
gapScore += CalculatePlayerTechGapScore(tech1, tech2);
|
||||
gapScore -= CalculatePlayerTechGapScore(tech2, tech1);
|
||||
}
|
||||
}
|
||||
|
||||
return player1Score - player2Score + gapScore;
|
||||
}
|
||||
|
||||
private static int CalculatePlayerTechGapScore(TechType techType1, TechType techType2)
|
||||
{
|
||||
if (techType1 == TechType.Archery && techType2 == TechType.Smithery) return 1;
|
||||
|
||||
if (techType1 == TechType.Strategy && techType2 == TechType.Archery) return 1;
|
||||
if (techType1 == TechType.Strategy && techType2 == TechType.Riding) return 1;
|
||||
if (techType1 == TechType.Strategy && techType2 == TechType.Chivalry) return 1;
|
||||
|
||||
if (techType1 == TechType.Riding && techType2 == TechType.Archery) return 1;
|
||||
if (techType1 == TechType.Riding && techType2 == TechType.Mathematics) return 2;
|
||||
if (techType1 == TechType.Riding && techType2 == TechType.Philosophy) return 2;
|
||||
|
||||
if (techType1 == TechType.Chivalry && techType2 == TechType.Archery) return 3;
|
||||
if (techType1 == TechType.Chivalry && techType2 == TechType.Mathematics) return 3;
|
||||
if (techType1 == TechType.Chivalry && techType2 == TechType.Philosophy) return 3;
|
||||
|
||||
if (techType1 == TechType.Mathematics && techType2 == TechType.Strategy) return 1;
|
||||
if (techType1 == TechType.Mathematics && techType2 == TechType.Smithery) return 2;
|
||||
|
||||
if (techType1 == TechType.Smithery && techType2 == TechType.Riding) return 2;
|
||||
if (techType1 == TechType.Smithery && techType2 == TechType.Chivalry) return 2;
|
||||
|
||||
if (techType1 == TechType.Philosophy && techType2 == TechType.Strategy) return 2;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -595,7 +1087,8 @@ namespace Logic.AI
|
||||
public int Distance;
|
||||
}
|
||||
|
||||
public static (bool found, Vector2Int[] path, int length) FindPath(int width, int height, Vector2Int start, Vector2Int end, MapData mapData, PlayerData playerData)
|
||||
public static (bool found, Vector2Int[] path, int length) FindPath(int width, int height, Vector2Int start, Vector2Int end,
|
||||
MapData mapData, PlayerData playerData)
|
||||
{
|
||||
if (start == end) return(true, null, 0);
|
||||
if (!IsValidPosition(width, height, start) || !IsValidPosition(width, height , end))
|
||||
|
||||
@ -9,6 +9,8 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using Logic.Action;
|
||||
using NodeCanvas.BehaviourTrees;
|
||||
using NodeCanvas.Framework;
|
||||
using UnityEngine;
|
||||
using RuntimeData;
|
||||
using Debug = UnityEngine.Debug;
|
||||
@ -37,29 +39,38 @@ namespace Logic.AI
|
||||
public class AILogic
|
||||
{
|
||||
public AILogicState AILogicState;
|
||||
|
||||
|
||||
private float _recordTime;
|
||||
private AIActionScoreCalculator _scoreCalculator;
|
||||
private AIActionGenerator _generator;
|
||||
|
||||
|
||||
private List<AIActionBase> RecordActions;
|
||||
private AIActionBase MaxScoreAction;
|
||||
|
||||
private MapData _mapData;
|
||||
private PlayerData _playerData;
|
||||
private AIConfigAsset _cfg;
|
||||
|
||||
|
||||
|
||||
private GameObject _logicObject;
|
||||
private BehaviourTreeOwner _btOwner;
|
||||
private AICalculatorData _data;
|
||||
|
||||
|
||||
public AILogic()
|
||||
{
|
||||
AILogicState = AILogicState.Prepare;
|
||||
RecordActions = new List<AIActionBase>();
|
||||
_scoreCalculator = new AIActionScoreCalculator();
|
||||
_cfg = Resources.Load<AIConfigAsset>("DataAssets/AIConfig");
|
||||
|
||||
_generator = new AIActionGenerator();
|
||||
|
||||
_logicObject = GameObject.Find("AIBT");
|
||||
_btOwner = _logicObject.GetComponent<BehaviourTreeOwner>();
|
||||
_data = new AICalculatorData();
|
||||
var data = _btOwner.blackboard.GetVariable<AICalculatorData>("Data");
|
||||
data.value = _data;
|
||||
}
|
||||
|
||||
|
||||
// 开始 AI 逻辑
|
||||
public void StartAILogic(MapData mapData, PlayerData playerData)
|
||||
{
|
||||
@ -67,8 +78,9 @@ namespace Logic.AI
|
||||
_mapData = mapData;
|
||||
_playerData = playerData;
|
||||
_generator.Init(_mapData, _playerData);
|
||||
_data.Refresh(mapData, playerData);
|
||||
}
|
||||
|
||||
|
||||
// 结束 AI 逻辑
|
||||
public void FinishAILogic()
|
||||
{
|
||||
@ -81,69 +93,97 @@ namespace Logic.AI
|
||||
if (AILogicState == AILogicState.Finished || AILogicState == AILogicState.Prepare) return;
|
||||
if (AILogicState == AILogicState.Pausing)
|
||||
{
|
||||
if (Time.time - _recordTime > DebugCenter.Instance.DebugAIActionTime) AILogicState = AILogicState.Playing;
|
||||
if (Time.time - _recordTime > DebugCenter.Instance.DebugAIActionTime)
|
||||
AILogicState = AILogicState.Playing;
|
||||
}
|
||||
|
||||
if (AILogicState == AILogicState.Playing)
|
||||
{
|
||||
Stopwatch sw = new Stopwatch();
|
||||
sw.Start();
|
||||
RecordActions.Clear();
|
||||
_generator.GeneratorOneStepActions(_mapData, _playerData, RecordActions);
|
||||
CalculateMaxScoreAction();
|
||||
if (sw.Elapsed.TotalMilliseconds > 20) Debug.Log($"{_generator.ActionType} 耗时:{sw.Elapsed.TotalMilliseconds} ms");
|
||||
|
||||
// AI 执行已结束
|
||||
if (!GetAILogicPermission())
|
||||
var index = 0;
|
||||
while (true)
|
||||
{
|
||||
AILogicState = AILogicState.Finished;
|
||||
}
|
||||
// 无行动可执行
|
||||
else if(MaxScoreAction == null)
|
||||
{
|
||||
AILogicState = AILogicState.Finished;
|
||||
FinishAILogic();
|
||||
}
|
||||
// 执行行动
|
||||
else
|
||||
{
|
||||
MaxScoreAction.Param.MapData = _mapData;
|
||||
MaxScoreAction.Param.RefreshParams();
|
||||
if (MainEditor.Instance.IsEditor && !MainEditor.Instance.IsGo) return;
|
||||
index++;
|
||||
_data.ClearCache();
|
||||
sw.Start();
|
||||
_btOwner.UpdateBehaviour();
|
||||
if (sw.Elapsed.TotalMilliseconds > 20)
|
||||
Debug.Log($"{_generator.ActionType} 耗时:{sw.Elapsed.TotalMilliseconds} ms");
|
||||
MainEditor.Instance.IsGo = false;
|
||||
|
||||
if (MaxScoreAction.ActionLogic is UnitAttackAction)
|
||||
{
|
||||
_mapData.GetGridDataByUnitId(MaxScoreAction.Param.UnitData.Id, out var grid);
|
||||
_mapData.GetGridDataByUnitId(MaxScoreAction.Param.TargetUnitData.Id, out var target);
|
||||
/*Debug.Log($"小兵攻击 {MaxScoreAction.Param.UnitData.Id}, " +
|
||||
$"位置{grid.Pos.X}, {grid.Pos.Y}, " +
|
||||
$"目标 {MaxScoreAction.Param.TargetUnitData.Id}, " +
|
||||
$"目标位置{target.Pos.X}, {target.Pos.Y}");*/
|
||||
}
|
||||
|
||||
if (MaxScoreAction.ActionLogic is UnitMoveAction)
|
||||
{
|
||||
_mapData.GetGridDataByUnitId(MaxScoreAction.Param.UnitData.Id, out var grid);
|
||||
/*Debug.Log($"小兵移动 {MaxScoreAction.Param.UnitData.Id}, " +
|
||||
$"位置{grid.Pos.X}, {grid.Pos.Y}, " +
|
||||
$"目标 {MaxScoreAction.Param.GridData.Pos.X}, {MaxScoreAction.Param.GridData.Pos.Y}");*/
|
||||
}
|
||||
|
||||
MaxScoreAction.CheckIsActionInPlayerSight();
|
||||
MaxScoreAction.ActionLogic.Execute(MaxScoreAction.Param);
|
||||
AILogicState = AILogicState.Pausing;
|
||||
_recordTime = Time.time;
|
||||
if (!MaxScoreAction.IsInSight) _recordTime -= DebugCenter.Instance.DebugAIActionTime - 0.04f;
|
||||
MaxScoreAction = null;
|
||||
if (index > 20 || _data.IsExcute || _data.IsFinish) break;
|
||||
}
|
||||
|
||||
if (_data.IsExcute)
|
||||
{
|
||||
AILogicState = AILogicState.Pausing;
|
||||
if (!_data.IsInSight) _recordTime -= DebugCenter.Instance.DebugAIActionTime - 0.04f;
|
||||
else _recordTime = Time.time;
|
||||
}
|
||||
else AILogicState = AILogicState.Finished;
|
||||
}
|
||||
|
||||
// if (AILogicState == AILogicState.Playing)
|
||||
// {
|
||||
// Stopwatch sw = new Stopwatch();
|
||||
// sw.Start();
|
||||
// RecordActions.Clear();
|
||||
// _generator.GeneratorOneStepActions(_mapData, _playerData, RecordActions);
|
||||
// CalculateMaxScoreAction();
|
||||
// if (sw.Elapsed.TotalMilliseconds > 20) Debug.Log($"{_generator.ActionType} 耗时:{sw.Elapsed.TotalMilliseconds} ms");
|
||||
//
|
||||
// // AI 执行已结束
|
||||
// if (!GetAILogicPermission())
|
||||
// {
|
||||
// AILogicState = AILogicState.Finished;
|
||||
// }
|
||||
// // 无行动可执行
|
||||
// else if(MaxScoreAction == null)
|
||||
// {
|
||||
// AILogicState = AILogicState.Finished;
|
||||
// FinishAILogic();
|
||||
// }
|
||||
// // 执行行动
|
||||
// else
|
||||
// {
|
||||
// MaxScoreAction.Param.MapData = _mapData;
|
||||
// MaxScoreAction.Param.RefreshParams();
|
||||
//
|
||||
// if (MaxScoreAction.ActionLogic is UnitAttackAction)
|
||||
// {
|
||||
// _mapData.GetGridDataByUnitId(MaxScoreAction.Param.UnitData.Id, out var grid);
|
||||
// _mapData.GetGridDataByUnitId(MaxScoreAction.Param.TargetUnitData.Id, out var target);
|
||||
// Debug.Log($"小兵攻击 {MaxScoreAction.Param.UnitData.Id}, " +
|
||||
// $"位置{grid.Pos.X}, {grid.Pos.Y}, " +
|
||||
// $"目标 {MaxScoreAction.Param.TargetUnitData.Id}, " +
|
||||
// $"目标位置{target.Pos.X}, {target.Pos.Y}");
|
||||
// }
|
||||
//
|
||||
// if (MaxScoreAction.ActionLogic is UnitMoveAction)
|
||||
// {
|
||||
// _mapData.GetGridDataByUnitId(MaxScoreAction.Param.UnitData.Id, out var grid);
|
||||
// Debug.Log($"小兵移动 {MaxScoreAction.Param.UnitData.Id}, " +
|
||||
// $"位置{grid.Pos.X}, {grid.Pos.Y}, " +
|
||||
// $"目标 {MaxScoreAction.Param.GridData.Pos.X}, {MaxScoreAction.Param.GridData.Pos.Y}");
|
||||
// }
|
||||
//
|
||||
// MaxScoreAction.CheckIsActionInPlayerSight();
|
||||
// MaxScoreAction.ActionLogic.Execute(MaxScoreAction.Param);
|
||||
// AILogicState = AILogicState.Pausing;
|
||||
// _recordTime = Time.time;
|
||||
// if (!MaxScoreAction.IsInSight) _recordTime -= DebugCenter.Instance.DebugAIActionTime - 0.04f;
|
||||
// MaxScoreAction = null;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
// 获取 AI 执行权限
|
||||
private bool GetAILogicPermission()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// 选取最高得分行动
|
||||
private void CalculateMaxScoreAction()
|
||||
{
|
||||
|
||||
@ -99,6 +99,14 @@ namespace Logic.Action
|
||||
TargetUnitData = target;
|
||||
}
|
||||
}
|
||||
public void OnParamChanged()
|
||||
{
|
||||
if (PlayerData != null) PlayerId = PlayerData.Id;
|
||||
if (UnitData != null) UnitId = UnitData.Id;
|
||||
if (CityData != null) CityId = CityData.Id;
|
||||
if (GridData != null) GridId = GridData.Id;
|
||||
if (TargetUnitData != null) TargetUnitId = TargetUnitData.Id;
|
||||
}
|
||||
|
||||
public CommonActionParams GetCopyParam()
|
||||
{
|
||||
@ -226,10 +234,10 @@ namespace Logic.Action
|
||||
ActionLogicDict = new Dictionary<CommonActionId, ActionLogicBase>();
|
||||
CommonActionId commonActionId;
|
||||
|
||||
// commonActionId = new CommonActionId { ActionType = CommonActionType.UnitMove };
|
||||
// ActionLogicDict[commonActionId] = new UnitMoveAction(commonActionId);
|
||||
// commonActionId = new CommonActionId { ActionType = CommonActionType.UnitAttack };
|
||||
// ActionLogicDict[commonActionId] = new UnitAttackAction(commonActionId);
|
||||
commonActionId = new CommonActionId { ActionType = CommonActionType.UnitMove };
|
||||
ActionLogicDict[commonActionId] = new UnitMoveAction(commonActionId);
|
||||
commonActionId = new CommonActionId { ActionType = CommonActionType.UnitAttack };
|
||||
ActionLogicDict[commonActionId] = new UnitAttackAction(commonActionId);
|
||||
|
||||
foreach (ResourceType resourceType in System.Enum.GetValues(typeof(ResourceType)))
|
||||
{
|
||||
|
||||
@ -145,6 +145,7 @@ namespace Logic
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
MainEditor.Instance.Update();
|
||||
GameLogic.Update();
|
||||
PlayerLogic.Update(MapData);
|
||||
//先处理玩家输入
|
||||
|
||||
38
My project/Assets/Scripts/Logic/Main/MainEditor.cs
Normal file
38
My project/Assets/Scripts/Logic/Main/MainEditor.cs
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* @Author: 白哉
|
||||
* @Description:
|
||||
* @Date: 2025年06月18日 星期三 15:06:25
|
||||
* @Modify:
|
||||
*/
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace Logic
|
||||
{
|
||||
public class MainEditor
|
||||
{
|
||||
public bool IsEditor = false;
|
||||
public bool IsGo = false;
|
||||
|
||||
public static MainEditor Instance = new MainEditor();
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (Input.GetKeyDown(KeyCode.F10))
|
||||
{
|
||||
IsEditor = true;
|
||||
Debug.LogWarning("F10");
|
||||
}
|
||||
if (Input.GetKeyDown(KeyCode.F11))
|
||||
{
|
||||
IsEditor = false;
|
||||
Debug.LogWarning("F11");
|
||||
}
|
||||
if (Input.GetKeyDown(KeyCode.Space))
|
||||
{
|
||||
IsGo = true;
|
||||
Debug.LogWarning("Space");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
3
My project/Assets/Scripts/Logic/Main/MainEditor.cs.meta
Normal file
3
My project/Assets/Scripts/Logic/Main/MainEditor.cs.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ade4142431a947a385ca79f56e997f1e
|
||||
timeCreated: 1750231509
|
||||
@ -169,9 +169,9 @@ namespace Logic
|
||||
continue;
|
||||
if (!mapData.GetPlayerDataByUnitId(unit.Id, out var player1))
|
||||
continue;
|
||||
if (curPlayer.Sight.CheckIsInSight(grid.Id) && !curPlayer.MeetPlayerSet.Contains(player1.Id))
|
||||
if (curPlayer.Sight.CheckIsInSight(grid.Id) && !curPlayer.MeetPlayers.Contains(player1.Id))
|
||||
{
|
||||
curPlayer.MeetPlayerSet.Add(player1.Id);
|
||||
curPlayer.MeetPlayers.Add(player1.Id);
|
||||
//如果是玩家,出发ui提示。加钱的操作要在ui提示关闭的时候由ui来出发
|
||||
if (curPlayer == mapData.PlayerMap.SelfPlayerData)
|
||||
{
|
||||
|
||||
@ -85,6 +85,8 @@ namespace Logic
|
||||
if (!mapData.GetCityDataByUnitId(unit2.Id, out var city2)) return false;
|
||||
if (!mapData.GetGridDataByUnitId(unit1.Id, out var grid1)) return false;
|
||||
if (!mapData.GetGridDataByUnitId(unit2.Id, out var grid2)) return false;
|
||||
player1.CurAttackPlayers.Add(player2.Id);
|
||||
player2.CurAttackPlayers.Add(player1.Id);
|
||||
mapData.OnUnitAttack(unit1, unit2);
|
||||
unit1.BeforeAttack(mapData, unit2);
|
||||
player1.TurnNoAttack = 0;
|
||||
|
||||
@ -51,7 +51,7 @@ public class RankingUI
|
||||
row.Find("Head3/Text").GetComponent<TextMeshProUGUI>().text = player.PlayerScore.ToString();
|
||||
row.Find("Head1/TextGroup/Text1").GetComponent<TextMeshProUGUI>().color = Color.black;
|
||||
|
||||
if (!selfPlayer.MeetPlayerSet.Contains(player.Id))
|
||||
if (!selfPlayer.MeetPlayers.Contains(player.Id))
|
||||
{
|
||||
forceName = "未知领袖";
|
||||
civName = "带领 <未知文明>";
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user