Upload from upload_mods.ps1

This commit is contained in:
Nathaniel Cosford
2025-06-04 16:44:53 +09:30
commit f1fbbe67bb
1722 changed files with 165268 additions and 0 deletions

View File

@@ -0,0 +1,290 @@
using System.Collections.Generic;
using System.Text;
using Audio;
using static UIPopupList;
public class EventsManagerRebirth
{
private static EventsManagerRebirth instance = null;
public static List<eventInfo> playerEvents = new List<eventInfo>();
private static bool loadedEvents = false;
public static int nextFeralSenseDay = 0;
public static int nextFeralSensePeriod = 0;
private static int nextScreamerNight = 0;
private static bool isScreamerEventActivated = false;
private static float updateCheck = 0f;
private static float updateTick = 30f;
private static float updateTickCheckScreamer = 60f;
public static bool HasInstance => instance != null;
public class eventInfo
{
public int playerID;
public float eventCheckScreamer;
public float eventCheckEntity;
public float eventCheckEvent;
public eventInfo()
{
}
public eventInfo(int _playerID,
float _eventCheckScreamer,
float _eventCheckEntity,
float _eventCheckEvent
)
{
this.playerID = _playerID;
this.eventCheckScreamer = _eventCheckScreamer;
this.eventCheckEntity = _eventCheckEntity;
this.eventCheckEvent = _eventCheckEvent;
}
}
public static EventsManagerRebirth Instance
{
get
{
return instance;
}
}
public static void Init()
{
EventsManagerRebirth.instance = new EventsManagerRebirth();
//Log.Out("Starting Events Manager");
//Load();
//Log.Out("EventsManagerRebirth-Init LOADED EVENTS");
loadedEvents = true;
int minimum = 2;
if (!GameManager.Instance.World.IsDaytime())
{
minimum = 3;
}
if (nextScreamerNight == 0)
{
nextScreamerNight = GameUtils.WorldTimeToDays(GameManager.Instance.World.worldTime) + Manager.random.RandomRange(minimum, 7);
//Log.Out("EventsManagerRebirth-Init nextScreamerNight: " + nextScreamerNight);
}
if (nextFeralSenseDay == 0)
{
nextFeralSenseDay = GameUtils.WorldTimeToDays(GameManager.Instance.World.worldTime) + Manager.random.RandomRange(minimum, 7);
nextFeralSensePeriod = Manager.random.RandomRange(0, 3);
}
ModEvents.GameUpdate.RegisterHandler(Update);
}
public static void AddEvent(int _playerID,
float _eventCheckScreamer,
float _eventCheckEntity,
float _eventCheckEvent
)
{
//Log.Out("EventsManagerRebirth-AddEvent START");
bool foundEvent = false;
foreach (eventInfo eventData in playerEvents)
{
if (eventData.playerID == _playerID)
{
foundEvent = true;
break;
}
}
if (!foundEvent)
{
eventInfo newEvent = new eventInfo();
newEvent.playerID = _playerID;
newEvent.eventCheckScreamer = _eventCheckScreamer;
newEvent.eventCheckEntity = _eventCheckEntity;
newEvent.eventCheckEvent = _eventCheckEvent;
playerEvents.Add(newEvent);
}
}
public static void Update()
{
if (RebirthVariables.noHit && (Time.time - RebirthVariables.noHitCheck) > RebirthVariables.noHitTick)
{
RebirthVariables.noHit = false;
//Log.Out("============================== NO HIT LOGGING ENDED ==============================");
}
if (!RebirthUtilities.IsHordeNight() && (Time.time - updateCheck) > updateTick)
{
updateCheck = Time.time;
//Log.Out("EventsManagerRebirth-Update TICK");
if (nextFeralSenseDay < GameUtils.WorldTimeToDays(GameManager.Instance.World.worldTime))
{
nextFeralSenseDay = GameUtils.WorldTimeToDays(GameManager.Instance.World.worldTime) + Manager.random.RandomRange(0, 3);
nextFeralSensePeriod = Manager.random.RandomRange(0, 3);
}
bool isClient = SingletonMonoBehaviour<ConnectionManager>.Instance.IsClient;
if (!isClient)
{
DictionaryList<int, AIDirectorPlayerState> trackedPlayers = GameManager.Instance.World.aiDirector.GetComponent<AIDirectorPlayerManagementComponent>().trackedPlayers;
for (int i = 0; i < trackedPlayers.list.Count; i++)
{
AIDirectorPlayerState aidirectorPlayerState = trackedPlayers.list[i];
if (!aidirectorPlayerState.Player.IsDead())
{
//Log.Out("EventsManagerRebirth-Update player: " + aidirectorPlayerState.Player.entityId);
bool foundPlayer = false;
foreach (eventInfo eventData in playerEvents)
{
if (eventData.playerID == aidirectorPlayerState.Player.entityId)
{
//Log.Out("EventsManagerRebirth-Update FOUND PLAYER");
foundPlayer = true;
string optionScreamerNights = RebirthVariables.customScreamerNights;
if (optionScreamerNights != "none")
{
//Log.Out("EventsManagerRebirth-Update SCREAMER NIGHTS TURNED ON nextScreamerNight: " + nextScreamerNight);
if (!GameManager.Instance.World.IsDaytime())
{
//Log.Out("EventsManagerRebirth-Update isScreamerEventActivated: " + isScreamerEventActivated);
if (!isScreamerEventActivated && (nextScreamerNight == GameUtils.WorldTimeToDays(GameManager.Instance.World.worldTime)))
{
isScreamerEventActivated = true;
//Log.Out("EventsManagerRebirth-Update isScreamerEventActivated: " + isScreamerEventActivated);
}
//Log.Out("EventsManagerRebirth-Update IS NIGHT");
if (isScreamerEventActivated && (Time.time - eventData.eventCheckScreamer) > updateTickCheckScreamer)
{
eventData.eventCheckScreamer = Time.time;
//Log.Out("EventsManagerRebirth-Update SCREAMER TICK");
int playerLevel = aidirectorPlayerState.Player.Progression.Level;
int topLevel = 150;
if (optionScreamerNights == "higher")
{
topLevel = 75;
}
else if (optionScreamerNights == "lower")
{
topLevel = 225;
}
if (playerLevel >= 20)
{
//Log.Out("EventsManagerRebirth-Update CAN SPAWN SCREAMER");
int playerLevelDifference = topLevel - playerLevel;
if (playerLevelDifference < 0)
{
playerLevelDifference = 0;
}
int baseChance = topLevel - playerLevelDifference;
int randomInt = aidirectorPlayerState.Player.rand.RandomRange(0, topLevel);
//Log.Out("EventsManagerRebirth-Update playerLevel: " + playerLevel);
//Log.Out("EventsManagerRebirth-Update topLevel: " + topLevel);
//Log.Out("EventsManagerRebirth-Update playerLevelDifference: " + playerLevelDifference);
//Log.Out("EventsManagerRebirth-Update randomInt: " + randomInt);
//Log.Out("EventsManagerRebirth-Update baseChance: " + baseChance);
if (randomInt < baseChance)
{
int searchDistance = 150;
List<Entity> entitiesInBounds = aidirectorPlayerState.Player.world.GetEntitiesInBounds(typeof(EntityZombieScreamerRebirth), BoundsUtils.BoundsForMinMax(aidirectorPlayerState.Player.position.x - searchDistance, aidirectorPlayerState.Player.position.y - 50, aidirectorPlayerState.Player.position.z - searchDistance, aidirectorPlayerState.Player.position.x + searchDistance, aidirectorPlayerState.Player.position.y + 50, aidirectorPlayerState.Player.position.z + searchDistance), new List<Entity>());
//Log.Out("EventsManagerRebirth-Update NUM Screamers: " + entitiesInBounds.Count);
if (entitiesInBounds.Count < RebirthVariables.customScreamerMax)
{
//Log.Out("EventsManagerRebirth-Update randomInt < baseChance SPAWNED SCREAMER");
RebirthUtilities.SpawnScreamer(aidirectorPlayerState.Player.position, (int)(playerLevel / 40));
}
else
{
//Log.Out("EventsManagerRebirth-Update TOO MANY SCREAMERS ALREADY");
}
}
else
{
//Log.Out("EventsManagerRebirth-Update randomInt >= baseChance NO SPAWN");
}
}
else
{
//Log.Out("EventsManagerRebirth-Update CAN'T SPAWN SCREAMER");
}
}
else
{
//Log.Out("EventsManagerRebirth-Update NEED TO WAIT A BIT");
}
}
else
{
if (isScreamerEventActivated)
{
isScreamerEventActivated = false;
if (optionScreamerNights == "higher")
{
nextScreamerNight = GameUtils.WorldTimeToDays(GameManager.Instance.World.worldTime) + Manager.random.RandomRange(1, 2);
}
else if (optionScreamerNights == "lower")
{
nextScreamerNight = GameUtils.WorldTimeToDays(GameManager.Instance.World.worldTime) + Manager.random.RandomRange(4, 6);
}
else
{
nextScreamerNight = GameUtils.WorldTimeToDays(GameManager.Instance.World.worldTime) + Manager.random.RandomRange(2, 4);
}
//Log.Out("EventsManagerRebirth-Update IS DAY, nextScreamerNight: " + nextScreamerNight);
}
//Log.Out("EventsManagerRebirth-Update IS DAY");
if (nextScreamerNight < GameUtils.WorldTimeToDays(GameManager.Instance.World.worldTime))
{
nextScreamerNight = GameUtils.WorldTimeToDays(GameManager.Instance.World.worldTime) + Manager.random.RandomRange(0, 3);
isScreamerEventActivated = false;
}
}
}
else
{
//Log.Out("EventsManagerRebirth-Update SCREAMER NIGHTS TURNED OFF");
}
}
}
if (!foundPlayer)
{
//Log.Out("EventsManagerRebirth-Update DIDN'T FIND PLAYER");
AddEvent(aidirectorPlayerState.Player.entityId, 0, 0, 0);
}
}
}
}
}
}
}

View File

@@ -0,0 +1,159 @@
using System.Collections.Generic;
using System.Linq;
public class GamestageManagerRebirth
{
private static GamestageManagerRebirth instance = null;
private static float gamestageUpdateTick = 10f;
private static float generalGroupsUpdateTick = 600f;
private static float biomeGroupsUpdateTick = 1200f;
private static float bloodMoonGroupsUpdateTick = 2400f;
private static float gamestageUpdateCheck = 0f;
private static float generalGroupsUpdateCheck = 0f;
private static float biomeGroupsUpdateCheck = 0f;
private static float bloodMoonGroupsUpdateCheck = 0f;
public static bool HasInstance => instance != null;
public static GamestageManagerRebirth Instance
{
get
{
return instance;
}
}
public static void Init()
{
GamestageManagerRebirth.instance = new GamestageManagerRebirth();
Log.Out("Starting Gamestage Manager");
ModEvents.GameUpdate.RegisterHandler(Update);
}
public static void Update()
{
/*if ((Time.time - prefabUpdateCheck) > prefabUpdateTick)
{
prefabUpdateCheck = Time.time;
List<PrefabInstance> dynamicPrefabs = GameManager.Instance.GetDynamicPrefabDecorator()?.GetDynamicPrefabs();
if (dynamicPrefabs != null)
{
foreach (PrefabInstance _prefabInstance in dynamicPrefabs)
{
if (_prefabInstance.prefab.DifficultyTier > 0)
{
bool cleared = true;
foreach (SleeperVolume volume in _prefabInstance.sleeperVolumes)
{
if (!volume.wasCleared)
{
cleared = false;
break;
}
}
if (cleared)
{
Log.Out("GamestageManagerRebirth-Update prefab was cleared: " + _prefabInstance.prefab.PrefabName + " (" + _prefabInstance.boundingBoxPosition.x + ", " + _prefabInstance.boundingBoxPosition.y + ", " + _prefabInstance.boundingBoxPosition.z + ")");
}
}
}
}
}*/
if ((Time.time - gamestageUpdateCheck) > gamestageUpdateTick)
{
gamestageUpdateCheck = Time.time;
//Log.Out("GamestageManagerRebirth-Update START");
if (RebirthUtilities.sleepersLow.Count == 0)
{
RebirthUtilities.BuildSpawnGroups();
RebirthUtilities.BuildSpecificEntityGroups(ref RebirthUtilities.generalGroups);
RebirthUtilities.BuildSpecificEntityGroups(ref RebirthUtilities.biomeGroups, true);
RebirthUtilities.BuildSpecificEntityGroups(ref RebirthUtilities.bloodMoonGroups, false, true);
/*foreach (var group in RebirthUtilities.generalGroups)
{
Log.Out("=============================== GENERAL GROUP ===============================");
Log.Out("GamestageManagerRebirth-Update group.min: " + group.Key.min);
Log.Out("GamestageManagerRebirth-Update group.max: " + group.Key.max);
int i = 0;
foreach (int entity in group.Value)
{
Log.Out("GamestageManagerRebirth-Update entity[" + i + "]: " + EntityClass.GetEntityClassName(entity));
i++;
}
}
foreach (var group in RebirthUtilities.biomeGroups)
{
Log.Out("=============================== BIOME GROUP ===============================");
Log.Out("GamestageManagerRebirth-Update group.min: " + group.Key.min);
Log.Out("GamestageManagerRebirth-Update group.max: " + group.Key.max);
int i = 0;
foreach (int entity in group.Value)
{
Log.Out("GamestageManagerRebirth-Update entity[" + i + "]: " + EntityClass.GetEntityClassName(entity));
i++;
}
}
foreach (var group in RebirthUtilities.bloodMoonGroups)
{
Log.Out("=============================== BLOOD MOON GROUP ===============================");
Log.Out("GamestageManagerRebirth-Update group.min: " + group.Key.min);
Log.Out("GamestageManagerRebirth-Update group.max: " + group.Key.max);
int i = 0;
foreach (int entity in group.Value)
{
Log.Out("GamestageManagerRebirth-Update entity[" + i + "]: " + EntityClass.GetEntityClassName(entity));
i++;
}
}*/
}
//Log.Out("GamestageManagerRebirth-Update time to process: " + watch.ElapsedMilliseconds + " ms");
//Build Bandit Groups and Survivor Groups
// Build weapon categories based on what the npc's bagitem property
}
if (!RebirthUtilities.IsHordeNight())
{
if ((Time.time - generalGroupsUpdateCheck) > generalGroupsUpdateTick)
{
generalGroupsUpdateCheck = Time.time;
if (RebirthUtilities.sleepersLow.Count > 0)
{
RebirthUtilities.BuildSpecificEntityGroups(ref RebirthUtilities.generalGroups);
}
}
if ((Time.time - biomeGroupsUpdateCheck) > biomeGroupsUpdateTick)
{
biomeGroupsUpdateCheck = Time.time;
if (RebirthUtilities.sleepersLow.Count > 0)
{
RebirthUtilities.BuildSpecificEntityGroups(ref RebirthUtilities.biomeGroups, true);
}
}
if ((Time.time - bloodMoonGroupsUpdateCheck) > bloodMoonGroupsUpdateTick)
{
bloodMoonGroupsUpdateCheck = Time.time;
if (RebirthUtilities.sleepersLow.Count > 0)
{
RebirthUtilities.BuildSpecificEntityGroups(ref RebirthUtilities.bloodMoonGroups, false, true);
}
}
}
}
}

View File

