public override void OnResearchComplete(ColonyScienceState manager, EResearchCompletionReason reason) { base.OnResearchComplete(manager, reason); try { foreach (var p in manager.Colony.Owners) { p.GetTempValues(true).Set(TmpValueKey, Value); p.GetTempValues(true).Set(LevelKey, Level); } manager.Colony.TemporaryData.SetAs(TmpValueKey, Value); manager.Colony.TemporaryData.SetAs(LevelKey, Level); if (ResearchComplete != null) { ResearchComplete(this, new ResearchCompleteEventArgs(this, manager)); } } catch (Exception ex) { APILogger.LogError(ex, $"Error OnResearchComplete for {TmpValueKey} Level: {Level}."); } }
public override void OnResearchComplete(ColonyScienceState manager, EResearchCompletionReason reason) { manager.Colony.RecipeData.UnlockRecipe(new RecipeKey("Nach0ChickenCoopJobBlock-pipliz.crafter")); manager.Colony.RecipeData.UnlockRecipe(new RecipeKey("Nach0ChickenFence-pipliz.crafter")); manager.Colony.RecipeData.UnlockRecipe(new RecipeKey("Nach0ChickenFenceCorner-pipliz.crafter")); manager.Colony.RecipeData.UnlockRecipe(new RecipeKey("Nach0ChickenFeed-pipliz.crafter")); manager.Colony.RecipeData.UnlockRecipe(new RecipeKey("Nach0CookedChickenMeat-pipliz.baker")); }
static void DiggerLimitResearch(AbstractResearchable res, ColonyScienceState manager, EResearchCompletionReason reason) { int current = manager.Colony.TemporaryData.GetAsOrDefault("pipliz.diggerlimit", 0); int next = DiggerLimits[res.GetKey()]; manager.Colony.TemporaryData.SetAs("pipliz.diggerlimit", Math.Max(current, next)); ConstructionHelper.SendPacket(manager.Colony); }
public override void OnResearchComplete(ColonyScienceState manager, EResearchCompletionReason reason) { manager.Colony.TemporaryData.SetAs("pipliz.healthmax", 350f); if (reason == EResearchCompletionReason.ProgressCompleted) { for (int i = 0; i < manager.Colony.Owners.Length; i++) { if (manager.Colony.Owners[i].ShouldSendData) { manager.Colony.Owners[i].SendHealthPacket(); } } } }
public override void OnResearchComplete(ColonyScienceState manager, EResearchCompletionReason reason) { manager.Colony.RecipeData.UnlockRecipe(new RecipeKey("Nach0ChickenPie-pipliz.baker")); }
public override void OnResearchComplete(ColonyScienceState manager, EResearchCompletionReason reason) { manager.Colony.TemporaryData.SetAs("pipliz.builderlimit", 25000000); ConstructionHelper.SendPacket(manager.Colony); }
public override void OnResearchComplete(ColonyScienceState manager, EResearchCompletionReason reason) { manager.Colony.TemporaryData.SetAs("pipliz.healthregenmax", 200f); }
public ResearchCompleteEventArgs(PandaResearchable research, ColonyScienceState player) { Research = research; Manager = player; }
public override void OnResearchComplete(ColonyScienceState manager, EResearchCompletionReason reason) { manager.Colony.RecipeData.UnlockRecipe(new RecipeKey("Nach0ButcherBlock-pipliz.crafter")); }
public virtual void OnNPCAtJob(BlockJobInstance blockJobInstance, ref NPCState state) { ScientistJobInstance instance = blockJobInstance as ScientistJobInstance; if (instance == null) { state.JobIsDone = true; return; } Colony owner = instance.Owner; instance.NPC.LookAt(instance.Position.Vector); ColonyScienceState scienceData = owner.ScienceData; state.JobIsDone = true; // if no stored items - check if the stockpile contains the items required for any of the researches var completedCycles = scienceData.CompletedCycles; if (instance.StoredItemCount <= 0) { if (completedCycles.Count == 0) { // done for now state.SetIndicator(new Shared.IndicatorState(Random.NextFloat(8f, 16f), BuiltinBlocks.Indices.erroridle)); return; } int possibles = 0; for (int i = 0; i < completedCycles.Count; i++) { ScienceKey cyclesResearch = completedCycles.GetKeyAtIndex(i); if (cyclesResearch.Researchable.TryGetCyclesCondition(out ScientistCyclesCondition cyclesData) && completedCycles.GetValueAtIndex(i) < cyclesData.CycleCount) { possibles++; if (owner.Stockpile.Contains(cyclesData.ItemsPerCycle)) { instance.ShouldTakeItems = true; state.SetCooldown(0.3); return; // found an in-progress research that we have items for } } } // missing items, find random requirement to use as indicator if (possibles > 0) { int possiblesIdx = Random.Next(0, possibles); for (int i = 0; i < completedCycles.Count; i++) { ScienceKey cyclesResearch = completedCycles.GetKeyAtIndex(i); if (cyclesResearch.Researchable.TryGetCyclesCondition(out ScientistCyclesCondition cyclesData) && completedCycles.GetValueAtIndex(i) < cyclesData.CycleCount) { if (possiblesIdx-- <= 0) { MissingItemHelper(cyclesData.ItemsPerCycle, owner.Stockpile, ref state); return; } } } // should be unreachable } // done for now state.SetIndicator(new Shared.IndicatorState(Random.NextFloat(8f, 16f), BuiltinBlocks.Indices.erroridle)); return; } // have stored items, try to forward an active science if (completedCycles.Count == 0) { instance.StoredItemCount = 0; state.SetCooldown(0.3); return; } var happyData = owner.HappinessData; float cyclesToAdd = happyData.ScienceSpeedMultiplierCalculator.GetSpeedMultiplier(happyData.CachedHappiness, instance.NPC); int doneScienceIndex = -1; const float MINIMUM_CYCLES_TO_ADD = 0.001f; if (cyclesToAdd <= MINIMUM_CYCLES_TO_ADD) { state.SetIndicator(new Shared.IndicatorState(CraftingCooldown, BuiltinBlocks.Indices.missingerror)); Log.WriteWarning($"Cycles below minimum for science job at {instance.Position}!"); return; } for (int i = 0; i < completedCycles.Count && cyclesToAdd >= 0f; i++) { AbstractResearchable research = completedCycles.GetKeyAtIndex(i).Researchable; float progress = completedCycles.GetValueAtIndex(i); if (!research.TryGetCyclesCondition(out ScientistCyclesCondition cyclesCondition) || progress >= cyclesCondition.CycleCount) { continue; } bool atCycleBoundary = Math.Abs(progress - Math.RoundToInt(progress)) < MINIMUM_CYCLES_TO_ADD; float freeCycles = (float)System.Math.Ceiling(progress) - progress; if (!atCycleBoundary) { if (cyclesToAdd <= freeCycles) { OnDoFullCycles(ref state); // cycles <= freecycles, just add all return; } else { OnDoPartialCycles(ref state, Math.Min(freeCycles, cyclesToAdd)); } } if (progress >= cyclesCondition.CycleCount) { // completed on a partial cycle (it wasn't completed a few lines up) continue; } // at boundary and/or will cross a boundary with the cyclesToAdd List <InventoryItem> requirements = cyclesCondition.ItemsPerCycle; if (owner.Stockpile.TryRemove(requirements)) { // got the items, deal with recycling, then just add the full cyclesToAdd int recycled = 0; for (int j = 0; j < requirements.Count; j++) { ushort type = requirements[j].Type; if (type == BuiltinBlocks.Indices.sciencebaglife || type == BuiltinBlocks.Indices.sciencebagbasic || type == BuiltinBlocks.Indices.sciencebagmilitary ) { recycled += requirements[j].Amount; } } for (int j = recycled; j > 0; j--) { if (Random.NextDouble() > RECYCLE_CHANCE) { recycled--; } } if (recycled > 0) { owner.Stockpile.Add(BuiltinBlocks.Indices.linenbag, recycled); } OnDoFullCycles(ref state); return; } continue; // unreachable void OnDoFullCycles(ref NPCState stateCopy) { scienceData.CyclesAddProgress(research.AssignedKey, cyclesToAdd); stateCopy.SetIndicator(new Shared.IndicatorState(CraftingCooldown, NPCIndicatorType.Science, (ushort)research.AssignedKey.Index)); instance.StoredItemCount--; progress += cyclesToAdd; if (progress >= cyclesCondition.CycleCount && research.AreConditionsMet(scienceData)) { SendCompleteMessage(); } } void OnDoPartialCycles(ref NPCState stateCopy, float cyclesToUse) { cyclesToAdd -= cyclesToUse; scienceData.CyclesAddProgress(research.AssignedKey, cyclesToUse); progress += cyclesToUse; if (progress >= cyclesCondition.CycleCount && research.AreConditionsMet(scienceData)) { SendCompleteMessage(); } doneScienceIndex = (int)research.AssignedKey.Index; } void SendCompleteMessage() { Players.Player[] owners = owner.Owners; for (int j = 0; j < owners.Length; j++) { Players.Player player = owners[j]; if (player.ConnectionState == Players.EConnectionState.Connected && player.ActiveColony == owner) { string msg = Localization.GetSentence(player.LastKnownLocale, "chat.onscienceready"); string res = Localization.GetSentence(player.LastKnownLocale, research.GetKey() + ".name"); msg = string.Format(msg, res); Chatting.Chat.Send(player, msg); } } } } if (doneScienceIndex >= 0) { // did some freecoasting state.SetIndicator(new Shared.IndicatorState(CraftingCooldown, NPCIndicatorType.Science, (ushort)doneScienceIndex)); instance.StoredItemCount--; return; } // had stored items, but for some reason couldn't dump them in existing research // reset the job basically instance.StoredItemCount = 0; state.SetCooldown(0.3); return; void MissingItemHelper(IList <InventoryItem> requirements, Stockpile stockpile, ref NPCState stateCopy) { ushort missing = 0; for (int i = 0; i < requirements.Count; i++) { if (!stockpile.Contains(requirements[i])) { missing = requirements[i].Type; break; } } float cooldown = Random.NextFloat(8f, 16f); stateCopy.SetIndicator(new Shared.IndicatorState(cooldown, missing, true, false)); stateCopy.JobIsDone = false; } }
public override void OnResearchComplete(ColonyScienceState manager, EResearchCompletionReason reason) { manager.Colony.RecipeData.UnlockRecipe(new RecipeKey("nach0.recipes.fishersremastered.pipliz.merchant.lure")); }
public override void OnResearchComplete(ColonyScienceState manager, EResearchCompletionReason reason) { manager.Colony.RecipeData.UnlockRecipe(new RecipeKey("nach0.recipes.fishersremastered.pipliz.crafter.rod")); manager.Colony.RecipeData.UnlockRecipe(new RecipeKey("nach0.recipes.fishersremastered.pipliz.baker.cookedfish")); }
public bool IsConditionMet(AbstractResearchable researchable, ColonyScienceState manager) { return(QuestingSystem.CompletedQuests.TryGetValue(manager.Colony, out var completed) && completed.Contains(QuestKey)); }