2026-05-28 20:48:48 +08:00

1326 lines
46 KiB
C#
Raw Permalink 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: 2026年02月26日 星期四 15:02:29
* @Modify:
*/
using System.Collections.Generic;
using Logic;
using Logic.Action;
using Logic.AI;
using Logic.Skill;
using MemoryPack;
using RuntimeData;
using TH1_Core.Events;
using TH1_Core.Managers;
using TH1_Logic.Core;
namespace TH1_Logic.MatchConfig
{
[MemoryPackable]
public partial class MomentData
{
public List<MomentItemBase> Items;
[MemoryPackConstructor]
public MomentData()
{
Items = new List<MomentItemBase>();
}
public MomentData(MomentData copyData)
{
Items = new List<MomentItemBase>();
}
public void DeepCopy(MomentData copyData)
{
Items ??= new List<MomentItemBase>();
}
// MemoryPack 反序列化之后的后处理
[MemoryPackOnDeserialized]
public void OnAfterMemoryPackDeserialize()
{
Items ??= new List<MomentItemBase>();
EnsureMomentItems();
}
public void InitItems()
{
Items.Clear();
AddAllMomentItems();
}
private void EnsureMomentItems()
{
for (int i = Items.Count - 1; i >= 0; i--)
{
if (Items[i] is ExploitWonderMomentItem)
Items.RemoveAt(i);
}
var existingTypes = new HashSet<System.Type>();
foreach (var item in Items)
{
if (item != null)
existingTypes.Add(item.GetType());
}
AddAllMomentItems(existingTypes);
}
private void AddAllMomentItems(HashSet<System.Type> existingTypes = null)
{
var baseType = typeof(MomentItemBase);
var assembly = baseType.Assembly;
foreach (var type in assembly.GetTypes())
{
if (type.IsClass && !type.IsAbstract && baseType.IsAssignableFrom(type))
{
if (type == typeof(ExploitWonderMomentItem)) continue;
if (existingTypes != null && existingTypes.Contains(type)) continue;
var item = (MomentItemBase)System.Activator.CreateInstance(type);
Items.Add(item);
}
}
}
// 获取所有文化值 Moment
public List<MomentItemBase> GetCultureMoment()
{
List<MomentItemBase> cultureMoments = new List<MomentItemBase>();
foreach (var item in Items)
{
if (item.PlayerCultureValue > 0) cultureMoments.Add(item);
}
cultureMoments.Sort((a, b) =>
{
var aSubType = a.GetMomentSubType();
var bSubType = b.GetMomentSubType();
var aPriority = Table.Instance.CultureCardDataAssets.GetCultureTaskInfo(aSubType, out var aInfo) ? aInfo.Priority : int.MaxValue;
var bPriority = Table.Instance.CultureCardDataAssets.GetCultureTaskInfo(bSubType, out var bInfo) ? bInfo.Priority : int.MaxValue;
var priorityCompare = aPriority.CompareTo(bPriority);
return priorityCompare != 0 ? priorityCompare : aSubType.CompareTo(bSubType);
});
return cultureMoments;
}
}
[MemoryPackable]
[MemoryPackUnion(1, typeof(BattleHeroDieMomentItem))]
[MemoryPackUnion(2, typeof(BattleCaptainLostMomentItem))]
[MemoryPackUnion(3, typeof(BattleCityLostMomentItem))]
[MemoryPackUnion(4, typeof(BattleCityFireMomentItem))]
[MemoryPackUnion(5, typeof(BattleCityBesiegedMomentItem))]
[MemoryPackUnion(6, typeof(BattleSacrifyMomentItem))]
[MemoryPackUnion(7, typeof(BattleTreasureMomentItem))]
[MemoryPackUnion(8, typeof(BattleLevelupMomentItem))]
[MemoryPackUnion(9, typeof(BattleNarrowVictoryMomentItem))]
[MemoryPackUnion(10, typeof(BattleCounterKillMomentItem))]
[MemoryPackUnion(11, typeof(BattleLastStandMomentItem))]
[MemoryPackUnion(12, typeof(BattleKillGiantMomentItem))]
[MemoryPackUnion(13, typeof(BattleKillTreasureMomentItem))]
[MemoryPackUnion(14, typeof(BattleCaptureVillageMomentItem))]
[MemoryPackUnion(15, typeof(BattleOccupyFirstCityMomentItem))]
[MemoryPackUnion(16, typeof(BattleOccupyCityMomentItem))]
[MemoryPackUnion(17, typeof(Battle3KillMomentItem))]
[MemoryPackUnion(18, typeof(Battle4KillMomentItem))]
[MemoryPackUnion(19, typeof(BattleKillFullHealthMomentItem))]
[MemoryPackUnion(20, typeof(BattleKillOfficerMomentItem))]
[MemoryPackUnion(21, typeof(ExploitBigCityMomentItem))]
[MemoryPackUnion(22, typeof(ExploitWealth10MomentItem))]
[MemoryPackUnion(23, typeof(ExploitWealth20MomentItem))]
[MemoryPackUnion(24, typeof(ExploitWealth30MomentItem))]
[MemoryPackUnion(25, typeof(ExploitTech5MomentItem))]
[MemoryPackUnion(26, typeof(ExploitTech10MomentItem))]
[MemoryPackUnion(27, typeof(ExploitFirstBattleShipMomentItem))]
[MemoryPackUnion(28, typeof(ExploitFirstSwordsmanMomentItem))]
[MemoryPackUnion(29, typeof(ExploitFirstKnightMomentItem))]
[MemoryPackUnion(30, typeof(ExploitFirstCatapultMomentItem))]
[MemoryPackUnion(31, typeof(ExploitFirstGiantMomentItem))]
[MemoryPackUnion(32, typeof(ExploitFirstPreserveMomentItem))]
[MemoryPackUnion(33, typeof(ExploitFirstAcademyMomentItem))]
[MemoryPackUnion(34, typeof(ExploitFirstWindmillMomentItem))]
[MemoryPackUnion(35, typeof(ExploitFirstMarketMomentItem))]
[MemoryPackUnion(36, typeof(ExploitFirstForgeMomentItem))]
[MemoryPackUnion(37, typeof(ExploitFirstSawmillMomentItem))]
[MemoryPackUnion(38, typeof(ExploitFirstNavalBaseMomentItem))]
[MemoryPackUnion(39, typeof(DiplomacyBreakMomentItem))]
[MemoryPackUnion(40, typeof(Battle5KillMomentItem))]
[MemoryPackUnion(41, typeof(Battle6PlusKillMomentItem))]
[MemoryPackUnion(42, typeof(BattleOccupyCaptainMomentItem))]
[MemoryPackUnion(43, typeof(BattleKillHeroMomentItem))]
[MemoryPackUnion(44, typeof(BattleOccupyOurCityMomentItem))]
[MemoryPackUnion(45, typeof(BattleOccupyOurCaptainMomentItem))]
[MemoryPackUnion(46, typeof(ExploitWonderMomentItem))]
[MemoryPackUnion(47, typeof(ExploitWealth50MomentItem))]
[MemoryPackUnion(48, typeof(ExploitWealth100MomentItem))]
[MemoryPackUnion(49, typeof(ExploitTech20MomentItem))]
[MemoryPackUnion(50, typeof(ExploitFirstSuperCityMomentItem))]
[MemoryPackUnion(51, typeof(ExploitFirstBigPreserveMomentItem))]
[MemoryPackUnion(52, typeof(ExploitFirstBigAcademyMomentItem))]
[MemoryPackUnion(53, typeof(ExploitFirstBigWindmillMomentItem))]
[MemoryPackUnion(54, typeof(ExploitFirstBigMarketMomentItem))]
[MemoryPackUnion(55, typeof(ExploitFirstBigForgeMomentItem))]
[MemoryPackUnion(56, typeof(ExploitFirstBigSawmillMomentItem))]
[MemoryPackUnion(57, typeof(BattleHasTwoHeroMomentItem))]
[MemoryPackUnion(58, typeof(BattleHasThreeHeroMomentItem))]
[MemoryPackUnion(59, typeof(ExploitWonderPeaceMomentItem))]
[MemoryPackUnion(60, typeof(ExploitWonderKnowledgeMomentItem))]
[MemoryPackUnion(61, typeof(ExploitWonderTradeMomentItem))]
[MemoryPackUnion(62, typeof(ExploitWonderWealthMomentItem))]
[MemoryPackUnion(63, typeof(ExploitWonderPowerMomentItem))]
[MemoryPackUnion(64, typeof(ExploitWonderParkMomentItem))]
[MemoryPackUnion(65, typeof(ExploitWonderEyeMomentItem))]
public abstract partial class MomentItemBase
{
public bool IsExecute = false;
public int PlayerCultureValue = 0;
public int ExecuteCount = 0;
public abstract MomentSubType GetMomentSubType();
public virtual string GetFallbackDesc()
{
return string.Empty;
}
public virtual string GetProgressText(MapData map, PlayerData player)
{
return string.Empty;
}
public virtual void Execute(PlayerData player)
{
ExecuteCount++;
player.PlayerCultureInfo.PlayerCulture += PlayerCultureValue;
if (Main.MapData.PlayerMap.SelfPlayerData != player) return;
EventManager.Publish(new ShowUINotifyMoment()
{
MomentSubType = GetMomentSubType(),
Empire = Main.MapData.PlayerMap.SelfPlayerData.Empire
});
}
public virtual void OnTurnStart()
{
}
public virtual void OnActionExecuted(MapData mapData, ActionLogicBase action, CommonActionParams param)
{
}
public virtual void OnDamageOther(MapData mapData, PlayerData self, SettlementInfo info)
{
}
public virtual void OnDamaged(MapData mapData, PlayerData self, SettlementInfo info)
{
}
public virtual void OnCaptureCity(MapData mapData, PlayerData self, CityData city)
{
}
public virtual void OnTrainUnit(MapData mapData, PlayerData self, UnitData unit)
{
}
public virtual void OnTransformUnit(MapData mapData, PlayerData self, UnitData unit)
{
}
public virtual void OnNewResourceGet(MapData mapData, PlayerData self, ResourceType type, int level)
{
}
public virtual void OnAddHero(MapData mapData, PlayerData self, UnitFullType fullType)
{
}
public virtual void OnUpgradeHero(MapData mapData, PlayerData self, UnitFullType fullType)
{
}
public virtual void OnWonderBuild(MapData map, PlayerData player, WonderTypeEnum wonderType)
{
}
}
[MemoryPackable]
public partial class BattleHeroDieMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.BattleHeroDie;
// 暂时由外部写死
// public override void OnDamaged(MapData mapData, SettlementInfo info)
// {
// if (info.IsKill && info.DamageTarget.UnitType == UnitType.Giant) Excute();
// }
}
[MemoryPackable]
public partial class BattleCaptainLostMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.BattleCaptainLost;
}
[MemoryPackable]
public partial class BattleCityLostMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.BattleCityLost;
}
[MemoryPackable]
public partial class BattleCityFireMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.BattleCityFire;
}
[MemoryPackable]
public partial class BattleCityBesiegedMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.BattleCityBesieged;
}
[MemoryPackable]
public partial class BattleSacrifyMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.BattleSacrify;
}
[MemoryPackable]
public partial class BattleTreasureMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.BattleTreasure;
}
[MemoryPackable]
public partial class BattleLevelupMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.BattleLevelup;
}
[MemoryPackable]
public partial class BattleNarrowVictoryMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.BattleNarrowVictory;
}
[MemoryPackable]
public partial class BattleCounterKillMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.BattleCounterKill;
}
[MemoryPackable]
public partial class BattleLastStandMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.BattleLastStand;
}
[MemoryPackable]
public partial class BattleKillGiantMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.BattleKillGiant;
}
[MemoryPackable]
public partial class BattleKillTreasureMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.BattleKillTreasure;
}
[MemoryPackable]
public partial class BattleCaptureVillageMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.BattleCaptureVillage;
}
[MemoryPackable]
public partial class BattleOccupyFirstCityMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.BattleOccupyFirstCity;
public override void OnCaptureCity(MapData mapData, PlayerData self, CityData city)
{
if (IsExecute) return;
if (city.Level <= 5 && !city.IsCapital)
{
IsExecute = true;
Execute(self);
}
}
}
[MemoryPackable]
public partial class BattleOccupyCityMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.BattleOccupyCity;
}
[MemoryPackable]
public partial class Battle3KillMomentItem : MomentItemBase
{
public Dictionary<uint, int> UnitKillCount = new Dictionary<uint, int>();
public HashSet<uint> ExecutedUnits = new HashSet<uint>();
public override MomentSubType GetMomentSubType() => MomentSubType.Battle3Kill;
public override void OnTurnStart()
{
ExecutedUnits.Clear();
UnitKillCount.Clear();
}
public override void OnDamageOther(MapData mapData, PlayerData self, SettlementInfo info)
{
if (!info.IsKill) return;
if (ExecutedUnits.Contains(info.DamageOrigin.Id)) return;
UnitKillCount.TryAdd(info.DamageOrigin.Id, 0);
UnitKillCount[info.DamageOrigin.Id]++;
if (UnitKillCount[info.DamageOrigin.Id] >= 3)
{
ExecutedUnits.Add(info.DamageOrigin.Id);
Execute(self);
}
}
}
[MemoryPackable]
public partial class Battle4KillMomentItem : MomentItemBase
{
public Dictionary<uint, int> UnitKillCount = new Dictionary<uint, int>();
public HashSet<uint> ExecutedUnits = new HashSet<uint>();
public override MomentSubType GetMomentSubType() => MomentSubType.Battle4Kill;
public override void OnTurnStart()
{
ExecutedUnits.Clear();
UnitKillCount.Clear();
}
public override void OnDamageOther(MapData mapData, PlayerData self, SettlementInfo info)
{
if (!info.IsKill) return;
if (ExecutedUnits.Contains(info.DamageOrigin.Id)) return;
UnitKillCount.TryAdd(info.DamageOrigin.Id, 0);
UnitKillCount[info.DamageOrigin.Id]++;
if (UnitKillCount[info.DamageOrigin.Id] >= 4)
{
ExecutedUnits.Add(info.DamageOrigin.Id);
Execute(self);
}
}
}
[MemoryPackable]
public partial class BattleKillFullHealthMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.BattleKillFullHealth;
}
[MemoryPackable]
public partial class BattleKillOfficerMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.BattleKillOfficer;
}
[MemoryPackable]
public partial class ExploitBigCityMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.ExploitBigCity;
}
[MemoryPackable]
public partial class ExploitWealth10MomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.ExploitWealth10;
public override void OnActionExecuted(MapData mapData, ActionLogicBase action, CommonActionParams param)
{
if (IsExecute) return;
if (Main.PlayerLogic.GetPlayerCoinPerTurn(mapData, param.PlayerId) >= 10)
{
IsExecute = true;
Execute(param.PlayerData);
}
}
}
[MemoryPackable]
public partial class ExploitWealth20MomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.ExploitWealth20;
public override void OnActionExecuted(MapData mapData, ActionLogicBase action, CommonActionParams param)
{
if (IsExecute) return;
if (Main.PlayerLogic.GetPlayerCoinPerTurn(mapData, param.PlayerId) >= 20)
{
IsExecute = true;
Execute(param.PlayerData);
}
}
}
[MemoryPackable]
public partial class ExploitWealth30MomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.ExploitWealth30;
public override void OnActionExecuted(MapData mapData, ActionLogicBase action, CommonActionParams param)
{
if (IsExecute) return;
if (Main.PlayerLogic.GetPlayerCoinPerTurn(mapData, param.PlayerId) >= 30)
{
IsExecute = true;
Execute(param.PlayerData);
}
}
}
[MemoryPackable]
public partial class ExploitTech5MomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.ExploitTech5;
public override void OnActionExecuted(MapData mapData, ActionLogicBase action, CommonActionParams param)
{
if (IsExecute) return;
if (Main.PlayerLogic.GetPlayerTechPointPerTurn(mapData, param.PlayerId) >= 5)
{
IsExecute = true;
Execute(param.PlayerData);
}
}
}
[MemoryPackable]
public partial class ExploitTech10MomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.ExploitTech10;
public override void OnActionExecuted(MapData mapData, ActionLogicBase action, CommonActionParams param)
{
if (IsExecute) return;
if (Main.PlayerLogic.GetPlayerTechPointPerTurn(mapData, param.PlayerId) >= 10)
{
IsExecute = true;
Execute(param.PlayerData);
}
}
}
[MemoryPackable]
public partial class ExploitFirstBattleShipMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.ExploitFirstBattleShip;
public override void OnTrainUnit(MapData mapData, PlayerData self, UnitData unit)
{
if (IsExecute) return;
if (unit.UnitFullType.UnitType is UnitType.BomberShip or UnitType.KomeijiIndianBomberShip)
{
IsExecute = true;
Execute(self);
}
}
}
[MemoryPackable]
public partial class ExploitFirstSwordsmanMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.ExploitFirstSwordsman;
public override void OnTrainUnit(MapData mapData, PlayerData self, UnitData unit)
{
if (IsExecute) return;
if (unit.UnitFullType.UnitType == UnitType.Swordsman)
{
IsExecute = true;
Execute(self);
}
}
}
[MemoryPackable]
public partial class ExploitFirstKnightMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.ExploitFirstKnight;
public override void OnTrainUnit(MapData mapData, PlayerData self, UnitData unit)
{
if (IsExecute) return;
if (unit.UnitFullType.UnitType == UnitType.Knights)
{
IsExecute = true;
Execute(self);
}
}
}
[MemoryPackable]
public partial class ExploitFirstCatapultMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.ExploitFirstCatapult;
public override void OnTrainUnit(MapData mapData, PlayerData self, UnitData unit)
{
if (IsExecute) return;
if (unit.UnitFullType.UnitType == UnitType.Catapult)
{
IsExecute = true;
Execute(self);
}
}
}
[MemoryPackable]
public partial class ExploitFirstGiantMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.ExploitFirstGiant;
public override void OnTrainUnit(MapData mapData, PlayerData self, UnitData unit)
{
if (IsExecute) return;
if (unit.IsBigGuy())
{
IsExecute = true;
Execute(self);
}
}
// Hebi Lv3 需要通过合成Transform首次出现需要特判
public override void OnTransformUnit(MapData mapData, PlayerData self, UnitData unit)
{
if (IsExecute) return;
if (unit.UnitFullType.UnitType == UnitType.MoriyaHebi && unit.UnitFullType.UnitLevel >= 3)
{
IsExecute = true;
Execute(self);
}
}
}
[MemoryPackable]
public partial class ExploitFirstPreserveMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.ExploitFirstPreserve;
public override void OnNewResourceGet(MapData mapData, PlayerData self, ResourceType type, int level)
{
if (IsExecute) return;
if (type == ResourceType.Preserve)
{
IsExecute = true;
Execute(self);
}
}
public override void OnActionExecuted(MapData mapData, ActionLogicBase action, CommonActionParams param)
{
if (IsExecute) return;
if (action.ActionId.ResourceType == ResourceType.Preserve)
{
IsExecute = true;
Execute(param.PlayerData);
}
}
}
[MemoryPackable]
public partial class ExploitFirstAcademyMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.ExploitFirstAcademy;
public override void OnNewResourceGet(MapData mapData, PlayerData self, ResourceType type, int level)
{
if (IsExecute) return;
if (type == ResourceType.Academy)
{
IsExecute = true;
Execute(self);
}
}
public override void OnActionExecuted(MapData mapData, ActionLogicBase action, CommonActionParams param)
{
if (IsExecute) return;
if (action.ActionId.ResourceType == ResourceType.Academy)
{
IsExecute = true;
Execute(param.PlayerData);
}
}
}
[MemoryPackable]
public partial class ExploitFirstWindmillMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.ExploitFirstWindmill;
public override void OnNewResourceGet(MapData mapData, PlayerData self, ResourceType type, int level)
{
if (IsExecute) return;
if (type == ResourceType.Windmill)
{
IsExecute = true;
Execute(self);
}
}
public override void OnActionExecuted(MapData mapData, ActionLogicBase action, CommonActionParams param)
{
if (IsExecute) return;
if (action.ActionId.ResourceType == ResourceType.Windmill)
{
IsExecute = true;
Execute(param.PlayerData);
}
}
}
[MemoryPackable]
public partial class ExploitFirstMarketMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.ExploitFirstMarket;
public override void OnNewResourceGet(MapData mapData, PlayerData self, ResourceType type, int level)
{
if (IsExecute) return;
if (type == ResourceType.Market)
{
IsExecute = true;
Execute(self);
}
}
public override void OnActionExecuted(MapData mapData, ActionLogicBase action, CommonActionParams param)
{
if (IsExecute) return;
if (action.ActionId.ResourceType == ResourceType.Market)
{
IsExecute = true;
Execute(param.PlayerData);
}
}
}
[MemoryPackable]
public partial class ExploitFirstForgeMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.ExploitFirstForge;
public override void OnNewResourceGet(MapData mapData, PlayerData self, ResourceType type, int level)
{
if (IsExecute) return;
if (type == ResourceType.Forge)
{
IsExecute = true;
Execute(self);
}
}
public override void OnActionExecuted(MapData mapData, ActionLogicBase action, CommonActionParams param)
{
if (IsExecute) return;
if (action.ActionId.ResourceType == ResourceType.Forge)
{
IsExecute = true;
Execute(param.PlayerData);
}
}
}
[MemoryPackable]
public partial class ExploitFirstSawmillMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.ExploitFirstSawmill;
public override void OnNewResourceGet(MapData mapData, PlayerData self, ResourceType type, int level)
{
if (IsExecute) return;
if (type == ResourceType.Sawmill)
{
IsExecute = true;
Execute(self);
}
}
public override void OnActionExecuted(MapData mapData, ActionLogicBase action, CommonActionParams param)
{
if (IsExecute) return;
if (action.ActionId.ResourceType == ResourceType.Sawmill)
{
IsExecute = true;
Execute(param.PlayerData);
}
}
}
[MemoryPackable]
public partial class ExploitFirstNavalBaseMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.ExploitFirstNavalBase;
public override void OnNewResourceGet(MapData mapData, PlayerData self, ResourceType type, int level)
{
if (IsExecute) return;
if (type == ResourceType.NavalBase)
{
IsExecute = true;
Execute(self);
}
}
public override void OnActionExecuted(MapData mapData, ActionLogicBase action, CommonActionParams param)
{
if (IsExecute) return;
if (action.ActionId.ResourceType == ResourceType.NavalBase)
{
IsExecute = true;
Execute(param.PlayerData);
}
}
}
[MemoryPackable]
public partial class DiplomacyBreakMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.DiplomacyBreak;
}
[MemoryPackable]
public partial class Battle5KillMomentItem : MomentItemBase
{
public Dictionary<uint, int> UnitKillCount = new Dictionary<uint, int>();
public HashSet<uint> ExecutedUnits = new HashSet<uint>();
public override MomentSubType GetMomentSubType() => MomentSubType.Battle5Kill;
public override void OnTurnStart()
{
ExecutedUnits.Clear();
UnitKillCount.Clear();
}
public override void OnDamageOther(MapData mapData, PlayerData self, SettlementInfo info)
{
if (!info.IsKill) return;
if (ExecutedUnits.Contains(info.DamageOrigin.Id)) return;
UnitKillCount.TryAdd(info.DamageOrigin.Id, 0);
UnitKillCount[info.DamageOrigin.Id]++;
if (UnitKillCount[info.DamageOrigin.Id] >= 5)
{
ExecutedUnits.Add(info.DamageOrigin.Id);
Execute(self);
}
}
}
[MemoryPackable]
public partial class Battle6PlusKillMomentItem : MomentItemBase
{
public Dictionary<uint, int> UnitKillCount = new Dictionary<uint, int>();
public HashSet<uint> ExecutedUnits = new HashSet<uint>();
public override MomentSubType GetMomentSubType() => MomentSubType.Battle6PlusKill;
public override void OnTurnStart()
{
ExecutedUnits.Clear();
UnitKillCount.Clear();
}
public override void OnDamageOther(MapData mapData, PlayerData self, SettlementInfo info)
{
if (!info.IsKill) return;
if (ExecutedUnits.Contains(info.DamageOrigin.Id)) return;
UnitKillCount.TryAdd(info.DamageOrigin.Id, 0);
UnitKillCount[info.DamageOrigin.Id]++;
if (UnitKillCount[info.DamageOrigin.Id] > 5)
{
ExecutedUnits.Add(info.DamageOrigin.Id);
Execute(self);
}
}
}
[MemoryPackable]
public partial class BattleOccupyCaptainMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.BattleOccupyCaptain;
}
[MemoryPackable]
public partial class BattleKillHeroMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.BattleKillHero;
}
[MemoryPackable]
public partial class BattleOccupyOurCityMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.BattleOccupyOurCity;
}
[MemoryPackable]
public partial class BattleOccupyOurCaptainMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.BattleOccupyOurCaptain;
}
[MemoryPackable]
public partial class ExploitWonderMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.ExploitWonder;
public override void OnWonderBuild(MapData map, PlayerData player, WonderTypeEnum wonderType)
{
}
}
public abstract partial class ExploitSpecificWonderMomentItem : MomentItemBase
{
protected abstract WonderTypeEnum WonderType { get; }
protected abstract string FallbackDesc { get; }
public ExploitSpecificWonderMomentItem()
{
PlayerCultureValue = 5;
}
public override string GetFallbackDesc()
{
return FallbackDesc;
}
public override void OnWonderBuild(MapData map, PlayerData player, WonderTypeEnum wonderType)
{
if (IsExecute) return;
if (wonderType != WonderType) return;
IsExecute = true;
Execute(player);
}
public override string GetProgressText(MapData map, PlayerData player)
{
if (map == null || player == null) return string.Empty;
if (IsExecute) return string.Empty;
switch (WonderType)
{
case WonderTypeEnum.PEACE:
return $"{ClampProgress(player.TurnNoAttack, 5)}/5";
case WonderTypeEnum.KNOWLEDGE:
return GetTechProgress(player);
case WonderTypeEnum.TRADE:
return $"{ClampProgress(Main.PlayerLogic.GetConnectedCityCount(map, player), 5)}/5";
case WonderTypeEnum.WEALTH:
return $"{ClampProgress(player.PlayerCoin, 100)}/100";
case WonderTypeEnum.POWER:
return $"{ClampProgress(player.TotalKill, 10)}/10";
case WonderTypeEnum.PARK:
return $"{ClampProgress(Main.PlayerLogic.GetMaxCityLevel(map, player), 6)}/6";
case WonderTypeEnum.EYE:
return $"{GetTowerInSightCount(map, player)}/4";
default:
return string.Empty;
}
}
private static int ClampProgress(int value, int max)
{
if (value < 0) return 0;
return value > max ? max : value;
}
private static string GetTechProgress(PlayerData player)
{
if (player.TechTree.HasAllTech(player)) return "1/1";
return "0/1";
}
private static int GetTowerInSightCount(MapData map, PlayerData player)
{
int count = 0;
if (map.GridMap.GetGridDataByPos(0, 0, out var g1) && player.Sight.CheckIsInSight(g1.Id)) count++;
if (map.GridMap.GetGridDataByPos(0, (int)map.MapConfig.Height - 1, out var g2) && player.Sight.CheckIsInSight(g2.Id)) count++;
if (map.GridMap.GetGridDataByPos((int)map.MapConfig.Width - 1, 0, out var g3) && player.Sight.CheckIsInSight(g3.Id)) count++;
if (map.GridMap.GetGridDataByPos((int)map.MapConfig.Width - 1, (int)map.MapConfig.Height - 1, out var g4) && player.Sight.CheckIsInSight(g4.Id)) count++;
return count;
}
}
[MemoryPackable]
public partial class ExploitWonderPeaceMomentItem : ExploitSpecificWonderMomentItem
{
protected override WonderTypeEnum WonderType => WonderTypeEnum.PEACE;
protected override string FallbackDesc => "完成和平奇观";
public override MomentSubType GetMomentSubType() => MomentSubType.ExploitWonderPEACE;
}
[MemoryPackable]
public partial class ExploitWonderKnowledgeMomentItem : ExploitSpecificWonderMomentItem
{
protected override WonderTypeEnum WonderType => WonderTypeEnum.KNOWLEDGE;
protected override string FallbackDesc => "完成知识奇观";
public override MomentSubType GetMomentSubType() => MomentSubType.ExploitWonderKNOWLEDGE;
}
[MemoryPackable]
public partial class ExploitWonderTradeMomentItem : ExploitSpecificWonderMomentItem
{
protected override WonderTypeEnum WonderType => WonderTypeEnum.TRADE;
protected override string FallbackDesc => "完成贸易奇观";
public override MomentSubType GetMomentSubType() => MomentSubType.ExploitWonderTRADE;
}
[MemoryPackable]
public partial class ExploitWonderWealthMomentItem : ExploitSpecificWonderMomentItem
{
protected override WonderTypeEnum WonderType => WonderTypeEnum.WEALTH;
protected override string FallbackDesc => "完成财富奇观";
public override MomentSubType GetMomentSubType() => MomentSubType.ExploitWonderWEALTH;
}
[MemoryPackable]
public partial class ExploitWonderPowerMomentItem : ExploitSpecificWonderMomentItem
{
protected override WonderTypeEnum WonderType => WonderTypeEnum.POWER;
protected override string FallbackDesc => "完成战争奇观";
public override MomentSubType GetMomentSubType() => MomentSubType.ExploitWonderPOWER;
}
[MemoryPackable]
public partial class ExploitWonderParkMomentItem : ExploitSpecificWonderMomentItem
{
protected override WonderTypeEnum WonderType => WonderTypeEnum.PARK;
protected override string FallbackDesc => "完成文化奇观";
public override MomentSubType GetMomentSubType() => MomentSubType.ExploitWonderPARK;
}
[MemoryPackable]
public partial class ExploitWonderEyeMomentItem : ExploitSpecificWonderMomentItem
{
protected override WonderTypeEnum WonderType => WonderTypeEnum.EYE;
protected override string FallbackDesc => "完成探索奇观";
public override MomentSubType GetMomentSubType() => MomentSubType.ExploitWonderEYE;
}
[MemoryPackable]
public partial class ExploitWealth50MomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.ExploitWealth50;
public override void OnActionExecuted(MapData mapData, ActionLogicBase action, CommonActionParams param)
{
if (IsExecute) return;
if (Main.PlayerLogic.GetPlayerCoinPerTurn(mapData, param.PlayerId) >= 50)
{
IsExecute = true;
Execute(param.PlayerData);
}
}
}
[MemoryPackable]
public partial class ExploitWealth100MomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.ExploitWealth100;
public override void OnActionExecuted(MapData mapData, ActionLogicBase action, CommonActionParams param)
{
if (IsExecute) return;
if (Main.PlayerLogic.GetPlayerCoinPerTurn(mapData, param.PlayerId) >= 100)
{
IsExecute = true;
Execute(param.PlayerData);
}
}
}
[MemoryPackable]
public partial class ExploitTech20MomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.ExploitTech20;
public override void OnActionExecuted(MapData mapData, ActionLogicBase action, CommonActionParams param)
{
if (IsExecute) return;
if (Main.PlayerLogic.GetPlayerTechPointPerTurn(mapData, param.PlayerId) >= 20)
{
IsExecute = true;
Execute(param.PlayerData);
}
}
}
[MemoryPackable]
public partial class ExploitFirstSuperCityMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.ExploitFirstSuperCity;
public override void OnActionExecuted(MapData mapData, ActionLogicBase action, CommonActionParams param)
{
if (IsExecute) return;
var cityList = new List<CityData>();
mapData.GetCityDataListByPlayerId(param.PlayerId, cityList);
foreach (var city in cityList)
{
if (city.Level >= 10)
{
IsExecute = true;
Execute(param.PlayerData);
return;
}
}
}
}
[MemoryPackable]
public partial class ExploitFirstBigPreserveMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.ExploitFirstBigPreserve;
public override void OnNewResourceGet(MapData mapData, PlayerData self, ResourceType type, int level)
{
if (IsExecute) return;
if (type == ResourceType.Preserve && level == 2)
{
IsExecute = true;
Execute(self);
}
}
public override void OnActionExecuted(MapData mapData, ActionLogicBase action, CommonActionParams param)
{
if (IsExecute) return;
if (action.ActionId.ResourceType == ResourceType.Preserve && param.GridData != null && param.GridData.buildingLevel == 2)
{
IsExecute = true;
Execute(param.PlayerData);
}
}
}
[MemoryPackable]
public partial class ExploitFirstBigAcademyMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.ExploitFirstBigAcademy;
public override void OnNewResourceGet(MapData mapData, PlayerData self, ResourceType type, int level)
{
if (IsExecute) return;
if (type == ResourceType.Academy && level == 4)
{
IsExecute = true;
Execute(self);
}
}
public override void OnActionExecuted(MapData mapData, ActionLogicBase action, CommonActionParams param)
{
if (IsExecute) return;
if (action.ActionId.ResourceType == ResourceType.Academy && param.GridData != null && param.GridData.buildingLevel == 4)
{
IsExecute = true;
Execute(param.PlayerData);
}
}
}
[MemoryPackable]
public partial class ExploitFirstBigWindmillMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.ExploitFirstBigWindmill;
public override void OnNewResourceGet(MapData mapData, PlayerData self, ResourceType type, int level)
{
if (IsExecute) return;
if (type == ResourceType.Windmill && level == 5)
{
IsExecute = true;
Execute(self);
}
}
public override void OnActionExecuted(MapData mapData, ActionLogicBase action, CommonActionParams param)
{
if (IsExecute) return;
if (action.ActionId.ResourceType == ResourceType.Windmill && param.GridData != null && param.GridData.buildingLevel == 5)
{
IsExecute = true;
Execute(param.PlayerData);
}
}
}
[MemoryPackable]
public partial class ExploitFirstBigMarketMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.ExploitFirstBigMarket;
public override void OnNewResourceGet(MapData mapData, PlayerData self, ResourceType type, int level)
{
if (IsExecute) return;
if (type == ResourceType.Market && level == 5)
{
IsExecute = true;
Execute(self);
}
}
public override void OnActionExecuted(MapData mapData, ActionLogicBase action, CommonActionParams param)
{
if (IsExecute) return;
if (action.ActionId.ResourceType == ResourceType.Market && param.GridData != null && param.GridData.buildingLevel == 5)
{
IsExecute = true;
Execute(param.PlayerData);
}
}
}
[MemoryPackable]
public partial class ExploitFirstBigForgeMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.ExploitFirstBigForge;
public override void OnNewResourceGet(MapData mapData, PlayerData self, ResourceType type, int level)
{
if (IsExecute) return;
if (type == ResourceType.Forge && level == 4)
{
IsExecute = true;
Execute(self);
}
}
public override void OnActionExecuted(MapData mapData, ActionLogicBase action, CommonActionParams param)
{
if (IsExecute) return;
if (action.ActionId.ResourceType == ResourceType.Forge && param.GridData != null && param.GridData.buildingLevel == 4)
{
IsExecute = true;
Execute(param.PlayerData);
}
}
}
[MemoryPackable]
public partial class ExploitFirstBigSawmillMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.ExploitFirstBigSawmill;
public override void OnNewResourceGet(MapData mapData, PlayerData self, ResourceType type, int level)
{
if (IsExecute) return;
if (type == ResourceType.Sawmill && level == 5)
{
IsExecute = true;
Execute(self);
}
}
public override void OnActionExecuted(MapData mapData, ActionLogicBase action, CommonActionParams param)
{
if (IsExecute) return;
if (action.ActionId.ResourceType == ResourceType.Sawmill && param.GridData != null && param.GridData.buildingLevel == 5)
{
IsExecute = true;
Execute(param.PlayerData);
}
}
}
[MemoryPackable]
public partial class BattleHasTwoHeroMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.BattleHasTwoHero;
public override void Execute(PlayerData player)
{
ExecuteCount++;
player.PlayerCultureInfo.CultureCardList.Add(CultureCardType.Lv2Hero);
var card = CultureCardFactory.GetCultureCardBase(CultureCardType.Lv2Hero);
card.OnGetCultureCard(null, player);
player.PlayerCultureInfo.CardList.Add(card);
if (Main.MapData.PlayerMap.SelfPlayerData != player) return;
EventManager.Publish(new ShowUINotifyMoment()
{
MomentSubType = GetMomentSubType(),
Empire = Main.MapData.PlayerMap.SelfPlayerData.Empire
});
}
public override void OnUpgradeHero(MapData mapData, PlayerData self, UnitFullType fullType)
{
if (IsExecute) return;
if (fullType.UnitLevel != 2) return;
Execute(self);
IsExecute = true;
}
}
[MemoryPackable]
public partial class BattleHasThreeHeroMomentItem : MomentItemBase
{
public override MomentSubType GetMomentSubType() => MomentSubType.BattleHasThreeHero;
public override void Execute(PlayerData player)
{
ExecuteCount++;
player.PlayerCultureInfo.CultureCardList.Add(CultureCardType.Lv3Hero);
var card = CultureCardFactory.GetCultureCardBase(CultureCardType.Lv3Hero);
card.OnGetCultureCard(null, player);
player.PlayerCultureInfo.CardList.Add(card);
if (Main.MapData.PlayerMap.SelfPlayerData != player) return;
EventManager.Publish(new ShowUINotifyMoment()
{
MomentSubType = GetMomentSubType(),
Empire = Main.MapData.PlayerMap.SelfPlayerData.Empire
});
}
public override void OnUpgradeHero(MapData mapData, PlayerData self, UnitFullType fullType)
{
if (IsExecute) return;
if (fullType.UnitLevel != 3) return;
Execute(self);
IsExecute = true;
}
}
}