public override void OnNPCDoJob(ref NPCBase.NPCState state)
        {
            state.JobIsDone = true;
            usedNPC.LookAt(position.Vector);
            if (!state.Inventory.IsEmpty)
            {
                storedFuel += state.Inventory.TotalFuel;
                state.Inventory.ClearFuel();
                state.Inventory.Dump(blockInventory);
            }
            if (selectedRecipe != null)
            {
                if (recipesToCraft > 0 && selectedRecipe.IsPossible(usedNPC.Colony.UsedStockpile, blockInventory, storedFuel))
                {
                    storedFuel -= selectedRecipe.FuelPerCraft;
                    blockInventory.Remove(selectedRecipe.Requirements);
                    blockInventory.Add(selectedRecipe.Results);
                    recipesToCraft--;
                    OnLit();
                    state.SetIndicator(NPCIndicatorType.Crafted, TimeBetweenJobs, selectedRecipe.Results[0].Type);
                    state.JobIsDone = false;
                    return;
                }
                else
                {
                    recipesToCraft = 0;
                    selectedRecipe = null;
                    blockInventory.Dump(usedNPC.Inventory);
                    if (!state.Inventory.IsEmpty)
                    {
                        shouldTakeItems = true;
                    }
                    OverrideCooldown(0.1);
                }
            }
            else
            {
                var recipeMatch = Recipe.MatchRecipe(GetPossibleRecipes, usedNPC.Colony.UsedStockpile);
                switch (recipeMatch.MatchType)
                {
                case Recipe.RecipeMatchType.AllDone:
                case Recipe.RecipeMatchType.FoundMissingRequirements:
                    if (!state.Inventory.IsEmpty || !blockInventory.IsEmpty)
                    {
                        blockInventory.Dump(usedNPC.Inventory);
                        shouldTakeItems = true;
                    }
                    else
                    {
                        state.JobIsDone = false;
                        float cooldown = Random.NextFloat(8f, 16f);
                        if (recipeMatch.MatchType == Recipe.RecipeMatchType.AllDone)
                        {
                            state.SetIndicator(NPCIndicatorType.SuccessIdle, cooldown);
                        }
                        else
                        {
                            state.SetIndicator(NPCIndicatorType.MissingItem, cooldown, recipeMatch.FoundRecipe.FindMissingType(owner));
                        }
                        OverrideCooldown(cooldown);
                    }
                    break;

                case Recipe.RecipeMatchType.FoundCraftable:
                    blockInventory.Dump(usedNPC.Inventory);
                    selectedRecipe  = recipeMatch.FoundRecipe;
                    shouldTakeItems = true;
                    OverrideCooldown(0.5);
                    break;
                }
            }
            OnUnlit();
        }
