Compare commits

...

2 Commits

Author SHA1 Message Date
0453dd3ba8 增加保护 2026-05-09 16:57:17 +08:00
41a77ab922 备注 2026-05-08 17:03:23 +08:00
6 changed files with 147 additions and 50 deletions

View File

@ -173,9 +173,15 @@ namespace TH1_Core.Managers
public static void CheckNotCurQueue()
{
if (Main.MapData?.CurPlayer == null || Main.MapData?.PlayerMap?.SelfPlayerData == null) return;
if (Main.MapData.CurPlayer != Main.MapData.PlayerMap.SelfPlayerData)return;
var mapData = Main.MapData;
var playerMap = mapData?.PlayerMap;
var netData = mapData?.Net;
if (playerMap == null || netData == null) return;
var curPlayer = playerMap.GetPlayerData(netData.CurPlayerId);
var selfPlayer = playerMap.SelfPlayerData;
if (curPlayer == null || selfPlayer == null) return;
if (curPlayer != selfPlayer) return;
while(_taskNotCurPlayList.Count > 0)
_taskQueue.Enqueue(_taskNotCurPlayList.Dequeue());
}
@ -330,4 +336,4 @@ namespace TH1_Core.Managers
return controller.GetPos(actionType, out pos);
}
}
}
}

View File

@ -811,6 +811,7 @@ namespace RuntimeData
pA.GetCountryDiplomacyInfo(pidB,out var dipInfo);
return dipInfo.DiplomacyState == DiplomacyState.League;
}
public bool SameUnionByUnitId(uint uidA, uint uidB)
{
if (!GetPlayerDataByUnitId(uidA, out var pA)) return false;
@ -1351,7 +1352,8 @@ namespace RuntimeData
// 当场上有小兵受伤前
public void BeforeUnitDamaged(SettlementInfo info)
{
foreach (var unit in UnitMap.UnitList)
var copyUnits = new List<UnitData>(UnitMap.UnitList);
foreach (var unit in copyUnits)
{
//避免在遍历的时候直接改到了skillsList
var copy = new List<SkillBase>(unit.Skills);
@ -1393,7 +1395,7 @@ namespace RuntimeData
}
}
// 当场小兵死上有亡时
// 当场上有小兵死亡时
public void OnAnyUnitDie(MapData map, UnitData dieUnit)
{
var unitListCopy = new List<UnitData>(UnitMap.UnitList);

View File

@ -53,11 +53,11 @@ namespace RuntimeData
// 外交关系枚举
public enum DiplomacyState
{
NoDiplomacy,
Neutral,
League,
War,
LeagueRupture,
NoDiplomacy, // 未建交
Neutral, // 中立的
League, // 联盟
War, // 战争
LeagueRupture, // 联盟破裂
}
@ -1318,7 +1318,7 @@ namespace RuntimeData
}
// 主动攻击我的敌人信息
// 外交信息
[MemoryPackable]
public partial class DiplomacyData
{
@ -1453,6 +1453,9 @@ namespace RuntimeData
// 冷静期标记
[MemoryPackIgnore]
public int IsCalm;
// PlayerId 是我的队友 (逻辑相当于同盟)
public bool IsTeammate;
[MemoryPackConstructor]
public CountryDiplomacyInfo()
@ -1462,6 +1465,7 @@ namespace RuntimeData
IsEmbassy = false;
IsLeagueRupture = false;
IsLeagueRequest = false;
IsTeammate = false;
FeelingStrategyList = new List<FeelingStrategy>();
}
@ -1478,6 +1482,7 @@ namespace RuntimeData
IsLeagueRupture = copyData.IsLeagueRupture;
IsLeagueRequest = copyData.IsLeagueRequest;
IsCalm = copyData.IsCalm;
IsTeammate = copyData.IsTeammate;
}
public void DeepCopy(CountryDiplomacyInfo copyData)
@ -1493,6 +1498,7 @@ namespace RuntimeData
IsLeagueRupture = copyData.IsLeagueRupture;
IsLeagueRequest = copyData.IsLeagueRequest;
IsCalm = copyData.IsCalm;
IsTeammate = copyData.IsTeammate;
}
}

View File

