예제 #1
0
        public virtual void PerformGoal(ref NPC.NPCBase.NPCState state)
        {
            StoredItem[] remaining = new StoredItem[0];
            state.SetCooldown(1);

            if (ItemsToStore != null && ItemsToStore.Length != 0)
            {
                state.SetIndicator(new Shared.IndicatorState(1, ItemsToStore.FirstOrDefault().Id.Name));
            }

            if (WalkingTo == StorageType.Crate)
            {
                if (StorageFactory.CrateLocations[Job.Owner].TryGetValue(CurrentCratePosition, out CrateInventory ci))
                {
                    remaining = ci.TryAdd(ItemsToStore).ToArray();
                }
            }
            else
            {
                StorageFactory.StoreItems(Job.Owner, ItemsToStore);
            }

            if (remaining.Length > 0)
            {
                ItemsToStore = remaining;
                LastCratePosition.Add(CurrentCratePosition);
            }
            else
            {
                PandaJobFactory.SetActiveGoal(Job, NextGoal, ref state);
            }
        }
예제 #2
0
        public void PerformGoal(ref NPCBase.NPCState state)
        {
            state.JobIsDone = true;

            if (!Foraging)
            {
                Foraging = true;
                var nextTime = Pipliz.Random.Next(ForagingTimeMinSec, ForagingTimeMaxSec);
                ForageEndTime = ServerTimeStamp.Now.Add(nextTime * 1000);
                state.SetCooldown(1, 2);
                state.SetIndicator(new Shared.IndicatorState(Pipliz.Random.NextFloat(1, 2), LootTable.LootPoolList.GetRandomItem().Item));
            }
            else if (ForageEndTime.IsPassed)
            {
                var items = LootTable.GetDrops(LuckMod);

                foreach (var item in items)
                {
                    Job.NPC.Inventory.Add(item.Key, item.Value);
                }

                state.SetCooldown(1);

                Foraging = false;
                PandaJobFactory.SetActiveGoal(Job, new PutItemsInCrateGoal(Job, JobPos, this, Job.NPC.Inventory.Inventory, this), ref state);
                Job.NPC.Inventory.Inventory.Clear();
            }
            else
            {
                RandomizePos();
                var nextTime = Pipliz.Random.Next(5, 7);
                state.SetCooldown(nextTime);
                state.SetIndicator(new Shared.IndicatorState(nextTime, LootTable.LootPoolList.GetRandomItem().Item));
            }
        }
예제 #3
0
        public void PerformGoal(ref NPC.NPCBase.NPCState state)
        {
            StoredItem[] remaining = new StoredItem[0];
            state.JobIsDone = true;
            state.SetCooldown(_waitTime);

            if (remaining != null && remaining.Length != 0)
            {
                state.SetIndicator(new Shared.IndicatorState(_waitTime, remaining.FirstOrDefault().Id.Name, true, false));
            }

            if (WalkingTo == StorageType.Crate)
            {
                if (StorageFactory.CrateLocations[Job.Owner].TryGetValue(CurrentCratePosition, out CrateInventory ci))
                {
                    remaining = ci.TryTake(ItemsToGet).Values.ToArray();
                }
            }
            else
            {
                remaining = StorageFactory.TryTakeItemsReturnRemaining(Job.Owner, ItemsToGet);
                LastCratePosition.Clear();
                WalkingTo = StorageType.Crate;
            }

            if (remaining.Length != 0)
            {
                ItemsToGet = remaining;
                LastCratePosition.Add(CurrentCratePosition);
            }
            else
            {
                PandaJobFactory.SetActiveGoal(Job, NextGoal, ref state);
            }
        }
예제 #4
0
        private void Shop(IJob instance, ref NPCBase.NPCState state)
        {
            var items             = GuardSettings.ShootItem.Select(i => new StoredItem(i.Type, i.Amount * 50)).ToArray();
            var getitemsfromCrate = new GetItemsFromCrateGoal(instance, GuardJob.Position, this, items, this);

            PandaJobFactory.SetActiveGoal(instance, new PutItemsInCrateGoal(Job, GuardJob.Position, getitemsfromCrate, state.Inventory.Inventory, this), ref state);
            state.Inventory.Inventory.Clear();
            state.Inventory.Add(items);
        }
예제 #5
0
 public virtual void GetItemsFromCrate(ref NPCBase.NPCState state)
 {
     if (recipeMatch.FoundRecipe != null)
     {
         state.SetCooldown(0.4, 0.6);
         state.Inventory.Add(recipeMatch.FoundRecipe.Requirements.ToList(), recipeMatch.FoundRecipeCount);
         PandaJobFactory.SetActiveGoal(Job, new GetItemsFromCrateGoal(Job, JobInstance.Position, this, recipeMatch.FoundRecipe.Requirements, this), ref state);
     }
 }