Example #2
0
        public override void OnNPCAtJob(ref NPCBase.NPCState state)
        {
            state.JobIsDone = true;
            usedNPC.LookAt(position.Vector);
            if (!state.Inventory.IsEmpty)
            {
                usedNPC.Inventory.Dump(blockInventory);
            }
            if (selectedRecipe != null)
            {
                if (recipesToCraft > 0 && selectedRecipe.IsPossible(usedNPC.Colony.UsedStockpile, blockInventory))
                {
                    blockInventory.Remove(selectedRecipe.Requirements);

                    craftingResults.Clear();
                    for (int i = 0; i < selectedRecipe.Results.Count; i++)
                    {
                        craftingResults.Add(selectedRecipe.Results[i]);
                    }
                    ModLoader.TriggerCallbacks(ModLoader.EModCallbackType.OnNPCCraftedRecipe, (IJob)this, selectedRecipe, craftingResults);

                    if (craftingResults.Count > 0)
                    {
                        blockInventory.Add(craftingResults);
                        ushort typeToShow;
                        typeToShow = craftingResults[0].Type;
                        if (craftingResults.Count > 1)
                        {
                            int totalTypes = 0;
                            for (int i = 0; i < craftingResults.Count; i++)
                            {
                                totalTypes += craftingResults[i].Amount;
                            }
                            totalTypes = Random.Next(0, totalTypes + 1);
                            for (int i = 0; i < craftingResults.Count; i++)
                            {
                                totalTypes -= craftingResults[i].Amount;
                                if (totalTypes <= 0)
                                {
                                    typeToShow = craftingResults[i].Type;
                                    break;
                                }
                            }
                        }

                        state.SetIndicator(new Shared.IndicatorState(CraftingCooldown, typeToShow));
                    }
                    else
                    {
                        state.SetIndicator(new Shared.IndicatorState(CraftingCooldown, NPCIndicatorType.None));
                    }

                    state.JobIsDone = false;
                    recipesToCraft--;
                    OnRecipeCrafted();
                }
                else
                {
                    selectedRecipe = null;
                    recipesToCraft = 0;
                    blockInventory.Dump(usedNPC.Inventory);
                    if (!state.Inventory.IsEmpty)
                    {
                        shouldTakeItems = true;
                    }
                    state.SetCooldown(0.1);
                    if (wasCrafting)
                    {
                        OnStopCrafting();
                    }
                }
            }
            else
            {
                var recipeMatch = Recipe.MatchRecipe <Recipe, IList <Recipe> >(GetPossibleRecipes, usedNPC.Colony.UsedStockpile);
                switch (recipeMatch.MatchType)
                {
                case Recipe.RecipeMatchType.AllDone:
                case Recipe.RecipeMatchType.FoundMissingRequirements:
                    if (!state.Inventory.IsEmpty || !blockInventory.IsEmpty)
                    {
                        blockInventory.Dump(usedNPC.Inventory);
                        shouldTakeItems = true;
                        state.SetCooldown(0.3);
                    }
                    else
                    {
                        state.JobIsDone = false;
                        float cooldown = Random.NextFloat(8f, 16f);
                        if (recipeMatch.MatchType == Recipe.RecipeMatchType.AllDone)
                        {
                            state.SetIndicator(new Shared.IndicatorState(cooldown, BlockTypes.Builtin.BuiltinBlocks.ErrorIdle));
                        }
                        else
                        {
                            state.SetIndicator(new Shared.IndicatorState(cooldown, recipeMatch.FoundRecipe.FindMissingType(owner), true, false));
                        }
                    }
                    break;

                case Recipe.RecipeMatchType.FoundCraftable:
                    blockInventory.Dump(usedNPC.Inventory);
                    selectedRecipe  = recipeMatch.FoundRecipe;
                    shouldTakeItems = true;
                    state.SetCooldown(0.3);
                    break;

                default:
                    Assert.IsTrue(false, "Unexpected RecipeMatchType: " + recipeMatch.MatchType);
                    break;
                }
                if (wasCrafting)
                {
                    OnStopCrafting();
                }
            }
        }
        public override void OnNPCAtJob(ref NPCBase.NPCState state)
        {
            state.JobIsDone = true;
            usedNPC.LookAt(position.Vector);
            if (!state.Inventory.IsEmpty)
            {
                usedNPC.Inventory.Dump(blockInventory);
            }
            if (selectedRecipe != null)
            {
                if (recipesToCraft > 0 && selectedRecipe.IsPossible(usedNPC.Colony.UsedStockpile, blockInventory))
                {
                    blockInventory.Remove(selectedRecipe.Requirements);
                    blockInventory.Add(selectedRecipe.Results);
                    state.SetIndicator(new Shared.IndicatorState(CraftingCooldown, selectedRecipe.Results[0].Type));
                    state.JobIsDone = false;
                    recipesToCraft--;
                    OnRecipeCrafted();
                }
                else
                {
                    selectedRecipe = null;
                    recipesToCraft = 0;
                    blockInventory.Dump(usedNPC.Inventory);
                    if (!state.Inventory.IsEmpty)
                    {
                        shouldTakeItems = true;
                    }
                    state.SetCooldown(0.1);
                    if (wasCrafting)
                    {
                        OnStopCrafting();
                    }
                }
            }
            else
            {
                var recipeMatch = Recipe.MatchRecipe <Recipe, IList <Recipe> >(GetPossibleRecipes, usedNPC.Colony.UsedStockpile);
                switch (recipeMatch.MatchType)
                {
                case Recipe.RecipeMatchType.AllDone:
                case Recipe.RecipeMatchType.FoundMissingRequirements:
                    if (!state.Inventory.IsEmpty || !blockInventory.IsEmpty)
                    {
                        blockInventory.Dump(usedNPC.Inventory);
                        shouldTakeItems = true;
                        state.SetCooldown(0.3);
                    }
                    else
                    {
                        state.JobIsDone = false;
                        float cooldown = Random.NextFloat(8f, 16f);
                        if (recipeMatch.MatchType == Recipe.RecipeMatchType.AllDone)
                        {
                            state.SetIndicator(new Shared.IndicatorState(cooldown, BlockTypes.Builtin.BuiltinBlocks.ErrorIdle));
                        }
                        else
                        {
                            state.SetIndicator(new Shared.IndicatorState(cooldown, recipeMatch.FoundRecipe.FindMissingType(owner), true, false));
                        }
                    }
                    break;

                case Recipe.RecipeMatchType.FoundCraftable:
                    blockInventory.Dump(usedNPC.Inventory);
                    selectedRecipe  = recipeMatch.FoundRecipe;
                    shouldTakeItems = true;
                    state.SetCooldown(0.3);
                    break;

                default:
                    Assert.IsTrue(false, "Unexpected RecipeMatchType: " + recipeMatch.MatchType);
                    break;
                }
                if (wasCrafting)
                {
                    OnStopCrafting();
                }
            }
        }
