public virtual void GetNextRecipe(ref NPCBase.NPCState state) { NextRecipe = Recipe.MatchRecipe(CraftingJobSettings.GetPossibleRecipes(CraftingJobInstance), Job.Owner, RecipeSettingsGroup); switch (NextRecipe.MatchType) { case Recipe.RecipeMatchType.FoundMissingRequirements: case Recipe.RecipeMatchType.AllDone: { if (!state.Inventory.IsEmpty) { PutItemsInCrate(ref state); break; } float cooldown = Pipliz.Random.NextFloat(8f, 16f); if (NextRecipe.MatchType == Recipe.RecipeMatchType.AllDone) { state.SetIndicator(new IndicatorState(cooldown, BuiltinBlocks.Indices.erroridle)); } else { GetItemsFromCrate(ref state); } Job.Owner.Stats.RecordNPCIdleSeconds(Job.NPCType, cooldown); break; } case Recipe.RecipeMatchType.FoundCraftable: CraftingJobInstance.SelectedRecipe = NextRecipe.FoundRecipe; CraftingJobInstance.SelectedRecipeCount = NextRecipe.FoundRecipeCount; GetItemsFromCrate(ref state); state.SetCooldown(0.2, 0.4); NextRecipe = Recipe.MatchRecipe(CraftingJobSettings.GetPossibleRecipes(CraftingJobInstance), Job.Owner, RecipeSettingsGroup); break; default: UnityEngine.Assertions.Assert.IsTrue(condition: false, "Unexpected RecipeMatchType: " + NextRecipe.MatchType); break; } }
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)); } } }
public void PerformGoal(ref NPCBase.NPCState state) { CraftingJobWaterInstance instance = JobInstance; Colony owner = instance.Owner; state.JobIsDone = true; if (!this.CheckWater(instance)) { state.SetCooldown(0.3, 0.5); } else { int index1; if (WaterSettings.BlockTypes.ContainsByReference <ItemTypes.ItemType>(instance.BlockType, out index1)) { UnityEngine.Vector3 vector = instance.NPC.Position.Vector; switch (index1) { case 1: ++vector.x; break; case 2: --vector.x; break; case 3: ++vector.z; break; case 4: --vector.z; break; } instance.NPC.LookAt(vector); } recipeMatch = Recipe.MatchRecipe <AvailableRecipesEnumerator>(owner.RecipeData.GetAvailableRecipes(WaterSettings.NPCTypeString), owner); switch (recipeMatch.MatchType) { case Recipe.RecipeMatchType.FoundCraftable: Recipe foundRecipe = recipeMatch.FoundRecipe; if (state.Inventory.TryRemove(foundRecipe.Requirements)) { CraftingResults.Clear(); for (int index2 = 0; index2 < foundRecipe.Results.Count; ++index2) { CraftingResults.Add(foundRecipe.Results[index2]); } if (WaterSettings.OnCraftedAudio != null) { AudioManager.SendAudio(instance.Position.Vector, WaterSettings.OnCraftedAudio); } ModLoader.Callbacks.OnNPCCraftedRecipe.Invoke(Job, foundRecipe, CraftingResults); RecipeResult weightedRandom = RecipeResult.GetWeightedRandom(CraftingResults); float timeToShow = WaterSettings.Cooldown * Pipliz.Random.NextFloat(0.9f, 1.1f); if (weightedRandom.Amount > 0) { state.SetIndicator(new IndicatorState(timeToShow, weightedRandom.Type)); } else { state.SetCooldown((double)timeToShow); } state.Inventory.Add(CraftingResults); ++instance.GatheredCount; if (instance.GatheredCount < WaterSettings.MaxGatheredBeforeCrate) { break; } instance.GatheredCount = 0; PutItemsInCrate(ref state); break; } else { GetItemsFromCrate(ref state); } break; case Recipe.RecipeMatchType.FoundMissingRequirements: case Recipe.RecipeMatchType.AllDone: if (state.Inventory.IsEmpty) { state.JobIsDone = true; if (recipeMatch.MatchType == Recipe.RecipeMatchType.AllDone) { state.SetIndicator(new IndicatorState(WaterSettings.Cooldown, BuiltinBlocks.Indices.erroridle)); } else { state.SetIndicator(new IndicatorState(WaterSettings.Cooldown, recipeMatch.FoundRecipe.FindMissingType(owner.Stockpile), true, false)); } Job.Owner.Stats.RecordNPCIdleSeconds(WaterSettings.NPCType, WaterSettings.Cooldown); GetItemsFromCrate(ref state); break; } GetItemsFromCrate(ref state); break; } } }
public override void OnNPCAtJob(ref NPCBase.NPCState state) { OliveFarmerAreaJob def = (OliveFarmerAreaJob)definition; ThreadManager.AssertIsMainThread(); state.JobIsDone = true; positionSub = Vector3Int.invalidPos; if (!treeLocation.IsValid) // probably idling about { state.SetCooldown(Random.NextFloat(8f, 16f)); return; } if (!World.TryGetTypeAt(treeLocation, out ushort type)) { state.SetCooldown(10.0); return; } if (type == BuiltinBlocks.Indices.logtemperate) // gather olives { var recipes = Owner.RecipeData.GetAvailableRecipes(def.NPCTypeString); Recipe.RecipeMatch match = Recipe.MatchRecipe(recipes, Owner); switch (match.MatchType) { case Recipe.RecipeMatchType.AllDone: case Recipe.RecipeMatchType.FoundMissingRequirements: if (state.Inventory.IsEmpty) { state.JobIsDone = true; if (match.MatchType == Recipe.RecipeMatchType.AllDone) { state.SetIndicator(new Shared.IndicatorState(def.Cooldown, BuiltinBlocks.Indices.erroridle)); } else { state.SetIndicator(new Shared.IndicatorState(def.Cooldown, match.FoundRecipe.FindMissingType(Owner.Stockpile), true, false)); } } else { shouldDumpInventory = true; } return; case Recipe.RecipeMatchType.FoundCraftable: var recipe = match.FoundRecipe; if (Owner.Stockpile.TryRemove(recipe.Requirements)) { // should always succeed, as the match above was succesfull GatherResults.Clear(); for (int i = 0; i < recipe.Results.Count; i++) { GatherResults.Add(recipe.Results[i]); } ModLoader.Callbacks.OnNPCCraftedRecipe.Invoke(this, recipe, GatherResults); RecipeResult toShow = RecipeResult.GetWeightedRandom(GatherResults); if (toShow.Amount > 0) { state.SetIndicator(new Shared.IndicatorState(def.Cooldown, toShow.Type)); } else { state.SetCooldown(def.Cooldown); } NPC.Inventory.Add(GatherResults); GatheredCount++; if (GatheredCount >= def.MaxGathersPerRun) { GatheredCount = 0; shouldDumpInventory = true; } } return; } } else if (type == 0) // maybe plant sapling? { if (World.TryGetTypeAt(treeLocation.Add(0, -1, 0), out ItemTypes.ItemType typeBelow)) { if (typeBelow.IsFertile) { ServerManager.TryChangeBlock(treeLocation, BuiltinBlocks.Types.air, BuiltinBlocks.Types.olivesapling, Owner, ESetBlockFlags.DefaultAudio); state.SetCooldown(2.0); return; } } else { state.SetCooldown(10.0); return; } } else { // very likely it's a sapling, so idle about } // something unexpected or idling state.SetCooldown(Random.NextFloat(4f, 8f)); return; }