예제 #6
0
        public override Vector3Int GetJobLocation()
        {
            if (!PandaJobFactory.TryGetActiveGoal(this, out var goal))
            {
                goal = new FarmingGoal(this, Definition as AbstractFarmAreaJobDefinition);
                PandaJobFactory.SetActiveGoal(this, goal);
            }

            return(goal.GetPosition());
        }
예제 #7
0
        public override Pipliz.Vector3Int GetJobLocation(BlockJobInstance instance)
        {
            if (!PandaJobFactory.TryGetActiveGoal(instance, out var goal))
            {
                goal = goal = new WaterGatherGoal(instance as CraftingJobWaterInstance, this);
                PandaJobFactory.SetActiveGoal(instance, goal);
            }

            return(goal.GetPosition());
        }
        public override Vector3Int GetJobLocation(BlockJobInstance instance)
        {
            if (!PandaJobFactory.TryGetActiveGoal(instance, out var goal))
            {
                goal = new CraftingLitGoal(instance, this);
                PandaJobFactory.SetActiveGoal(instance, goal);
            }

            return(goal.GetPosition());
        }
예제 #9
0
 public virtual void GetItemsFromCrate(ref NPCBase.NPCState state)
 {
     if (CraftingJobInstance.SelectedRecipe != null)
     {
         state.Inventory.Add(CraftingJobInstance.SelectedRecipe.Requirements.ToList(), CraftingJobInstance.SelectedRecipeCount);
         PandaJobFactory.SetActiveGoal(Job, new GetItemsFromCrateGoal(Job, CraftingJobInstance.Position, this, CraftingJobInstance.SelectedRecipe.Requirements, this), ref state);
     }
     else if (NextRecipe.MatchType != Recipe.RecipeMatchType.Invalid)
     {
         state.Inventory.Add(NextRecipe.FoundRecipe.Requirements.ToList(), NextRecipe.FoundRecipeCount);
         PandaJobFactory.SetActiveGoal(Job, new GetItemsFromCrateGoal(Job, CraftingJobInstance.Position, this, NextRecipe.FoundRecipe.Requirements, this), ref state);
     }
 }
예제 #10
0
        public void PerformGoal(ref NPC.NPCBase.NPCState state)
        {
            if (!HasWaited)
            {
                if (MissingItem != null)
                {
                    state.SetIndicator(new Shared.IndicatorState(10f, MissingItem.Id.Id, true, false));
                }

                state.SetCooldown(10);
                HasWaited = true;
            }
            else
            {
                PandaJobFactory.SetActiveGoal(Job, NextGoal, ref state);
            }
        }
예제 #11
0
        public void PerformGoal(ref NPCBase.NPCState state)
        {
            state.JobIsDone = true;
            MinerJobInstance instance = (MinerJobInstance)BlockJobInstance;

            if (instance.BlockTypeBelow == null || instance.BlockTypeBelow == BuiltinBlocks.Types.air)
            {
                if (!World.TryGetTypeAt(instance.Position.Add(0, -1, 0), out ItemTypes.ItemType foundType))
                {
                    state.SetCooldown(5.0, 7.0);
                    return;
                }
                if (foundType == BuiltinBlocks.Types.air)
                {
                    ThreadManager.InvokeOnMainThread(delegate
                    {
                        ServerManager.TryChangeBlock(instance.Position, instance.BlockType, BuiltinBlocks.Types.air, instance.Owner);
                    });
                    state.SetCooldown(2.5, 3.5);
                    return;
                }
                instance.BlockTypeBelow = foundType;
            }

            if (!MinerSettings.MinableTypes.Contains(instance.BlockTypeBelow.Name))
            {
                state = DestoryJob(state, instance);
                return;
            }

            if (MinerSettings.MiningCooldown <= 0f)
            {
                float cooldown = 0f;
                if (instance.BlockTypeBelow.CustomDataNode?.TryGetAs("minerMiningTime", out cooldown) ?? false)
                {
                    MinerSettings.MiningCooldown = cooldown;
                }
                if (MinerSettings.MiningCooldown <= 0f)
                {
                    state = DestoryJob(state, instance);
                    return;
                }
            }

            if (MinerSettings.BlockTypes.ContainsByReference(instance.BlockType, out int index))
            {
                UnityEngine.Vector3 rotate = instance.NPC.Position.Vector;
                switch (index)
                {
                case 1:
                    rotate.x += 1f;
                    break;

                case 2:
                    rotate.x -= 1f;
                    break;

                case 3:
                    rotate.z += 1f;
                    break;

                case 4:
                    rotate.z -= 1f;
                    break;
                }
                instance.NPC.LookAt(rotate);
            }

            AudioManager.SendAudio(instance.Position.Vector, MinerSettings.OnCraftedAudio);
            GatherResults.Clear();
            List <ItemTypes.ItemTypeDrops> itemList = instance.BlockTypeBelow.OnRemoveItems;

            for (int i = 0; i < itemList.Count; i++)
            {
                GatherResults.Add(itemList[i]);
            }
            ModLoader.Callbacks.OnNPCGathered.Invoke(instance, instance.Position.Add(0, -1, 0), GatherResults);
            InventoryItem toShow = ItemTypes.ItemTypeDrops.GetWeightedRandom(GatherResults);
            float         cd     = Pipliz.Random.NextFloat(0.9f, 1.1f) * MinerSettings.MiningCooldown;

            if (toShow.Amount > 0)
            {
                state.SetIndicator(new IndicatorState(cd, toShow.Type));
            }
            else
            {
                state.SetCooldown(cd);
            }
            state.Inventory.Add(GatherResults);
            instance.GatheredItemCount++;
            if (instance.GatheredItemCount >= MinerSettings.MaxCraftsPerRun)
            {
                PandaJobFactory.SetActiveGoal(BlockJobInstance, new PutItemsInCrateGoal(BlockJobInstance, BlockJobInstance.Position, this, state.Inventory.Inventory, this), ref state);
                state.Inventory.Inventory.Clear();
            }
        }