Example #4
0
 public override void OnNPCAtJob(ref NPCBase.NPCState state)
 {
     state.JobIsDone = true;
     usedNPC.LookAt(position.Vector);
     if (!state.Inventory.IsEmpty)
     {
         state.Inventory.Dump(BlockInventory);
     }
     if (Todoblocks.Count < 1)
     {
         BlockInventory.Dump(usedNPC.Inventory);
         ShouldTakeItems = true;
     }
     else
     {
         bool placed = false;
         if (!ItemTypes.IndexLookup.TryGetIndex(Fullname, out ushort bluetype))
         {
             string msg = $"Bob here from site at {position}, the blueprint '{Fullname}' does not exist, stopped work here";
             Log.WriteError(msg);
             Chat.Send(usedNPC.Colony.Owner, msg);
             Todoblocks.Clear();
             return;
         }
         ushort scaffoldType = ItemTypes.IndexLookup.GetIndex(ScaffoldsModEntries.SCAFFOLD_ITEM_TYPE);
         string jobname      = TypeHelper.RotatableToBasetype(Fullname);
         for (int i = Todoblocks.Count - 1; i >= 0; i--)
         {
             BlueprintTodoBlock todoblock    = Todoblocks [i];
             Vector3Int         realPosition = todoblock.GetWorldPosition(jobname, position, bluetype);
             if (realPosition.y <= 0)
             {
                 Todoblocks.RemoveAt(i);
                 continue;
             }
             string todoblockBaseTypename    = TypeHelper.RotatableToBasetype(todoblock.Typename);
             string todoblockRotatedTypename = todoblock.Typename;
             if (!todoblockBaseTypename.Equals(todoblock.Typename))
             {
                 Vector3Int jobVec      = TypeHelper.RotatableToVector(Fullname);
                 Vector3Int blockVec    = TypeHelper.RotatableToVector(todoblock.Typename);
                 Vector3Int combinedVec = new Vector3Int(-jobVec.z * blockVec.x + jobVec.x * blockVec.z, 0, jobVec.x * blockVec.x + jobVec.z * blockVec.z);
                 todoblockRotatedTypename = todoblockBaseTypename + TypeHelper.VectorToXZ(combinedVec);
             }
             if (!LookupAndWarnItemIndex(todoblockRotatedTypename, out ushort todoblockRotatedType))
             {
                 Todoblocks.RemoveAt(i);
             }
             else if (!World.TryGetTypeAt(realPosition, out ushort actualType) || actualType == todoblockRotatedType)
             {
                 Todoblocks.RemoveAt(i);
             }
             else
             {
                 if (!LookupAndWarnItemIndex(todoblockBaseTypename, out ushort todoblockBaseType))
                 {
                     Todoblocks.RemoveAt(i);
                 }
                 else if (todoblockRotatedType == BuiltinBlocks.Air || BlockInventory.TryGetOneItem(todoblockBaseType))
                 {
                     Todoblocks.RemoveAt(i);
                     if (ServerManager.TryChangeBlock(realPosition, todoblockRotatedType, owner))
                     {
                         state.JobIsDone = true;
                         if (todoblockRotatedType == BuiltinBlocks.Air)
                         {
                             state.SetCooldown(ConstructionModEntries.EXCAVATION_DELAY);
                             state.SetIndicator(new Shared.IndicatorState(ConstructionModEntries.EXCAVATION_DELAY, actualType));
                         }
                         else if (!BlockInventory.IsEmpty && i > 0)
                         {
                             state.SetIndicator(new Shared.IndicatorState(0.5f, todoblockRotatedType));
                         }
                         if (actualType != BuiltinBlocks.Air && actualType != BuiltinBlocks.Water && actualType != scaffoldType)
                         {
                             usedNPC.Inventory.Add(ItemTypes.GetType(actualType).OnRemoveItems);
                         }
                         placed = true;
                         break;
                     }
                 }
             }
         }
         if (!placed)
         {
             BlockInventory.Dump(usedNPC.Inventory);
             ShouldTakeItems = true;
         }
     }
 }
