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(); }
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(); } } }
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; } } }
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; } } }