예제 #12
0
 public virtual void PutItemsInCrate(ref NPCBase.NPCState state)
 {
     PandaJobFactory.SetActiveGoal(Job, new PutItemsInCrateGoal(Job, FarmingJob.KeyLocation, this, state.Inventory.Inventory.ToList(), this), ref state);
     state.Inventory.Inventory.Clear();
     state.SetCooldown(0.2, 0.4);
 }
예제 #13
0
        public void PerformGoal(ref NPCBase.NPCState state)
        {
            ThreadManager.AssertIsMainThread();
            state.JobIsDone = true;

            if (!FarmingJob.PositionSub.IsValid)
            {
                state.SetCooldown(8.0, 12.0);
            }
            else
            {
                BlockFarmAreaJobDefinition definition = (BlockFarmAreaJobDefinition)this.Definition;
                Vector3Int vector3Int = FarmingJob.BlockLocation.IsValid ? FarmingJob.BlockLocation : FarmingJob.PositionSub;
                FarmingJob.PositionSub = Vector3Int.invalidPos;
                ItemTypes.ItemType val1;
                if (!World.TryGetTypeAt(vector3Int, out val1))
                {
                    state.SetCooldown(8.0, 12.0);
                }
                else
                {
                    if (val1 == definition.PlacedBlockType)
                    {
                        RecipeMatch = Recipe.MatchRecipe(FarmingJob.Owner.RecipeData.GetAvailableRecipes(definition.NPCTypeString), FarmingJob.Owner, FarmingJob.Owner.RecipeData.GetRecipeGroup(FarmingJob.CraftingGroupID));
                        switch (RecipeMatch.MatchType)
                        {
                        case Recipe.RecipeMatchType.FoundCraftable:
                            Recipe foundRecipe = RecipeMatch.FoundRecipe;
                            if (FarmingJob.NPC.Inventory.TryRemove(foundRecipe.Requirements))
                            {
                                CraftingResults.Clear();

                                for (int index = 0; index < foundRecipe.Results.Count; ++index)
                                {
                                    CraftingResults.Add(foundRecipe.Results[index]);
                                }

                                ModLoader.Callbacks.OnNPCCraftedRecipe.Invoke(Job, foundRecipe, CraftingResults);
                                RecipeResult weightedRandom = RecipeResult.GetWeightedRandom(CraftingResults);
                                float        timeToShow     = definition.Cooldown * Pipliz.Random.NextFloat(0.9f, 1.1f);

                                if (weightedRandom.Amount > 0)
                                {
                                    state.SetIndicator(new IndicatorState(timeToShow, weightedRandom.Type));
                                }
                                else
                                {
                                    state.SetCooldown(timeToShow);
                                }

                                FarmingJob.NPC.Inventory.Add(CraftingResults);
                                ++FarmingJob.GatherCount;

                                if (FarmingJob.GatherCount < definition.MaxGathersPerRun)
                                {
                                    return;
                                }

                                FarmingJob.GatherCount = 0;
                                PutItemsInCrate(ref state);
                                return;
                            }
                            else
                            {
                                PandaJobFactory.SetActiveGoal(Job, new GetItemsFromCrateGoal(Job, FarmingJob.KeyLocation, this, foundRecipe.Requirements, this), ref state);
                                FarmingJob.NPC.Inventory.Add(foundRecipe.Requirements, RecipeMatch.FoundRecipeCount);
                            }
                            state.SetCooldown(0.4, 0.6);
                            return;

                        case Recipe.RecipeMatchType.FoundMissingRequirements:
                        case Recipe.RecipeMatchType.AllDone:
                            if (state.Inventory.IsEmpty)
                            {
                                state.JobIsDone = true;
                                float cooldown = definition.Cooldown;
                                if (RecipeMatch.MatchType == Recipe.RecipeMatchType.AllDone)
                                {
                                    state.SetIndicator(new IndicatorState(cooldown, BuiltinBlocks.Indices.erroridle));
                                }
                                else
                                {
                                    state.SetIndicator(new IndicatorState(cooldown, RecipeMatch.FoundRecipe.FindMissingType(FarmingJob.Owner.Stockpile), true, false));
                                }
                                FarmingJob.Owner.Stats.RecordNPCIdleSeconds(FarmingJob.NPCType, cooldown);
                                return;
                            }
                            PutItemsInCrate(ref state);
                            return;
                        }
                    }
                    if (val1 == BuiltinBlocks.Types.air)
                    {
                        ItemTypes.ItemType val2;
                        if (World.TryGetTypeAt(vector3Int.Add(0, -1, 0), out val2))
                        {
                            if (!definition.PlacedBlockType.RequiresFertileBelow || val2.IsFertile)
                            {
                                if (definition.RequiredBlockItem.Amount != 0 && Job.NPC.Colony.Stockpile.TryRemove(definition.RequiredBlockItem))
                                {
                                    state.SetCooldown(1.5, 2.5);
                                    PandaJobFactory.SetActiveGoal(Job, new GetItemsFromCrateGoal(Job, FarmingJob.KeyLocation, this, new[] { new StoredItem(definition.RequiredBlockItem) }, this), ref state);
                                    Job.NPC.Inventory.Add(definition.RequiredBlockItem);
                                }

                                if (definition.RequiredBlockItem.Amount == 0)
                                {
                                    ServerManager.TryChangeBlock(vector3Int, BuiltinBlocks.Types.air, definition.PlacedBlockType, Job.Owner, ESetBlockFlags.DefaultAudio);
                                    state.SetCooldown(1.5, 2.5);
                                    return;
                                }
                                state.SetIndicator(new IndicatorState(Pipliz.Random.NextFloat(8f, 14f), definition.RequiredBlockItem.Type, true, false));
                                return;
                            }
                        }
                        else
                        {
                            state.SetCooldown(8.0, 12.0);
                            return;
                        }
                    }
                    state.SetCooldown((double)Pipliz.Random.NextFloat(3f, 6f));
                }
            }
        }
