TH1/My project/Assets/Scripts/Logic/Achievement/AchievementCondition.cs
2025-05-15 14:56:15 +08:00

604 lines
17 KiB
C#

/*
* @Author: 白哉
* @Description: 成就条件
* @Date: 2025年05月13日 星期二 17:05:32
* @Modify:
*/
using System;
using System.Collections.Generic;
using RuntimeData;
using UnityEngine;
namespace Logic.Achievement
{
public enum AchievementConditionType
{
// 召唤 n 次伟人
TrainGiant,
// 建造 n 次奇观
BuildWonder,
// 奇观属于城市
WonderInCity,
// 奇观上有单位持续 n 回合
UnitOnWonder,
// 周围有 n 个建筑
AroundBuildings,
// 周围有 n 个奇观
AroundWonders,
// 周围有 n 个敌方单位
AroundEnemyUnits,
// 周围有 n 个友方单位
AroundSelfUnits,
// 周围有 n 个特定城市格子
AroundCityGrids,
// n 回合有击杀无伤亡
KillNoAttacked,
// 在地图中央竖线上
InMiddleLine,
// 从上至下第 n 行
InRow,
// 地图规格 n * m
MapSize,
// 夺回奇观城市 n 次
ReclaimWonderCity,
// 属于特定城市
InCity,
// 在 n 个不同城市建造过这个奇观
BuildInDifferentCity,
// 某 职阶 的伟人占领过奇观的拥有城市
OccupyWonderCity,
// 与特定城市通过 n 个 资源连接
ConnectCity,
// n 个不同伟人到过此处
DifferentGiantArrive,
// 间隔回合消灭从海上登陆该奇观的小兵
KillLandTroop,
// 建造 n 回合内信仰翻 n 倍
FaithTimes,
// 周围有 n 个文明的土地(曾经来自)
AroundCivilizationLand,
// 所在城市有 n 个 资源
InCityResources,
// 转换该奇观上的地方单位
ConvertUnit,
// 使用非 某阵营 持续 n 回合达成其余条件
NotCiv,
// 己方特定类型 unit type 在奇观上死亡
UnitTypeDie,
}
[Serializable]
public abstract class AchievementConditionBase : ISerializationCallbackReceiver
{
public virtual void OnBeforeSerialize() { }
public virtual void OnAfterDeserialize() { }
public abstract AchievementConditionType GetConditionType();
public abstract void ClearCache();
public abstract bool CheckCondition(AchievementItem item, MapData map);
public virtual void OnTurnStart(MapData map, PlayerData player)
{
}
public virtual void OnTrainUnit(MapData map, PlayerData player, CityData city, UnitData newUnit)
{
}
public virtual void OnBuildWonder(MapData map, PlayerData player, CityData city, GridData grid)
{
}
public virtual void OnKillUnit(MapData map, UnitData origin, UnitData target)
{
}
public virtual void OnUnitMove(MapData map, UnitData unit, GridData gridData)
{
}
public virtual string GetConditionDescription()
{
return string.Empty;
}
}
[Serializable]
public class TrainGiantCondition : AchievementConditionBase
{
public int TargetCount;
public GiantType TargetGiant;
public int TrainCount;
public TrainGiantCondition()
{
TargetCount = 1;
TrainCount = 0;
TargetGiant = GiantType.None;
}
public override AchievementConditionType GetConditionType()
{
return AchievementConditionType.TrainGiant;
}
public override void OnTrainUnit(MapData map, PlayerData player, CityData city, UnitData newUnit)
{
if (player.Id != map.PlayerMap.SelfPlayerId) return;
if (newUnit.GiantType == GiantType.None) return;
if (newUnit.GiantType != TargetGiant) return;
TrainCount ++;
}
public override void ClearCache()
{
}
public override bool CheckCondition(AchievementItem item, MapData map)
{
return TrainCount >= TargetCount;
}
}
[Serializable]
public class BuildWonderConditionCondition : AchievementConditionBase
{
public int TargetCount;
public WonderLibrary Wonder;
public int BuildCount;
public BuildWonderConditionCondition()
{
TargetCount = 1;
BuildCount = 0;
Wonder = WonderLibrary.EgyptianRemiliaPEACE;
}
public override AchievementConditionType GetConditionType()
{
return AchievementConditionType.BuildWonder;
}
public override void OnBuildWonder(MapData map, PlayerData player, CityData city, GridData grid)
{
if (player.Id != map.PlayerMap.SelfPlayerId) return;
if (grid.Wonder != Wonder) return;
BuildCount++;
}
public override void ClearCache()
{
}
public override bool CheckCondition(AchievementItem item, MapData map)
{
return BuildCount >= TargetCount;
}
}
[Serializable]
public class WonderInCityConditionCondition : AchievementConditionBase
{
public WonderLibrary Wonder;
public CityLibrary TargetCity;
public WonderInCityConditionCondition()
{
TargetCity = CityLibrary.Cairo;
}
public override AchievementConditionType GetConditionType()
{
return AchievementConditionType.WonderInCity;
}
public override void ClearCache()
{
}
public override bool CheckCondition(AchievementItem item, MapData map)
{
var cityList = new List<CityData>();
map.GetCityDataListByPlayerId(map.PlayerMap.SelfPlayerId, cityList);
foreach (var city in cityList)
{
if (city.CityInfo != TargetCity) continue;
foreach (var gridId in city.Territory.TerritoryArea)
{
if (!map.GridMap.GetGridDataByGid(gridId, out var gridData)) continue;
if (gridData.Wonder != Wonder) continue;
return true;
}
}
return false;
}
}
[Serializable]
public class UnitOnWonderConditionCondition : AchievementConditionBase
{
public WonderLibrary Wonder;
public GiantType Giant;
public int TargetTurns;
public uint RecordTurn;
public uint _gridId;
public UnitOnWonderConditionCondition()
{
Wonder = WonderLibrary.EgyptianRemiliaEYE;
Giant = GiantType.None;
TargetTurns = 1;
RecordTurn = 0;
_gridId = 0;
}
public override AchievementConditionType GetConditionType()
{
return AchievementConditionType.UnitOnWonder;
}
public override void OnTurnStart(MapData map, PlayerData player)
{
}
public override void ClearCache()
{
RecordTurn = 0;
}
public override bool CheckCondition(AchievementItem item, MapData map)
{
if (!map.GridMap.GetGridDataByGid(_gridId, out var gridData))
{
foreach (var grid in map.GridMap.GridList)
{
if (grid.Wonder != Wonder) continue;
gridData = grid;
break;
}
}
if (gridData == null)
{
RecordTurn = map.PlayerMap.SelfPlayerData.Turn;
return false;
}
_gridId = gridData.Id;
if (!map.GetUnitDataByGid(gridData.Id, out var unitData))
{
RecordTurn = map.PlayerMap.SelfPlayerData.Turn;
return false;
}
if (unitData.GiantType != Giant)
{
RecordTurn = map.PlayerMap.SelfPlayerData.Turn;
return false;
}
return RecordTurn + TargetTurns <= map.PlayerMap.SelfPlayerData.Turn;
}
}
[Serializable]
public class AroundBuildingsConditionCondition : AchievementConditionBase
{
public WonderLibrary Wonder;
public int OffsetX;
public int OffsetY;
public int TargetCount;
public TerrainType Terrain;
public TerrainFeature Feature;
public Vegetation Vegetation;
public ResourceType Resource;
private uint _gridId;
private uint _recordCount;
public AroundBuildingsConditionCondition()
{
OffsetX = 1;
OffsetY = 1;
TargetCount = 1;
Terrain = TerrainType.None;
Feature = TerrainFeature.None;
Vegetation = Vegetation.None;
Resource = ResourceType.None;
}
public override AchievementConditionType GetConditionType()
{
return AchievementConditionType.AroundBuildings;
}
public override void ClearCache()
{
}
public override bool CheckCondition(AchievementItem item, MapData map)
{
_recordCount = 0;
if (!map.GridMap.GetGridDataByGid(_gridId, out var gridData))
{
foreach (var grid in map.GridMap.GridList)
{
if (grid.Wonder != Wonder) continue;
gridData = grid;
break;
}
}
if (gridData == null) return false;
_gridId = gridData.Id;
var aroundGrids = map.GridMap.GetAroundGridData(OffsetX, OffsetY, gridData);
foreach (var aroundGrid in aroundGrids)
{
if (Terrain != TerrainType.None && aroundGrid.Terrain == Terrain) _recordCount++;
if (Feature != TerrainFeature.None && aroundGrid.Feature == Feature) _recordCount++;
if (Vegetation != Vegetation.None && aroundGrid.Vegetation == Vegetation) _recordCount++;
if (Resource != ResourceType.None && aroundGrid.Resource == Resource) _recordCount++;
}
return _recordCount >= TargetCount;
}
}
[Serializable]
public class AroundWondersConditionCondition : AchievementConditionBase
{
public WonderLibrary Wonder;
public WonderLibrary AroundWonder;
public int OffsetX;
public int OffsetY;
public int TargetCount;
private uint _gridId;
private uint _recordCount;
public AroundWondersConditionCondition()
{
OffsetX = 1;
OffsetY = 1;
TargetCount = 1;
}
public override AchievementConditionType GetConditionType()
{
return AchievementConditionType.AroundWonders;
}
public override void ClearCache()
{
}
public override bool CheckCondition(AchievementItem item, MapData map)
{
_recordCount = 0;
if (!map.GridMap.GetGridDataByGid(_gridId, out var gridData))
{
foreach (var grid in map.GridMap.GridList)
{
if (grid.Wonder != Wonder) continue;
gridData = grid;
break;
}
}
if (gridData == null) return false;
_gridId = gridData.Id;
var aroundGrids = map.GridMap.GetAroundGridData(OffsetX, OffsetY, gridData);
foreach (var aroundGrid in aroundGrids)
{
if (aroundGrid.Wonder == AroundWonder) _recordCount++;
}
return _recordCount >= TargetCount;
}
}
[Serializable]
public class AroundEnemyUnitsConditionCondition : AchievementConditionBase
{
public WonderLibrary Wonder;
public int TargetCount;
public int OffsetX;
public int OffsetY;
private uint _gridId;
private uint _recordCount;
public AroundEnemyUnitsConditionCondition()
{
OffsetX = 1;
OffsetY = 1;
TargetCount = 1;
}
public override AchievementConditionType GetConditionType()
{
return AchievementConditionType.AroundEnemyUnits;
}
public override void ClearCache()
{
}
public override bool CheckCondition(AchievementItem item, MapData map)
{
if (!map.GridMap.GetGridDataByGid(_gridId, out var gridData))
{
foreach (var grid in map.GridMap.GridList)
{
if (grid.Wonder != Wonder) continue;
gridData = grid;
break;
}
}
if (gridData == null) return false;
_gridId = gridData.Id;
var aroundGrids = map.GridMap.GetAroundGridData(OffsetX, OffsetY, gridData);
_recordCount = 0;
var selfUnits = new HashSet<UnitData>();
map.GetUnitDataListByPlayerId(map.PlayerMap.SelfPlayerId, selfUnits);
foreach (var aroundGrid in aroundGrids)
{
if (!map.GetUnitDataByGid(aroundGrid.Id, out var unit)) continue;
if (selfUnits.Contains(unit)) continue;
_recordCount++;
}
return _recordCount >= TargetCount;
}
}
[Serializable]
public class AroundSelfUnitsConditionCondition : AchievementConditionBase
{
public WonderLibrary Wonder;
public int TargetCount;
public int OffsetX;
public int OffsetY;
private uint _gridId;
private uint _recordCount;
public AroundSelfUnitsConditionCondition()
{
OffsetX = 1;
OffsetY = 1;
TargetCount = 1;
}
public override AchievementConditionType GetConditionType()
{
return AchievementConditionType.AroundSelfUnits;
}
public override void ClearCache()
{
}
public override bool CheckCondition(AchievementItem item, MapData map)
{
if (!map.GridMap.GetGridDataByGid(_gridId, out var gridData))
{
foreach (var grid in map.GridMap.GridList)
{
if (grid.Wonder != Wonder) continue;
gridData = grid;
break;
}
}
if (gridData == null) return false;
_gridId = gridData.Id;
var aroundGrids = map.GridMap.GetAroundGridData(OffsetX, OffsetY, gridData);
_recordCount = 0;
var selfUnits = new HashSet<UnitData>();
map.GetUnitDataListByPlayerId(map.PlayerMap.SelfPlayerId, selfUnits);
foreach (var aroundGrid in aroundGrids)
{
if (!map.GetUnitDataByGid(aroundGrid.Id, out var unit)) continue;
if (!selfUnits.Contains(unit)) continue;
_recordCount++;
}
return _recordCount >= TargetCount;
}
}
[Serializable]
public class AroundCityGridsConditionCondition : AchievementConditionBase
{
public WonderLibrary Wonder;
public CityLibrary TargetCity;
public int TargetCount;
public int OffsetX;
public int OffsetY;
private uint _gridId;
private uint _recordCount;
public AroundCityGridsConditionCondition()
{
OffsetX = 1;
OffsetY = 1;
}
public override AchievementConditionType GetConditionType()
{
return AchievementConditionType.AroundCityGrids;
}
public override void ClearCache()
{
}
public override bool CheckCondition(AchievementItem item, MapData map)
{
if (!map.GridMap.GetGridDataByGid(_gridId, out var gridData))
{
foreach (var grid in map.GridMap.GridList)
{
if (grid.Wonder != Wonder) continue;
gridData = grid;
break;
}
}
if (gridData == null) return false;
_gridId = gridData.Id;
var aroundGrids = map.GridMap.GetAroundGridData(OffsetX, OffsetY, gridData);
_recordCount = 0;
foreach (var aroundGrid in aroundGrids)
{
if (!map.GetCityDataByTerritoryGid(aroundGrid.Id, out var city)) continue;
if (city.CityInfo != TargetCity) continue;
_recordCount++;
}
return _recordCount >= TargetCount;
}
}
}