public void AfterWorldLoad() { StringBuilder sb = new StringBuilder(); PandaLogger.Log(ChatColor.lime, "-------------------Bosses Loaded----------------------"); var i = 0; foreach (var monster in LoadedAssembalies) { if (Activator.CreateInstance(monster) is IPandaBoss pandaBoss && !string.IsNullOrEmpty(pandaBoss.name)) { sb.Append($"{pandaBoss.name}, "); MonsterManager.AddBoss(pandaBoss); i++; if (i > 5) { sb.Append("</color>"); i = 0; sb.AppendLine(); sb.Append("<color=lime>"); } } } PandaLogger.Log(ChatColor.lime, sb.ToString()); PandaLogger.Log(ChatColor.lime, "------------------------------------------------------"); }
public static void OnLoadingPlayer(JSONNode n, Players.Player p) { if (n.TryGetChild(GameLoader.NAMESPACE + ".Machines", out var machinesNode)) { lock (Machines) { foreach (var node in machinesNode.LoopArray()) { RegisterMachineState(p, new MachineState(node, p)); } if (Machines.ContainsKey(p)) { PandaLogger.Log(ChatColor.lime, $"{Machines[p].Count} machines loaded from save for {p.ID.steamID.m_SteamID}!"); } else { PandaLogger.Log(ChatColor.lime, $"No machines found in save for {p.ID.steamID.m_SteamID}."); } } } else { PandaLogger.Log(ChatColor.lime, $"No machines found in save for {p.ID.steamID.m_SteamID}."); } }
public static void ResortSeasons() { for (var j = 0; j < _seasons.Count; j++) { for (var i = 0; i < _seasons.Count - 1; i++) { var s = _seasons[i]; _seasons.Remove(s); AddSeason(s); } } var sb = new StringBuilder(); sb.Append("Season order: "); for (var j = 0; j < _seasons.Count; j++) { sb.Append(_seasons[j].Name); if (j != _seasons.Count - 1) { sb.Append(", "); } } PandaLogger.Log(sb.ToString()); }
public void ColonyCreated(Colony c) { StringBuilder sb = new StringBuilder(); PandaLogger.Log(ChatColor.lime, "-------------------Happiness Effects Loaded----------------------"); var i = 0; foreach (var item in LoadedAssembalies) { if (Activator.CreateInstance(item) is IHappinessEffect effect) { c.HappinessData.HappinessEffects.Add(effect); sb.Append($"{effect.GetType().Name}, "); i++; if (i > 5) { sb.Append("</color>"); i = 0; sb.AppendLine(); sb.Append("<color=lime>"); } } } PandaLogger.Log(ChatColor.lime, sb.ToString()); PandaLogger.Log(ChatColor.lime, "---------------------------------------------------------"); }
public void AfterModsLoaded(List <ModLoader.ModDescription> list) { StringBuilder sb = new StringBuilder(); PandaLogger.Log(ChatColor.lime, "-------------------Connected Block CalculationType Loaded----------------------"); var i = 0; foreach (var s in LoadedAssembalies) { if (Activator.CreateInstance(s) is IConnectedBlockCalculationType connectedBlockCalcType && !string.IsNullOrEmpty(connectedBlockCalcType.name)) { sb.Append($"{connectedBlockCalcType.name}, "); ConnectedBlockCalculator.CalculationTypes[connectedBlockCalcType.name] = connectedBlockCalcType; i++; if (i > 5) { sb.Append("</color>"); i = 0; sb.AppendLine(); sb.Append("<color=lime>"); } } } PandaLogger.Log(ChatColor.lime, sb.ToString()); PandaLogger.Log(ChatColor.lime, "---------------------------------------------------------"); }
public static void Register() { var researchDic = new Dictionary <ushort, int>(); PandaLogger.Log("Registering Panda Research."); AddBanner(researchDic); AddReducedWaste(researchDic); AddArmorSmithing(researchDic); AddColonistHealth(researchDic); AddSwordSmithing(researchDic); AddKnightResearch(researchDic); AddImprovedSlings(researchDic); AddImprovedBows(researchDic); AddImprovedCrossbows(researchDic); AddImprovedMatchlockgun(researchDic); AddMachines(researchDic); AddImprovedDuarability(researchDic); AddImprovedFuelCapacity(researchDic); AddIncreasedCapacity(researchDic); AddHerbResearch(researchDic); AddApocthResearch(researchDic); AddAdvanceApocthResearch(researchDic); PandaLogger.Log("Panda Research Registering Complete!"); }
public void AfterItemTypesDefined() { StringBuilder sb = new StringBuilder(); PandaLogger.Log(ChatColor.lime, "-------------------Roaming Job Objective Loaded----------------------"); var i = 0; foreach (var s in LoadedAssembalies) { if (Activator.CreateInstance(s) is IRoamingJobObjective roamingJobObjective && !string.IsNullOrEmpty(roamingJobObjective.name)) { sb.Append($"{roamingJobObjective.name}, "); RoamingJobManager.RegisterObjectiveType(roamingJobObjective); i++; if (i > 5) { sb.Append("</color>"); i = 0; sb.AppendLine(); sb.Append("<color=lime>"); } } } PandaLogger.Log(ChatColor.lime, sb.ToString()); PandaLogger.Log(ChatColor.lime, "---------------------------------------------------------"); }
public void AfterSelectedWorld() { StringBuilder sb = new StringBuilder(); PandaLogger.Log(ChatColor.lime, "-------------------Texture Mapping Loaded----------------------"); var i = 0; foreach (var item in LoadedAssembalies) { if (Activator.CreateInstance(item) is ICSTextureMapping texture && !string.IsNullOrEmpty(texture.name)) { ItemTypesServer.SetTextureMapping(texture.name, new ItemTypesServer.TextureMapping(texture.JsonSerialize())); sb.Append($"{texture.name}, "); i++; if (i > 5) { sb.Append("</color>"); i = 0; sb.AppendLine(); sb.Append("<color=lime>"); } } } PandaLogger.Log(ChatColor.lime, sb.ToString()); PandaLogger.Log(ChatColor.lime, "---------------------------------------------------------"); }
private static void LoadImplementation(List <ModLoader.ModDescription> list) { foreach (var mod in list.Where(m => m.HasAssembly && !string.IsNullOrEmpty(m.assemblyPath) && !m.assemblyPath.Contains("Pipliz\\modInfo.json"))) { try { // Get all Types available in the assembly in an array var typeArray = mod.LoadedAssembly.GetTypes(); // Walk through each Type and list their Information foreach (var type in typeArray) { var ifaces = type.GetInterfaces(); foreach (var iface in ifaces) { foreach (var e in _settlersExtensions) { if (!string.IsNullOrEmpty(e.InterfaceName) && e.InterfaceName == iface.Name && !type.IsInterface) { var constructor = type.GetConstructor(Type.EmptyTypes); if (constructor != null) { e.LoadedAssembalies.Add(type); } } } if (!string.IsNullOrEmpty(iface.Name) && nameof(IOnTimedUpdate) == iface.Name && !type.IsInterface) { var constructor = type.GetConstructor(Type.EmptyTypes); if (constructor != null && Activator.CreateInstance(type) is IOnTimedUpdate onUpdateCallback) { PandaLogger.Log(ChatColor.lime, "OnTimedUpdateLoaded: {0}", onUpdateCallback.GetType().Name); _timedUpdate.Add(onUpdateCallback); } } } foreach (var e in _settlersExtensions) { if (e.ClassType != null && type.Equals(e.ClassType)) { e.LoadedAssembalies.Add(type); } } } } catch (Exception) { // Do not log it is not the correct type. } } }
public static IMachineSettings GetCallbacks(string machineName) { if (MachineCallbacks.ContainsKey(machineName)) { return(MachineCallbacks[machineName]); } PandaLogger.Log($"Unknown machine {machineName}. Returning {nameof(Miner)}."); return(MachineCallbacks[nameof(Miner)]); }
public static void OnPlayerConnectedEarly(Players.Player p) { if (p.IsConnected && !Configuration.OfflineColonies) { foreach (Colony c in p.Colonies) { if (c.Owners.Count(own => own.IsConnected) == 1) { var file = $"{GameLoader.GAMEDATA_FOLDER}/savegames/{ServerManager.WorldName}/NPCArchive/{c.ColonyID}.json"; if (File.Exists(file) && JSON.Deserialize(file, out var followersNode, false)) { File.Delete(file); PandaLogger.Log(ChatColor.cyan, $"Player {p.ID.steamID} is reconnected. Restoring Colony."); foreach (var node in followersNode.LoopArray()) { try { node.SetAs("id", GetAIID()); var npc = new NPCBase(c, node); c.RegisterNPC(npc); NPCTracker.Add(npc); ModLoader.TriggerCallbacks(ModLoader.EModCallbackType.OnNPCLoaded, npc, node); foreach (var job in new List <IJob>(c.JobFinder.JobsData.OpenJobs)) { if (node.TryGetAs("JobPoS", out JSONNode pos) && job.GetJobLocation() == (Vector3Int)pos) { if (job.IsValid && job.NeedsNPC) { npc.TakeJob(job); c.JobFinder.Remove(job); } break; } } } catch (Exception ex) { PandaLogger.LogError(ex); } } JSON.Serialize(file, new JSONNode(NodeType.Array)); c.JobFinder.Update(); c.SendCommonData(); } } } } }
public void AfterWorldLoad() { StringBuilder sb = new StringBuilder(); PandaLogger.Log(ChatColor.lime, "-------------------Recipes Loaded----------------------"); var i = 0; foreach (var item in LoadedAssembalies) { if (Activator.CreateInstance(item) is ICSRecipe recipe && !string.IsNullOrEmpty(recipe.name)) { var requirements = new List <InventoryItem>(); var results = new List <RecipeResult>(); recipe.JsonSerialize(); foreach (var ri in recipe.requires) { if (ItemTypes.IndexLookup.TryGetIndex(ri.type, out var itemIndex)) { requirements.Add(new InventoryItem(itemIndex, ri.amount)); } } foreach (var ri in recipe.results) { results.Add(ri); } var newRecipe = new Recipe(recipe.name, requirements, results, recipe.defaultLimit, 0, (int)recipe.defaultPriority); ServerManager.RecipeStorage.AddLimitTypeRecipe(recipe.Job, newRecipe); if (recipe.isOptional) { ServerManager.RecipeStorage.AddScienceRequirement(newRecipe); } sb.Append($"{recipe.name}, "); i++; if (i > 5) { sb.Append("</color>"); i = 0; sb.AppendLine(); sb.Append("<color=lime>"); } } } PandaLogger.Log(ChatColor.lime, sb.ToString()); PandaLogger.Log(ChatColor.lime, "---------------------------------------------------------"); }
public static void ProcessEntityException(DbEntityValidationException e) { foreach (var eve in e.EntityValidationErrors) { PandaLogger.Log(ChatColor.red, "Entity of type \"{0}\" in state \"{1}\" has the following validation errors:", eve.Entry.Entity.GetType().Name, eve.Entry.State); foreach (var ve in eve.ValidationErrors) { PandaLogger.Log(ChatColor.red, "- Property: \"{0}\", Error: \"{1}\"", ve.PropertyName, ve.ErrorMessage); } } }
public bool PositionIsValid() { if (Position != null && World.TryGetTypeAt(Position, out var objType)) { #if Debug PandaLogger.Log(ChatColor.lime, $"PositionIsValid {ItemTypes.IndexLookup.GetName(objType)}. POS {Position}"); #endif return(objType == MachineSettings.ItemIndex); } #if Debug PandaLogger.Log(ChatColor.lime, $"PositionIsValid Trt Get Failed {Position == null}."); #endif return(Position != null); }
public static void OnPlayerConnectedEarly(Players.Player p) { if (p.IsConnected && !Configuration.OfflineColonies) { var jf = JobTracker.GetOrCreateJobFinder(p) as JobTracker.JobFinder; var file = $"{GameLoader.GAMEDATA_FOLDER}/savegames/{ServerManager.WorldName}/players/NPCArchive/{p.ID.steamID.ToString()}.json"; if (File.Exists(file) && JSON.Deserialize(file, out var followersNode, false)) { PandaLogger.Log(ChatColor.cyan, $"Player {p.ID.steamID} is reconnected. Restoring Colony."); foreach (var node in followersNode.LoopArray()) { try { node.SetAs("id", GetAIID()); var npc = new NPCBase(p, node); ModLoader.TriggerCallbacks(ModLoader.EModCallbackType.OnNPCLoaded, npc, node); foreach (var job in jf.openJobs) { if (node.TryGetAs("JobPoS", out JSONNode pos) && job.KeyLocation == (Vector3Int)pos) { if (job.IsValid && job.NeedsNPC) { npc.TakeJob(job); job.NPC = npc; JobTracker.Remove(p, job.KeyLocation); } break; } } } catch (Exception ex) { PandaLogger.LogError(ex); } } JSON.Serialize(file, new JSONNode(NodeType.Array)); jf.Update(); } } }
public void AfterSelectedWorld() { StringBuilder sb = new StringBuilder(); PandaLogger.Log(ChatColor.lime, "-------------------Generate Type Loaded----------------------"); var i = 0; List <ICSGenerateType> json = new List <ICSGenerateType>(); foreach (var item in LoadedAssembalies) { if (Activator.CreateInstance(item) is ICSGenerateType generateType && !string.IsNullOrEmpty(generateType.typeName)) { json.Add(generateType); sb.Append($"{generateType.typeName}, "); i++; if (i > 5) { sb.Append("</color>"); i = 0; sb.AppendLine(); sb.Append("<color=lime>"); } } } if (json.Count != 0) { var strValue = JsonConvert.SerializeObject(json, Formatting.None, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore }); PandaLogger.LogToFile(strValue); ItemTypesServer.BlockRotator.Patches.AddPatch(new ItemTypesServer.BlockRotator.BlockGeneratePatch(GameLoader.MOD_FOLDER, -99999, JSON.DeserializeString(strValue))); } PandaLogger.Log(ChatColor.lime, sb.ToString()); PandaLogger.Log(ChatColor.lime, "---------------------------------------------------------"); }
public void OnAddResearchables() { StringBuilder sb = new StringBuilder(); PandaLogger.Log(ChatColor.lime, "-------------------Research Loaded----------------------"); var i = 0; foreach (var s in LoadedAssembalies) { if (Activator.CreateInstance(s) is IPandaResearch pandaResearch && !string.IsNullOrEmpty(pandaResearch.name)) { var research = new PandaResearchable(pandaResearch, 1); research.ResearchComplete += pandaResearch.ResearchComplete; if (pandaResearch.NumberOfLevels > 1) { for (var l = 2; l <= pandaResearch.NumberOfLevels; l++) { research = new PandaResearchable(pandaResearch, l); research.ResearchComplete += pandaResearch.ResearchComplete; } } sb.Append(pandaResearch.name + ", "); pandaResearch.OnRegister(); i++; if (i > 5) { sb.Append("</color>"); i = 0; sb.AppendLine(); sb.Append("<color=lime>"); } } } PandaLogger.Log(ChatColor.lime, sb.ToString()); PandaLogger.Log(ChatColor.lime, "---------------------------------------------------------"); }
public static void Register() { var researchDic = new Dictionary <ushort, int>(); PandaLogger.Log("Registering Panda Research."); AddMaxSettlers(researchDic); AddMinSettlers(researchDic); AddTimeBetween(researchDic); AddSettlerChance(researchDic); AddSkilledLaborer(researchDic); AddNumberSkilledLaborer(researchDic); AddReducedWaste(researchDic); AddBanner(researchDic); AddArmorSmithing(researchDic); AddColonistHealth(researchDic); AddSwordSmithing(researchDic); AddKnightResearch(researchDic); AddImprovedSlings(researchDic); AddImprovedBows(researchDic); AddImprovedCrossbows(researchDic); AddImprovedMatchlockgun(researchDic); AddMachines(researchDic); AddImprovedDuarability(researchDic); AddImprovedFuelCapacity(researchDic); AddIncreasedCapacity(researchDic); AddApocthResearch(researchDic); AddAdvanceApocthResearch(researchDic); AddManaResearch(researchDic); AddElementiumResearch(researchDic); AddTeleporters(researchDic); AddBuildersWandResearch(researchDic); AddBetterBuildersWandResearch(researchDic); PandaLogger.Log("Panda Research Registering Complete!"); }
private static void AfterWorldLoad() { Instance = new PandaMonsterSpawner(); MonsterTracker.MonsterSpawner = Instance; PandaLogger.Log("PandaMonsterSpawner Initialized!"); }
public static bool EvaluateSettlers(Players.Player p) { var update = false; if (p.IsConnected) { var colony = Colony.Get(p); var state = PlayerState.GetPlayerState(p); if (state.NextGenTime == 0) { state.NextGenTime = Time.SecondsSinceStartDouble + Random.Next(8, 16 - Pipliz.Math.RoundToInt(p.GetTempValues(true) .GetOrDefault(PandaResearch.GetResearchKey(PandaResearch.TimeBetween), 0f))) * TimeCycle .SecondsPerHour; } if (Time.SecondsSinceStartDouble > state.NextGenTime && colony.FollowerCount >= MAX_BUYABLE) { var chance = p.GetTempValues(true) .GetOrDefault(PandaResearch.GetResearchKey(PandaResearch.SettlerChance), 0f) + state.Difficulty.AdditionalChance; chance += SettlerEvaluation.SpawnChance(p, colony, state); var rand = Random.NextFloat(); if (chance > rand) { var addCount = Math.Floor(state.MaxPerSpawn * chance); // if we lost alot of colonists add extra to help build back up. if (colony.FollowerCount < state.HighestColonistCount) { var diff = state.HighestColonistCount - colony.FollowerCount; addCount += Math.Floor(diff * .25); } try { var skillChance = p.GetTempValues(true) .GetOrDefault(PandaResearch.GetResearchKey(PandaResearch.SkilledLaborer), 0f); var numbSkilled = 0; rand = Random.NextFloat(); try { if (skillChance > rand) { numbSkilled = state.Rand.Next(1, 2 + Pipliz.Math.RoundToInt(p.GetTempValues(true) .GetOrDefault(PandaResearch.GetResearchKey(PandaResearch.NumberSkilledLaborer), 0f))); } } catch (Exception ex) { PandaLogger.Log("NumberSkilledLaborer"); PandaLogger.LogError(ex); } if (addCount > 0) { if (addCount > 30) { addCount = 30; } var reason = string.Format(SettlerReasoning.GetSettleReason(), addCount); if (numbSkilled > 0) { if (numbSkilled == 1) { reason += string.Format(" {0} of them is skilled!", numbSkilled); } else { reason += string.Format(" {0} of them are skilled!", numbSkilled); } } PandaChat.Send(p, reason, ChatColor.magenta); var playerPos = new Vector3Int(p.Position); for (var i = 0; i < addCount; i++) { var newGuy = new NPCBase(NPCType.GetByKeyNameOrDefault("pipliz.laborer"), BannerTracker.GetClosest(p, playerPos).KeyLocation.Vector, colony); SettlerInventory.GetSettlerInventory(newGuy); newGuy.GetTempValues().Set(ISSETTLER, true); if (i <= numbSkilled) { var npcTemp = newGuy.GetTempValues(true); npcTemp.Set(GameLoader.ALL_SKILLS, state.Rand.Next(1, 10) * 0.002f); } update = true; ModLoader.TriggerCallbacks(ModLoader.EModCallbackType.OnNPCRecruited, newGuy); } } } catch (Exception ex) { PandaLogger.Log("SkilledLaborer"); PandaLogger.LogError(ex); } if (colony.FollowerCount > state.HighestColonistCount) { state.HighestColonistCount = colony.FollowerCount; } } state.NextGenTime = Time.SecondsSinceStartDouble + Random.Next(8, 16 - Pipliz.Math.RoundToInt(p.GetTempValues(true) .GetOrDefault(PandaResearch.GetResearchKey(PandaResearch.TimeBetween), 0f))) * TimeCycle .SecondsPerHour; colony.SendUpdate(); } } return(update); }
public static void OnUpdate() { if (!World.Initialized || AIManager.IsBusy()) { return; } var secondsSinceStartDouble = Time.SecondsSinceStartDouble; if (_nextUpdateTime < secondsSinceStartDouble) { IMonster m = null; foreach (var monster in GetAllMonsters()) { if (m == null || Vector3.Distance(monster.Value.Position, m.Position) > 15 && Random.NextBool()) { m = monster.Value; ServerManager.SendAudio(monster.Value.Position, GameLoader.NAMESPACE + ".ZombieAudio"); } } _nextUpdateTime = secondsSinceStartDouble + 5; } IPandaBoss bossType = null; if (World.Initialized && !AIManager.IsBusy()) { if (!BossActive && _nextBossUpdateTime <= secondsSinceStartDouble) { BossActive = true; bossType = GetMonsterType(); if (Players.CountConnected != 0) { PandaLogger.Log(ChatColor.yellow, $"Boss Active! Boss is: {bossType.Name}"); } } if (BossActive) { var turnOffBoss = true; var worldSettings = ServerManager.WorldSettings; Dictionary <PlayerState, List <Banner> > banners = new Dictionary <PlayerState, List <Banner> >(); var spawnBanners = new List <Banner>(); for (var i = 0; i < BannerTracker.GetCount(); i++) { if (BannerTracker.TryGetAtIndex(i, out var newBanner)) { var bps = PlayerState.GetPlayerState(newBanner.Owner); if (!banners.ContainsKey(bps)) { banners.Add(bps, new List <Banner>()); } banners[bps].Add(newBanner); } } foreach (var bkvp in banners) { if (bkvp.Value.Count > 1) { var next = Pipliz.Random.Next(bkvp.Value.Count); spawnBanners.Add(bkvp.Value[next]); } else if (bkvp.Value.Count == 1) { spawnBanners.Add(bkvp.Value[0]); } } foreach (var bannerGoal in spawnBanners) { var ps = PlayerState.GetPlayerState(bannerGoal.Owner); var colony = Colony.Get(ps.Player); if (ps.BossesEnabled && ps.Player.IsConnected && colony.FollowerCount > Configuration.GetorDefault("MinColonistsCountForBosses", 15)) { if (bossType != null && !_spawnedBosses.ContainsKey(ps)) { Vector3Int positionFinal; switch (MonsterSpawner.TryGetSpawnLocation(bannerGoal, 500f, out positionFinal)) { case MonsterSpawner.ESpawnResult.Success: if (AIManager.ZombiePathFinder.TryFindPath(positionFinal, bannerGoal.KeyLocation, out var path, 2000000000) == EPathFindingResult.Success) { var pandaboss = bossType.GetNewBoss(path, ps.Player); _spawnedBosses.Add(ps, pandaboss); BossSpawned?.Invoke(MonsterTracker.MonsterSpawner, new BossSpawnedEvent(ps, pandaboss)); ModLoader.TriggerCallbacks <IMonster>(ModLoader.EModCallbackType.OnMonsterSpawned, pandaboss); MonsterTracker.Add(pandaboss); colony.OnZombieSpawn(true); ps.FaiedBossSpawns = 0; PandaChat.Send(ps.Player, $"[{pandaboss.Name}] {pandaboss.AnnouncementText}", ChatColor.red); if (!string.IsNullOrEmpty(pandaboss.AnnouncementAudio)) { ServerManager.SendAudio(ps.Player.Position, pandaboss.AnnouncementAudio); } } break; case MonsterSpawner.ESpawnResult.NotLoaded: case MonsterSpawner.ESpawnResult.Impossible: colony.OnZombieSpawn(true); break; case MonsterSpawner.ESpawnResult.Fail: CantSpawnBoss(ps, colony); break; } if (_spawnedBosses.ContainsKey(ps) && _spawnedBosses[ps].IsValid && _spawnedBosses[ps].CurrentHealth > 0) { if (ps.Player.GetTempValues(true).GetOrDefault("BossIndicator", 0) < Time.SecondsSinceStartInt) { Indicator.SendIconIndicatorNear(new Vector3Int(_spawnedBosses[ps].Position), _spawnedBosses[ps].ID, new IndicatorState(1, GameLoader.Poisoned_Icon, false, false)); ps.Player.GetTempValues(true) .Set("BossIndicator", Time.SecondsSinceStartInt + 1); } turnOffBoss = false; } } } if (turnOffBoss) { if (Players.CountConnected != 0 && _spawnedBosses.Count != 0) { PandaLogger.Log(ChatColor.yellow, $"All bosses cleared!"); var boss = _spawnedBosses.FirstOrDefault().Value; PandaChat.SendToAll($"[{boss.Name}] {boss.DeathText}", ChatColor.red); } BossActive = false; _spawnedBosses.Clear(); GetNextBossSpawnTime(); } } } } }
public void AfterWorldLoad() { StringBuilder sb = new StringBuilder(); PandaLogger.Log(ChatColor.lime, "-------------------Armor Loaded----------------------"); var i = 0; List <IArmor> armors = new List <IArmor>(); foreach (var item in LoadedAssembalies) { if (Activator.CreateInstance(item) is IArmor armor && !string.IsNullOrEmpty(armor.name)) { armors.Add(armor); } } var settings = GameLoader.GetJSONSettingPaths(GameLoader.NAMESPACE + ".CSItems"); foreach (var modInfo in settings) { foreach (var path in modInfo.Value) { try { var jsonFile = JSON.Deserialize(modInfo.Key + "/" + path); if (jsonFile.NodeType == NodeType.Array && jsonFile.ChildCount > 0) { foreach (var item in jsonFile.LoopArray()) { if (item.TryGetAs("Durability", out int durability)) { armors.Add(item.JsonDeerialize <MagicArmor>()); } } } } catch (Exception ex) { PandaLogger.LogError(ex); } } } foreach (var armor in armors) { if (ItemTypes.IndexLookup.TryGetIndex(armor.name, out var index)) { ArmorFactory.ArmorLookup[index] = armor; sb.Append($"{armor.name}, "); i++; if (i > 5) { sb.Append("</color>"); i = 0; sb.AppendLine(); sb.Append("<color=lime>"); } } } PandaLogger.Log(ChatColor.lime, sb.ToString()); PandaLogger.Log(ChatColor.lime, "---------------------------------------------------------"); }
public static void EvaluateBanners() { if (!GameLoader.WorldLoaded) { return; } _bannerCounts.Clear(); var banners = BannerTracker.GetCount(); if (banners > 0) { for (var i = 0; i < banners; i++) { if (BannerTracker.TryGetAtIndex(i, out var banner)) { if (!_bannerCounts.ContainsKey(banner.Owner)) { _bannerCounts.Add(banner.Owner, 1); } else { _bannerCounts[banner.Owner]++; } } } } foreach (var p in _bannerCounts) { var ps = PlayerState.GetPlayerState(p.Key); if (ps == null) { continue; } var numberOfBanners = p.Key.GetTempValues(true) .GetOrDefault(PandaResearch.GetLevelKey(PandaResearch.Settlement), 0) + 1; var inv = Inventory.GetInventory(p.Key); var sockBanner = Stockpile.GetStockPile(p.Key).AmountContained(BuiltinBlocks.Banner); var inventoryBanners = 0; if (inv != null) { foreach (var item in inv.Items) { if (item.Type == BuiltinBlocks.Banner) { inventoryBanners = item.Amount; } } } var totalBanners = p.Value + sockBanner + inventoryBanners; #if Debug PandaLogger.Log($"Number of research banners: {numberOfBanners}"); PandaLogger.Log($"Number of banners: {p.Value}"); PandaLogger.Log($"Number of stockpile banners: {sockBanner}"); PandaLogger.Log($"Number of Inventory banners: {inventoryBanners}"); PandaLogger.Log($"Total banners: {totalBanners}"); PandaLogger.Log($"Add Banner: {totalBanners < numberOfBanners}"); #endif if (totalBanners < numberOfBanners) { if (!Inventory.GetInventory(p.Key).TryAdd(BuiltinBlocks.Banner)) { Stockpile.GetStockPile(p.Key).Add(BuiltinBlocks.Banner); } } } }
public void AfterWorldLoad() { PandaLogger.Log(ChatColor.lime, "-------------------Items Loaded----------------------"); PandaLogger.Log(ChatColor.lime, _sb.ToString()); PandaLogger.Log(ChatColor.lime, "------------------------------------------------------"); }
public void AddItemTypes(Dictionary <string, ItemTypesServer.ItemTypeRaw> itemTypes) { var i = 0; Dictionary <string, ICSType> loadedItems = new Dictionary <string, ICSType>(); foreach (var item in LoadedAssembalies) { try { if (Activator.CreateInstance(item) is ICSType itemType && !string.IsNullOrEmpty(itemType.name)) { loadedItems[itemType.name] = itemType; var permutations = ConnectedBlockCalculator.GetPermutations(itemType); foreach (var permutation in permutations) { loadedItems[permutation.name] = permutation; } } } catch (Exception ex) { PandaLogger.LogError(ex); } } var settings = GameLoader.GetJSONSettingPaths(GameLoader.NAMESPACE + ".CSItems"); foreach (var modInfo in settings) { foreach (var path in modInfo.Value) { try { var jsonFile = JSON.Deserialize(modInfo.Key + "/" + path); if (jsonFile.NodeType == NodeType.Object && jsonFile.ChildCount > 0) { foreach (var item in jsonFile.LoopObject()) { foreach (var property in _fixRelativePaths) { if (item.Value.TryGetAs(property, out string propertyPath) && propertyPath.StartsWith("./")) { item.Value[property] = new JSONNode(modInfo.Key + "/" + propertyPath.Substring(2)); } } if (item.Value.TryGetAs("Durability", out int durability)) { var ma = item.Value.JsonDeerialize <MagicArmor>(); loadedItems[ma.name] = ma; } else if (item.Value.TryGetAs("WepDurability", out bool wepDurability)) { var mw = item.Value.JsonDeerialize <MagicWeapon>(); loadedItems[mw.name] = mw; } else if (item.Value.TryGetAs("IsMagical", out bool isMagic)) { var mi = item.Value.JsonDeerialize <PlayerMagicItem>(); loadedItems[mi.name] = mi; } else { var newItem = item.Value.JsonDeerialize <CSType>(); loadedItems[newItem.name] = newItem; var permutations = ConnectedBlockCalculator.GetPermutations(newItem); foreach (var permutation in permutations) { loadedItems[permutation.name] = permutation; } } } } } catch (Exception ex) { PandaLogger.LogError(ex); } } } foreach (var itemType in loadedItems.Values) { ConnectedBlockSystem.AddConnectedBlock(itemType); var rawItem = new ItemTypesServer.ItemTypeRaw(itemType.name, itemType.JsonSerialize()); if (itemTypes.ContainsKey(itemType.name)) { PandaLogger.Log(ChatColor.yellow, "Item {0} already loaded...Overriding item.", itemType.name); itemTypes[itemType.name] = rawItem; } else { itemTypes.Add(itemType.name, rawItem); } if (itemType.StaticItemSettings != null && !string.IsNullOrWhiteSpace(itemType.StaticItemSettings.Name)) { StaticItems.List.Add(itemType.StaticItemSettings); } if (itemType is IPlayerMagicItem pmi) { MagicItemsCache.PlayerMagicItems[pmi.name] = pmi; } if (itemType.OpensMenuSettings != null && !string.IsNullOrEmpty(itemType.OpensMenuSettings.ItemName)) { Help.UIManager.OpenMenuItems.Add(itemType.OpensMenuSettings); } _sb.Append($"{itemType.name}, "); i++; if (i > 5) { _sb.Append("</color>"); i = 0; _sb.AppendLine(); _sb.Append("<color=lime>"); } } }
public static void SaveOffline(Colony colony) { if (colony.OwnerIsOnline()) { return; } try { var folder = $"{GameLoader.GAMEDATA_FOLDER}/savegames/{ServerManager.WorldName}/NPCArchive/"; if (!Directory.Exists(folder)) { Directory.CreateDirectory(folder); } var file = $"{folder}{colony.ColonyID}.json"; if (!Configuration.OfflineColonies) { if (!JSON.Deserialize(file, out var followers, false)) { followers = new JSONNode(NodeType.Array); } followers.ClearChildren(); PandaLogger.Log(ChatColor.cyan, $"All players from {colony.ColonyID} have disconnected. Clearing colony until reconnect."); var copyOfFollowers = new List <NPCBase>(); foreach (var follower in colony.Followers) { JSONNode jobloc = null; if (follower.IsValid) { var job = follower.Job; if (job != null && job.GetJobLocation() != Vector3Int.invalidPos) { jobloc = (JSONNode)job.GetJobLocation(); job.SetNPC(null); follower.ClearJob(); } } if (follower.TryGetJSON(out var node)) { if (jobloc != null) { node.SetAs("JobPoS", jobloc); } ModLoader.TriggerCallbacks(ModLoader.EModCallbackType.OnNPCSaved, follower, node); followers.AddToArray(node); copyOfFollowers.Add(follower); } } JSON.Serialize(file, followers); foreach (var deadMan in copyOfFollowers) { deadMan.OnDeath(); } colony.ForEachOwner(o => MonsterTracker.KillAllZombies(o)); } } catch (Exception ex) { PandaLogger.LogError(ex); } }
public static void RegisterMachineType(string machineType, MachineSettings callback) { PandaLogger.Log(machineType + " Registered as a Machine Type!"); _machineCallbacks[machineType] = callback; }
public static bool EvaluateSettlers(ColonyState state) { var update = false; if (state.ColonyRef.OwnerIsOnline()) { if (state.NextGenTime == 0) { state.NextGenTime = Time.SecondsSinceStartDouble + Random.Next(8, 16) * IN_GAME_HOUR_IN_SECONDS; } if (Time.SecondsSinceStartDouble > state.NextGenTime && state.ColonyRef.FollowerCount >= MAX_BUYABLE) { var chance = state.ColonyRef.TemporaryData.GetAsOrDefault(GameLoader.NAMESPACE + ".SettlerChance", 0f) + state.Difficulty.AdditionalChance; chance += SettlerEvaluation.SpawnChance(state); var rand = Random.NextFloat(); if (chance > rand) { var addCount = Math.Floor(state.MaxPerSpawn * chance); // if we lost alot of colonists add extra to help build back up. if (state.ColonyRef.FollowerCount < state.HighestColonistCount) { var diff = state.HighestColonistCount - state.ColonyRef.FollowerCount; addCount += Math.Floor(diff * .25); } try { var skillChance = state.ColonyRef.TemporaryData.GetAsOrDefault(GameLoader.NAMESPACE + ".SkilledLaborer", 0f); var numbSkilled = 0; rand = Random.NextFloat(); try { if (skillChance > rand) { numbSkilled = Pipliz.Random.Next(1, 2 + Pipliz.Math.RoundToInt(state.ColonyRef.TemporaryData.GetAsOrDefault(GameLoader.NAMESPACE + ".NumberSkilledLaborer", 0f))); } } catch (Exception ex) { PandaLogger.Log("NumberSkilledLaborer"); PandaLogger.LogError(ex); } if (addCount > 0) { if (addCount > 30) { addCount = 30; } if (!state.NotifySettlers) { AddNewSettlers(addCount, numbSkilled, state); } else { foreach (var p in state.ColonyRef.Owners) { if (p.IsConnected()) { NetworkMenu menu = new NetworkMenu(); menu.LocalStorage.SetAs("header", addCount + _localizationHelper.LocalizeOrDefault("NewSettlers", p)); menu.Width = 600; menu.Height = 300; menu.Items.Add(new ButtonCallback(GameLoader.NAMESPACE + ".NewSettlers.Accept." + addCount + "." + numbSkilled, new LabelData(_localizationHelper.GetLocalizationKey("Accept"), UnityEngine.Color.black, UnityEngine.TextAnchor.MiddleCenter))); menu.Items.Add(new ButtonCallback(GameLoader.NAMESPACE + ".NewSettlers.Decline", new LabelData(_localizationHelper.GetLocalizationKey("Decline"), UnityEngine.Color.black, UnityEngine.TextAnchor.MiddleCenter))); NetworkMenuManager.SendServerPopup(p, menu); } } } } } catch (Exception ex) { PandaLogger.Log("SkilledLaborer"); PandaLogger.LogError(ex); } if (state.ColonyRef.FollowerCount > state.HighestColonistCount) { state.HighestColonistCount = state.ColonyRef.FollowerCount; } } state.NextGenTime = Time.SecondsSinceStartDouble + Random.Next(8, 16) * IN_GAME_HOUR_IN_SECONDS; state.ColonyRef.SendCommonData(); } } return(update); }
//Ref menu is added for change LocalStorage -> avoid client error public static bool LoadItem(JSONNode item, ref NetworkMenu menu, Players.Player player, out List <IItem> menuItem) { string itemType = item.GetAs <string>("type").Trim().ToLower(); bool found = false; menuItem = null; switch (itemType) { case "label": { menuItem = new List <IItem>() { new Label(GetLabelData(item)).ApplyPosition(item) }; found = true; } break; case "space": { item.TryGetAsOrDefault <int>("height", out int height, 10); menuItem = new List <IItem>() { new EmptySpace(height).ApplyPosition(item) }; found = true; } break; case "line": { UnityEngine.Color color = UnityEngine.Color.black; if (item.HasChild("color")) { color = GetColor(item.GetAs <string>("color")); } item.TryGetAsOrDefault <int>("height", out int height, 4); item.TryGetAsOrDefault <int>("width", out int width, -1); menuItem = new List <IItem>() { new Line(color, height, width).ApplyPosition(item) }; found = true; } break; case "icon": { item.TryGetAsOrDefault <string>("name", out string icon, "missingerror"); menuItem = new List <IItem>() { new ItemIcon(icon).ApplyPosition(item) }; found = true; } break; case "jobrecipies": { if (item.TryGetAs("job", out string job)) { List <Recipes.Recipe> recipes = new List <Recipes.Recipe>(); menuItem = new List <IItem>(); if (ServerManager.RecipeStorage.RecipesPerLimitType.TryGetValue(job, out var recipesDefault)) { recipes.AddRange(recipesDefault); } foreach (var recipe in recipes.OrderBy(r => r.Name)) { menuItem.Add(RecipeLines(menu, player, recipe, item)); } found = true; } } break; case "item": { if (!item.HasChild("name")) { PandaLogger.Log("Item: Not name defined"); return(found); } item.TryGetAs <string>("name", out string name); if (!ItemTypes.IndexLookup.TryGetIndex(name, out ushort index)) { PandaLogger.Log("Item: Not item found with name: " + name); return(found); } if (!Localization.TryGetSentence(player.LastKnownLocale, _localizationHelper.GetLocalizationKey("ItemDetails." + name), out var extendedDetail)) { extendedDetail = ""; } else { extendedDetail = Environment.NewLine + extendedDetail; } if (Localization.TryGetType(player.LastKnownLocale, index, out string localeName) && Localization.TryGetTypeUse(player.LastKnownLocale, index, out var description)) { menuItem = new List <IItem>() { new HorizontalSplit(new ItemIcon(index), new Label(new LabelData(localeName + Environment.NewLine + description + extendedDetail, UnityEngine.Color.black)), 30, .3f).ApplyPosition(item) }; found = true; } } break; case "itemrecipe": { if (!item.HasChild("name")) { PandaLogger.Log("ItemRecipe: Not name defined"); return(found); } item.TryGetAs <string>("name", out string name); if (!ItemTypes.IndexLookup.TryGetIndex(name, out ushort index)) { PandaLogger.Log("ItemRecipe: Not item found with name: " + name); return(found); } if (!ItemRecipe.TryGetValue(index, out var recipe)) { PandaLogger.Log("ItemRecipe: Not recipe found for: " + name); return(found); } menuItem = new List <IItem>(); if (Localization.TryGetType(player.LastKnownLocale, index, out string localeName)) { menuItem.Add(new Label(localeName + ":").ApplyPosition(item)); } else { menuItem.Add(new Label(name + ":").ApplyPosition(item)); } menuItem.Add(RecipeLines(menu, player, recipe, item)); found = true; } break; case "dropdown": { string id; if (item.HasChild("id")) { id = item.GetAs <string>("id"); } else { id = "dropdown"; PandaLogger.Log("Dropdown without ID defined, default: dropdown"); } List <string> options = new List <string>(); if (item.HasChild("options")) { JSONNode optionsj = item.GetAs <JSONNode>("options"); foreach (var option in optionsj.LoopArray()) { options.Add(option.GetAs <string>()); } } else { options.Add("No options available"); PandaLogger.Log(string.Format("dropdown {0} without options", id)); } item.TryGetAsOrDefault <int>("height", out int height, 30); item.TryGetAsOrDefault <int>("marginHorizontal", out int marginHorizontal, 4); item.TryGetAsOrDefault <int>("marginVertical", out int marginVertical, 2); // if label dropdown else dropdownNOLABEL if (item.TryGetChild("label", out JSONNode labelj)) { LabelData label = GetLabelData(labelj); menuItem = new List <IItem>() { new DropDown(label.text, id, options).ApplyPosition(item) }; } else { menuItem = new List <IItem>() { new DropDownNoLabel(id, options, height).ApplyPosition(item) }; } menu.LocalStorage.SetAs(id, 0); found = true; } break; case "toggle": { string id; if (item.HasChild("id")) { id = item.GetAs <string>("id"); } else { id = "toggle"; PandaLogger.Log("Toggle without ID defined, default: toggle"); } item.TryGetAsOrDefault <int>("height", out int height, 25); item.TryGetAsOrDefault <int>("toggleSize", out int toggleSize, 20); // if label toggle else togglenolabel if (item.TryGetChild("label", out JSONNode labelj)) { LabelData label = GetLabelData(labelj); menuItem = new List <IItem>() { new Toggle(label, id, height, toggleSize).ApplyPosition(item) }; } else { menuItem = new List <IItem>() { new ToggleNoLabel(id, toggleSize).ApplyPosition(item) }; } found = true; menu.LocalStorage.SetAs(id, false); } break; case "button": { string id; if (item.HasChild("id")) { id = item.GetAs <string>("id"); } else { id = "button"; PandaLogger.Log("Button without ID defined, default: button"); } item.TryGetAsOrDefault <int>("width", out int width, -1); item.TryGetAsOrDefault <int>("height", out int height, 25); if (item.TryGetChild("label", out JSONNode labelj)) { LabelData label = GetLabelData(labelj); menuItem = new List <IItem>() { new ButtonCallback(id, label, width, height).ApplyPosition(item) }; } else { PandaLogger.Log(string.Format("Button {0} without label", id)); menuItem = new List <IItem>() { new ButtonCallback(id, new LabelData("Key label not defined"), width, height).ApplyPosition(item) }; } found = true; } break; case "link": { string url; if (item.HasChild("url")) { url = GameLoader.NAMESPACE + ".link_" + item.GetAs <string>("url"); } else { PandaLogger.Log("Link without URL defined"); return(found); } item.TryGetAsOrDefault <int>("width", out int width, -1); item.TryGetAsOrDefault <int>("height", out int height, 25); if (item.TryGetChild("label", out JSONNode labelj)) { LabelData label = GetLabelData(labelj); menuItem = new List <IItem>() { new ButtonCallback(url, label, width, height).ApplyPosition(item) }; } else { PandaLogger.Log(string.Format("Link {0} without label", url)); menuItem = new List <IItem>() { new ButtonCallback(url, new LabelData("Key label not defined"), width, height).ApplyPosition(item) }; } found = true; } break; case "table": { item.TryGetAsOrDefault <int>("row_height", out int height, 30); if (item.TryGetAs("rows", out JSONNode rows) && rows.ChildCount != 0) { menuItem = new List <IItem>(); found = true; foreach (JSONNode row in rows.LoopArray()) { List <ValueTuple <IItem, int> > items = new List <ValueTuple <IItem, int> >(); var width = menu.Width / row.ChildCount; foreach (JSONNode col in row.LoopArray()) { if (LoadItem(col, ref menu, player, out var newMenuItems)) { foreach (var newItem in newMenuItems) { if (col.TryGetAs("col_width", out int setWidth)) { items.Add(ValueTuple.Create(newItem, setWidth)); } else { items.Add(ValueTuple.Create(newItem, width)); } } } } menuItem.Add(new HorizontalRow(items, height).ApplyPosition(item)); } } } break; default: { PandaLogger.Log(string.Format("It doesn't exist an item of type: {0}", itemType)); } break; } return(found); }