@@ -0,0 +1,1067 @@
using System.Collections.Generic;
public class HiresManagerRebirth
{
private static HiresManagerRebirth instance = null;
private static readonly object Locker = new object();
public static bool loadedHires = false;
private const string saveFile = "RebirthManager.dat";
private static ThreadManager.ThreadInfo dataSaveThreadInfo;
public static List<hireInfo> playerHires = new List<hireInfo>();
public static List<chunkObservers> observers = new List<chunkObservers>();
private static float updateCheck = 0f;
private static float updateTick = 10f;
public static bool HasInstance => instance != null;
public class chunkObservers
{
public int entityID;
public ChunkManager.ChunkObserver observerRef;
public chunkObservers()
{
}
public chunkObservers(int entityID, ChunkManager.ChunkObserver observerRef)
{
this.entityID = entityID;
this.observerRef = observerRef;
}
}
public class hireInfo
{
public int playerID;
public int hireID;
public string name;
public string className;
public Vector3 spawnPosition;
public Vector3 spawnRotation;
public Vector3 reSpawnPosition;
public Vector3 reSpawnRotation;
public int numKills;
public int numMine;
public int order;
public bool playerSpawned;
//eventually add backpack and toolbelt content
public hireInfo()
{
}
public hireInfo(int playerID,
int hireID,
string name,
string className,
Vector3 spawnPosition,
Vector3 spawnRotation,
Vector3 reSpawnPosition,
Vector3 reSpawnRotation,
int numKills,
int numMine,
int order,
bool playerSpawned = false
)
{
this.playerID = playerID;
this.hireID = hireID;
this.name = name;
this.className = className;
this.spawnPosition = spawnPosition;
this.spawnRotation = spawnRotation;
this.reSpawnPosition = reSpawnPosition;
this.reSpawnRotation = reSpawnRotation;
this.numKills = numKills;
this.numMine = numMine;
this.order = order;
this.playerSpawned = playerSpawned;
}
}
public static HiresManagerRebirth Instance
{
get
{
return instance;
}
}
public static void Init()
{
HiresManagerRebirth.instance = new HiresManagerRebirth();
//Log.Out("Starting Hires Manager");
Load();
//Log.Out("HiresManagerRebirth-Init LOADED HIRES");
loadedHires = true;
ModEvents.GameUpdate.RegisterHandler(Update);
}
public static void Update()
{
//lock (Locker)
{
if (!RebirthUtilities.IsHordeNight() && (Time.time - updateCheck) > updateTick)
{
updateCheck = Time.time;
bool isClient = SingletonMonoBehaviour<ConnectionManager>.Instance.IsClient;
if (!isClient)
{
for (int i = 0; i < observers.Count; i++)
{
bool foundHire = false;
foreach (hireInfo hire in playerHires)
{
if (observers[i].entityID == hire.hireID && (hire.order == 1 || hire.order == 2))
{
foundHire = true;
break;
}
}
if (!foundHire)
{
GameManager.Instance.RemoveChunkObserver(observers[i].observerRef);
observers.RemoveAt(i);
//Log.Out("HiresManagerRebirth-Update A REMOVED OBSERVER");
break;
}
}
List<EntityPlayer> spawnedPlayers = new List<EntityPlayer>();
foreach (hireInfo hire in playerHires)
{
EntityPlayer player = GameManager.Instance.World.GetEntity(hire.playerID) as EntityPlayer;
if (player)
{
if (player.IsSpawned() && !player.AttachedToEntity)
{
if (!spawnedPlayers.Contains(player))
{
spawnedPlayers.Add(player);
}
//Log.Out("HiresManagerRebirth-Update Player Spawned: " + hire.playerID);
if (hire.order == 1 || hire.order == 2)
{
bool foundHire = false;
foreach (chunkObservers observer in observers)
{
if (observer.entityID == hire.hireID)
{
foundHire = true;
break;
}
}
if (!foundHire)
{
//Log.Out("HiresManagerRebirth-Update ADDED CHUNK OBSERVER for: " + hire.hireID);
ChunkManager.ChunkObserver observerRef = GameManager.Instance.AddChunkObserver(hire.spawnPosition, false, 3, -1);
observers.Add(new chunkObservers(hire.hireID, observerRef));
}
}
else if (hire.order == 0)
{
for (int i = 0; i < observers.Count; i++)
{
if (observers[i].entityID == hire.hireID)
{
GameManager.Instance.RemoveChunkObserver(observers[i].observerRef);
observers.RemoveAt(i);
//Log.Out("HiresManagerRebirth-Update REMOVED OBSERVER");
break;
}
}
}
hire.playerSpawned = true;
}
else
{
//Log.Out("HiresManagerRebirth-Update Player NOT Spawned: " + hire.playerID);
}
}
////Log.Out("HiresManagerRebirth-Update hire.playerID: " + hire.playerID);
//Log.Out("HiresManagerRebirth-Update hire.hireID: " + hire.hireID);
//Log.Out("HiresManagerRebirth-Update hire.name: " + hire.name);
//Log.Out("HiresManagerRebirth-Update hire.className: " + hire.className);
//Log.Out("HiresManagerRebirth-Update hire.spawnPosition: " + hire.spawnPosition);
//Log.Out("HiresManagerRebirth-Update hire.spawnRotation: " + hire.spawnRotation);
//Log.Out("HiresManagerRebirth-Update hire.reSpawnPosition: " + hire.reSpawnPosition);
//Log.Out("HiresManagerRebirth-Update hire.reSpawnRotation: " + hire.reSpawnRotation);
////Log.Out("HiresManagerRebirth-Update hire.numKills: " + hire.numKills);
////Log.Out("HiresManagerRebirth-Update hire.numMine: " + hire.numMine);
////Log.Out("HiresManagerRebirth-Update hire.order: " + hire.order);
//Log.Out("HiresManagerRebirth-Update hire.playerSpawned: " + hire.playerSpawned);
}
//Log.Out("HiresManagerRebirth-Update observers.Count: " + observers.Count);
/*foreach (chunkObservers observer in observers)
{
//Log.Out("HiresManagerRebirth-Update observer: " + observer.entityID);
//Log.Out("HiresManagerRebirth-Update observer.observerRef.position: " + observer.observerRef.position);
}*/
foreach (EntityPlayer player in spawnedPlayers)
{
//Log.Out("HiresManagerRebirth-Update CHECKING PLAYER: " + player.entityId + " / OWNED HIRES: " + playerHires.Count);
if (player.Buffs.HasBuff("god") || player.Buffs.HasBuff("FuriousRamsayDelay-10") || player.Buffs.HasBuff("FuriousRamsayDelay-5") || player.AttachedToEntity)
{
continue;
}
Chunk chunkPlayer = (Chunk)GameManager.Instance.World.GetChunkFromWorldPos((int)player.position.x, (int)player.position.z);
for (int i = 0; i < playerHires.Count; i++)
{
hireInfo hire = playerHires[i];
//Log.Out("HiresManagerRebirth-Update CHECKING HIRE: " + hire.hireID + " / entity: " + hire.className + " / rsSpawnPosition: " + hire.reSpawnPosition);
if (hire.playerID == player.entityId)
{
EntityNPCRebirth hiredNPC = GameManager.Instance.World.GetEntity(hire.hireID) as EntityNPCRebirth;
if (hiredNPC == null)
{
//Log.Out("HiresManagerRebirth-Update HIRE COULDN'T BE FOUND IN WORLD");
Vector3 respawnPosition = new Vector3(0, 0, 0);
Vector3 respawnRotation = new Vector3(0, 0, 0);
if (hire.reSpawnPosition != new Vector3(0, 0, 0))
{
//Log.Out("HiresManagerRebirth-CheckHires RESPAWN POINT WAS SET, USING IT");
respawnPosition = hire.reSpawnPosition;
respawnRotation.y = player.rotation.y;
}
else
{
//Log.Out("HiresManagerRebirth-CheckHires NO RESPAWN POINT WAS SET, USING BEDROLL IF ONE EXISTS");
SpawnPosition spawnPoint = RebirthUtilities.GetSpawnPoint(player);
if (spawnPoint.IsUndef())
{
//Log.Out("HiresManagerRebirth-CheckHires NO BEDROLL FOUND, USING PLAYER'S POSITION");
respawnPosition = player.position;
respawnRotation.y = player.rotation.y;
continue;
}
else
{
//Log.Out("HiresManagerRebirth-CheckHires BEDROLL FOUND, USING IT");
respawnPosition = spawnPoint.position;
respawnRotation.y = player.rotation.y;
}
}
//Log.Out("HiresManagerRebirth-CheckHires Player's position: " + player.position);
//Log.Out("HiresManagerRebirth-CheckHires respawnPosition: " + respawnPosition);
Chunk chunkHire = (Chunk)GameManager.Instance.World.GetChunkFromWorldPos((int)respawnPosition.x, (int)respawnPosition.z);
//Log.Out("HiresManagerRebirth-Update chunkPlayer pos: " + chunkPlayer.ChunkPos);
if (chunkHire != null && (
((chunkHire.ChunkPos.x == chunkPlayer.ChunkPos.x) &&
(chunkHire.ChunkPos.z == chunkPlayer.ChunkPos.z)) ||
((chunkHire.ChunkPos.x == chunkPlayer.ChunkPos.x + 1) &&
(chunkHire.ChunkPos.z == chunkPlayer.ChunkPos.z)) ||
((chunkHire.ChunkPos.x == chunkPlayer.ChunkPos.x - 1) &&
(chunkHire.ChunkPos.z == chunkPlayer.ChunkPos.z)) ||
((chunkHire.ChunkPos.x == chunkPlayer.ChunkPos.x) &&
(chunkHire.ChunkPos.z == chunkPlayer.ChunkPos.z - 1)) ||
((chunkHire.ChunkPos.x == chunkPlayer.ChunkPos.x + 1) &&
(chunkHire.ChunkPos.z == chunkPlayer.ChunkPos.z - 1)) ||
((chunkHire.ChunkPos.x == chunkPlayer.ChunkPos.x - 1) &&
(chunkHire.ChunkPos.z == chunkPlayer.ChunkPos.z)) ||
((chunkHire.ChunkPos.x == chunkPlayer.ChunkPos.x) &&
(chunkHire.ChunkPos.z == chunkPlayer.ChunkPos.z + 1)) ||
((chunkHire.ChunkPos.x == chunkPlayer.ChunkPos.x + 1) &&
(chunkHire.ChunkPos.z == chunkPlayer.ChunkPos.z + 1)) ||
((chunkHire.ChunkPos.x == chunkPlayer.ChunkPos.x - 1) &&
(chunkHire.ChunkPos.z == chunkPlayer.ChunkPos.z))
)
)
{
//Log.Out("HiresManagerRebirth-Update chunkHire pos: " + chunkHire.ChunkPos);
Entity entity = player.world.GetEntity(hire.hireID);
if (entity == null)
{
//Log.Out("HiresManagerRebirth-Update ADDED MISSING HIRE: " + hire.hireID);
EntityNPCRebirth NewEntity = EntityFactory.CreateEntity(EntityClass.FromString(hire.className), respawnPosition, respawnRotation) as EntityNPCRebirth;
NewEntity.SetSpawnerSource(EnumSpawnerSource.StaticSpawner);
NewEntity._strMyName = hire.name;
RebirthUtilities.SetLeaderAndOwner(NewEntity.entityId, player.entityId);
NewEntity.IsEntityUpdatedInUnloadedChunk = true;
NewEntity.bWillRespawn = true;
NewEntity.bIsChunkObserver = true;
NewEntity.belongsPlayerId = player.entityId;
NewEntity.guardPosition = respawnPosition;
bool addObserver = false;
GameManager.Instance.World.SpawnEntityInWorld(NewEntity);
int oldHireID = hire.hireID;
hire.hireID = NewEntity.entityId;
hire.order = 1;
SaveCurrent();
//Log.Out("HiresManagerRebirth-Update player.entityId: " + player.entityId);
//Log.Out("HiresManagerRebirth-Update NewEntity.entityId: " + NewEntity.entityId);
RebirthManager.UpdateHireInfo(oldHireID, "newid", "", "", "", NewEntity.entityId);
if (hire.order == (int)EntityUtilities.Orders.None)
{
//Log.Out("HiresManagerRebirth-Update SET TO FOLLOW");
NewEntity.Buffs.SetCustomVar("CurrentOrder", (int)EntityUtilities.Orders.Follow);
}
else if (hire.order == (int)EntityUtilities.Orders.Follow)
{
//Log.Out("HiresManagerRebirth-Update SET TO STAY");
NewEntity.Buffs.SetCustomVar("CurrentOrder", (int)EntityUtilities.Orders.Stay);
addObserver = true;
}
else
{
//Log.Out("HiresManagerRebirth-Update SET TO STAY (GUARD)");
NewEntity.Buffs.SetCustomVar("CurrentOrder", (int)EntityUtilities.Orders.Stay);
addObserver = true;
}
RebirthUtilities.SetLeaderAndOwner(NewEntity.entityId, player.entityId);
bool foundObserver = false;
for (int j = 0; j < observers.Count; j++)
{
if (observers[j].entityID == hire.hireID)
{
//Log.Out("HiresManagerRebirth-CheckHires UPDATED OBSERVER, hire: " + hire.hireID);
observers[j].entityID = NewEntity.entityId;
foundObserver = true;
break;
}
}
float flMode = player.Buffs.GetCustomVar("varNPCModMode");
float flHalt = player.Buffs.GetCustomVar("varNPCModStopAttacking");
if (flMode == 0)
{
NewEntity.Buffs.AddBuff("buffNPCModFullControlMode");
}
else
{
NewEntity.Buffs.RemoveBuff("buffNPCModFullControlMode");
}
if (flHalt == 1)
{
NewEntity.Buffs.AddBuff("buffNPCModStopAttacking");
}
else
{
NewEntity.Buffs.RemoveBuff("buffNPCModStopAttacking");
}
if (addObserver && !foundObserver)
{
//Log.Out("HiresManagerRebirth-CheckHires ADDED CHUNK OBSERVER, hire: " + hire.hireID);
ChunkManager.ChunkObserver observerRef = GameManager.Instance.AddChunkObserver(NewEntity.position, false, 3, -1);
observers.Add(new chunkObservers(NewEntity.entityId, observerRef));
}
}
else
{
//Log.Out("HiresManagerRebirth-CheckHires HIRE EXISTS AT THIS POSITION: " + entity.position);
}
}
}
}
}
}
}
else
{
/*foreach (hireInfo hire in playerHires)
{
Log.Out("HiresManagerRebirth-Update hire.hireID: " + hire.hireID);
Log.Out("HiresManagerRebirth-Update hire.className: " + hire.className);
Log.Out("HiresManagerRebirth-Update hire.playerSpawned: " + hire.playerSpawned);
}*/
}
}
}
}
public static void RemoveHire(int entityID, bool removeObserver = false)
{
//Log.Out("HiresManagerRebirth-RemoveHire entityID: " + entityID);
bool foundHire = false;
for (int i = 0; i < playerHires.Count; i++)
{
//Log.Out("HiresManagerRebirth-RemoveHire 2, playerHires[i].hireID: " + playerHires[i].hireID);
if (playerHires[i].hireID == entityID)
{
foundHire = true;
//Log.Out("HiresManagerRebirth-RemoveHire 3");
if (SingletonMonoBehaviour<ConnectionManager>.Instance.IsServer)
{
//Log.Out("HiresManagerRebirth-RemoveHire IS SERVER");
if (RebirthUtilities.SendToClient(playerHires[i].playerID))
{
SingletonMonoBehaviour<ConnectionManager>.Instance.SendPackage(NetPackageManager.GetPackage<NetPackageRemoveHireRebirth>().Setup(entityID
), false, playerHires[i].playerID, -1, -1, null, 192);
//Log.Out("HiresManagerRebirth-RemoveHire SENT TO CLIENT");
}
playerHires.RemoveAt(i);
if (removeObserver)
{
//Log.Out("HiresManagerRebirth-RemoveHire 4");
for (int j = 0; j < observers.Count; j++)
{
if (observers[j].entityID == entityID)
{
//Log.Out("HiresManagerRebirth-RemoveHire REMOVED OBSERVER, hire: " + entityID);
GameManager.Instance.RemoveChunkObserver(observers[j].observerRef);
observers.RemoveAt(j);
break;
}
}
}
SaveCurrent();
}
else
{
SingletonMonoBehaviour<ConnectionManager>.Instance.SendToServer(NetPackageManager.GetPackage<NetPackageRemoveHireRebirth>().Setup(entityID
), false);
playerHires.RemoveAt(i);
//Log.Out("HiresManagerRebirth-RemoveHire SENT TO SERVER");
}
//Log.Out("HiresManagerRebirth-RemoveHire Removed Hire: " + entityID);
break;
}
}
if (!foundHire)
{
//Log.Out("HiresManagerRebirth-RemoveHire COULD NOT FIND HIRE");
if (SingletonMonoBehaviour<ConnectionManager>.Instance.IsClient)
{
//Log.Out("HiresManagerRebirth-RemoveHire IS CLIENT");
SingletonMonoBehaviour<ConnectionManager>.Instance.SendToServer(NetPackageManager.GetPackage<NetPackageRemoveHireRebirth>().Setup(entityID
), false);
}
}
}
public static void AddHire(int playerID,
int hireID,
string name,
string className,
Vector3 spawnPosition,
Vector3 spawnRotation,
Vector3 reSpawnPosition,
Vector3 reSpawnRotation,
int numKills,
int numMine,
int order,
bool playerSpawned
)
{
bool foundHire = false;
foreach (hireInfo hire in playerHires)
{
if (hire.playerID == playerID && hire.hireID == hireID)
{
foundHire = true;
break;
}
}
if (!foundHire)
{
hireInfo newHire = new hireInfo();
newHire.playerID = playerID;
newHire.hireID = hireID;
newHire.name = name;
newHire.className = className;
newHire.spawnPosition = spawnPosition;
newHire.spawnRotation = spawnRotation;
newHire.reSpawnPosition = reSpawnPosition;
newHire.reSpawnRotation = reSpawnRotation;
newHire.numMine = numKills;
newHire.numKills = numMine;
newHire.order = order;
newHire.playerSpawned = playerSpawned;
playerHires.Add(newHire);
EntityAlive entity = GameManager.Instance.World.GetEntity(hireID) as EntityAlive;
if (entity != null)
{
entity.Buffs.SetCustomVar("$Leader", playerID);
}
}
if (SingletonMonoBehaviour<ConnectionManager>.Instance.IsServer)
{
SaveCurrent();
if (RebirthUtilities.SendToClient(playerID))
{
SingletonMonoBehaviour<ConnectionManager>.Instance.SendPackage(NetPackageManager.GetPackage<NetPackageAddHireRebirth>().Setup(playerID,
hireID,
name,
className,
spawnPosition,
spawnRotation,
reSpawnPosition,
reSpawnRotation,
numKills,
numMine,
order,
playerSpawned
), false, playerID, -1, -1, null, 192);
//Log.Out("HiresManagerRebirth-AddHire SENT TO CLIENT");
}
}
else
{
SingletonMonoBehaviour<ConnectionManager>.Instance.SendToServer(NetPackageManager.GetPackage<NetPackageAddHireRebirth>().Setup(playerID,
hireID,
name,
className,
spawnPosition,
spawnRotation,
reSpawnPosition,
reSpawnRotation,
numKills,
numMine,
order,
playerSpawned
), false);
//Log.Out("HiresManagerRebirth-AddHire SENT TO SERVER");
}
//Log.Out("HiresManagerRebirth-AddHire Added Hire: " + hireID);
}
public static void UpdateHireInfo(int hiredID, string action, string value, string position = "", string rotation = "", int newhiredID = -1)
{
//Log.Out("HiresManagerRebirth-UpdateHireInfo START");
//Log.Out("HiresManagerRebirth-UpdateHireInfo hireID: " + hiredID);
//Log.Out("HiresManagerRebirth-UpdateHireInfo action: " + action);
//Log.Out("HiresManagerRebirth-UpdateHireInfo value: " + value);
//Log.Out("HiresManagerRebirth-UpdateHireInfo position: " + position);
//Log.Out("HiresManagerRebirth-UpdateHireInfo rotation: " + rotation);
//Log.Out("HiresManagerRebirth-UpdateHireInfo newhiredID: " + newhiredID);
foreach (hireInfo hire in playerHires)
{
if (hire.hireID == hiredID || hire.hireID == newhiredID)
{
//Log.Out("HiresManagerRebirth-UpdateHireInfo FOUND HIRE");
bool changed = false;
bool addObserver = false;
bool removeObserver = false;
if (action == "newid")
{
changed = true;
}
else if (action == "order")
{
//Log.Out("HiresManagerRebirth-UpdateHireInfo order value: " + value);
if (value == "follow")
{
hire.order = 0;
changed = true;
removeObserver = true;
}
else if (value == "stay")
{
hire.order = 1;
hire.spawnPosition = StringParsers.ParseVector3(position);
hire.spawnRotation = StringParsers.ParseVector3(rotation);
changed = true;
addObserver = true;
}
else if (value == "guard")
{
hire.order = 2;
hire.spawnPosition = StringParsers.ParseVector3(position);
hire.spawnRotation = StringParsers.ParseVector3(rotation);
changed = true;
addObserver = true;
}
}
else if (action == "reSpawnPosition")
{
//Log.Out("HiresManagerRebirth-UpdateHireInfo reSpawnPosition: " + position);
//Log.Out("HiresManagerRebirth-UpdateHireInfo reSpawnRotation: " + rotation);
hire.reSpawnPosition = StringParsers.ParseVector3(position);
hire.reSpawnRotation = StringParsers.ParseVector3(rotation);
hire.spawnPosition = StringParsers.ParseVector3(position);
hire.spawnRotation = StringParsers.ParseVector3(rotation);
changed = true;
}
if (changed)
{
//Log.Out("HiresManagerRebirth-UpdateHireInfo CHANGE HIRE INFO");
if (SingletonMonoBehaviour<ConnectionManager>.Instance.IsServer)
{
SaveCurrent();
bool sendToClient = RebirthUtilities.SendToClient(hire.playerID);
//Log.Out("HiresManagerRebirth-UpdateHireInfo sendToClient: " + sendToClient);
if (sendToClient)
{
//Log.Out("HiresManagerRebirth-UpdateHireInfo current ID: " + hiredID);
//Log.Out("HiresManagerRebirth-UpdateHireInfo new ID: " + newhiredID);
SingletonMonoBehaviour<ConnectionManager>.Instance.SendPackage(NetPackageManager.GetPackage<NetPackageChangeHireInfoRebirth>().Setup(hire.playerID,
hiredID,
hire.name,
hire.spawnPosition,
hire.spawnRotation,
hire.reSpawnPosition,
hire.reSpawnRotation,
hire.numKills,
hire.numMine,
hire.order,
hire.playerSpawned,
action,
value,
newhiredID
), false, hire.playerID, -1, -1, null, 192);
//Log.Out("HiresManagerRebirth-UpdateHireInfo SENT TO CLIENT");
}
}
else
{
SingletonMonoBehaviour<ConnectionManager>.Instance.SendToServer(NetPackageManager.GetPackage<NetPackageChangeHireInfoRebirth>().Setup(hire.playerID,
hiredID,
hire.name,
hire.spawnPosition,
hire.spawnRotation,
hire.reSpawnPosition,
hire.reSpawnRotation,
hire.numKills,
hire.numMine,
hire.order,
hire.playerSpawned,
action,
value,
newhiredID
), false);
//Log.Out("HiresManagerRebirth-UpdateHireInfo SENT TO SERVER");
}
}
}
}
}
public static bool CheckHires(int playerID, int hireID)
{
EntityPlayer player = GameManager.Instance.World.GetEntity(playerID) as EntityPlayer;
if (player == null)
{
return true;
}
if (!player.IsSpawned())
{
return true;
}
Chunk chunkPlayer = (Chunk)GameManager.Instance.World.GetChunkFromWorldPos((int)player.position.x, (int)player.position.z);
//Log.Out("HiresManagerRebirth-CheckHires START");
foreach (hireInfo hire in playerHires)
{
if (hire.playerID == playerID && hire.hireID == hireID && hire.playerSpawned)
{
if (SingletonMonoBehaviour<ConnectionManager>.Instance.IsServer)
{
bool addObserver = false;
//Log.Out("HiresManagerRebirth-CheckHires playerID: " + playerID + " / hireID: " + hireID);*/
Vector3 position = player.position;
Vector3 rotation = player.rotation;
bool setPosition = false;
if (hire.order == 1 || hire.order == 2 && hire.spawnPosition != new Vector3(0, 0, 0))
{
position = hire.spawnPosition;
rotation = hire.spawnRotation;
setPosition = true;
//Log.Out("HiresManagerRebirth-CheckHires SPAWN WHERE THEY LAST STAYED: " + position);
}
if (hire.reSpawnPosition != new Vector3(0, 0, 0))
{
position = hire.reSpawnPosition;
rotation = hire.reSpawnRotation;
hire.order = 1;
setPosition = true;
//Log.Out("HiresManagerRebirth-CheckHires SPAWNING AT REGROUP POINT: " + position);
}
if (!setPosition)
{
SpawnPosition spawnPoint = RebirthUtilities.GetSpawnPoint(player);
if (!spawnPoint.IsUndef() && spawnPoint.position != new Vector3(0, 0, 0))
{
position = spawnPoint.position;
rotation = player.rotation;
hire.order = 1;
setPosition = true;
//Log.Out("HiresManagerRebirth-CheckHires SPAWNING AT BEDROLL: " + position);
}
else
{
//Log.Out("HiresManagerRebirth-CheckHires SPAWNING AT PLAYER LOCATION: " + position);
}
}
Chunk chunkHire = (Chunk)GameManager.Instance.World.GetChunkFromWorldPos((int)position.x, (int)position.z);
if (chunkHire != null)
{
//Log.Out("HiresManagerRebirth-CheckHires chunkHire pos: " + chunkHire.ChunkPos);
//Log.Out("HiresManagerRebirth-CheckHires chunkPlayer pos: " + chunkPlayer.ChunkPos);
}
if (chunkHire != null)
{
Entity entity = GameManager.Instance.World.GetEntity(hire.hireID) as Entity;
if (entity == null)
{
bool skipEntity = true; // false;
if (!skipEntity)
{
////Log.Out("HiresManagerRebirth-CheckHires Couldn't find owned entity in the world");
//Log.Out("HiresManagerRebirth-CheckHires Created Missing Hire: " + hireID + " / " + hire.className + " / " + hire.name);
EntityNPCRebirth NewEntity = EntityFactory.CreateEntity(EntityClass.FromString(hire.className), position, rotation) as EntityNPCRebirth;
NewEntity.SetSpawnerSource(EnumSpawnerSource.StaticSpawner);
NewEntity._strMyName = hire.name;
RebirthUtilities.SetLeaderAndOwner(NewEntity.entityId, player.entityId);
NewEntity.IsEntityUpdatedInUnloadedChunk = true;
NewEntity.bWillRespawn = true;
NewEntity.bIsChunkObserver = true;
NewEntity.belongsPlayerId = playerID;
NewEntity.guardPosition = position;
if (hire.order == (int)EntityUtilities.Orders.None)
{
//Log.Out("HiresManagerRebirth-Update SET TO FOLLOW B");
NewEntity.Buffs.SetCustomVar("CurrentOrder", (int)EntityUtilities.Orders.Follow);
}
else if (hire.order == (int)EntityUtilities.Orders.Follow)
{
//Log.Out("HiresManagerRebirth-Update SET TO STAY B");
NewEntity.Buffs.SetCustomVar("CurrentOrder", (int)EntityUtilities.Orders.Stay);
addObserver = true;
}
else
{
//Log.Out("HiresManagerRebirth-Update SET TO STAY (GUARD) B");
NewEntity.Buffs.SetCustomVar("CurrentOrder", (int)EntityUtilities.Orders.Stay);
addObserver = true;
}
GameManager.Instance.World.SpawnEntityInWorld(NewEntity);
hire.hireID = NewEntity.entityId;
RebirthUtilities.SetLeaderAndOwner(NewEntity.entityId, player.entityId);
bool foundObserver = false;
for (int i = 0; i < observers.Count; i++)
{
if (observers[i].entityID == hireID)
{
//Log.Out("HiresManagerRebirth-CheckHires UPDATED OBSERVER, hire: " + hireID);
observers[i].entityID = NewEntity.entityId;
foundObserver = true;
break;
}
}
float flMode = player.Buffs.GetCustomVar("varNPCModMode");
float flHalt = player.Buffs.GetCustomVar("varNPCModStopAttacking");
if (flMode == 0)
{
NewEntity.Buffs.AddBuff("buffNPCModFullControlMode");
}
else
{
NewEntity.Buffs.RemoveBuff("buffNPCModFullControlMode");
}
if (flHalt == 1)
{
NewEntity.Buffs.AddBuff("buffNPCModStopAttacking");
}
else
{
NewEntity.Buffs.RemoveBuff("buffNPCModStopAttacking");
}
if (addObserver && !foundObserver)
{
//Log.Out("HiresManagerRebirth-CheckHires ADDED CHUNK OBSERVER, hire: " + hireID);
ChunkManager.ChunkObserver observerRef = GameManager.Instance.AddChunkObserver(position, false, 3, -1);
observers.Add(new chunkObservers(NewEntity.entityId, observerRef));
}
return true;
}
}
}
else
{
//Log.Out("HiresManagerRebirth-CheckHires CAN'T LOAD HIRE CHUNK: " + position);
return true;
}
}
}
}
return false;
}
public static void Write(BinaryWriter _bw)
{
//Log.Out("HiresManagerRebirth-Write playerHires.Count: " + playerHires.Count);
foreach (hireInfo hire in playerHires)
{
//Log.Out("HiresManagerRebirth-Write hire.playerID: " + hire.playerID);
//Log.Out("HiresManagerRebirth-Write hire.hireID: " + hire.hireID);
//Log.Out("HiresManagerRebirth-Write hire.name: " + hire.name);
_bw.Write(hire.playerID.ToString());
_bw.Write(hire.hireID.ToString());
_bw.Write(hire.name);
_bw.Write(hire.className);
_bw.Write(hire.spawnPosition.ToString());
_bw.Write(hire.spawnRotation.ToString());
_bw.Write(hire.reSpawnPosition.ToString());
_bw.Write(hire.reSpawnRotation.ToString());
_bw.Write(hire.numKills.ToString());
_bw.Write(hire.numMine.ToString());
_bw.Write(hire.order.ToString());
_bw.Write(hire.playerSpawned);
}
}
public static void Read(BinaryReader _br)
{
//Log.Out("HiresManagerRebirth-Read START");
while (_br.BaseStream.Position != _br.BaseStream.Length)
{
hireInfo hire = new hireInfo();
hire.playerID = int.Parse(_br.ReadString());
hire.hireID = int.Parse(_br.ReadString());
hire.name = _br.ReadString();
hire.className = _br.ReadString();
hire.spawnPosition = StringParsers.ParseVector3(_br.ReadString());
hire.spawnRotation = StringParsers.ParseVector3(_br.ReadString());
hire.reSpawnPosition = StringParsers.ParseVector3(_br.ReadString());
hire.reSpawnRotation = StringParsers.ParseVector3(_br.ReadString());
hire.numKills = int.Parse(_br.ReadString());
hire.numMine = int.Parse(_br.ReadString());
hire.order = int.Parse(_br.ReadString());
hire.playerSpawned = _br.ReadBoolean();
playerHires.Add(hire);
//Log.Out("NetPackageGetHiresRebirth-Read Added playerID: " + hire.playerID);
//Log.Out("NetPackageGetHiresRebirth-Read Added hire: " + hire.hireID);
//Log.Out("NetPackageGetHiresRebirth-Read Added name: " + hire.name);
//Log.Out("NetPackageGetHiresRebirth-Read hire.order: " + hire.order);
////Log.Out("NetPackageGetHiresRebirth-Read GameManager.IsDedicatedServer: " + GameManager.IsDedicatedServer);
}
}
private static int saveDataThreaded(ThreadManager.ThreadInfo _threadInfo)
{
//Log.Out("HiresManagerRebirth-saveDataThreaded START");
PooledExpandableMemoryStream pooledExpandableMemoryStream = (PooledExpandableMemoryStream)_threadInfo.parameter;
string text = string.Format("{0}/{1}", GameIO.GetSaveGameDir(), saveFile);
if (!Directory.Exists(GameIO.GetSaveGameDir()))
{
Directory.CreateDirectory(GameIO.GetSaveGameDir());
}
if (File.Exists(text))
{
File.Copy(text, string.Format("{0}/{1}", GameIO.GetSaveGameDir(), $"{saveFile}.bak"), true);
}
pooledExpandableMemoryStream.Position = 0L;
StreamUtils.WriteStreamToFile(pooledExpandableMemoryStream, text);
pooledExpandableMemoryStream.Dispose();
////Log.Out($"Broadcast Manager {text} Saving: {Broadcastmap.Count}");
return -1;
}
public static void Save()
{
//Log.Out("HiresManagerRebirth-Save START");
if (dataSaveThreadInfo == null || !ThreadManager.ActiveThreads.ContainsKey("silent_HiresManagerDataSave"))
{
PooledExpandableMemoryStream pooledExpandableMemoryStream = MemoryPools.poolMemoryStream.AllocSync(true);
using (PooledBinaryWriter pooledBinaryWriter = MemoryPools.poolBinaryWriter.AllocSync(false))
{
pooledBinaryWriter.SetBaseStream(pooledExpandableMemoryStream);
Write(pooledBinaryWriter);
}
dataSaveThreadInfo = ThreadManager.StartThread("silent_HiresManagerDataSave", null, new ThreadManager.ThreadFunctionLoopDelegate(saveDataThreaded), null, System.Threading.ThreadPriority.Normal, pooledExpandableMemoryStream, null, false);
}
}
public static void Load()
{
//Log.Out("HiresManagerRebirth-Load START");
string path = string.Format("{0}/{1}", GameIO.GetSaveGameDir(), saveFile);
if (Directory.Exists(GameIO.GetSaveGameDir()) && File.Exists(path))
{
//Log.Out("HiresManagerRebirth-Load 1");
try
{
using (FileStream fileStream = File.OpenRead(path))
{
using (PooledBinaryReader pooledBinaryReader = MemoryPools.poolBinaryReader.AllocSync(false))
{
//Log.Out("HiresManagerRebirth-Load 2");
pooledBinaryReader.SetBaseStream(fileStream);
Read(pooledBinaryReader);
}
}
}
catch (Exception)
{
path = string.Format("{0}/{1}", GameIO.GetSaveGameDir(), $"{saveFile}.bak");
if (File.Exists(path))
{
//Log.Out("HiresManagerRebirth-Load 3");
using (FileStream fileStream2 = File.OpenRead(path))
{
using (PooledBinaryReader pooledBinaryReader2 = MemoryPools.poolBinaryReader.AllocSync(false))
{
//Log.Out("HiresManagerRebirth-Load 4");
pooledBinaryReader2.SetBaseStream(fileStream2);
Read(pooledBinaryReader2);
}
}
}
}
}
}
private static void WaitOnSave()
{
if (dataSaveThreadInfo != null)
{
dataSaveThreadInfo.WaitForEnd();
dataSaveThreadInfo = null;
}
}
public static void Cleanup()
{
if (instance != null)
{
SaveAndClear();
}
}
public static void SaveCurrent()
{
//Log.Out("HiresManagerRebirth-SaveCurrent SAVED CURRENT");
WaitOnSave();
Save();
WaitOnSave();
}
private static void SaveAndClear()
{
WaitOnSave();
Save();
WaitOnSave();
playerHires.Clear();
observers.Clear();
instance = null;
//Log.Out("Hires Manager stopped");
}
}