@ -1,7 +1,8 @@
using System;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Logic.CrashSight;
using Logic.Pool;
using MemoryPack;
using Steamworks;
using TH1_Logic.Net;
@ -517,11 +518,17 @@ namespace TH1_Logic.Steam
// 轮询接收消息
public void PollMessages()
{
// 为每个连接轮询消息
foreach (var kvp in _connections)
using var pooled = THCollectionPool.GetListHandle<CSteamID>(out var peers);
peers.AddRange(_connections.Keys);
// 使用快照遍历,避免处理消息时修改 _connections 导致枚举器失效
for (int i = 0; i < peers.Count; i++)
{
var steamID = kvp.Key;
var connection = kvp.Value;
var steamID = peers[i];
if (!_connections.TryGetValue(steamID, out var connection))
{
continue;
}
PollMessagesForConnection(steamID, connection);
}

View File

@ -1594,6 +1594,18 @@ namespace Logic
public void UnitTypeTransform(MapData mapData, UnitData unitData, UnitType targetType,
GiantType giantType = GiantType.None, uint unitLevel = 0)
{
if (mapData == null || unitData == null)
{
LogSystem.LogError($"UnitTypeTransform param is null. mapData:{mapData} unitData:{unitData}");
return;
}
if (Table.Instance?.UnitTypeDataAssets == null)
{
LogSystem.LogError("UnitTypeTransform failed: Table.Instance.UnitTypeDataAssets is null.");
return;
}
//Debug.Log($"Check Transform Before APMPCP = {unitData.GetActionPoint(ActionPointType.Attack)} , {unitData.GetActionPoint(ActionPointType.Move)} ,{unitData.GetActionPoint(ActionPointType.Capture)} ");
//重新处理一下:
//生命周期: 1 . 卸载所有原来的skill
@ -1603,11 +1615,18 @@ namespace Logic
Table.Instance.UnitTypeDataAssets.GetUnitTypeInfo(targetType, giantType, unitLevel, out var targetInfo);
if (originInfo == null || targetInfo == null) return;
unitData.SkillCache ??= new List<SkillBase>();
unitData.Skills ??= new List<SkillBase>();
bool useCache = unitData.FullTypeCache == new UnitFullType(targetType, giantType, unitLevel);
using var pooledSkillCache = THCollectionPool.GetDictionaryHandle<SkillType, SkillBase>(out var skillCache);
using var pooledOriginSkills = THCollectionPool.GetListHandle<SkillBase>(out var originSkills);
foreach (var t in unitData.Skills) originSkills.Add(t);
foreach (var t in unitData.SkillCache) skillCache[t.GetSkillType()] = t;
foreach (var t in unitData.SkillCache)
{
if (t == null) continue;
skillCache[t.GetSkillType()] = t;
}
unitData.SkillCache.Clear();
using var pooledReservedSkillTypes = THCollectionPool.GetHashSetHandle<SkillType>(out var reservedSkillTypes);
@ -1616,7 +1635,18 @@ namespace Logic
// if (targetInfo.Skills.Contains(skillType)) continue;
if (skill == null) continue;
var fullType = new UnitFullType(targetType, giantType, unitLevel);
if (skill.ReservedOnTransform(unitData, fullType))
bool reserved;
try
{
reserved = skill.ReservedOnTransform(unitData, fullType);
}
catch (Exception e)
{
LogSystem.LogError($"UnitTypeTransform ReservedOnTransform failed. skill:{skill.GetType().Name} unit:{unitData.Id} ex:{e.Message}");
reserved = false;
}
if (reserved)
{
reservedSkillTypes.Add(skill.GetSkillType());
continue;
@ -1626,22 +1656,25 @@ namespace Logic
unitData.SkillCache.Add(skill);
}
foreach (var skillType in targetInfo.Skills)
if (targetInfo.Skills != null)
{
// 如果该技能已经作为Reserve保留在单位身上跳过不重建
if (reservedSkillTypes.Contains(skillType)) continue;
if (unitData.GetSkill(skillType, out var skill))
foreach (var skillType in targetInfo.Skills)
{
unitData.RemoveSkill(skill.GetSkillType(), mapData);
unitData.SkillCache.Add(skill);
// 如果该技能已经作为Reserve保留在单位身上跳过不重建
if (reservedSkillTypes.Contains(skillType)) continue;
if (unitData.GetSkill(skillType, out var skill))
{
unitData.RemoveSkill(skill.GetSkillType(), mapData);
unitData.SkillCache.Add(skill);
}
if (useCache && skillCache.TryGetValue(skillType, out var value)) unitData.AddOrOverrideSkill(value, mapData, unitData.Id);
else unitData.AddOrOverrideSkill(skillType, mapData, unitData.Id);
unitData.GetSkill(skillType, out var newSkill);
newSkill?.NewSkillOnTransform(unitData.SkillCache);
}
if (useCache && skillCache.TryGetValue(skillType, out var value)) unitData.AddOrOverrideSkill(value, mapData, unitData.Id);
else unitData.AddOrOverrideSkill(skillType, mapData, unitData.Id);
unitData.GetSkill(skillType, out var newSkill);
newSkill?.NewSkillOnTransform(unitData.SkillCache);
}
unitData.FullTypeCache = unitData.UnitFullType;
@ -1651,14 +1684,19 @@ namespace Logic
//Debug.Log($"Check Transform After APMPCP = {unitData.GetActionPoint(ActionPointType.Attack)} , {unitData.GetActionPoint(ActionPointType.Move)} ,{unitData.GetActionPoint(ActionPointType.Capture)} ");
//遍历所有techAtom,填加科技技能
foreach (var atom in unitData.Player(mapData).TechTree.TechAtomCacheSet)
var unitPlayer = unitData.Player(mapData);
var techAtoms = unitPlayer?.TechTree?.TechAtomCacheSet;
if (techAtoms != null)
{
if(!Table.Instance.TechDataAssets.GetTechAtomInfo(atom,out var info))continue;
if (!info.IsAddSkill) continue;
if (!info.CheckCondition(unitData.UnitFullType)) continue;
unitData.AddInitSkill(info.AddSkillType, mapData);
unitData.GetSkill(info.AddSkillType, out var newSkill);
newSkill?.NewSkillOnTransform(unitData.SkillCache);
foreach (var atom in techAtoms)
{
if(!Table.Instance.TechDataAssets.GetTechAtomInfo(atom,out var info))continue;
if (!info.IsAddSkill) continue;
if (!info.CheckCondition(unitData.UnitFullType)) continue;
unitData.AddInitSkill(info.AddSkillType, mapData);
unitData.GetSkill(info.AddSkillType, out var newSkill);
newSkill?.NewSkillOnTransform(unitData.SkillCache);
}
}
var originFullType = new UnitFullType(unitData.UnitType, unitData.GiantType, unitData.UnitLevel);
@ -1666,15 +1704,20 @@ namespace Logic
if (mapData.GetPlayerDataByUnitId(unitData.Id, out var playerData))
{
foreach (var kv in playerData.PlayerHeroData.HeroTaskDict)
kv.Value.OnTransformUnit(mapData, playerData, unitData);
foreach (var item in playerData.MomentData.Items) item.OnTransformUnit(mapData, playerData, unitData);
if (playerData.PlayerHeroData?.HeroTaskDict != null)
foreach (var kv in playerData.PlayerHeroData.HeroTaskDict)
kv.Value?.OnTransformUnit(mapData, playerData, unitData);
if (playerData.MomentData?.Items != null)
foreach (var item in playerData.MomentData.Items)
item?.OnTransformUnit(mapData, playerData, unitData);
// culture card 调用
playerData.PlayerCultureInfo.OnUnitTransform(mapData, unitData, originFullType, targetFullType);
playerData.PlayerCultureInfo?.OnUnitTransform(mapData, unitData, originFullType, targetFullType);
}
// Collect 调用
CollectManager.Instance.TransformUnitCollect(mapData, unitData, originFullType, targetFullType);
CollectManager.Instance?.TransformUnitCollect(mapData, unitData, originFullType, targetFullType);
}
public void PassiveMoveAway(MapData mapData,UnitData unitData)

View File

@ -1,5 +1,6 @@
using System.Collections;
using System.Collections.Generic;
using Logic.CrashSight;
using Logic.Multilingual;
using TMPro;
using UnityEngine;
@ -35,23 +36,44 @@ namespace TH1_Renderer
private void PrepareHouseList(int level)
private bool PrepareHouseList(int level)
{
if (LevelBar == null)
{
LogSystem.LogError("CityInfoMono.PrepareHouseList: LevelBar is null.");
return false;
}
if(_houseList == null)
_houseList = new List<CityInfoHouseMono>();
while (_houseList.Count < level)
{
if (HousePrefab == null)
{
LogSystem.LogError("CityInfoMono.PrepareHouseList: HousePrefab is null.");
return false;
}
var obj = Instantiate(HousePrefab,LevelBar);
if (obj == null)
{
LogSystem.LogError("CityInfoMono.PrepareHouseList: Instantiate HousePrefab failed.");
return false;
}
var mono = obj.GetComponent<CityInfoHouseMono>();
if (mono == null) continue;
if (mono == null)
{
LogSystem.LogError("CityInfoMono.PrepareHouseList: HousePrefab missing CityInfoHouseMono.");
Destroy(obj);
return false;
}
_houseList.Add(mono);
obj.SetActive(true);
}
for(int i = level;i < _houseList.Count;i++)
_houseList[i].gameObject.SetActive(false);
_houseList[i]?.gameObject.SetActive(false);
//TODO 这里check是否要强制刷新layout group
return true;
}
public void SetBG(bool self)
@ -61,9 +83,20 @@ namespace TH1_Renderer
public void SetLevelBar(bool showLevelBar,int level,int levelExp,int pop)
{
if (LevelBar == null)
{
LogSystem.LogError("CityInfoMono.SetLevelBar: LevelBar is null.");
return;
}
LevelBar.gameObject.SetActive(showLevelBar);
PrepareHouseList(level);
for (int i = 0; i < level; i++)
if (!showLevelBar) return;
level = Mathf.Max(0, level);
if (!PrepareHouseList(level)) return;
var houseCount = _houseList?.Count ?? 0;
var count = Mathf.Min(level, houseCount);
for (int i = 0; i < count; i++)
{
CityInfoHouseMono.CityInfoHouseStatusEnum status = i + 1 > Mathf.Abs(levelExp) ? CityInfoHouseMono.CityInfoHouseStatusEnum.NoExp:
(levelExp > 0 ? CityInfoHouseMono.CityInfoHouseStatusEnum.Exp: CityInfoHouseMono.CityInfoHouseStatusEnum.LackExp);
@ -138,4 +171,4 @@ namespace TH1_Renderer
}
}
}