예제 #14
0
        public Vector3Int GetPosition()
        {
            List <Vector3Int> cratesWithItems = new List <Vector3Int>();
            var stockpileLoc = StorageFactory.GetStockpilePosition(Job.Owner);

            cratesWithItems.Add(stockpileLoc.Position);
            bool stockpileHasItems = true;

            foreach (var item in ItemsToGet)
            {
                if (!Job.Owner.Stockpile.Contains(item))
                {
                    stockpileHasItems = false;
                }

                if (StorageFactory.ItemCrateLocations.TryGetValue(Job.Owner, out var itemCrates) && itemCrates.TryGetValue(item.Id, out var locations))
                {
                    if (!LastCratePosition.Contains(ItemsForGoal.ClosestCrate) && locations.Contains(ItemsForGoal.ClosestCrate))
                    {
                        cratesWithItems.Add(ItemsForGoal.ClosestCrate);
                    }
                    else
                    {
                        foreach (var loc in locations)
                        {
                            if (!LastCratePosition.Contains(loc))
                            {
                                cratesWithItems.AddIfUnique(loc);
                            }
                        }
                    }
                }
            }

            if (cratesWithItems.Count == 0 || cratesWithItems[0] == stockpileLoc.Position)
            {
                if (stockpileHasItems)
                {
                    WalkingTo = StorageType.Stockpile;

                    if (stockpileLoc.Position == Vector3Int.invalidPos || stockpileLoc.Position == default(Vector3Int))
                    {
                        return(Job.Owner.Banners.FirstOrDefault().Position);
                    }
                    else
                    {
                        return(stockpileLoc.Position);
                    }
                }
                else
                {
                    PandaJobFactory.SetActiveGoal(Job, new StandAtJobGoal(Job, NextGoal, OriginalPosition, ItemsToGet.FirstOrDefault()));
                    return(OriginalPosition);
                }
            }
            else
            {
                WalkingTo = StorageType.Crate;

                if (cratesWithItems.Count == 1)
                {
                    CurrentCratePosition = cratesWithItems[0];
                }
                else
                {
                    var pos = OriginalPosition.GetClosestPosition(cratesWithItems);

                    if (pos == stockpileLoc.Position)
                    {
                        WalkingTo = StorageType.Stockpile;
                        return(stockpileLoc.Position);
                    }
                    else
                    {
                        CurrentCratePosition = pos;
                    }
                }

                return(CurrentCratePosition);
            }
        }