View File

@@ -0,0 +1,947 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using UnityEngine;
public class HiresManagerRebirth
{
private static HiresManagerRebirth instance = null;
private static readonly object Locker = new object();
public static bool loadedHires = false;
private const string saveFile = "HiresManagerRebirth.dat";
private static ThreadManager.ThreadInfo dataSaveThreadInfo;
public static List<hireInfo> playerHires = new List<hireInfo>();
public static List<chunkObservers> observers = new List<chunkObservers>();
private static Dictionary<int, hireInfo> playerHiresDict = new Dictionary<int, hireInfo>();
private static Dictionary<int, chunkObservers> observersDict = new Dictionary<int, chunkObservers>();
private static float updateCheck = 0f;
private static float updateTick = 60;
// Variables to break down heavy update operations
private static bool isProcessingUpdate = false;
private static int updatePhase = 0;
private static List<EntityPlayer> spawnedPlayersForProcessing = new List<EntityPlayer>(); // Reused, cleared instead of reallocated
public static bool HasInstance => instance != null;
public class chunkObservers
{
public int entityID;
public ChunkManager.ChunkObserver observerRef;
public chunkObservers() { }
public chunkObservers(int entityID, ChunkManager.ChunkObserver observerRef)
{
this.entityID = entityID;
this.observerRef = observerRef;
}
}
public class hireInfo
{
public int playerID;
public int hireID;
public string name;
public string className;
public Vector3 spawnPosition;
public Vector3 spawnRotation;
public Vector3 reSpawnPosition;
public Vector3 reSpawnRotation;
public int numKills;
public int numMine;
public int order;
public bool playerSpawned;
public hireInfo() { }
public hireInfo(int playerID,
int hireID,
string name,
string className,
Vector3 spawnPosition,
Vector3 spawnRotation,
Vector3 reSpawnPosition,
Vector3 reSpawnRotation,
int numKills,
int numMine,
int order,
bool playerSpawned = false)
{
this.playerID = playerID;
this.hireID = hireID;
this.name = name;
this.className = className;
this.spawnPosition = spawnPosition;
this.spawnRotation = spawnRotation;
this.reSpawnPosition = reSpawnPosition;
this.reSpawnRotation = reSpawnRotation;
this.numKills = numKills;
this.numMine = numMine;
this.order = order;
this.playerSpawned = playerSpawned;
}
}
public static HiresManagerRebirth Instance => instance;
public static void Init()
{
instance = new HiresManagerRebirth();
Load();
loadedHires = true;
ModEvents.GameUpdate.RegisterHandler(Update);
//GameManager.Instance.StartCoroutine(delayExecution(10f));
RebuildDictionaries();
}
public static IEnumerator delayExecution(float delay)
{
while (true)
{
Update();
yield return new WaitForSeconds(delay);
}
}
private static void RebuildDictionaries()
{
playerHiresDict.Clear();
for (int i = 0; i < playerHires.Count; i++)
{
hireInfo hire = playerHires[i];
playerHiresDict[hire.hireID] = hire;
}
observersDict.Clear();
for (int i = 0; i < observers.Count; i++)
{
var obs = observers[i];
observersDict[obs.entityID] = obs;
}
}
public static void Update()
{
//return;
if (!HasInstance || !loadedHires)
{
return;
}
GameManager gm = GameManager.Instance;
ConnectionManager connectionManager = SingletonMonoBehaviour<ConnectionManager>.Instance;
float currentTime = Time.time;
bool isHordeNight = RebirthUtilities.IsHordeNight();
bool isClient = connectionManager.IsClient;
int hiresCount = playerHires.Count;
int observersCount = observers.Count;
if (isHordeNight)
{
return;
}
if (!isProcessingUpdate && hiresCount == 0 && observersCount == 0)
{
return;
}
if (isProcessingUpdate)
{
ProcessScheduledWork(gm, connectionManager, isClient);
return;
}
if (isClient)
{
return;
}
//if ((currentTime - updateCheck) > updateTick)
{
isProcessingUpdate = true;
updatePhase = 0;
// Clear instead of reassigning a new list
spawnedPlayersForProcessing.Clear();
}
}
private static void ProcessScheduledWork(GameManager gm, ConnectionManager connectionManager, bool isClient)
{
if (isClient)
{
CompleteProcessing();
return;
}
int hiresCount = playerHires.Count;
int observersCount = observers.Count;
if (hiresCount == 0 && observersCount == 0)
{
CompleteProcessing();
return;
}
switch (updatePhase)
{
case 0:
// Observers cleanup phase
for (int i = observersCount - 1; i >= 0; i--)
{
var currentObserver = observers[i];
int entityID = currentObserver.entityID;
if (!playerHiresDict.TryGetValue(entityID, out hireInfo hireCheck) ||
(hireCheck.order != 1 && hireCheck.order != 2))
{
gm.RemoveChunkObserver(currentObserver.observerRef);
observersDict.Remove(entityID);
observers.RemoveAt(i);
}
}
break;
case 1:
// Process hires and build the list of spawnedPlayers
for (int i = 0; i < hiresCount; i++)
{
hireInfo hire = playerHires[i];
EntityPlayer player = gm.World.GetEntity(hire.playerID) as EntityPlayer;
if (player != null && player.IsSpawned() && !player.AttachedToEntity)
{
// Avoid Contains check if possible. If spawnedPlayersForProcessing is small, it's minor anyway.
if (!spawnedPlayersForProcessing.Contains(player))
{
spawnedPlayersForProcessing.Add(player);
}
int order = hire.order;
int hireID = hire.hireID;
if (order == 1 || order == 2)
{
if (!observersDict.ContainsKey(hireID))
{
ChunkManager.ChunkObserver observerRef = gm.AddChunkObserver(hire.spawnPosition, false, 3, -1);
var newObs = new chunkObservers(hireID, observerRef);
observers.Add(newObs);
observersDict[hireID] = newObs;
}
}
else if (order == 0)
{
if (observersDict.TryGetValue(hireID, out var obs))
{
gm.RemoveChunkObserver(obs.observerRef);
observersDict.Remove(hireID);
// Instead of RemoveAll, remove manually:
for (int idx = observers.Count - 1; idx >= 0; idx--)
{
if (observers[idx].entityID == hireID)
{
observers.RemoveAt(idx);
}
}
}
}
hire.playerSpawned = true;
}
}
break;
case 2:
int spawnedPlayersCount = spawnedPlayersForProcessing.Count;
if (spawnedPlayersCount == 0)
break;
for (int p = 0; p < spawnedPlayersCount; p++)
{
EntityPlayer player = spawnedPlayersForProcessing[p];
var playerBuffs = player.Buffs;
bool playerHasGod = playerBuffs.HasBuff("god");
bool playerHasDelay10 = playerBuffs.HasBuff("FuriousRamsayDelay-10");
bool playerHasDelay5 = playerBuffs.HasBuff("FuriousRamsayDelay-5");
if (playerHasGod || playerHasDelay10 || playerHasDelay5 || player.AttachedToEntity)
continue;
Vector3 playerPos = player.position;
Vector3 playerRot = player.rotation;
Chunk chunkPlayer = (Chunk)gm.World.GetChunkFromWorldPos((int)playerPos.x, (int)playerPos.z);
int playerEntityId = player.entityId;
int playerHiresCount = playerHires.Count;
for (int i = 0; i < playerHiresCount; i++)
{
hireInfo hire = playerHires[i];
if (hire.playerID == playerEntityId)
{
int hireEntityID = hire.hireID;
Entity hiredNPC = gm.World.GetEntity(hireEntityID);
if (hiredNPC == null)
{
Vector3 respawnPosition;
Vector3 respawnRotation = Vector3.zero;
Vector3 hireRespawnPos = hire.reSpawnPosition;
if (hireRespawnPos != Vector3.zero)
{
respawnPosition = hireRespawnPos;
respawnRotation.y = playerRot.y;
}
else
{
SpawnPosition spawnPoint = RebirthUtilities.GetSpawnPoint(player);
if (spawnPoint.IsUndef())
{
respawnPosition = playerPos;
respawnRotation.y = playerRot.y;
continue;
}
else
{
respawnPosition = spawnPoint.position;
respawnRotation.y = playerRot.y;
}
}
Chunk chunkHire = (Chunk)gm.World.GetChunkFromWorldPos((int)respawnPosition.x, (int)respawnPosition.z);
if (chunkHire != null && IsAdjacentOrSameChunk(chunkPlayer, chunkHire))
{
// Check again if entity is null (redundant, but safe)
if (player.world.GetEntity(hireEntityID) == null)
{
int entityClass = EntityClass.FromString(hire.className);
EntityNPCRebirth NewEntity = EntityFactory.CreateEntity(entityClass, respawnPosition, respawnRotation) as EntityNPCRebirth;
NewEntity.SetSpawnerSource(EnumSpawnerSource.StaticSpawner);
NewEntity._strMyName = hire.name;
RebirthUtilities.SetLeaderAndOwner(NewEntity.entityId, playerEntityId);
NewEntity.IsEntityUpdatedInUnloadedChunk = true;
NewEntity.bWillRespawn = true;
NewEntity.bIsChunkObserver = true;
NewEntity.belongsPlayerId = playerEntityId;
NewEntity.guardPosition = respawnPosition;
gm.World.SpawnEntityInWorld(NewEntity);
int oldHireID = hire.hireID;
hire.hireID = NewEntity.entityId;
hire.order = 1;
SaveCurrent();
UpdateHireInfo(oldHireID, "newid", "", "", "", NewEntity.entityId);
int hireOrder = hire.order;
if (hireOrder == (int)EntityUtilities.Orders.None)
{
NewEntity.Buffs.SetCustomVar("CurrentOrder", (int)EntityUtilities.Orders.Follow);
}
else if (hireOrder == (int)EntityUtilities.Orders.Follow)
{
NewEntity.Buffs.SetCustomVar("CurrentOrder", (int)EntityUtilities.Orders.Stay);
}
else
{
NewEntity.Buffs.SetCustomVar("CurrentOrder", (int)EntityUtilities.Orders.Stay);
}
RebirthUtilities.SetLeaderAndOwner(NewEntity.entityId, playerEntityId);
bool foundObserver = false;
int obsCount = observers.Count;
for (int oi = 0; oi < obsCount; oi++)
{
var o = observers[oi];
if (o.entityID == oldHireID)
{
o.entityID = NewEntity.entityId;
observersDict.Remove(oldHireID);
observersDict[NewEntity.entityId] = o;
foundObserver = true;
break;
}
}
float flMode = player.Buffs.GetCustomVar("varNPCModMode");
float flHalt = player.Buffs.GetCustomVar("varNPCModStopAttacking");
if (flMode == 0)
{
NewEntity.Buffs.AddBuff("buffNPCModFullControlMode");
}
else
{
NewEntity.Buffs.RemoveBuff("buffNPCModFullControlMode");
}
if (flHalt == 1)
{
NewEntity.Buffs.AddBuff("buffNPCModStopAttacking");
}
else
{
NewEntity.Buffs.RemoveBuff("buffNPCModStopAttacking");
}
if (!foundObserver)
{
ChunkManager.ChunkObserver observerRef = gm.AddChunkObserver(NewEntity.position, false, 3, -1);
var newObs = new chunkObservers(NewEntity.entityId, observerRef);
observers.Add(newObs);
observersDict[NewEntity.entityId] = newObs;
}
playerHiresDict.Remove(oldHireID);
playerHiresDict[NewEntity.entityId] = hire;
}
}
}
}
}
}
break;
}
updatePhase++;
if (updatePhase > 2)
{
CompleteProcessing();
}
}
private static void CompleteProcessing()
{
isProcessingUpdate = false;
updateCheck = Time.time;
}
private static bool IsAdjacentOrSameChunk(Chunk chunkPlayer, Chunk chunkHire)
{
int px = chunkPlayer.ChunkPos.x;
int pz = chunkPlayer.ChunkPos.z;
int hx = chunkHire.ChunkPos.x;
int hz = chunkHire.ChunkPos.z;
return (hx == px && hz == pz) ||
(hx == px + 1 && hz == pz) ||
(hx == px - 1 && hz == pz) ||
(hx == px && hz == pz - 1) ||
(hx == px + 1 && hz == pz - 1) ||
(hx == px - 1 && hz == pz) ||
(hx == px && hz == pz + 1) ||
(hx == px + 1 && hz == pz + 1) ||
(hx == px - 1 && hz == pz);
}
public static void RemoveHire(int entityID, bool removeObserver = false)
{
ConnectionManager connectionManager = SingletonMonoBehaviour<ConnectionManager>.Instance;
GameManager gm = GameManager.Instance;
int hireCount = playerHires.Count;
for (int i = 0; i < hireCount; i++)
{
hireInfo hire = playerHires[i];
if (hire.hireID == entityID)
{
bool isServer = connectionManager.IsServer;
if (isServer)
{
if (RebirthUtilities.SendToClient(hire.playerID))
{
connectionManager.SendPackage(
NetPackageManager.GetPackage<NetPackageRemoveHireRebirth>().Setup(entityID),
false, hire.playerID, -1, -1, null, 192);
}
playerHiresDict.Remove(entityID);
playerHires.RemoveAt(i);
if (removeObserver && observersDict.TryGetValue(entityID, out var obs))
{
gm.RemoveChunkObserver(obs.observerRef);
observersDict.Remove(entityID);
// Manual removal instead of RemoveAll()
for (int idx = observers.Count - 1; idx >= 0; idx--)
{
if (observers[idx].entityID == entityID)
{
observers.RemoveAt(idx);
}
}
}
SaveCurrent();
}
else
{
connectionManager.SendToServer(
NetPackageManager.GetPackage<NetPackageRemoveHireRebirth>().Setup(entityID),
false);
playerHiresDict.Remove(entityID);
playerHires.RemoveAt(i);
}
return;
}
}
if (connectionManager.IsClient)
{
connectionManager.SendToServer(
NetPackageManager.GetPackage<NetPackageRemoveHireRebirth>().Setup(entityID), false);
}
}
public static void AddHire(int playerID,
int hireID,
string name,
string className,
Vector3 spawnPosition,
Vector3 spawnRotation,
Vector3 reSpawnPosition,
Vector3 reSpawnRotation,
int numKills,
int numMine,
int order,
bool playerSpawned)
{
var connectionManager = SingletonMonoBehaviour<ConnectionManager>.Instance;
var gm = GameManager.Instance;
if (!playerHiresDict.ContainsKey(hireID))
{
hireInfo newHire = new hireInfo(playerID, hireID, name, className, spawnPosition, spawnRotation, reSpawnPosition, reSpawnRotation, numKills, numMine, order, playerSpawned);
playerHires.Add(newHire);
playerHiresDict[hireID] = newHire;
EntityAlive entity = gm.World.GetEntity(hireID) as EntityAlive;
if (entity != null)
{
entity.Buffs.SetCustomVar("$Leader", playerID);
}
}
bool isServer = connectionManager.IsServer;
if (isServer)
{
SaveCurrent();
if (RebirthUtilities.SendToClient(playerID))
{
connectionManager.SendPackage(
NetPackageManager.GetPackage<NetPackageAddHireRebirth>().Setup(
playerID,
hireID,
name,
className,
spawnPosition,
spawnRotation,
reSpawnPosition,
reSpawnRotation,
numKills,
numMine,
order,
playerSpawned),
false, playerID, -1, -1, null, 192);
}
}
else
{
connectionManager.SendToServer(
NetPackageManager.GetPackage<NetPackageAddHireRebirth>().Setup(
playerID,
hireID,
name,
className,
spawnPosition,
spawnRotation,
reSpawnPosition,
reSpawnRotation,
numKills,
numMine,
order,
playerSpawned),
false);
}
}
public static void UpdateHireInfo(int hiredID, string action, string value, string position = "", string rotation = "", int newhiredID = -1)
{
var connectionManager = SingletonMonoBehaviour<ConnectionManager>.Instance;
bool isServer = connectionManager.IsServer;
int hireCount = playerHires.Count;
for (int i = 0; i < hireCount; i++)
{
var hire = playerHires[i];
int currentHireID = hire.hireID;
if (currentHireID == hiredID || currentHireID == newhiredID)
{
bool changed = false;
if (action == "newid")
{
changed = true;
}
else if (action == "order")
{
if (value == "follow")
{
hire.order = 0;
changed = true;
}
else if (value == "stay")
{
hire.order = 1;
hire.spawnPosition = StringParsers.ParseVector3(position);
hire.spawnRotation = StringParsers.ParseVector3(rotation);
changed = true;
}
else if (value == "guard")
{
hire.order = 2;
hire.spawnPosition = StringParsers.ParseVector3(position);
hire.spawnRotation = StringParsers.ParseVector3(rotation);
changed = true;
}
}
else if (action == "reSpawnPosition")
{
Vector3 parsedPosition = StringParsers.ParseVector3(position);
Vector3 parsedRotation = StringParsers.ParseVector3(rotation);
hire.reSpawnPosition = parsedPosition;
hire.reSpawnRotation = parsedRotation;
hire.spawnPosition = parsedPosition;
hire.spawnRotation = parsedRotation;
changed = true;
}
if (changed)
{
if (isServer)
{
SaveCurrent();
bool sendToClient = RebirthUtilities.SendToClient(hire.playerID);
if (sendToClient)
{
connectionManager.SendPackage(
NetPackageManager.GetPackage<NetPackageChangeHireInfoRebirth>().Setup(
hire.playerID,
hiredID,
hire.name,
hire.spawnPosition,
hire.spawnRotation,
hire.reSpawnPosition,
hire.reSpawnRotation,
hire.numKills,
hire.numMine,
hire.order,
hire.playerSpawned,
action,
value,
newhiredID),
false, hire.playerID, -1, -1, null, 192);
}
}
else
{
connectionManager.SendToServer(
NetPackageManager.GetPackage<NetPackageChangeHireInfoRebirth>().Setup(
hire.playerID,
hiredID,
hire.name,
hire.spawnPosition,
hire.spawnRotation,
hire.reSpawnPosition,
hire.reSpawnRotation,
hire.numKills,
hire.numMine,
hire.order,
hire.playerSpawned,
action,
value,
newhiredID), false);
}
}
}
}
}
public static bool CheckHires(int playerID, int hireID)
{
var gm = GameManager.Instance;
EntityPlayer player = gm.World.GetEntity(playerID) as EntityPlayer;
if (player == null || !player.IsSpawned())
{
return true;
}
if (playerHiresDict.TryGetValue(hireID, out hireInfo hire) && hire.playerSpawned)
{
// Additional checks if necessary
}
return false;
}
public static void Write(BinaryWriter _bw)
{
int hireCount = playerHires.Count;
for (int i = 0; i < hireCount; i++)
{
hireInfo hire = playerHires[i];
_bw.Write(hire.playerID);
_bw.Write(hire.hireID);
_bw.Write(hire.name);
_bw.Write(hire.className);
_bw.Write(hire.spawnPosition.x);
_bw.Write(hire.spawnPosition.y);
_bw.Write(hire.spawnPosition.z);
_bw.Write(hire.spawnRotation.x);
_bw.Write(hire.spawnRotation.y);
_bw.Write(hire.spawnRotation.z);
_bw.Write(hire.reSpawnPosition.x);
_bw.Write(hire.reSpawnPosition.y);
_bw.Write(hire.reSpawnPosition.z);
_bw.Write(hire.reSpawnRotation.x);
_bw.Write(hire.reSpawnRotation.y);
_bw.Write(hire.reSpawnRotation.z);
_bw.Write(hire.numKills);
_bw.Write(hire.numMine);
_bw.Write(hire.order);
_bw.Write(hire.playerSpawned);
}
}
private static void ReadNewFormat(BinaryReader _br)
{
while (_br.BaseStream.Position < _br.BaseStream.Length)
{
hireInfo hire = new hireInfo();
hire.playerID = _br.ReadInt32();
hire.hireID = _br.ReadInt32();
hire.name = _br.ReadString();
hire.className = _br.ReadString();
float sx = _br.ReadSingle();
float sy = _br.ReadSingle();
float sz = _br.ReadSingle();
hire.spawnPosition = new Vector3(sx, sy, sz);
float rx = _br.ReadSingle();
float ry = _br.ReadSingle();
float rz = _br.ReadSingle();
hire.spawnRotation = new Vector3(rx, ry, rz);
float rsx = _br.ReadSingle();
float rsy = _br.ReadSingle();
float rsz = _br.ReadSingle();
hire.reSpawnPosition = new Vector3(rsx, rsy, rsz);
float rrx = _br.ReadSingle();
float rry = _br.ReadSingle();
float rrz = _br.ReadSingle();
hire.reSpawnRotation = new Vector3(rrx, rry, rrz);
hire.numKills = _br.ReadInt32();
hire.numMine = _br.ReadInt32();
hire.order = _br.ReadInt32();
hire.playerSpawned = _br.ReadBoolean();
playerHires.Add(hire);
}
}
public static void ReadOldFormat(BinaryReader _br)
{
while (_br.BaseStream.Position != _br.BaseStream.Length)
{
hireInfo hire = new hireInfo();
hire.playerID = int.Parse(_br.ReadString());
hire.hireID = int.Parse(_br.ReadString());
hire.name = _br.ReadString();
hire.className = _br.ReadString();
hire.spawnPosition = StringParsers.ParseVector3(_br.ReadString());
hire.spawnRotation = StringParsers.ParseVector3(_br.ReadString());
hire.reSpawnPosition = StringParsers.ParseVector3(_br.ReadString());
hire.reSpawnRotation = StringParsers.ParseVector3(_br.ReadString());
hire.numKills = int.Parse(_br.ReadString());
hire.numMine = int.Parse(_br.ReadString());
hire.order = int.Parse(_br.ReadString());
hire.playerSpawned = _br.ReadBoolean();
playerHires.Add(hire);
}
}
private static int saveDataThreaded(ThreadManager.ThreadInfo _threadInfo)
{
PooledExpandableMemoryStream pooledExpandableMemoryStream = (PooledExpandableMemoryStream)_threadInfo.parameter;
string text = string.Format("{0}/{1}", GameIO.GetSaveGameDir(), saveFile);
if (!Directory.Exists(GameIO.GetSaveGameDir()))
{
Directory.CreateDirectory(GameIO.GetSaveGameDir());
}
if (File.Exists(text))
{
File.Copy(text, string.Format("{0}/{1}", GameIO.GetSaveGameDir(), $"{saveFile}.bak"), true);
}
pooledExpandableMemoryStream.Position = 0L;
StreamUtils.WriteStreamToFile(pooledExpandableMemoryStream, text);
pooledExpandableMemoryStream.Dispose();
return -1;
}
public static void Save()
{
WaitOnSave();
PooledExpandableMemoryStream pooledExpandableMemoryStream = MemoryPools.poolMemoryStream.AllocSync(true);
using (PooledBinaryWriter pooledBinaryWriter = MemoryPools.poolBinaryWriter.AllocSync(false))
{
pooledBinaryWriter.SetBaseStream(pooledExpandableMemoryStream);
// Write version number for new format
pooledBinaryWriter.Write(1); // version = 1
Write(pooledBinaryWriter);
}
dataSaveThreadInfo = ThreadManager.StartThread("silent_HiresManagerDataSave", null, new ThreadManager.ThreadFunctionLoopDelegate(saveDataThreaded), null, System.Threading.ThreadPriority.Normal, pooledExpandableMemoryStream, null, false);
}
public static void Load()
{
string path = string.Format("{0}/{1}", GameIO.GetSaveGameDir(), saveFile);
if (Directory.Exists(GameIO.GetSaveGameDir()) && File.Exists(path))
{
try
{
using (FileStream fileStream = File.OpenRead(path))
{
using (PooledBinaryReader pooledBinaryReader = MemoryPools.poolBinaryReader.AllocSync(false))
{
pooledBinaryReader.SetBaseStream(fileStream);
int version;
try
{
version = pooledBinaryReader.ReadInt32();
}
catch
{
pooledBinaryReader.BaseStream.Position = 0;
ReadOldFormat(pooledBinaryReader);
RebuildDictionaries();
return;
}
if (version == 1)
{
ReadNewFormat(pooledBinaryReader);
}
else
{
pooledBinaryReader.BaseStream.Position = 0;
ReadOldFormat(pooledBinaryReader);
}
}
}
}
catch
{
// Attempt backup
string backupPath = string.Format("{0}/{1}", GameIO.GetSaveGameDir(), $"{saveFile}.bak");
if (File.Exists(backupPath))
{
using (FileStream fileStream2 = File.OpenRead(backupPath))
{
using (PooledBinaryReader pooledBinaryReader2 = MemoryPools.poolBinaryReader.AllocSync(false))
{
pooledBinaryReader2.SetBaseStream(fileStream2);
try
{
int version = pooledBinaryReader2.ReadInt32();
if (version == 1)
ReadNewFormat(pooledBinaryReader2);
else
{
pooledBinaryReader2.BaseStream.Position = 0;
ReadOldFormat(pooledBinaryReader2);
}
}
catch
{
pooledBinaryReader2.BaseStream.Position = 0;
ReadOldFormat(pooledBinaryReader2);
}
}
}
}
}
}
RebuildDictionaries();
}
private static void WaitOnSave()
{
if (dataSaveThreadInfo != null)
{
dataSaveThreadInfo.WaitForEnd();
dataSaveThreadInfo = null;
}
}
public static void Cleanup()
{
if (instance != null)
{
SaveAndClear();
}
}
public static void SaveCurrent()
{
WaitOnSave();
Save();
WaitOnSave();
}
private static void SaveAndClear()
{
WaitOnSave();
Save();
WaitOnSave();
playerHires.Clear();
playerHiresDict.Clear();
observers.Clear();
observersDict.Clear();
instance = null;
}
}