Example #5
0
 public override void OnNPCDoJob(ref NPCBase.NPCState state)
 {
     state.JobIsDone = true;
     usedNPC.LookAt(position.Vector);
     if (!state.Inventory.IsEmpty)
     {
         state.Inventory.Dump(blockInventory);
     }
     if (todoblocks.Count < 1)
     {
         blockInventory.Dump(usedNPC.Inventory);
         shouldTakeItems = true;
     }
     else
     {
         bool   placed       = false;
         ushort bluetype     = ItemTypes.IndexLookup.GetIndex(fullname);
         ushort scaffoldType = ItemTypes.IndexLookup.GetIndex(ScaffoldsModEntries.SCAFFOLD_ITEM_TYPE);
         string jobname      = fullname.Substring(0, fullname.Length - 2);
         for (int i = todoblocks.Count - 1; i >= 0; i--)
         {
             BlueprintTodoBlock todoblock    = todoblocks[i];
             Vector3Int         realPosition = todoblock.GetWorldPosition(jobname, position, bluetype);
             if (realPosition.y <= 0)
             {
                 todoblocks.RemoveAt(i);
                 continue;
             }
             ushort newType = ItemTypes.IndexLookup.GetIndex(todoblock.typename);
             ushort actualType;
             if (World.TryGetTypeAt(realPosition, out actualType) && actualType != newType)
             {
                 ushort baseType = ItemTypes.IndexLookup.GetIndex(TypeHelper.RotatableToBasetype(todoblock.typename));
                 if (newType == BlockTypes.Builtin.BuiltinBlocks.Air || blockInventory.TryGetOneItem(baseType))
                 {
                     todoblocks.RemoveAt(i);
                     if (ServerManager.TryChangeBlock(realPosition, newType, ServerManager.SetBlockFlags.DefaultAudio))
                     {
                         state.JobIsDone = true;
                         if (newType == BlockTypes.Builtin.BuiltinBlocks.Air)
                         {
                             OverrideCooldown(ConstructionModEntries.EXCAVATION_DELAY);
                             state.SetIndicator(NPCIndicatorType.MissingItem, ConstructionModEntries.EXCAVATION_DELAY, actualType);
                         }
                         else if (!blockInventory.IsEmpty && i > 0)
                         {
                             state.SetIndicator(NPCIndicatorType.Crafted, TimeBetweenJobs, ItemTypes.IndexLookup.GetIndex(todoblocks[i].typename));
                         }
                         if (actualType != BlockTypes.Builtin.BuiltinBlocks.Air && actualType != scaffoldType)
                         {
                             usedNPC.Inventory.Add(ItemTypes.RemovalItems(actualType));
                         }
                         placed = true;
                         break;
                     }
                 }
             }
             else
             {
                 todoblocks.RemoveAt(i);
             }
         }
         if (!placed)
         {
             blockInventory.Dump(usedNPC.Inventory);
             shouldTakeItems = true;
         }
     }
 }
        public override void OnNPCDoJob(ref NPCBase.NPCState state)
        {
            state.JobIsDone = true;
            usedNPC.LookAt(position.Vector);
            if (!state.Inventory.IsEmpty)
            {
                usedNPC.Inventory.Dump(blockInventory);
            }
            if (selectedRecipe != null)
            {
                if (selectedRecipe.IsPossible(usedNPC.Colony.UsedStockpile, blockInventory))
                {
                    blockInventory.Take(selectedRecipe.Requirements);
                    blockInventory.Add(selectedRecipe.Results);
                    state.SetIndicator(NPCIndicatorType.Crafted, TimeBetweenJobs, selectedRecipe.Results[0].Type);
                    state.JobIsDone = false;
                }
                else
                {
                    selectedRecipe = null;
                    blockInventory.Dump(usedNPC.Inventory);
                    if (!state.Inventory.IsEmpty)
                    {
                        shouldTakeItems = true;
                    }
                    OverrideCooldown(0.1);
                }
            }
            else
            {
                var recipeMatch = Recipe.MatchRecipe(GetPossibleRecipes, usedNPC.Colony.UsedStockpile);
                switch (recipeMatch.MatchType)
                {
                case Recipe.RecipeMatchType.AllDone:
                case Recipe.RecipeMatchType.FoundMissingRequirements:
                    if (!state.Inventory.IsEmpty || !blockInventory.IsEmpty)
                    {
                        blockInventory.Dump(usedNPC.Inventory);
                        shouldTakeItems = true;
                    }
                    else
                    {
                        state.JobIsDone = false;
                        if (recipeMatch.MatchType == Recipe.RecipeMatchType.AllDone)
                        {
                            state.SetIndicator(NPCIndicatorType.SuccessIdle, 6f);
                        }
                        else
                        {
                            state.SetIndicator(NPCIndicatorType.MissingItem, 6f, recipeMatch.FoundRecipe.Requirements[0].Type);
                        }
                        OverrideCooldown(6.0);
                    }
                    break;

                case Recipe.RecipeMatchType.FoundCraftable:
                    blockInventory.Dump(usedNPC.Inventory);
                    selectedRecipe  = recipeMatch.FoundRecipe;
                    shouldTakeItems = true;
                    OverrideCooldown(0.5);
                    break;
                }
            }
        }