public Pipliz.Vector3Int GetJobLocation(BlockJobInstance instance) { if (instance is RoamingJob roamingJob) { return(roamingJob.OriginalPosition); } return(Pipliz.Vector3Int.invalidPos); }
public virtual void OnNPCAtStockpile(BlockJobInstance blockJobInstance, ref NPCState state) { MinerJobInstance inst = (MinerJobInstance)blockJobInstance; inst.ShouldTakeItems = false; inst.GatheredItemCount = 0; state.Inventory.Dump(blockJobInstance.Owner.Stockpile); state.SetCooldown(0.3); state.JobIsDone = true; }
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 void OnGoalChanged(BlockJobInstance jobInstance, NPCBase.NPCGoal goalOld, NPCBase.NPCGoal goalNew) { MachineJobInstance instance = (MachineJobInstance)jobInstance; if (goalOld == NPCBase.NPCGoal.Job && instance.IsCrafting) { instance.IsCrafting = false; OnStopCrafting(instance); } }
public virtual Vector3Int GetJobLocation(BlockJobInstance instance) { if (!PandaJobFactory.TryGetActiveGoal(instance, out var goal)) { goal = new ForagingGoal(instance, instance.Position, LootTable, ForagingTimeMinSec, ForagingTimeMaxSec, LuckMod); PandaJobFactory.SetActiveGoal(instance, goal); } return(goal.GetPosition()); }
public void OnGoalChanged(BlockJobInstance instanceBlock, NPCBase.NPCGoal goalOld, NPCBase.NPCGoal goalNew) { GeneratorJobInstance instance = (GeneratorJobInstance)instanceBlock; if (goalOld == NPCBase.NPCGoal.Job && instance.IsCrafting) { instance.IsCrafting = false; OnStopCrafting(instance); } }
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()); }
public virtual void OnNPCAtStockpile(BlockJobInstance instance, ref NPCState state) { ScientistJobInstance scientist = instance as ScientistJobInstance; if (scientist != null) { scientist.StoredItemCount = ItemsToTakePerHaul; } state.SetCooldown(0.5); state.JobIsDone = true; instance.ShouldTakeItems = false; }
public virtual void OnNPCAtJob(BlockJobInstance blockJobInstance, ref NPCBase.NPCState state) { GeneratorJobInstance instance = (GeneratorJobInstance)blockJobInstance; NPCLookAtJobBlock(blockJobInstance); state.JobIsDone = true; //Make sure NPC actually has items if (state.Inventory.IsEmpty == false) { //Setup power info int power, maxpower; PowerManager.GetPower(blockJobInstance.Position, out power); PowerManager.GetMaxPower(blockJobInstance.Position, out maxpower); //Make sure generator needs power so resources are not wasted if (power != maxpower) { //Remove EnergyItem from inventory state.Inventory.Remove(EnergyItem); state.SetIndicator(new Shared.IndicatorState(CraftingCooldown, ItemTypes.IndexLookup.GetIndex("electricity"), false, false)); //Generate power! PowerManager.GeneratePower(blockJobInstance.Position); if (instance.IsCrafting == false) { instance.IsCrafting = true; OnStartCrafting(instance); } } else { if (instance.IsCrafting == true) { OnStopCrafting(instance); } state.SetIndicator(new Shared.IndicatorState(0.3f, ItemTypes.IndexLookup.GetIndex("electricity"), false, true)); } } else { //Go get the needed items blockJobInstance.ShouldTakeItems = true; state.SetCooldown(0.3); if (instance.IsCrafting == true) { OnStopCrafting(instance); } } }
public override void OnNPCAtJob(BlockJobInstance blockJobInstance, ref NPC.NPCBase.NPCState state) { GeneratorJobWaterInstance instance = (GeneratorJobWaterInstance)blockJobInstance; //Colony owner = instance.Owner; state.JobIsDone = true; if (!CheckWater(instance)) { state.SetCooldown(0.3); return; } if (instance.counter >= 10) { instance.counter = 0; instance.ShouldTakeItems = true; } else { //Setup power info PowerManager.GetPower(blockJobInstance.Position, out int power); PowerManager.GetMaxPower(blockJobInstance.Position, out int maxpower); if (power != maxpower) { state.SetIndicator(new Shared.IndicatorState(CraftingCooldown, ItemTypes.IndexLookup.GetIndex("electricity"), false, false)); PowerManager.GeneratePower(blockJobInstance.Position); if (instance.IsCrafting == false) { instance.IsCrafting = true; OnStartCrafting(blockJobInstance); } instance.counter++; } else { state.SetCooldown(0.5); if (instance.IsCrafting == true) { instance.IsCrafting = false; OnStopCrafting(blockJobInstance); } } } }
public override void OnStopCrafting(BlockJobInstance instance) { if (!BlockTypes.ContainsByReference(instance.BlockType, out int index)) { return; } int num = index; if ((uint)(num - 6) <= 3u) { ItemTypes.ItemType newType = BlockTypes[index - 5]; ESetBlockFlags flags = ESetBlockFlags.None; if (ServerManager.TryChangeBlock(instance.Position, instance.BlockType, newType, instance.Owner, flags) == EServerChangeBlockResult.Success) { instance.BlockType = newType; } } }
// perform guard duty public void OnNPCAtJob(BlockJobInstance blockInstance, ref NPCBase.NPCState state) { AngryGuardJobInstance instance = (AngryGuardJobInstance)blockInstance; instance.target = PlayerTracker.FindTarget(instance.Owner, instance.eyePosition, this.Range); if (instance.target != null) { Vector3 positionToAimFor = instance.target.Position; positionToAimFor[1] += 1; instance.NPC.LookAt(positionToAimFor); this.ShootAtTarget(instance, ref state); } else { state.SetCooldown((double)this.CooldownSearchingTarget); Vector3 val = instance.Position.Vector; int num; if (this.BlockTypes.ContainsByReference <ItemTypes.ItemType>(instance.BlockType, out num)) { switch (num) { case 1: val += Vector3.right; break; case 2: val += Vector3.left; break; case 3: val += Vector3.forward; break; case 4: val += Vector3.back; break; } instance.NPC.LookAt(val); } } return; }
public void OnNPCAtStockpile(BlockJobInstance jobInstance, ref NPCBase.NPCState state) { MachineJobInstance instance = (MachineJobInstance)jobInstance; if (!state.Inventory.IsEmpty) { state.Inventory.Dump(instance.Owner.Stockpile); state.SetCooldown(0.3); } state.JobIsDone = true; if (!instance.ShouldTakeItems) { return; } instance.ShouldTakeItems = false; Recipes.Recipe.RecipeMatch recipeMatch = Recipes.Recipe.MatchRecipe(GetPossibleRecipes(instance), instance.Owner); switch (recipeMatch.MatchType) { case Recipes.Recipe.RecipeMatchType.FoundMissingRequirements: case Recipes.Recipe.RecipeMatchType.AllDone: state.SetCooldown(0.5); instance.SelectedRecipeCount = 0; break; case Recipes.Recipe.RecipeMatchType.FoundCraftable: { instance.SelectedRecipe = recipeMatch.FoundRecipe; instance.SelectedRecipeCount = Pipliz.Math.Min(recipeMatch.FoundRecipeCount, MaxCraftsPerHaul); List <InventoryItem> reqs = instance.SelectedRecipe.Requirements; for (int i = 0; i < reqs.Count; i++) { state.Inventory.Add(reqs[i] * instance.SelectedRecipeCount); instance.Owner.Stockpile.TryRemove(reqs[i] * instance.SelectedRecipeCount); } state.SetCooldown(0.5); break; } default: Assert.IsTrue(condition: false, "Unexpected RecipeMatchType: " + recipeMatch.MatchType); break; } }
public virtual Vector3Int GetJobLocation(BlockJobInstance instance) { if (!PandaJobFactory.TryGetActiveGoal(instance, out var goal)) { if (StorageType == PorterJobType.ToCrate) { var stc = new StockpikeToCrateGoal(instance); PandaJobFactory.SetActiveGoal(instance, stc); return(stc.GetPosition()); } else { var cts = new CrateToStockpikeGoal(instance); PandaJobFactory.SetActiveGoal(instance, cts); return(cts.GetPosition()); } } return(goal.GetPosition()); }
static void Postfix(ScientistJobSettingsHookOnNPCAtJob __instance, BlockJobInstance blockJobInstance, ref NPCBase.NPCState state) { // Log.WriteWarning("ScientistJobSettingsHookOnNPCAtJob::Postfix"); npc = null; }
public void OnNPCAtJob(BlockJobInstance instance, ref NPCBase.NPCState state) { instance.OnNPCAtJob(ref state); }
public virtual void OnStartCrafting(BlockJobInstance instance) { }
public MiningGoal(BlockJobInstance job, PandaMiningJobSettings settings) { MinerSettings = settings; Job = job; BlockJobInstance = job; }
public void OnNPCAtJob(BlockJobInstance jobInstance, ref NPCBase.NPCState state) { MachineJobInstance instance = (MachineJobInstance)jobInstance; NPCLookAtJobBlock(jobInstance); state.JobIsDone = true; if (instance.SelectedRecipe != null) { if (instance.SelectedRecipeCount > 0 && instance.SelectedRecipe.IsPossible(instance.Owner, state.Inventory)) { if (PowerManager.Operate(instance.Position)) { state.Inventory.Remove(instance.SelectedRecipe.Requirements); craftingResults.Clear(); craftingResults.Add(instance.SelectedRecipe.Results); ModLoader.Callbacks.OnNPCCraftedRecipe.Invoke(instance, instance.SelectedRecipe, craftingResults); if (craftingResults.Count > 0) { state.Inventory.Add(craftingResults); RecipeResult toShow = RecipeResult.GetWeightedRandom(craftingResults); if (toShow.Amount > 0) { //Possible way for varied Crafting speeds? //ItemTypes.GetType(toShow.AsItem.Type).CustomDataNode["craftspeed"].GetAs<float>(); state.SetIndicator(new IndicatorState(CraftingCooldown, toShow.Type)); } else { state.SetCooldown(CraftingCooldown); } if (OnCraftedAudio != null) { AudioManager.SendAudio(instance.Position.Vector, OnCraftedAudio); } } else { state.SetIndicator(new IndicatorState(CraftingCooldown, NPCIndicatorType.None)); } if (!instance.IsCrafting) { instance.IsCrafting = true; OnStartCrafting(instance); } state.JobIsDone = false; instance.SelectedRecipeCount--; } else { state.SetIndicator(new IndicatorState(0.3f, ItemTypes.IndexLookup.GetIndex("electricity"), true, false)); } } else { instance.SelectedRecipe = null; instance.SelectedRecipeCount = 0; if (!state.Inventory.IsEmpty) { instance.ShouldTakeItems = true; } state.SetCooldown(0.1); if (instance.IsCrafting) { instance.IsCrafting = false; OnStopCrafting(instance); } } return; } if (instance.IsCrafting) { instance.IsCrafting = false; OnStopCrafting(instance); } Recipes.Recipe.RecipeMatch recipeMatch = Recipes.Recipe.MatchRecipe(GetPossibleRecipes(instance), instance.Owner); switch (recipeMatch.MatchType) { case Recipes.Recipe.RecipeMatchType.FoundMissingRequirements: case Recipes.Recipe.RecipeMatchType.AllDone: { if (!state.Inventory.IsEmpty) { instance.ShouldTakeItems = true; state.SetCooldown(0.3); break; } state.JobIsDone = false; float cooldown = Pipliz.Random.NextFloat(8f, 16f); if (recipeMatch.MatchType == Recipes.Recipe.RecipeMatchType.AllDone) { state.SetIndicator(new IndicatorState(cooldown, BuiltinBlocks.Indices.erroridle)); } else { state.SetIndicator(new IndicatorState(cooldown, recipeMatch.FoundRecipe.FindMissingType(instance.Owner.Stockpile), striked: true, green: false)); } break; } case Recipes.Recipe.RecipeMatchType.FoundCraftable: instance.SelectedRecipe = recipeMatch.FoundRecipe; instance.ShouldTakeItems = true; state.SetCooldown(0.3); break; default: Assert.IsTrue(condition: false, "Unexpected RecipeMatchType: " + recipeMatch.MatchType); break; } }
public Vector3Int GetJobLocation(BlockJobInstance jobInstance) { return(jobInstance.Position); }
public virtual void OnNPCAtJob(BlockJobInstance instance, ref NPCBase.NPCState state) { PandaJobFactory.ActiveGoals[instance.Owner][instance].PerformGoal(ref state); }
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; } }
private void NPCLookAtJobBlock(BlockJobInstance jobInstance) { jobInstance.NPC.LookAt(jobInstance.Position.Vector); }
public override void OnNPCAtJob(BlockJobInstance blockInstance, ref NPCBase.NPCState state) { PandaJobFactory.ActiveGoals[blockInstance.Owner][blockInstance].PerformGoal(ref state); }
public virtual void OnGoalChanged(BlockJobInstance instance, NPCGoal oldGoal, NPCGoal newGoal) { }
public virtual Vector3Int GetJobLocation(BlockJobInstance instance) { return(instance.Position); }
public virtual void OnNPCAtJob(BlockJobInstance blockJobInstance, ref NPCState state) { ConstructionJobInstance instance = (ConstructionJobInstance)blockJobInstance; if (BlockTypes.ContainsByReference(instance.BlockType, out int index)) { 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); } if (instance.ConstructionArea != null && !instance.ConstructionArea.IsValid) { instance.ConstructionArea = null; } if (instance.ConstructionArea == null) { if (AreaJobTracker.ExistingAreaAt(instance.Position.Add(-1, -1, -1), instance.Position.Add(1, 1, 1), out List <IAreaJob> jobs)) { for (int i = 0; i < jobs.Count; i++) { if (jobs[i] is ConstructionArea neighbourArea) { instance.ConstructionArea = neighbourArea; break; } } AreaJobTracker.AreaJobListPool.Return(jobs); } if (instance.ConstructionArea == null) { if (instance.DidAreaPresenceTest) { state.SetCooldown(0.5); ServerManager.TryChangeBlock(instance.Position, instance.BlockType, BuiltinBlocks.Types.air, instance.Owner); } else { state.SetIndicator(new Shared.IndicatorState(Random.NextFloat(3f, 5f), BuiltinBlocks.Indices.erroridle)); instance.DidAreaPresenceTest = true; } return; } } Assert.IsNotNull(instance.ConstructionArea); instance.ConstructionArea.DoJob(instance, ref state); }
public void OnNPCAtStockpile(BlockJobInstance instance, ref NPCBase.NPCState state) { }
public void OnGoalChanged(BlockJobInstance instance, INPCGoal goalOld, INPCGoal goalNew) { }
public virtual void OnStopCrafting(BlockJobInstance jobInstance) { }