private static void NPCLeaving(NPCBase npc) { if (Random.NextFloat() > .49f) { float cost = PenalizeFood(npc.Colony, 0.05f); PandaChat.Send(npc.Colony, $"A colonist has left your colony taking {cost} food.", ChatColor.red); } else { var numberOfItems = Random.Next(1, 10); for (var i = 0; i < numberOfItems; i++) { var randItem = Random.Next(npc.Colony.Stockpile.ItemCount); var item = npc.Colony.Stockpile.GetByIndex(randItem); if (item.Type != ColonyBuiltIn.ItemTypes.AIR.Id && item.Amount != 0) { var leaveTax = Pipliz.Math.RoundToInt(item.Amount * .10); npc.Colony.Stockpile.TryRemove(item.Type, leaveTax); PandaChat.Send(npc.Colony, $"A leaving colonist has taken {leaveTax} {Models.ItemId.GetItemId(item.Type).Name}", ChatColor.red); } } PandaChat.Send(npc.Colony, $"A colonist has left your colony taking 10% of {numberOfItems} items from your stockpile.", ChatColor.red); } npc.health = 0; npc.OnDeath(); }
private static void AddNewSettlers(double addCount, int numbSkilled, ColonyState state) { 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(state.ColonyRef, reason, ChatColor.magenta); for (var i = 0; i < addCount; i++) { var newGuy = new NPCBase(state.ColonyRef, state.ColonyRef.GetRandomBanner().Position); NPCTracker.Add(newGuy); state.ColonyRef.RegisterNPC(newGuy); SettlerInventory.GetSettlerInventory(newGuy); newGuy.CustomData.SetAs(ISSETTLER, true); if (i <= numbSkilled) { newGuy.CustomData.SetAs(GameLoader.ALL_SKILLS, Random.Next(1, 10) * 0.002f); } ModLoader.Callbacks.OnNPCRecruited.Invoke(newGuy); } }
public static void OnNPCCraftedRecipe(IJob job, Recipe recipe, List <RecipeResult> results) { IncrimentSkill(job.NPC); var inv = SettlerInventory.GetSettlerInventory(job.NPC); inv.IncrimentStat("Number of Crafts"); double weightSum = 0; double roll = Random.Next() + inv.GetSkillModifier(); List <RecipeResult> bonusItems = new List <RecipeResult>(); foreach (var item in results) { weightSum += 1; if (roll > weightSum) { bonusItems.Add(new RecipeResult(item.Type, item.Amount)); } inv.IncrimentStat(ItemTypes.GetType(item.Type).Name, item.Amount); } results.AddRange(bonusItems); }
private static bool EvaluateBeds(ColonyState state) { var update = false; try { if (!TimeCycle.IsDay && Time.SecondsSinceStartDouble > _nextbedTime) { if (state.ColonyRef.OwnerIsOnline()) { // TODO Fix bed count var remainingBeds = ServerManager.BlockEntityTracker.BedTracker.CalculateBedCount(state.ColonyRef) - state.ColonyRef.FollowerCount; var left = 0; if (remainingBeds >= 0) { state.NeedsABed = 0; } else { if (state.NeedsABed == 0) { state.NeedsABed = Time.SecondsSinceStartDouble + LOABOROR_LEAVE_HOURS; PandaChat.Send(state.ColonyRef, SettlerReasoning.GetNeedBed(), ChatColor.grey); } if (state.NeedsABed != 0 && state.NeedsABed < Time.SecondsSinceStartDouble) { foreach (var follower in state.ColonyRef.Followers) { if (follower.UsedBed == null) { left++; NPCLeaving(follower); } } state.NeedsABed = 0; } if (left > 0) { PandaChat.Send(state.ColonyRef, string.Concat(SettlerReasoning.GetNoBed(), string.Format(" {0} colonists have left your colony.", left)), ChatColor.red); update = true; } } state.ColonyRef.SendCommonData(); } _nextbedTime = Time.SecondsSinceStartDouble + Random.Next(5, 8) * IN_GAME_HOUR_IN_SECONDS * 24; } } catch (Exception ex) { PandaLogger.LogError(ex, "EvaluateBeds"); } return(update); }
private static void UpdateMagicItemms(ColonyState state) { try { if (state.MagicUpdateTime < Time.SecondsSinceStartDouble) { var colony = state.ColonyRef; foreach (var follower in colony.Followers) { var inv = ColonistInventory.Get(follower); if (inv.MagicItemUpdateTime < Time.SecondsSinceStartDouble) { foreach (var item in inv.Armor) { if (item.Value.Id != 0 && ArmorFactory.ArmorLookup.TryGetValue(item.Value.Id, out var armor)) { armor.Update(); if (armor.HPTickRegen != 0) { follower.Heal(armor.HPTickRegen); } } } if (WeaponFactory.WeaponLookup.TryGetValue(inv.Weapon.Id, out var wep)) { wep.Update(); if (wep.HPTickRegen != 0) { follower.Heal(wep.HPTickRegen); } } inv.MagicItemUpdateTime = Time.SecondsSinceStartDouble + Random.Next(3, 5); } } state.MagicUpdateTime = Time.SecondsSinceStartDouble + 5; } } catch (Exception ex) { APILogger.LogError(ex); } }
public static void OnMonsterHit(IMonster monster, ModLoader.OnHitData d) { var ps = PlayerState.GetPlayerState(monster.OriginalGoal); var pandaArmor = monster as IPandaArmor; var turret = d.HitSourceObject as IPandaDamage; if (pandaArmor != null && Random.NextFloat() <= pandaArmor.MissChance) { d.ResultDamage = 0; return; } if (pandaArmor != null && turret != null) { var damage = 0f; foreach (var dt in turret.Damage) { var tmpDmg = dt.Key.CalcDamage(pandaArmor.ElementalArmor, dt.Value); if (pandaArmor.AdditionalResistance.TryGetValue(dt.Key, out var flatResist)) { tmpDmg = tmpDmg - tmpDmg * flatResist; } damage += tmpDmg; } d.ResultDamage = damage; } else if (pandaArmor != null) { d.ResultDamage = DamageType.Physical.CalcDamage(pandaArmor.ElementalArmor, d.ResultDamage); if (pandaArmor.AdditionalResistance.TryGetValue(DamageType.Physical, out var flatResist)) { d.ResultDamage = d.ResultDamage - d.ResultDamage * flatResist; } } d.ResultDamage = d.ResultDamage - d.ResultDamage * ps.Difficulty.MonsterDamageReduction; if (Random.NextFloat() > .5f) { ServerManager.SendAudio(monster.Position, GameLoader.NAMESPACE + ".ZombieAudio"); } }
private static bool EvaluateLaborers(Players.Player p) { var update = false; if (TimeCycle.IsDay && Time.SecondsSinceStartDouble > _nextLaborerTime) { if (p.IsConnected) { var unTrack = new List <NPCBase>(); var colony = Colony.Get(p); var state = PlayerState.GetPlayerState(p); var left = 0; for (var i = 0; i < colony.LaborerCount; i++) { var npc = colony.FindLaborer(i); var tmpVals = npc.GetTempValues(); if (!tmpVals.Contains(LEAVETIME_JOB)) { tmpVals.Set(LEAVETIME_JOB, Time.SecondsSinceStartDouble + LOABOROR_LEAVE_HOURS); } else if (tmpVals.Get <double>(LEAVETIME_JOB) < TimeCycle.TotalTime) { left++; NPCLeaving(npc); } } if (left > 0) { PandaChat.Send(p, string.Concat(SettlerReasoning.GetNoJobReason(), string.Format(" {0} colonists have left your colony.", left)), ChatColor.red); } update = unTrack.Count != 0; colony.SendUpdate(); } _nextLaborerTime = Time.SecondsSinceStartDouble + Random.Next(4, 6) * TimeCycle.SecondsPerHour; } return(update); }
private static bool EvaluateLaborers(ColonyState state) { var update = false; if (TimeCycle.IsDay && Time.SecondsSinceStartDouble > _nextLaborerTime) { if (state.ColonyRef.OwnerIsOnline()) { var unTrack = new List <NPCBase>(); var left = 0; for (var i = 0; i < state.ColonyRef.LaborerCount; i++) { var npc = state.ColonyRef.FindLaborer(i); if (!npc.CustomData.TryGetAs(LEAVETIME_JOB, out double leaveTime)) { npc.CustomData.SetAs(LEAVETIME_JOB, Time.SecondsSinceStartDouble + LOABOROR_LEAVE_HOURS); } else if (leaveTime < Time.SecondsSinceStartDouble) { left++; NPCLeaving(npc); } } if (left > 0) { PandaChat.Send(state.ColonyRef, string.Concat(SettlerReasoning.GetNoJobReason(), string.Format(" {0} colonists have left your colony.", left)), ChatColor.red); } update = unTrack.Count != 0; state.ColonyRef.SendCommonData(); } _nextLaborerTime = Time.SecondsSinceStartDouble + Random.Next(4, 6) * IN_GAME_HOUR_IN_SECONDS * 24; } return(update); }
private static IPandaBoss GetMonsterType() { IPandaBoss t = null; lock (_bossList) { var rand = _boss; while (rand == _boss) { rand = Random.Next(0, _bossList.Count); } t = _bossList[rand]; _boss = rand; } return(t); }
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); }
public static void OnUpdate() { if (ServerManager.ColonyTracker != null) { foreach (var colony in ServerManager.ColonyTracker.ColoniesByID.Values) { if (_magicUpdateTime < Time.SecondsSinceStartDouble) { foreach (var follower in colony.Followers) { var inv = SettlerInventory.GetSettlerInventory(follower); if (inv.MagicItemUpdateTime < Time.SecondsSinceStartDouble) { foreach (var item in inv.Armor) { if (item.Value.Id != 0 && ArmorFactory.ArmorLookup.TryGetValue(item.Value.Id, out var armor)) { armor.Update(); if (armor.HPTickRegen != 0) { follower.Heal(armor.HPTickRegen); } } } if (Items.Weapons.WeaponFactory.WeaponLookup.TryGetValue(inv.Weapon.Id, out var wep)) { wep.Update(); if (wep.HPTickRegen != 0) { follower.Heal(wep.HPTickRegen); } } var hasBandages = colony.Stockpile.Contains(TreatedBandage.Item.ItemIndex) || colony.Stockpile.Contains(Bandage.Item.ItemIndex); if (hasBandages && follower.health < follower.Colony.NPCHealthMax && !HealingOverTimeNPC.NPCIsBeingHealed(follower)) { var healing = false; if (follower.Colony.NPCHealthMax - follower.health > TreatedBandage.INITIALHEAL) { colony.Stockpile.TryRemove(TreatedBandage.Item.ItemIndex); healing = true; AudioManager.SendAudio(follower.Position.Vector, GameLoader.NAMESPACE + ".Bandage"); var heal = new HealingOverTimeNPC(follower, TreatedBandage.INITIALHEAL, TreatedBandage.TOTALHOT, 5, TreatedBandage.Item.ItemIndex); } if (!healing) { colony.Stockpile.TryRemove(Bandage.Item.ItemIndex); healing = true; AudioManager.SendAudio(follower.Position.Vector, GameLoader.NAMESPACE + ".Bandage"); var heal = new HealingOverTimeNPC(follower, Bandage.INITIALHEAL, Bandage.TOTALHOT, 5, Bandage.Item.ItemIndex); } } inv.MagicItemUpdateTime += 5000; } } } if (_updateTime < Time.SecondsSinceStartDouble && colony.OwnerIsOnline()) { NPCBase lastNPC = null; foreach (var follower in colony.Followers) { if (TimeCycle.IsDay) { if (lastNPC == null || UnityEngine.Vector3.Distance(lastNPC.Position.Vector, follower.Position.Vector) > 15 && Random.NextBool()) { lastNPC = follower; AudioManager.SendAudio(follower.Position.Vector, GameLoader.NAMESPACE + ".TalkingAudio"); } } } } var cs = ColonyState.GetColonyState(colony); if (cs.SettlersEnabled) { if (EvaluateSettlers(cs) || EvaluateLaborers(cs) || EvaluateBeds(cs)) { colony.SendCommonData(); } } UpdateFoodUse(cs); } } if (_magicUpdateTime < Time.SecondsSinceStartDouble) { _magicUpdateTime = Time.SecondsSinceStartDouble + 1; } if (_updateTime < Time.SecondsSinceStartDouble && TimeCycle.IsDay) { _updateTime = Time.SecondsSinceStartDouble + _UPDATE_TIME; } }
public static void OnUpdate() { Players.PlayerDatabase.ForeachValue(p => { var stockpile = Stockpile.GetStockPile(p); var colony = Colony.Get(p); var hasBandages = stockpile.Contains(TreatedBandage.Item.ItemIndex) || stockpile.Contains(Bandage.Item.ItemIndex); if (hasBandages) { foreach (var follower in colony.Followers) { if (follower.health < NPCBase.MaxHealth && !HealingOverTimeNPC.NPCIsBeingHealed(follower)) { var healing = false; if (NPCBase.MaxHealth - follower.health > TreatedBandage.INITIALHEAL) { stockpile.TryRemove(TreatedBandage.Item.ItemIndex); healing = true; ServerManager.SendAudio(follower.Position.Vector, GameLoader.NAMESPACE + ".Bandage"); var heal = new HealingOverTimeNPC(follower, TreatedBandage.INITIALHEAL, TreatedBandage.TOTALHOT, 5, TreatedBandage.Item.ItemIndex); } if (!healing) { stockpile.TryRemove(Bandage.Item.ItemIndex); healing = true; ServerManager.SendAudio(follower.Position.Vector, GameLoader.NAMESPACE + ".Bandage"); var heal = new HealingOverTimeNPC(follower, Bandage.INITIALHEAL, Bandage.TOTALHOT, 5, Bandage.Item.ItemIndex); } } } } if (_updateTime < Time.SecondsSinceStartDouble && TimeCycle.IsDay && p.IsConnected) { NPCBase lastNPC = null; foreach (var follower in colony.Followers) { if (lastNPC == null || Vector3.Distance(lastNPC.Position.Vector, follower.Position.Vector) > 15 && Random.NextBool()) { lastNPC = follower; ServerManager.SendAudio(follower.Position.Vector, GameLoader.NAMESPACE + ".TalkingAudio"); } } } var ps = PlayerState.GetPlayerState(p); if (ps.SettlersEnabled) { if (EvaluateSettlers(p) || EvaluateLaborers(p) || EvaluateBeds(p)) { colony.SendUpdate(); } } UpdateFoodUse(p); }); if (_updateTime < Time.SecondsSinceStartDouble && TimeCycle.IsDay) { _updateTime = Time.SecondsSinceStartDouble + 10; } }
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 OnMonsterHit(IMonster monster, ModLoader.OnHitData d) { var cs = ColonyState.GetColonyState(monster.OriginalGoal); var pandaArmor = monster as IPandaArmor; var pamdaDamage = d.HitSourceObject as IPandaDamage; var skilled = 0f; if (pandaArmor != null && Random.NextFloat() <= pandaArmor.MissChance) { d.ResultDamage = 0; return; } if (pamdaDamage == null && d.HitSourceType == ModLoader.OnHitData.EHitSourceType.NPC) { var npc = d.HitSourceObject as NPCBase; var inv = ColonistInventory.Get(npc); ColonistManager.IncrimentSkill(npc); skilled = inv.GetSkillModifier(); if (inv.Weapon != null && Items.Weapons.WeaponFactory.WeaponLookup.TryGetValue(inv.Weapon.Id, out var wep)) { pamdaDamage = wep; } } if (pandaArmor != null && pamdaDamage != null) { d.ResultDamage = Items.Weapons.WeaponFactory.CalcDamage(pandaArmor, pamdaDamage); } else if (pandaArmor != null) { d.ResultDamage = DamageType.Physical.CalcDamage(pandaArmor.ElementalArmor, d.ResultDamage); if (pandaArmor.AdditionalResistance.TryGetValue(DamageType.Physical, out var flatResist)) { d.ResultDamage = d.ResultDamage - d.ResultDamage * flatResist; } } double skillRoll = Pipliz.Random.Next() + skilled; if (skillRoll < skilled) { d.ResultDamage += d.ResultDamage; } d.ResultDamage = d.ResultDamage - d.ResultDamage * cs.Difficulty.MonsterDamageReduction; if (d.ResultDamage < 0) { d.ResultDamage = 0; } if (d.HitSourceType == ModLoader.OnHitData.EHitSourceType.NPC) { var npc = d.HitSourceObject as NPCBase; var inv = ColonistInventory.Get(npc); inv.IncrimentStat("Damage Done", d.ResultDamage); if (skillRoll < skilled) { inv.IncrimentStat("Double Damage Hits"); } } if (d.ResultDamage >= monster.CurrentHealth) { monster.OnRagdoll(); var rewardMonster = monster as IPandaZombie; string monsterType = "zombie"; if (rewardMonster != null) { monsterType = rewardMonster.MosterType; } if (monster.OriginalGoal.OwnerIsOnline()) { if (!string.IsNullOrEmpty(monsterType) && LootTables.Lookup.TryGetValue(monsterType, out var lootTable)) { float luck = 0; if (d.HitSourceObject is ILucky luckSrc) { luck = luckSrc.Luck; } else if ((d.HitSourceType == ModLoader.OnHitData.EHitSourceType.PlayerClick || d.HitSourceType == ModLoader.OnHitData.EHitSourceType.PlayerProjectile) && d.HitSourceObject is Players.Player player) { var ps = PlayerState.GetPlayerState(player); foreach (var armor in ps.Armor) { if (Items.Armor.ArmorFactory.ArmorLookup.TryGetValue(armor.Value.Id, out var a)) { luck += a.Luck; } } if (Items.Weapons.WeaponFactory.WeaponLookup.TryGetValue(ps.Weapon.Id, out var w)) { luck += w.Luck; } } else if (d.HitSourceType == ModLoader.OnHitData.EHitSourceType.NPC && d.HitSourceObject is NPCBase nPC) { var inv = ColonistInventory.Get(nPC); foreach (var armor in inv.Armor) { if (Items.Armor.ArmorFactory.ArmorLookup.TryGetValue(armor.Value.Id, out var a)) { luck += a.Luck; } } if (Items.Weapons.WeaponFactory.WeaponLookup.TryGetValue(inv.Weapon.Id, out var w)) { luck += w.Luck; } } var roll = lootTable.GetDrops(luck); foreach (var item in roll) { monster.OriginalGoal.Stockpile.Add(item.Key, item.Value); } } } } }
private static void GetNextBossSpawnTime() { _nextBossUpdateTime = Time.SecondsSinceStartInt + Random.Next(MinBossSpawnTimeSeconds, MaxBossSpawnTimeSeconds); }
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(); } } } } }
private static bool EvaluateBeds(Players.Player p) { var update = false; try { if (!TimeCycle.IsDay && Time.SecondsSinceStartDouble > _nextbedTime) { if (p.IsConnected) { var colony = Colony.Get(p); var state = PlayerState.GetPlayerState(p); var remainingBeds = BedBlockTracker.GetCount(p) - colony.FollowerCount; var left = 0; if (remainingBeds >= 0) { state.NeedsABed = 0; } else { if (state.NeedsABed == 0) { state.NeedsABed = Time.SecondsSinceStartDouble + LOABOROR_LEAVE_HOURS; PandaChat.Send(p, SettlerReasoning.GetNeedBed(), ChatColor.grey); } if (state.NeedsABed != 0 && state.NeedsABed < TimeCycle.TotalTime) { foreach (var follower in colony.Followers) { if (follower.GetFieldValue <BedBlock, NPCBase>("bed") == null) { left++; NPCLeaving(follower); } } state.NeedsABed = 0; } if (left > 0) { PandaChat.Send(p, string.Concat(SettlerReasoning.GetNoBed(), string.Format(" {0} colonists have left your colony.", left)), ChatColor.red); update = true; } } colony.SendUpdate(); } _nextbedTime = Time.SecondsSinceStartDouble + Random.Next(5, 8) * TimeCycle.SecondsPerHour; } } catch (Exception ex) { PandaLogger.LogError(ex, "EvaluateBeds"); } return(update); }
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(PandaResearch.GetResearchKey(PandaResearch.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(PandaResearch.GetResearchKey(PandaResearch.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(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(state.ColonyRef, reason, ChatColor.magenta); for (var i = 0; i < addCount; i++) { var newGuy = new NPCBase(state.ColonyRef, state.ColonyRef.GetRandomBanner().Position); NPCTracker.Add(newGuy); state.ColonyRef.RegisterNPC(newGuy); SettlerInventory.GetSettlerInventory(newGuy); newGuy.CustomData.SetAs(ISSETTLER, true); if (i <= numbSkilled) { newGuy.CustomData.SetAs(GameLoader.ALL_SKILLS, Random.Next(1, 10) * 0.002f); } update = true; ModLoader.TriggerCallbacks(ModLoader.EModCallbackType.OnNPCRecruited, newGuy); } } } 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); }