View File

@@ -0,0 +1,89 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using Audio;
public class OutbreakManagerRebirth
{
private static OutbreakManagerRebirth instance = null;
private static float outbreakUpdateCheck = 0f;
private static float outbreakUpdateTick = 10f;
public static bool HasInstance => instance != null;
public static OutbreakManagerRebirth Instance
{
get
{
return instance;
}
}
public static void Init()
{
OutbreakManagerRebirth.instance = new OutbreakManagerRebirth();
Log.Out("Starting Outbreak Manager");
RebirthVariables.isHerd = false;
RebirthVariables.stopWHSpawns = true;
RebirthVariables.herdDuration = 0f;
ModEvents.GameUpdate.RegisterHandler(Update);
}
public static void Update()
{
if (!RebirthUtilities.IsHordeNight())
{
if ((Time.time - outbreakUpdateCheck) > outbreakUpdateTick)
{
outbreakUpdateCheck = Time.time;
//Log.Out("OutbreakManagerRebirth-Update TICK");
//Log.Out("OutbreakManagerRebirth-Update RebirthVariables.isHerd: " + RebirthVariables.isHerd);
//Log.Out("OutbreakManagerRebirth-Update RebirthVariables.herdStartTime: " + RebirthVariables.herdStartTime);
//Log.Out("OutbreakManagerRebirth-Update RebirthVariables.herdDuration: " + RebirthVariables.herdDuration);
if (!RebirthVariables.stopWHSpawns && RebirthVariables.isWHSpawned)
{
float diff = Time.time - RebirthVariables.herdStartTime;
//Log.Out("OutbreakManagerRebirth-Update diff: " + diff + " / " + RebirthVariables.herdDuration);
AIDirectorWanderingHordeComponent director = GameManager.Instance.World.aiDirector.GetComponent<AIDirectorWanderingHordeComponent>();
if (director != null && director.spawners.Count > 0)
{
AIWanderingHordeSpawner spawner = director.spawners[director.spawners.Count - 1];
if (spawner != null)
{
//Log.Out("OutbreakManagerRebirth-Update spawner.commandList.Count: " + spawner.commandList.Count);
}
}
if (diff >= RebirthVariables.herdDuration)
{
Log.Out("OutbreakManagerRebirth-Update STOP OUTBREAK");
RebirthVariables.isHerd = false;
RebirthVariables.stopWHSpawns = true;
RebirthVariables.herdDuration = 0f;
if (director != null && director.spawners.Count > 0)
{
AIWanderingHordeSpawner spawner = director.spawners[director.spawners.Count - 1];
if (spawner != null)
{
spawner.Cleanup();
director.spawners.RemoveAt(director.spawners.Count - 1);
}
}
}
}
}
}
else
{
//Log.Out("OutbreakManagerRebirth-Update HORDE NIGHT, STOP WANDERING HORDE");
RebirthVariables.isHerd = false;
RebirthVariables.stopWHSpawns = true;
RebirthVariables.herdDuration = 0f;
}
}
}

