TH1/Unity/Assets/Scripts/TH1_Logic/Action/PlayerActionLogic.cs
2025-09-01 19:27:18 +08:00

416 lines
20 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* @Author: 白哉
* @Description: 行为逻辑类
* @Date: 2025年04月10日 星期四 11:04:44
* @Modify:
*/
using System;
using System.Collections.Generic;
using System.Linq;
using Logic.Action;
using RuntimeData;
using TH1_Core.Events;
using TH1_Core.Managers;
using TH1_Logic.Core;
using TH1Renderer;
using Unity.VisualScripting.Antlr3.Runtime.Tree;
using UnityEngine;
//这里是所有BuildAction派生子类的实现模块
namespace TH1_Logic.Action
{
public enum PlayerActionType
{
None,
OfferAlly,
AcceptAlly,
RefuseAlly,
BreakAlly,
Embassy,
Max
}
//UnitAction单位行动逻辑类
public class PlayerActionAction : ActionLogicBase
{
public PlayerActionAction(CommonActionId id) : base(id)
{
}
protected override bool Execute(CommonActionParams actionParams, bool isMoment)
{
//Step #1 鲁棒性判断
if (actionParams.PlayerData == null) return false;
if (actionParams.MainObjectType != MainObjectType.Player) return false;
if (actionParams.TargetPlayerData == null) return false;
if (!CheckCan(actionParams)) return false;
MapData map = actionParams.MapData;
PlayerData player = actionParams.PlayerData;
PlayerData targetPlayer = actionParams.TargetPlayerData;
if (!map.GetCapitalCityDataByPlayerId(actionParams.TargetPlayerData.Id, out var targetCity)) return false;
if (!map.GetCapitalCityDataByPlayerId(actionParams.PlayerData.Id, out var city)) return false;
if (!map.GetGridDataByCityId(targetCity.Id, out var targetGrid)) return false;
actionParams.PlayerData.DiplomacyData.GetCountryDiplomacyInfo(actionParams.TargetPlayerData.Id, out var dipInfo);
actionParams.TargetPlayerData.DiplomacyData.GetCountryDiplomacyInfo(actionParams.PlayerData.Id,out var dipInfo2);
//Step #2 处理大使馆
if (_actionId.PlayerActionType == PlayerActionType.Embassy)
{
//Step #1建立大使馆,
dipInfo.IsEmbassy = true;
//如果是真人玩家 在其他首都建立大使馆,更新对应城市的视觉,播放大使馆建立特效
if (actionParams.MapData == Main.MapData && player.Id == Main.MapData.PlayerMap.SelfPlayerId)
{
targetCity.CityInfoRenderMark = true;
targetGrid.VFXRenderMarkTreasure = true;
}
//如果是真人玩家 AI在真人玩家的首都建立大使馆更新对应城市的视觉,
if (actionParams.MapData == Main.MapData && targetPlayer.Id == Main.MapData.PlayerMap.SelfPlayerId)
{
city.CityInfoRenderMark = true;
}
//Step #2 如果对方还没有meet我加入meetlist
if(!targetPlayer.MeetPlayers.Contains(player.Id))
Main.PlayerLogic.AddMeetPlayer(map,targetPlayer,player);
//Step #3 更新大使馆周围一格的视野,会自动处理视觉部分
var gidList = map.GridMap.GetAroundGridIdList(1,targetGrid,true );
Main.PlayerLogic.UpdateSight(map,player,gidList);
//step #4 扣钱
player.PlayerWealth -= GetCost();
//Step #5 如果是真人玩家发起弹出一个announce,并关闭当前info
if (player.Id == Main.MapData.PlayerMap.SelfPlayerId)
{
var announcement = new ShowUIAnnounceDiplomacy { PlayerActionType = PlayerActionType.Embassy,PlayerId = player.Id,TargetPlayerId = targetPlayer.Id };
EventManager.Publish(announcement);
EventManager.Publish(new HideUIInfoDiplomacy());
}
//Step #6 如果是其他玩家发起但是目标是真人玩家弹出一个announce,并关闭当前info
if (targetPlayer.Id == Main.MapData.PlayerMap.SelfPlayerId)
{
var announcement = new ShowUIAnnounceDiplomacy { PlayerActionType = PlayerActionType.Embassy,PlayerId = player.Id,TargetPlayerId = targetPlayer.Id };
EventManager.Publish(announcement);
EventManager.Publish(new HideUIInfoDiplomacy());
}
return true;
}
//Step #3 处理申请结盟
if (_actionId.PlayerActionType == PlayerActionType.OfferAlly)
{
//Step #1 让对方收到我方邮件
dipInfo2.IsLeagueRequest = true;
//Step #2 如果对方还没有meet我加入meetlist
if(!targetPlayer.MeetPlayers.Contains(player.Id))
Main.PlayerLogic.AddMeetPlayer(map,targetPlayer,player);
//Step #3 如果是真人玩家发起弹出一个notify,并关闭当前info
if (Main.MapData == actionParams.MapData && player.Id == Main.MapData.PlayerMap.SelfPlayerId)
{
EventManager.Publish(new ShowUINotifyCommon(){UINotifyCommonType = UINotifyCommonType.DiplomacyOfferAlly});
EventManager.Publish(new HideUIInfoDiplomacy());
}
//Step #4 如果是真人玩家收到,那么要到下回合开始的时候才会触发
return true;
}
//Step #4 处理accept结盟
if (_actionId.PlayerActionType == PlayerActionType.AcceptAlly)
{
//Step #1 关闭我方的对方结盟信件请求标记,登记为盟友
dipInfo.IsLeagueRequest = false;
//如果我方也给对方发邮件,也关闭
dipInfo2.IsLeagueRequest = false;
dipInfo.DiplomacyState = DiplomacyState.League;
dipInfo2.DiplomacyState = DiplomacyState.League;
//Step #2 如果target是真map真人玩家 弹出一个presentationUI 提示达成盟友更新双方首都的cityinfo
if (map == Main.MapData && targetPlayer.Id == map.PlayerMap.SelfPlayerId)
{
var announcement = new ShowUIAnnounceDiplomacy { PlayerActionType = PlayerActionType.AcceptAlly,PlayerId = player.Id,TargetPlayerId = targetPlayer.Id };
EventManager.Publish(announcement);
city.CityInfoRenderMark = true;
targetCity.CityInfoRenderMark = true;
}
//Step #3 如果是真map我方是真人玩家更新双方首都的cityinfo
if (map == Main.MapData && player.Id == map.PlayerMap.SelfPlayerId)
{
city.CityInfoRenderMark = true;
targetCity.CityInfoRenderMark = true;
}
//Step #4 如果是真map双方有一个是真人玩家就要处理的视觉情况
if (map == Main.MapData && (player.Id == map.PlayerMap.SelfPlayerId) ||
(targetPlayer.Id == map.PlayerMap.SelfPlayerId))
{
foreach (var tunit in map.UnitMap.UnitList)
{
if(!map.GetPlayerDataByUnitId(tunit.Id,out var uplayer))continue;
if (uplayer.Id == map.PlayerMap.SelfPlayerId) continue;
if (uplayer.Id == targetPlayer.Id || uplayer.Id == player.Id)
tunit.RenderMark = true;
}
city.CityInfoRenderMark = true;
targetCity.CityInfoRenderMark = true;
EventManager.Publish(new HideUIInfoDiplomacy());
}
return true;
}
//Step #5 处理refuse结盟
if (_actionId.PlayerActionType == PlayerActionType.RefuseAlly)
{
//Step #1 关闭对方的结盟请求标记
dipInfo.IsLeagueRequest = false;
//Step #2 如果target是真map真人玩家 弹出一个presentationUI 提示,明确拒绝对方
if (map == Main.MapData && targetPlayer.Id == map.PlayerMap.SelfPlayerId)
{
var announcement = new ShowUIAnnounceDiplomacy { PlayerActionType = PlayerActionType.RefuseAlly,PlayerId = player.Id ,TargetPlayerId = targetPlayer.Id };
EventManager.Publish(announcement);
}
return true;
}
//Step #6 处理break结盟
if (_actionId.PlayerActionType == PlayerActionType.BreakAlly)
{
//Step #1 设置双方的外交状态为背盟
dipInfo.DiplomacyState = DiplomacyState.LeagueRupture;
dipInfo2.DiplomacyState = DiplomacyState.LeagueRupture;
var disbandList = new List<UnitData>();
//Step #2 所有单位跳过本回合,所有对方领土的单位自动解散
foreach (var unit in map.UnitMap.UnitList)
{
if(!map.GetPlayerDataByUnitId(unit.Id,out var uplayer))continue;
if(uplayer.Id != player.Id) continue;
if (!map.GetGridDataByUnitId(unit.Id, out var ugrid)) continue;
var gridHasPlayer = map.GetPlayerDataByTerritoryGridId(ugrid.Id, out var ugridPlayer);
//如果是对方领土上的己方unit强制解散
if (gridHasPlayer && ugridPlayer.Id == targetPlayer.Id)
{
//加入解散列表。不能就地解散因为会影响到map.UnitMap.UnitList
disbandList.Add(unit);
}
else
{
unit.ClearAPMPCP();
unit.RenderMark = true;
}
}
foreach (var unit in disbandList)
{
var action = ActionLogicFactory.GetActionLogic(new CommonActionId()
{ ActionType = CommonActionType.UnitAction, UnitActionType = UnitActionType.Disband });
if (action != null)
action.CompleteExecute(new CommonActionParams()
{
MainObjectType = MainObjectType.Unit,
MapData = map,
UnitData = unit,
PlayerData = player
},false);
}
//Step #3 如果target是真map真人玩家 弹出一个presentationUI 提示,明确背叛对方,更新双方cityinfo
if (map == Main.MapData && targetPlayer.Id == map.PlayerMap.SelfPlayerId)
{
var announcement = new ShowUIAnnounceDiplomacy { PlayerActionType = PlayerActionType.BreakAlly,PlayerId = player.Id,TargetPlayerId = targetPlayer.Id };
EventManager.Publish(announcement);
}
//Step #4 如果是真map双方有一个是真人玩家就要处理的视觉情况
if (map == Main.MapData && (player.Id == map.PlayerMap.SelfPlayerId) ||
(targetPlayer.Id == map.PlayerMap.SelfPlayerId))
{
foreach (var tunit in map.UnitMap.UnitList)
{
if(!map.GetPlayerDataByUnitId(tunit.Id,out var uplayer))continue;
if (uplayer.Id == map.PlayerMap.SelfPlayerId) continue;
if (uplayer.Id == targetPlayer.Id || uplayer.Id == player.Id)
tunit.RenderMark = true;
}
city.CityInfoRenderMark = true;
targetCity.CityInfoRenderMark = true;
EventManager.Publish(new HideUIInfoDiplomacy());
}
return true;
}
return false;
}
public override bool CheckCan(CommonActionParams actionParams)
{
//Step #1 鲁棒性判断
if (actionParams.PlayerData == null || !actionParams.PlayerData.Alive) return false;
if (actionParams.MainObjectType != MainObjectType.Player) return false;
if (actionParams.TargetPlayerData == null || !actionParams.TargetPlayerData.Alive ) return false;
//Step #2 判断钱够不够
if (GetCost() > actionParams.PlayerData.PlayerWealth)
return false;
//Step #3 如果不具备科技 return
if (!actionParams.PlayerData.TechTree.CheckActionCan(_actionId))
return false;
//Step #4 处理大使馆
if (_actionId.PlayerActionType == PlayerActionType.Embassy)
{
//如果对方没有原始首都,不可建立大使馆
actionParams.MapData.GetCapitalCityDataByPlayerId(actionParams.TargetPlayerData.Id,out var city);
if (!Main.CityLogic.CheckCradleCapital(actionParams.MapData, actionParams.TargetPlayerData, city))
return false;
//如果已经在对方建立了大使馆,不可再次建立大使馆
actionParams.PlayerData.DiplomacyData.GetCountryDiplomacyInfo(actionParams.TargetPlayerData.Id, out var dipInfo);
if (dipInfo.IsEmbassy) return false;
return true;
}
//Step #5 判断能否申请结盟
if (_actionId.PlayerActionType == PlayerActionType.OfferAlly)
{
actionParams.PlayerData.DiplomacyData.GetCountryDiplomacyInfo(actionParams.TargetPlayerData.Id, out var dipInfo);
//如果刚解除结盟或者已经结盟 return
if (dipInfo.DiplomacyState == DiplomacyState.League ||
dipInfo.DiplomacyState == DiplomacyState.LeagueRupture)
return false;
//如果对方已经有一个来自我方的结盟请求
actionParams.TargetPlayerData.DiplomacyData.GetCountryDiplomacyInfo(actionParams.PlayerData.Id,out var dipInfo2);
if (dipInfo2.IsLeagueRequest) return false;
return true;
}
//Step #6 && #7 判断能否refuse / accept 结盟
if (_actionId.PlayerActionType == PlayerActionType.RefuseAlly || _actionId.PlayerActionType == PlayerActionType.AcceptAlly)
{
actionParams.PlayerData.DiplomacyData.GetCountryDiplomacyInfo(actionParams.TargetPlayerData.Id, out var dipInfo);
//如果刚解除结盟或者已经结盟 return
if (dipInfo.DiplomacyState == DiplomacyState.League ||
dipInfo.DiplomacyState == DiplomacyState.LeagueRupture)
return false;
//如果对方没有结盟请求
//actionParams.TargetPlayerData.DiplomacyData.GetCountryDiplomacyInfo(actionParams.PlayerData.Id,out var dipInfo2);
if (!dipInfo.IsLeagueRequest) return false;
return true;
}
//Step #8 判断能否break结盟
if (_actionId.PlayerActionType == PlayerActionType.BreakAlly)
{
actionParams.PlayerData.DiplomacyData.GetCountryDiplomacyInfo(actionParams.TargetPlayerData.Id, out var dipInfo);
//如果没有结盟 return
if (dipInfo.DiplomacyState != DiplomacyState.League) return false;
//如果对方率先breakreturn
actionParams.TargetPlayerData.DiplomacyData.GetCountryDiplomacyInfo(actionParams.PlayerData.Id,out var dipInfo2);
if (dipInfo2.DiplomacyState == DiplomacyState.LeagueRupture) return false;
return true;
}
return false;
}
public override bool CheckShow(CommonActionParams actionParams)
{
//Step #1 鲁棒性判断
if (actionParams.PlayerData == null) return false;
if (actionParams.MainObjectType != MainObjectType.Player) return false;
if (actionParams.TargetPlayerData == null) return false;
actionParams.PlayerData.DiplomacyData.GetCountryDiplomacyInfo(actionParams.TargetPlayerData.Id, out var dipInfo);
//Step #2 如果与对方已经结盟,不能显示结盟按钮
if(dipInfo.DiplomacyState == DiplomacyState.League && _actionId.PlayerActionType == PlayerActionType.OfferAlly) return false;
//Step #2 如果未与结盟,不能显示接触结盟按钮
if(dipInfo.DiplomacyState != DiplomacyState.League && _actionId.PlayerActionType == PlayerActionType.BreakAlly) return false;
return true;
}
public override ActionShowState CheckShowState(CommonActionParams actionParams)
{
//Step #1 鲁棒性判断
if (actionParams.PlayerData == null) return ActionShowState.None;
if (actionParams.MainObjectType != MainObjectType.Player) return ActionShowState.None;
if (actionParams.TargetPlayerData == null) return ActionShowState.None;
MapData map = actionParams.MapData;
PlayerData player = actionParams.PlayerData;
PlayerData targetPlayer = actionParams.TargetPlayerData;
if (!map.GetCapitalCityDataByPlayerId(actionParams.TargetPlayerData.Id, out var city)) return ActionShowState.None;
if (!map.GetGridDataByCityId(city.Id, out var grid)) return ActionShowState.None;
actionParams.PlayerData.DiplomacyData.GetCountryDiplomacyInfo(actionParams.TargetPlayerData.Id, out var dipInfo);
actionParams.TargetPlayerData.DiplomacyData.GetCountryDiplomacyInfo(actionParams.PlayerData.Id,out var dipInfo2);
//Step #2 计算结盟按钮的情况
if (_actionId.PlayerActionType == PlayerActionType.OfferAlly)
{
//如果没有科技
if (!actionParams.PlayerData.TechTree.CheckActionCan(_actionId))
return ActionShowState.Unavailable;
//如果已经发送过,还没被回应
if(dipInfo2.IsLeagueRequest || dipInfo.DiplomacyState == DiplomacyState.LeagueRupture) return ActionShowState.Unavailable;
//如果已经结盟
if (dipInfo.DiplomacyState == DiplomacyState.League ) return ActionShowState.Finished;
//其他情况一律是available
return ActionShowState.Available;
}
//Step #3 计算breakAlly按钮的情况
if (_actionId.PlayerActionType == PlayerActionType.BreakAlly)
{
return ActionShowState.Available;
}
//Step #4 计算embassy按钮的情况
if (_actionId.PlayerActionType == PlayerActionType.Embassy)
{
//如果没有科技
if (!actionParams.PlayerData.TechTree.CheckActionCan(_actionId))
return ActionShowState.Unavailable;
//如果对方已经丢失原始首都
if (!map.GetCapitalCityDataByPlayerId(targetPlayer.Id, out var targetCapital)) return ActionShowState.None;
if (!Main.CityLogic.CheckCradleCapital(map, targetPlayer, targetCapital)) return ActionShowState.Unavailable;
//如果钱不够
if (player.PlayerWealth < GetCost()) return ActionShowState.Expensive;
//如果已经建立了大使馆
if (dipInfo.IsEmbassy) return ActionShowState.Finished;
//其他情况一律是available
return ActionShowState.Available;
}
return ActionShowState.None;
}
public override bool ExecuteViewBefore(CommonActionParams actionParams)
{
return false;
}
public override bool ExecuteViewAfter(CommonActionParams actionParams)
{
return false;
}
}
}