예제 #1
0
        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}.");
            }
        }
예제 #2
0
 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"));
 }
예제 #3
0
        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);
        }
예제 #4
0
 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();
             }
         }
     }
 }
예제 #5
0
 public override void OnResearchComplete(ColonyScienceState manager, EResearchCompletionReason reason)
 {
     manager.Colony.RecipeData.UnlockRecipe(new RecipeKey("Nach0ChickenPie-pipliz.baker"));
 }
예제 #6
0
 public override void OnResearchComplete(ColonyScienceState manager, EResearchCompletionReason reason)
 {
     manager.Colony.TemporaryData.SetAs("pipliz.builderlimit", 25000000);
     ConstructionHelper.SendPacket(manager.Colony);
 }
예제 #7
0
 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;
 }
예제 #9
0
 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;
            }
        }
예제 #11
0
 public override void OnResearchComplete(ColonyScienceState manager, EResearchCompletionReason reason)
 {
     manager.Colony.RecipeData.UnlockRecipe(new RecipeKey("nach0.recipes.fishersremastered.pipliz.merchant.lure"));
 }
예제 #12
0
 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"));
 }
예제 #13
0
 public bool IsConditionMet(AbstractResearchable researchable, ColonyScienceState manager)
 {
     return(QuestingSystem.CompletedQuests.TryGetValue(manager.Colony, out var completed) && completed.Contains(QuestKey));
 }