View File

@@ -0,0 +1,1143 @@
using Audio;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using static AstarManager;
public class ScenarioManagerRebirth
{
private static ScenarioManagerRebirth instance = null;
private static string SaveDataPath = "";
private static string ModPath = "";
private static float prefabUpdateTick = 0.25f;
private static float prefabUpdateCheck = 0f;
private static float cleanupUpdateTick = 60f;
private static float cleanupUpdateCheck = 0f;
public static List<PurgeKills> purgeKills = new List<PurgeKills>();
public static List<PrefabInfo> ClearedPrefabs = new List<PrefabInfo>();
public static List<PrefabInfo> DiscoveredPrefabs = new List<PrefabInfo>();
public static List<DynamicPrefab> dynamicPrefabs = new List<DynamicPrefab>();
public static bool dynamicPrefabsLoaded = false;
public static bool processingDynamicPrefabs = false;
public class DynamicPrefab
{
public string PrefabName { get; set; }
public Vector3 Position { get; set; }
public Vector3 Size { get; set; }
public int Difficulty { get; set; }
public string Biome { get; set; }
public string Tags { get; set; }
public DynamicPrefab(string prefabName, Vector3 position, Vector3 size, int difficulty, string biome, string tags)
{
PrefabName = prefabName;
Position = position;
Size = size;
Difficulty = difficulty;
Biome = biome;
Tags = tags;
}
}
public class PlayerKillInfo
{
public int PlayerID { get; set; }
public int Kills { get; set; }
public bool Redeemed { get; set; }
}
public class KillInfo
{
public int Kills { get; set; }
public bool Redeemed { get; set; }
}
public class PurgeKills
{
public string Name { get; set; }
public Vector3 Position { get; set; }
public Dictionary<int, KillInfo> Players { get; set; } = new Dictionary<int, KillInfo>(); // Player ID as key, Kills as value
}
public class PrefabInfo
{
public string Name { get; set; }
public Vector3 Position { get; set; }
public Vector3 Size { get; set; }
public int Difficulty { get; set; }
public int EntitiesCleared { get; set; }
public Dictionary<int, string> Players { get; set; } // Player ID as key, player name as value
public string PlayerName { get; set; }
public string Biome { get; set; }
}
public static bool HasInstance => instance != null;
public static ScenarioManagerRebirth Instance
{
get
{
return instance;
}
}
public static void Init()
{
ScenarioManagerRebirth.instance = new ScenarioManagerRebirth();
Log.Out("Starting Scenario Manager");
var mod = ModManager.GetMod("zzz_REBIRTH__Utils", true);
ModPath = mod.Path;
SaveDataPath = SaveDataPath = GameIO.GetUserGameDataDir() + "/RebirthData/Scenarios"; // mod.Path + "/Scenarios";
Directory.CreateDirectory(SaveDataPath);
ClearedPrefabs = new List<PrefabInfo>();
DiscoveredPrefabs = new List<PrefabInfo>();
foreach (KeyValuePair<int, string> biome in RebirthVariables.biomes)
{
int key = biome.Key; // The int key (0, 1, 2, etc.)
string value = biome.Value; // The string value ("pine_forest", "desert", etc.)
RebirthUtilities.AddPurgeBiome(value, 0);
}
//Log.Out("ScenarioManagerRebirth-Init RebirthVariables.purgeBiomes.Count: " + RebirthVariables.purgeBiomes.Count);
LoadScenario("purge");
if ((SingletonMonoBehaviour<ConnectionManager>.Instance.IsServer && !GameManager.IsDedicatedServer) || SingletonMonoBehaviour<ConnectionManager>.Instance.IsSinglePlayer)
{
foreach (var prefab in ScenarioManagerRebirth.ClearedPrefabs)
{
//Log.Out("ScenarioManagerRebirth-Init SCENARIO Purged prefab.Name: " + prefab.Name);
Vector3 vector = new Vector3(prefab.Position.x + prefab.Size.x / 2f, prefab.Position.y, prefab.Position.z + prefab.Size.z / 2f);
NavObject navPurged = NavObjectManager.Instance.RegisterNavObject("purge_waypoint", vector, "purge_waypoint");
if (navPurged != null)
{
navPurged.TrackedPosition = vector;
}
navPurged.trackedPosition = vector;
//navPurged.ForceDisabled = true;
//navPurged.IsActive = false;
}
foreach (var prefab in ScenarioManagerRebirth.DiscoveredPrefabs)
{
//Log.Out("ScenarioManagerRebirth-Init SCENARIO Discovered prefab.Name: " + prefab.Name);
Vector3 vector = new Vector3(prefab.Position.x + prefab.Size.x / 2f, prefab.Position.y, prefab.Position.z + prefab.Size.z / 2f);
NavObject navDiscovered = NavObjectManager.Instance.RegisterNavObject("discovered_waypoint_" + prefab.Difficulty, vector, "discovered_waypoint_" + prefab.Difficulty);
if (navDiscovered != null)
{
navDiscovered.TrackedPosition = vector;
}
navDiscovered.trackedPosition = vector;
}
}
ModEvents.GameUpdate.RegisterHandler(Update);
}
public static bool IsIgnoredPrefab(string prefabName)
{
// Check if the prefabName exists in the ignorePrefabs XML (case-insensitive)
return RebirthVariables.ignorePrefabs
.Descendants("prefab")
.Any(p => p.Attribute("name")?.Value.ToLower() == prefabName.ToLower());
}
public static List<PrefabInfo> GetIgnoredDiscoveredPrefabs()
{
// Create an empty list to hold the matching PrefabInfo objects
List<PrefabInfo> ignoredPrefabs = new List<PrefabInfo>();
// Get the list of prefab names from the ignorePrefabs XML
var ignoredNames = RebirthVariables.ignorePrefabs
.Descendants("prefab")
.Select(p => p.Attribute("name")?.Value)
.Where(n => !string.IsNullOrEmpty(n))
.ToList();
// Filter the DiscoveredPrefabs based on the prefab names in ignorePrefabs
foreach (var prefab in DiscoveredPrefabs)
{
if (ignoredNames.Contains(prefab.Name))
{
//Log.Out("ScenarioManager-Update ignoredPrefabs CLEANUP, prefab.Name: " + prefab.Name);
//Log.Out("ScenarioManager-Update ignoredPrefabs CLEANUP, prefab.Position: " + prefab.Position);
ignoredPrefabs.Add(prefab);
}
}
return ignoredPrefabs;
}
public static void Update()
{
if (GameUtils.IsPlaytesting())
{
return;
}
if ((Time.time - cleanupUpdateCheck) > cleanupUpdateTick)
{
cleanupUpdateCheck = Time.time;
//Log.Out("ScenarioManager-Update CLEANUP, ClearedPrefabs.Count: " + ClearedPrefabs.Count);
//Log.Out("ScenarioManager-Update CLEANUP, DiscoveredPrefabs.Count: " + DiscoveredPrefabs.Count);
List<PrefabInfo> ignoredPrefabs = GetIgnoredDiscoveredPrefabs();
foreach (var prefab in ignoredPrefabs)
{
// Example: remove them from DiscoveredPrefabs
DiscoveredPrefabs.Remove(prefab);
//Log.Out("ScenarioManager-Update ignoredPrefabs CLEANUP, prefab.Name: " + prefab.Name);
Vector3 location = new Vector3(prefab.Position.x + prefab.Size.x / 2f, prefab.Position.y, prefab.Position.z + prefab.Size.z / 2f);
if (SingletonMonoBehaviour<ConnectionManager>.Instance.IsSinglePlayer)
{
NavObjectManager.Instance.UnRegisterNavObjectByPosition(location, "discovered_waypoint_" + prefab.Difficulty);
}
else
{
if (!GameManager.IsDedicatedServer)
{
NavObjectManager.Instance.UnRegisterNavObjectByPosition(location, "discovered_waypoint_" + prefab.Difficulty);
}
SingletonMonoBehaviour<ConnectionManager>.Instance.SendPackage((NetPackage)NetPackageManager.GetPackage<NetPackageUnregisterNavObject>().Setup("discovered_waypoint_" + prefab.Difficulty, location.x, location.y, location.z), false);
}
}
SaveDiscovered();
var matchingPrefabs = DiscoveredPrefabs
.Where(discovered => ClearedPrefabs.Any(cleared =>
cleared.Name == discovered.Name && cleared.Position == discovered.Position))
.ToList();
// Optional: Log the number of matching prefabs found
//Log.Out($"ScenarioManager-Update CLEANUP: {matchingPrefabs.Count} discovered prefabs already cleared.");
// Perform any other cleanup actions or processing with matchingPrefabs
foreach (var prefab in matchingPrefabs)
{
// Example: remove them from DiscoveredPrefabs
DiscoveredPrefabs.Remove(prefab);
//Log.Out("ScenarioManager-Update CLEANUP, prefab.Name: " + prefab.Name);
Vector3 location = new Vector3(prefab.Position.x + prefab.Size.x / 2f, prefab.Position.y, prefab.Position.z + prefab.Size.z / 2f);
if (SingletonMonoBehaviour<ConnectionManager>.Instance.IsSinglePlayer)
{
NavObjectManager.Instance.UnRegisterNavObjectByPosition(location, "discovered_waypoint_" + prefab.Difficulty);
}
else
{
if (!GameManager.IsDedicatedServer)
{
NavObjectManager.Instance.UnRegisterNavObjectByPosition(location, "discovered_waypoint_" + prefab.Difficulty);
}
SingletonMonoBehaviour<ConnectionManager>.Instance.SendPackage((NetPackage)NetPackageManager.GetPackage<NetPackageUnregisterNavObject>().Setup("discovered_waypoint_" + prefab.Difficulty, location.x, location.y, location.z), false);
}
}
}
if ((Time.time - prefabUpdateCheck) > prefabUpdateTick)
{
prefabUpdateCheck = Time.time;
if (dynamicPrefabsLoaded)
{
/*Log.Out("ScenarioManager-Update LIST OF PREFABS LOADED, dynamicPrefabs.Count: " + dynamicPrefabs.Count);
if (dynamicPrefabs.Count > 0)
{
GameManager.Instance.StartCoroutine(RebirthUtilities.processDynamicPrefabs("pine_forest"));
GameManager.Instance.StartCoroutine(RebirthUtilities.processDynamicPrefabs("desert"));
GameManager.Instance.StartCoroutine(RebirthUtilities.processDynamicPrefabs("snow"));
GameManager.Instance.StartCoroutine(RebirthUtilities.processDynamicPrefabs("wasteland"));
GameManager.Instance.StartCoroutine(RebirthUtilities.processDynamicPrefabs("burnt_forest"));
}
else
{
prefabUpdateTick = 5f;
}*/
}
else
{
if (RebirthVariables.testPurge)
Log.Out("ScenarioManager-Update GET LIST OF PREFABS");
System.Diagnostics.Stopwatch watch = System.Diagnostics.Stopwatch.StartNew();
watch.Start();
int numPrefabs = 0;
int numPrefabs2 = 0;
int numPrefabs3 = 0;
List<PrefabInstance> tempDynamicPrefabs = GameManager.Instance.GetDynamicPrefabDecorator()?.GetDynamicPrefabs();
if (tempDynamicPrefabs != null)
{
if (RebirthVariables.testPurge)
Log.Out("ScenarioManager-Update RETRIEVED BASE LIST OF DYNAMIC PREFABS, tempDynamicPrefabs.Count: " + tempDynamicPrefabs.Count);
if (tempDynamicPrefabs.Count > 0)
{
foreach (PrefabInstance _prefabInstance in tempDynamicPrefabs)
{
numPrefabs++;
//if (!_prefabInstance.prefab.PrefabName.ToLower().Contains("_tile_") && !_prefabInstance.prefab.Tags.Test_AnySet(FastTags<TagGroup.Poi>.Parse("rwgonly,streettile,part,hideui")))
if (_prefabInstance.prefab.SleeperVolumes.Count > 0 && !_prefabInstance.prefab.Tags.Test_AnySet(FastTags<TagGroup.Poi>.Parse("rwgonly,streettile,hideui")))
{
numPrefabs2++;
BiomeDefinition biomeAt = GameManager.Instance.World.ChunkCache.ChunkProvider.GetBiomeProvider().GetBiomeAt(_prefabInstance.boundingBoxPosition.x, _prefabInstance.boundingBoxPosition.z);
if (biomeAt != null)
{
numPrefabs3++;
Vector3 location = new Vector3(_prefabInstance.boundingBoxPosition.x, _prefabInstance.boundingBoxPosition.y, _prefabInstance.boundingBoxPosition.z);
if (RebirthVariables.testPurge)
{
Log.Out("ScenarioManager-Update _prefabInstance.prefab.PrefabName: " + _prefabInstance.prefab.PrefabName);
Log.Out("ScenarioManager-Update _prefabInstance.boundingBoxPosition: " + _prefabInstance.boundingBoxPosition);
Log.Out("ScenarioManager-Update _prefabInstance.boundingBoxSize: " + _prefabInstance.boundingBoxSize);
Log.Out("ScenarioManager-Update _prefabInstance.prefab.Tags: " + _prefabInstance.prefab.Tags);
Log.Out("ScenarioManager-Update biomeAt.m_sBiomeName: " + biomeAt.m_sBiomeName);
Log.Out("ScenarioManager-Update _prefabInstance.prefab.SleeperVolumes.Count: " + _prefabInstance.prefab.SleeperVolumes.Count);
}
if (!IsIgnoredPrefab(_prefabInstance.prefab.PrefabName))
{
AddDynamicPrefab(new DynamicPrefab(_prefabInstance.prefab.PrefabName, location, new Vector3(_prefabInstance.boundingBoxSize.x, _prefabInstance.boundingBoxSize.y, _prefabInstance.boundingBoxSize.z), _prefabInstance.prefab.DifficultyTier, biomeAt.m_sBiomeName, _prefabInstance.prefab.Tags.ToString()));
}
}
}
}
if (!RebirthVariables.purgePrefabCount)
{
RebirthVariables.purgePrefabCount = true;
foreach (KeyValuePair<int, string> biome in RebirthVariables.biomes)
{
int key = biome.Key; // The int key (0, 1, 2, etc.)
string value = biome.Value; // The string value ("pine_forest", "desert", etc.)
for (int i = 0; i <= 6; i++)
{
int clearedPrefabs = GetClearedPrefabCount(value, i);
RebirthUtilities.AddSpawnedPrefab(value, ScenarioManagerRebirth.RetrieveTotalBiomePrefabs(value, i), i);
if (RebirthVariables.testPurge)
Log.Out($"ScenarioManager-Update {value} PREFABS, DIFFICULTY {i}: {RebirthUtilities.GetSpawnedPrefab(value, i)} / cleared: {clearedPrefabs}");
}
}
}
dynamicPrefabsLoaded = true;
}
}
//watch.Stop();
//Log.Out("ScenarioManager-Update time to process: " + watch.ElapsedMilliseconds + " ms");
if (RebirthVariables.testPurge)
{
Log.Out("ScenarioManager-Update numPrefabs: " + numPrefabs);
Log.Out("ScenarioManager-Update numPrefabs2: " + numPrefabs2);
Log.Out("ScenarioManager-Update numPrefabs3: " + numPrefabs3);
}
}
}
}
public static void AddDynamicPrefab(DynamicPrefab prefab)
{
dynamicPrefabs.Add(prefab);
}
// Remove from the list using prefabName and position
public static bool RemoveDynamicPrefab(string prefabName, Vector3 position)
{
var prefabToRemove = dynamicPrefabs.Find(p => p.PrefabName == prefabName && p.Position == position);
if (prefabToRemove != null)
{
dynamicPrefabs.Remove(prefabToRemove);
return true;
}
return false;
}
// Retrieve the first entry for a given difficulty and biome
public static DynamicPrefab RetrieveDynamicPrefab(int difficulty, string biome)
{
return dynamicPrefabs.Find(p => p.Difficulty == difficulty && p.Biome == biome);
}
public static DynamicPrefab RetrieveDynamicPrefab(List<DynamicPrefab> tempDynamicPrefabs, int difficulty, string biome)
{
return tempDynamicPrefabs.Find(p => p.Difficulty == difficulty && p.Biome == biome);
}
public static List<DynamicPrefab> RetrieveDynamicPrefabs(string biome)
{
// Filter prefabs based on the biome provided
List<DynamicPrefab> filteredPrefabs = dynamicPrefabs.FindAll(prefab => prefab.Biome == biome);
return filteredPrefabs;
}
public static List<DynamicPrefab> RetrieveDynamicPrefabsFromDistance(string biome, Vector3 playerPosition, float distance, int difficulty)
{
List<DynamicPrefab> filteredPrefabs = dynamicPrefabs.FindAll(prefab => prefab.Biome == biome && prefab.Difficulty == difficulty);
foreach (var prefab in dynamicPrefabs)
{
// Calculate the distance between the prefab position and the player's position
Vector3 location = new Vector3(prefab.Position.x + prefab.Size.x / 2f, prefab.Position.y, prefab.Position.z + prefab.Size.z / 2f);
float distanceToPrefab = Vector3.Distance(location, playerPosition);
// Check if the prefab is within the specified distance
if (distanceToPrefab > distance)
{
filteredPrefabs.Remove(prefab);
}
}
return filteredPrefabs;
}
public static int RetrieveTotalBiomePrefabs(string biome, int difficulty)
{
List<DynamicPrefab> filteredPrefabs = dynamicPrefabs.FindAll(prefab => prefab.Biome == biome && prefab.Difficulty == difficulty);
//Log.Out("ScenarioManagerRebirth-RetrieveTotalBiomePrefabs filteredPrefabs.Count: " + filteredPrefabs.Count);
return filteredPrefabs.Count;
}
private static void LoadScenario(string scenario)
{
string scenarioPath = $"{SaveDataPath}/{GamePrefs.GetString(EnumGamePrefs.GameWorld)}/{GamePrefs.GetString(EnumGamePrefs.GameName)}";
Directory.CreateDirectory(scenarioPath);
string scenarioFilePath = $"{scenarioPath}/" + scenario + ".xml";
string discoveredFilePath = $"{scenarioPath}/discoveredPrefabs.xml";
string purgeKillsFilePath = $"{scenarioPath}/purgeKillsInfo.xml";
bool exists = System.IO.File.Exists(scenarioFilePath);
bool createNew = false;
if (exists)
{
//Log.Out("ScenarioManagerRebirth-LoadScenario SCENARIO FILE EXISTS");
int currentDay = GameUtils.WorldTimeToDays(GameManager.Instance.World.worldTime);
//Log.Out("ScenarioManagerRebirth-LoadScenario currentDay: " + currentDay);
float currentTimeOfDayHours = GameUtils.WorldTimeToHours(GameManager.Instance.World.worldTime);
//Log.Out("ScenarioManagerRebirth-LoadScenario currentTimeOfDayHours: " + currentTimeOfDayHours);
float currentTimeOfDayMinutes = GameUtils.WorldTimeToMinutes(GameManager.Instance.World.worldTime);
//Log.Out("ScenarioManagerRebirth-LoadScenario currentTimeOfDayMinutes: " + currentTimeOfDayMinutes);
if (currentDay == 1 && currentTimeOfDayHours == 7 && currentTimeOfDayMinutes < 20)
{
//Log.Out("ScenarioManagerRebirth-LoadScenario EARLY MORNING");
try
{
Directory.Delete(scenarioFilePath);
}
catch { }
if (scenario == "purge")
{
try
{
Directory.Delete(purgeKillsFilePath);
}
catch { }
}
createNew = true;
}
}
else
{
//Log.Out("ScenarioManagerRebirth-LoadScenario SCENARIO FILE DOES NOT EXIST");
createNew = true;
}
if (createNew)
{
//Log.Out("ScenarioManagerRebirth-LoadScenario CREATE NEW FILE");
SaveScenario(scenario); // Save an empty file if it doesn't exist
SaveDiscovered();
if (scenario == "purge")
{
SavePurgeKills();
}
return;
}
//Log.Out("ScenarioManagerRebirth-LoadScenario LOAD EXISTING FILE");
if (scenario == "purge")
{
XDocument xmlDoc = XDocument.Load(scenarioFilePath);
ClearedPrefabs = (from prefab in xmlDoc.Root.Elements("Prefab")
select new PrefabInfo
{
Name = prefab.Element("Name").Value,
Position = new Vector3(
float.Parse(prefab.Element("Position").Element("X").Value),
float.Parse(prefab.Element("Position").Element("Y").Value),
float.Parse(prefab.Element("Position").Element("Z").Value)),
Size = new Vector3(
float.Parse(prefab.Element("Size").Element("X").Value),
float.Parse(prefab.Element("Size").Element("Y").Value),
float.Parse(prefab.Element("Size").Element("Z").Value)),
Difficulty = int.Parse(prefab.Element("Difficulty").Value),
EntitiesCleared = int.Parse(prefab.Element("EntitiesCleared").Value),
Players = prefab.Element("Players").Elements("Player")
.ToDictionary(p => int.Parse(p.Element("ID").Value), p => p.Element("Name").Value),
Biome = prefab.Element("Biome").Value
}).ToList();
if (File.Exists(discoveredFilePath))
{
xmlDoc = XDocument.Load(discoveredFilePath);
DiscoveredPrefabs = (from prefab in xmlDoc.Root.Elements("Prefab")
select new PrefabInfo
{
Name = prefab.Element("Name").Value,
Position = new Vector3(
float.Parse(prefab.Element("Position").Element("X").Value),
float.Parse(prefab.Element("Position").Element("Y").Value),
float.Parse(prefab.Element("Position").Element("Z").Value)),
Size = new Vector3(
float.Parse(prefab.Element("Size").Element("X").Value),
float.Parse(prefab.Element("Size").Element("Y").Value),
float.Parse(prefab.Element("Size").Element("Z").Value)),
Difficulty = int.Parse(prefab.Element("Difficulty").Value),
EntitiesCleared = int.Parse(prefab.Element("EntitiesCleared").Value),
Players = prefab.Element("Players").Elements("Player")
.ToDictionary(p => int.Parse(p.Element("ID").Value), p => p.Element("Name").Value),
Biome = prefab.Element("Biome").Value
}).ToList();
}
if (File.Exists(purgeKillsFilePath))
{
xmlDoc = XDocument.Load(purgeKillsFilePath);
purgeKills = (from purgeKill in xmlDoc.Root.Elements("PurgeKill")
select new PurgeKills
{
Name = purgeKill.Element("Name").Value,
Position = new Vector3(
float.Parse(purgeKill.Element("Position").Element("X").Value),
float.Parse(purgeKill.Element("Position").Element("Y").Value),
float.Parse(purgeKill.Element("Position").Element("Z").Value)),
Players = purgeKill.Element("Players").Elements("Player")
.ToDictionary(p => int.Parse(p.Element("ID").Value), p => new KillInfo
{
Kills = int.Parse(p.Element("Kills").Value),
Redeemed = bool.Parse(p.Element("Redeemed").Value) // Load Redeemed value
})
}).ToList();
}
}
}
public static void SaveScenario(string scenario)
{
string scenarioPath = $"{SaveDataPath}/{GamePrefs.GetString(EnumGamePrefs.GameWorld)}/{GamePrefs.GetString(EnumGamePrefs.GameName)}";
Directory.CreateDirectory(scenarioPath);
string scenarioFilePath = $"{scenarioPath}/" + scenario + ".xml";
XElement root = new XElement("Prefabs",
from prefab in ClearedPrefabs
select new XElement("Prefab",
new XElement("Name", prefab.Name),
new XElement("Position",
new XElement("X", prefab.Position.x),
new XElement("Y", prefab.Position.y),
new XElement("Z", prefab.Position.z)),
new XElement("Size",
new XElement("X", prefab.Size.x),
new XElement("Y", prefab.Size.y),
new XElement("Z", prefab.Size.z)),
new XElement("Difficulty", prefab.Difficulty),
new XElement("EntitiesCleared", prefab.EntitiesCleared),
new XElement("Players",
from player in prefab.Players
select new XElement("Player",
new XElement("ID", player.Key),
new XElement("Name", player.Value))),
new XElement("Biome", prefab.Biome)
));
XDocument xmlDoc = new XDocument(root);
xmlDoc.Save(scenarioFilePath);
}
public static void SaveDiscovered()
{
string scenarioPath = $"{SaveDataPath}/{GamePrefs.GetString(EnumGamePrefs.GameWorld)}/{GamePrefs.GetString(EnumGamePrefs.GameName)}";
Directory.CreateDirectory(scenarioPath);
string filePath = $"{scenarioPath}/discoveredPrefabs.xml";
XElement root = new XElement("Prefabs",
from prefab in DiscoveredPrefabs
select new XElement("Prefab",
new XElement("Name", prefab.Name),
new XElement("Position",
new XElement("X", prefab.Position.x),
new XElement("Y", prefab.Position.y),
new XElement("Z", prefab.Position.z)),
new XElement("Size",
new XElement("X", prefab.Size.x),
new XElement("Y", prefab.Size.y),
new XElement("Z", prefab.Size.z)),
new XElement("Difficulty", prefab.Difficulty),
new XElement("EntitiesCleared", prefab.EntitiesCleared),
new XElement("Players",
from player in prefab.Players
select new XElement("Player",
new XElement("ID", player.Key),
new XElement("Name", player.Value))),
new XElement("Biome", prefab.Biome)
));
XDocument xmlDoc = new XDocument(root);
xmlDoc.Save(filePath);
}
// PURGE KILLS HELPERS
public static int GetTotalPurgeKills(string name, Vector3 position)
{
// Get the list of players from the GetPurgeKillPlayers function
var players = GetPurgeKillPlayers(name, position);
// Sum the total kills of all players
return players.Sum(p => p.Kills);
}
public static List<PlayerKillInfo> GetPurgeKillPlayers(string name, Vector3 position)
{
var purgeKill = GetPurgeKillEntry(name, position);
if (purgeKill != null)
{
// Convert the Players dictionary to a list of PlayerKillInfo
return purgeKill.Players.Select(p => new PlayerKillInfo
{
PlayerID = p.Key,
Kills = p.Value.Kills, // Access kills from KillInfo
Redeemed = p.Value.Redeemed // Access redeemed status from KillInfo
}).ToList();
}
return new List<PlayerKillInfo>(); // Return an empty list if no matching PurgeKill entry is found
}
public static List<PurgeKills> GetPurgeKillEntries(int playerID)
{
return purgeKills.Where(pk => pk.Players.ContainsKey(playerID)).ToList();
}
private static PurgeKills GetPurgeKillEntry(string name, Vector3 position)
{
return purgeKills.FirstOrDefault(pk => pk.Name == name && pk.Position == position);
}
private static bool PurgeKillExists(string name, Vector3 position)
{
return purgeKills.Any(pk => pk.Name == name && pk.Position == position);
}
public static int GetTotalKills(int playerID)
{
// Sum the total kills for the playerID across all PurgeKills entries
int totalKills = purgeKills
.Where(purgeKill => purgeKill.Players.ContainsKey(playerID)) // Filter entries that have this playerID
.Sum(purgeKill => purgeKill.Players[playerID].Kills); // Sum the kills for this playerID
return totalKills;
}
public static List<PurgeKills> GetKills(string name, Vector3 position, int playerID)
{
return purgeKills.Where(pk => pk.Name == name && pk.Position == position && pk.Players.ContainsKey(playerID)).ToList();
}
public static bool RemoveKills(string name, Vector3 position, int playerID)
{
var purgeKill = GetPurgeKillEntry(name, position);
if (purgeKill != null && purgeKill.Players.ContainsKey(playerID))
{
purgeKill.Players.Remove(playerID);
if (purgeKill.Players.Count == 0)
{
purgeKills.Remove(purgeKill);
}
SavePurgeKills();
return true;
}
return false;
}
public static (int numKills, int numRedeemableKills) AddKill(string name, Vector3 position, int playerID)
{
var purgeKill = GetPurgeKillEntry(name, position);
if (purgeKill == null)
{
purgeKill = new PurgeKills
{
Name = name,
Position = position
};
purgeKills.Add(purgeKill);
}
if (!purgeKill.Players.ContainsKey(playerID))
{
purgeKill.Players[playerID] = new KillInfo { Kills = 0, Redeemed = false }; // Initialize with default values
}
purgeKill.Players[playerID].Kills++;
SavePurgeKills();
int numKills = GetCurrentPurgeKills(playerID);
int numRedeemableKills = GetCurrentRedeemablePurgeKills(playerID);
//Log.Out("ScenarioManagerRebirth-AddKill numKills: " + numKills);
//Log.Out("ScenarioManagerRebirth-AddKill numRedeemableKills: " + numRedeemableKills);
return (numKills, numRedeemableKills);
}
public static bool RedeemKills(string name, Vector3 position, int playerID)
{
// Find the matching PurgeKill entry
var purgeKill = GetPurgeKillEntry(name, position);
if (purgeKill != null && purgeKill.Players.ContainsKey(playerID))
{
// Check if the player has any kills
var killInfo = purgeKill.Players[playerID];
if (killInfo != null && !killInfo.Redeemed) // If not already redeemed
{
killInfo.Redeemed = true; // Mark as redeemed
SavePurgeKills(); // Save the updated kills
return true; // Return true if the operation was successful
}
}
return false; // Return false if the operation failed
}
public static int AutoRedeemKills(int playerID)
{
int totalKills = 0;
// Loop through all purge kills
foreach (var purgeKill in purgeKills)
{
// Check if the player is in the current PurgeKill entry
if (purgeKill.Players.ContainsKey(playerID) && IsPrefabCleared(purgeKill.Name, purgeKill.Position))
{
var killInfo = purgeKill.Players[playerID];
// If the kill entry was redeemed, reset it and add kills to total
if (!killInfo.Redeemed)
{
killInfo.Redeemed = true; // Reset the redeemed flag
totalKills += killInfo.Kills; // Add kills to the total count
}
}
}
// Save updated data
SavePurgeKills();
return totalKills; // Return total number of kills that were updated
}
public static int GetCurrentPurgeKills(int playerID)
{
int totalKills = 0;
// Loop through all purge kills
foreach (var purgeKill in purgeKills)
{
// Check if the player is in the current PurgeKill entry
if (purgeKill.Players.ContainsKey(playerID))
{
var killInfo = purgeKill.Players[playerID];
// If the kill entry was redeemed, reset it and add kills to total
if (!killInfo.Redeemed)
{
totalKills += killInfo.Kills; // Add kills to the total count
}
}
}
return totalKills;
}
public static int GetCurrentRedeemablePurgeKills(int playerID)
{
int totalKills = 0;
// Loop through all purge kills
foreach (var purgeKill in purgeKills)
{
// Check if the player is in the current PurgeKill entry
if (purgeKill.Players.ContainsKey(playerID) && !IsPrefabCleared(purgeKill.Name, purgeKill.Position))
{
var killInfo = purgeKill.Players[playerID];
// If the kill entry was redeemed, reset it and add kills to total
if (!killInfo.Redeemed)
{
totalKills += killInfo.Kills; // Add kills to the total count
}
}
}
return totalKills;
}
private static void SavePurgeKills()
{
if (GameManager.Instance.World.IsEditor())
{
return;
}
string scenarioPath = $"{SaveDataPath}/{GamePrefs.GetString(EnumGamePrefs.GameWorld)}/{GamePrefs.GetString(EnumGamePrefs.GameName)}";
string purgeKillsFilePath = $"{scenarioPath}/purgeKillsInfo.xml";
XElement root = new XElement("PurgeKills",
from purgeKill in purgeKills
select new XElement("PurgeKill",
new XElement("Name", purgeKill.Name),
new XElement("Position",
new XElement("X", purgeKill.Position.x),
new XElement("Y", purgeKill.Position.y),
new XElement("Z", purgeKill.Position.z)),
new XElement("Players",
from player in purgeKill.Players
select new XElement("Player",
new XElement("ID", player.Key),
new XElement("Kills", player.Value.Kills), // Save kills
new XElement("Redeemed", player.Value.Redeemed) // Save redeemed status
))
));
XDocument xmlDoc = new XDocument(root);
xmlDoc.Save(purgeKillsFilePath);
}
// PREFAB INFO HELPERS
public static string GetFirstPlayerName(PrefabInfo prefabInfo)
{
if (prefabInfo.Players != null && prefabInfo.Players.Count > 0)
{
// Get the first player's name (the first value from the dictionary)
return prefabInfo.Players.Values.First();
}
return null; // Return null if the dictionary is empty or not set
}
public static void AddPrefab(string name, Vector3 position, Vector3 size, int difficulty, int entitiesCleared, Dictionary<int, string> players, string biome)
{
if (IsPrefabCleared(name, position))
{
return;
}
PrefabInfo newPrefab = new PrefabInfo
{
Name = name,
Position = position,
Size = size,
Difficulty = difficulty,
EntitiesCleared = entitiesCleared,
Players = players,
Biome = biome
};
Vector3 vector = new Vector3(newPrefab.Position.x + newPrefab.Size.x / 2f, newPrefab.Position.y, newPrefab.Position.z + newPrefab.Size.z / 2f);
ClearedPrefabs.Add(newPrefab);
int clearedPrefabs = GetTotalClearedPrefabCount(biome);
int totalPrefabs = RebirthUtilities.GetTotalSpawnedPrefab(biome);
//Log.Out($"ScenarioManagerRebirth-AddPrefab biome: {biome} / clearedPrefabs: {clearedPrefabs} of {totalPrefabs}");
SaveScenario("purge"); // Automatically save after adding
// remove prefab from discovered
RemoveDiscoveredPrefab(name, position, vector);
RemoveDynamicPrefab(name, position);
//Debug.Log($"Prefab: {newPrefab.Name} / position: {newPrefab.Position} / size: {newPrefab.Size} / Difficulty: {newPrefab.Difficulty} / Entities Cleared: {newPrefab.EntitiesCleared} / Reported By: {players} / Biome: {newPrefab.Biome}");
bool reportLocal = false;
string report = string.Format(Localization.Get("PurgePurgedReport"), GetFirstPlayerName(newPrefab), entitiesCleared, Localization.Get(name), Localization.Get("biome_" + biome));
string sound = "purge_discovered";
if (SingletonMonoBehaviour<ConnectionManager>.Instance.IsSinglePlayer)
{
reportLocal = true;
RebirthVariables.purgeDisplayPercentage = ((float)clearedPrefabs / totalPrefabs) * 100;
int numPrefabs = clearedPrefabs;
if (clearedPrefabs > totalPrefabs)
{
numPrefabs = totalPrefabs;
}
RebirthVariables.purgeLabel = numPrefabs + "/" + totalPrefabs;
}
else
{
if (!GameManager.IsDedicatedServer)
{
reportLocal = true;
RebirthVariables.purgeDisplayPercentage = ((float)clearedPrefabs / totalPrefabs) * 100;
int numPrefabs = clearedPrefabs;
if (clearedPrefabs > totalPrefabs)
{
numPrefabs = totalPrefabs;
}
RebirthVariables.purgeLabel = numPrefabs + "/" + totalPrefabs;
}
SingletonMonoBehaviour<ConnectionManager>.Instance.SendPackage(NetPackageManager.GetPackage<NetPackageRegisterPrefabNavIcon>().Setup("purge_waypoint", vector.x, vector.y, vector.z, report, sound));
SingletonMonoBehaviour<ConnectionManager>.Instance.SendPackage(NetPackageManager.GetPackage<NetPackageUpdatePurgeDisplay>().Setup(name, position.x, position.y, position.z, 0, 0, 0, 0, 0, 0, 0), false);
}
if (reportLocal)
{
NavObject navPurged = NavObjectManager.Instance.RegisterNavObject("purge_waypoint", vector, "purge_waypoint");
if (navPurged != null)
{
navPurged.trackedPosition = vector;
}
EntityPlayerLocal primaryPlayer = GameManager.Instance.World.GetPrimaryPlayer();
if (primaryPlayer != null)
{
if (sound != "")
{
Manager.PlayInsidePlayerHead(sound);
}
//Log.Out("ScenarioManagerRebirth-AddPrefab report: " + report);
GameManager.ShowTooltip(primaryPlayer, report, string.Empty);
}
}
}
public static void AddDiscoveredPrefab(string name, Vector3 position, Vector3 size, int difficulty, int entitiesCleared, Dictionary<int, string> players, string biome)
{
//Log.Out("ScenarioManagerRebirth-AddDiscoveredPrefab START");
PrefabInfo newPrefab = new PrefabInfo
{
Name = name,
Position = position,
Size = size,
Difficulty = difficulty,
EntitiesCleared = entitiesCleared,
Players = players,
Biome = biome
};
//Log.Out($"Prefab: {newPrefab.Name} / position: {newPrefab.Position} / size: {newPrefab.Size} / Difficulty: {newPrefab.Difficulty} / Entities Cleared: {newPrefab.EntitiesCleared} / Reported By: {players} / Biome: {newPrefab.Biome}");
if (IsPrefabDiscovered(name, position))
{
//Log.Out("ScenarioManagerRebirth-AddDiscoveredPrefab ALREADY DISCOVERED");
return;
}
DiscoveredPrefabs.Add(newPrefab);
SaveDiscovered();
Vector3 vector = new Vector3(newPrefab.Position.x + newPrefab.Size.x / 2f, newPrefab.Position.y, newPrefab.Position.z + newPrefab.Size.z / 2f);
bool reportLocal = false;
string report = string.Format(Localization.Get("PurgeDiscoveryReport"), GetFirstPlayerName(newPrefab), Localization.Get(name), Localization.Get("biome_" + biome));
string sound = "purge_cleared";
if (SingletonMonoBehaviour<ConnectionManager>.Instance.IsSinglePlayer)
{
reportLocal = true;
}
else
{
if (!GameManager.IsDedicatedServer)
{
reportLocal = true;
}
if (players.ContainsKey(-1))
{
report = "";
}
SingletonMonoBehaviour<ConnectionManager>.Instance.SendPackage(NetPackageManager.GetPackage<NetPackageScenarioAddDiscoveredPrefab>().Setup("discovered_waypoint_" + difficulty, vector.x, vector.y, vector.z, report, sound));
}
if (reportLocal)
{
//Log.Out("ScenarioManagerRebirth-AddDiscoveredPrefab navobject: " + "discovered_waypoint_" + difficulty);
//Log.Out("ScenarioManagerRebirth-AddDiscoveredPrefab vector: " + vector);
NavObject navDiscovered = NavObjectManager.Instance.RegisterNavObject("discovered_waypoint_" + difficulty, vector, "discovered_waypoint_" + difficulty);
if (navDiscovered != null)
{
navDiscovered.trackedPosition = vector;
}
if (!players.ContainsKey(-1))
{
EntityPlayerLocal primaryPlayer = GameManager.Instance.World.GetPrimaryPlayer();
if (primaryPlayer != null)
{
if (sound != "")
{
Manager.PlayInsidePlayerHead(sound);
}
//Log.Out("ScenarioManagerRebirth-AddDiscoveredPrefab report: " + report);
GameManager.ShowTooltip(primaryPlayer, report, string.Empty);
}
}
}
}
// Check if a prefab is cleared by its name and position
public static bool IsPrefabCleared(string name, Vector3 position)
{
return ClearedPrefabs.Any(p => p.Name == name && p.Position == position);
}
public static bool IsPrefabDiscovered(string name, Vector3 position)
{
return DiscoveredPrefabs.Any(p => p.Name == name && p.Position == position && p.Difficulty != -1);
}
// Remove a prefab from the cleared list
public static void RemovePrefab(string name, Vector3 position)
{
var prefabToRemove = ClearedPrefabs.FirstOrDefault(p => p.Name == name && p.Position == position);
if (prefabToRemove != null)
{
ClearedPrefabs.Remove(prefabToRemove);
SaveScenario("purge");
}
else
{
Debug.LogWarning("Prefab not found.");
}
}
public static void UpdateDiscoveredPrefab(string name, Vector3 position, int entitiesCleared)
{
var prefab = DiscoveredPrefabs.FirstOrDefault(p => p.Name == name && p.Position == position);
// If the prefab is found, update the EntitiesCleared value
if (prefab != null)
{
prefab.EntitiesCleared = entitiesCleared;
}
}
public static int GetDiscoveredPrefabEntitiesCleared(string name, Vector3 position)
{
// Find the prefab in the list that matches the name and position
var prefab = DiscoveredPrefabs.FirstOrDefault(p => p.Name == name && p.Position == position);
// Return the EntitiesCleared value if the prefab is found, otherwise return a default value
return prefab != null ? prefab.EntitiesCleared : -1; // Return -1 if not found
}
public static void RemoveDiscoveredPrefab(string name, Vector3 position, Vector3 location)
{
//Log.Out("ScenarioManagerRebirth-RemoveDiscoveredPrefab START");
var prefabToRemove = DiscoveredPrefabs.FirstOrDefault(p => p.Name == name && p.Position == position);
if (prefabToRemove != null)
{
//Log.Out("ScenarioManagerRebirth-RemoveDiscoveredPrefab 1");
DiscoveredPrefabs.Remove(prefabToRemove);
if (SingletonMonoBehaviour<ConnectionManager>.Instance.IsSinglePlayer)
{
//Log.Out("ScenarioManagerRebirth-RemoveDiscoveredPrefab UNREGISTER LOCAL NAV OBJECT: " + "discovered_waypoint_" + prefabToRemove.Difficulty);
//Log.Out("ScenarioManagerRebirth-RemoveDiscoveredPrefab position: " + position);
//Log.Out("ScenarioManagerRebirth-RemoveDiscoveredPrefab location: " + location);
NavObjectManager.Instance.UnRegisterNavObjectByPosition(location, "discovered_waypoint_" + prefabToRemove.Difficulty);
}
else
{
if (!GameManager.IsDedicatedServer)
{
NavObjectManager.Instance.UnRegisterNavObjectByPosition(location, "discovered_waypoint_" + prefabToRemove.Difficulty);
}
//Log.Out("ScenarioManagerRebirth-RemoveDiscoveredPrefab SEND UNREGISTER TO CLIENTS");
SingletonMonoBehaviour<ConnectionManager>.Instance.SendPackage((NetPackage)NetPackageManager.GetPackage<NetPackageUnregisterNavObject>().Setup("discovered_waypoint_" + prefabToRemove.Difficulty, location.x, location.y, location.z), false);
}
SaveDiscovered();
}
else
{
Debug.LogWarning("Prefab not found.");
}
}
// Retrieve prefabs by player name
public static List<PrefabInfo> GetPrefabsByPlayer(string playerName)
{
return ClearedPrefabs.Where(p => p.PlayerName == playerName).ToList();
}
// Retrieve prefabs by name
public static List<PrefabInfo> GetPrefabsByName(string prefabName)
{
return ClearedPrefabs.Where(p => p.Name == prefabName).ToList();
}
// Retrieve prefabs by position
public static List<PrefabInfo> GetPrefabsByPosition(Vector3 position)
{
return ClearedPrefabs.Where(p => p.Position == position).ToList();
}
// Retrieve prefabs by difficulty
public static List<PrefabInfo> GetPrefabsByDifficulty(int difficulty)
{
return ClearedPrefabs.Where(p => p.Difficulty == difficulty).ToList();
}
// Retrieve prefabs by biome
public static List<PrefabInfo> GetPrefabsByBiome(string biome)
{
return ClearedPrefabs.Where(p => p.Biome == biome).ToList();
}
public static int GetClearedPrefabCount(string biome, int difficulty)
{
return ClearedPrefabs.Count(p => p.Biome == biome && p.Difficulty == difficulty);
}
public static int GetTotalClearedPrefabCount(string biome)
{
return ClearedPrefabs.Count(p => p.Biome == biome);
}
}