TH1/Unity/Assets/Scripts/TH1_Logic/Achievement/AchievementCondition.cs
2025-09-01 17:46:41 +08:00

618 lines
18 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年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);
// 用于记录回退,所以期望一定是返回 false 从而回退成就所以默认返回true
public virtual bool ReCheckCondition()
{
return true;
}
public virtual void ClearUserData() { }
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 void ClearUserData()
{
TrainCount = 0;
}
public override bool CheckCondition(AchievementItem item, MapData map)
{
return TrainCount >= TargetCount;
}
public override bool ReCheckCondition()
{
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;
}
}
}