Ничейные питомцы мода убираются сами

Раз в 5 с (на сервере, через 20 с после появления игрока) питомец нашего вида, которого нет в списке владения ни у одного игрока, удаляется.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
AlexCube
2026-10-13 14:13:59 +03:00
co-authored by Claude Opus 5.5
parent 533e6711d1
commit 74bd9eb2a1
2 changed files with 52 additions and 0 deletions
+1
View File
@@ -460,6 +460,7 @@ namespace NecromancerTome
// ВЫШЕ проверки на пустой список питомцев намеренно: трупы помечает Нож некроманта,
// и к тому, есть ли у игрока сейчас призванный питомец, они отношения не имеют.
CorpseLoot.RetryPendingTints(world);
Patch_ItemActionSpawnEntity_Spawn_PetLimit.RemoveOrphans(world);
if (TrackedPets.Count == 0)
{
+51
View File
@@ -517,6 +517,57 @@ namespace NecromancerTome
return best;
}
/// <summary>Ничейных питомцев - убрать (указание 13.10: «лучше чистить таких непривязанных»; стервятник
/// 14620 из старого сейва летал у игрока без хозяина). Раз в OrphanSweepInterval, только на сервере
/// (в одиночной игре он же), и не раньше OrphanGrace после появления игрока: до того список владения
/// игрока может быть ещё не прочитан из сейва, и под удаление попали бы все свои.</summary>
public static void RemoveOrphans(World _world)
{
if (!ConnectionManager.Instance.IsServer || _world.GetPrimaryPlayer() == null && _world.Players.list.Count == 0)
{
_orphanSweepAt = 0f;
return;
}
if (_orphanSweepAt == 0f)
{
_orphanSweepAt = Time.time + OrphanGrace;
return;
}
if (Time.time < _orphanSweepAt)
{
return;
}
_orphanSweepAt = Time.time + OrphanSweepInterval;
if (_orphanClassIds == null)
{
_orphanClassIds = new HashSet<int>();
foreach (string name in LimitedPets.Keys)
{
int id = EntityClass.GetId(name);
if (id != -1)
{
_orphanClassIds.Add(id);
}
}
}
for (int i = _world.EntityAlives.Count - 1; i >= 0; i--)
{
EntityAlive e = _world.EntityAlives[i];
if (e == null || e.IsDead() || !_orphanClassIds.Contains(e.entityClass) || Possession.IsPossessed(e) ||
OwnedByAnyPlayer(_world, e.entityId, e.entityClass))
{
continue;
}
Debug.Log("[NecromancerTome] SummonPatch: ничейный питомец " + e.EntityName + " (" + e.entityId + ") убран");
// WolfBag.DropFrom здесь нельзя: сумка одна на игрока, ничейный волк вывалил бы сумку своего.
_world.RemoveEntity(e.entityId, EnumRemoveEntityReason.Killed);
}
}
public const float OrphanGrace = 20f, OrphanSweepInterval = 5f;
static float _orphanSweepAt;
static HashSet<int> _orphanClassIds;
static bool OwnedByAnyPlayer(World _world, int _entityId, int _classId)
{
foreach (EntityPlayer p in _world.Players.list)