public override void Initialize() { Act unreserveAct = new Wrap(UnReserve); float time = 3 * (Item.ItemType.BaseCraftTime / Creature.AI.Stats.Intelligence); bool factionHasResources = Item.SelectedResources != null && Item.SelectedResources.Count > 0 && Creature.World.HasResources(Item.SelectedResources); Act getResources = null; if (Item.ExistingResource != null) { getResources = new Select(new Domain(() => Item.HasResources || Item.ResourcesReservedFor != null, true), new Domain(() => !Item.HasResources && (Item.ResourcesReservedFor == Agent || Item.ResourcesReservedFor == null), new Select( new Sequence(new Wrap(ReserveResources), new GetResourcesAct(Agent, new List <ResourceAmount>() { new ResourceAmount(Item.ExistingResource) }), new Wrap(SetSelectedResources)), new Sequence(new Wrap(UnReserve), Act.Status.Fail) ) ), new Domain(() => Item.HasResources || Item.ResourcesReservedFor != null, true)); } else if (!factionHasResources) { getResources = new Select(new Domain(() => Item.HasResources || Item.ResourcesReservedFor != null, true), new Domain(() => !Item.HasResources && (Item.ResourcesReservedFor == Agent || Item.ResourcesReservedFor == null), new Select( new Sequence(new Wrap(ReserveResources), new GetResourcesAct(Agent, Item.ItemType.RequiredResources), new Wrap(SetSelectedResources)), new Sequence(new Wrap(UnReserve), Act.Status.Fail) ) ), new Domain(() => Item.HasResources || Item.ResourcesReservedFor != null, true)); } else { getResources = new Select(new Domain(() => Item.HasResources || Item.ResourcesReservedFor != null, true), new Domain(() => !Item.HasResources && (Item.ResourcesReservedFor == Agent || Item.ResourcesReservedFor == null), new Sequence(new Wrap(ReserveResources), new GetResourcesAct(Agent, Item.SelectedResources)) | (new Wrap(UnReserve)) & false), new Domain(() => Item.HasResources || Item.ResourcesReservedFor != null, true)); } if (Item.ItemType.Type == CraftItem.CraftType.Object) { Act buildAct = null; if (Item.ExistingResource != null) { buildAct = new Always(Status.Success); } else { buildAct = new Wrap(() => Creature.HitAndWait(true, () => 1.0f, () => Item.Progress, () => Item.Progress += Creature.Stats.BuildSpeed / Item.ItemType.BaseCraftTime, // Todo: Account for creature debuffs, environment buffs () => Item.Location.WorldPosition + Vector3.One * 0.5f, "Craft")) { Name = "Construct object." }; } Tree = new Domain(IsNotCancelled, new Sequence( new ClearBlackboardData(Agent, "ResourcesStashed"), getResources, new Sequence(new Domain(ResourceStateValid, new Sequence( new GoToVoxelAct(Voxel, PlanAct.PlanType.Adjacent, Agent), new Wrap(() => DestroyResources(() => Item.Location.WorldPosition)), new Wrap(WaitForResources) { Name = "Wait for resources." }, buildAct, new CreateCraftItemAct(Voxel, Creature.AI, Item) ) )) )) | new Sequence(new Wrap(Creature.RestockAll), unreserveAct, false); } else if (Item.ItemType.Type == CraftItem.CraftType.Resource) { if (!String.IsNullOrEmpty(Item.ItemType.CraftLocation)) { Tree = new Sequence( new Wrap(() => Creature.FindAndReserve(Item.ItemType.CraftLocation, Item.ItemType.CraftLocation)), new ClearBlackboardData(Agent, "ResourcesStashed"), getResources, new Domain(ResourceStateValid, new Sequence( new GoToTaggedObjectAct(Agent) { Tag = Item.ItemType.CraftLocation, Teleport = true, TeleportOffset = new Vector3(0.5f, 0.0f, 0), ObjectName = Item.ItemType.CraftLocation, CheckForOcclusion = true }, new Wrap(() => DestroyResources(() => Agent.Position + MathFunctions.RandVector3Cube() * 0.5f)), new Wrap(WaitForResources) { Name = "Wait for resources." }, new Wrap(() => MaybeCreatePreviewBody(Item.SelectedResources)), new Wrap(() => Creature.HitAndWait(true, () => 1.0f, // Max Progress () => Item.Progress, // Current Progress () => { // Increment Progress var location = Creature.AI.Blackboard.GetData <GameComponent>(Item.ItemType.CraftLocation); float workstationBuff = 1.0f; if (location != null) { Creature.Physics.Face(location.Position); if (Item.PreviewResource != null) { Item.PreviewResource.LocalPosition = location.Position + Vector3.Up * 0.25f; } if (location.GetComponent <SteamPipes.BuildBuff>().HasValue(out var buff)) { workstationBuff = buff.GetBuffMultiplier(); } } // Todo: Account for environment buff & 'anvil' buff. Item.Progress += (Creature.Stats.BuildSpeed * workstationBuff) / Item.ItemType.BaseCraftTime; },
public override void Initialize() { Act unreserveAct = new Wrap(UnReserve); float time = 3 * (Item.ItemType.BaseCraftTime / Creature.AI.Stats.BuffedInt); Act getResources = null; if (Item.ExistingResource != null) { getResources = new Select(new Domain(() => Item.HasResources || Item.ResourcesReservedFor != null, true), new Domain(() => !Item.HasResources && (Item.ResourcesReservedFor == Agent || Item.ResourcesReservedFor == null), new Select( new Sequence(new Wrap(ReserveResources), new GetResourcesAct(Agent, new List <ResourceAmount>() { new ResourceAmount(Item.ExistingResource) }), new Wrap(SetSelectedResources)), new Sequence(new Wrap(UnReserve), Act.Status.Fail) ) ), new Domain(() => Item.HasResources || Item.ResourcesReservedFor != null, true)); } else if (Item.SelectedResources == null || Item.SelectedResources.Count == 0) { getResources = new Select(new Domain(() => Item.HasResources || Item.ResourcesReservedFor != null, true), new Domain(() => !Item.HasResources && (Item.ResourcesReservedFor == Agent || Item.ResourcesReservedFor == null), new Select( new Sequence(new Wrap(ReserveResources), new GetResourcesAct(Agent, Item.ItemType.RequiredResources), new Wrap(SetSelectedResources)), new Sequence(new Wrap(UnReserve), Act.Status.Fail) ) ), new Domain(() => Item.HasResources || Item.ResourcesReservedFor != null, true)); } else { getResources = new Select(new Domain(() => Item.HasResources || Item.ResourcesReservedFor != null, true), new Domain(() => !Item.HasResources && (Item.ResourcesReservedFor == Agent || Item.ResourcesReservedFor == null), new Sequence(new Wrap(ReserveResources), new GetResourcesAct(Agent, Item.SelectedResources))), new Domain(() => Item.HasResources || Item.ResourcesReservedFor != null, true)); } if (Item.ItemType.Type == CraftItem.CraftType.Object) { Act buildAct = null; if (Item.ExistingResource != null) { buildAct = new Always(Status.Success); } else { buildAct = new Wrap(() => Creature.HitAndWait(true, () => 1.0f, () => Item.Progress, () => Item.Progress += Creature.Stats.BuildSpeed / Item.ItemType.BaseCraftTime, () => Item.Location.WorldPosition + Vector3.One * 0.5f, "Craft")) { Name = "Construct object." }; } Tree = new Domain(IsNotCancelled, new Sequence( new ClearBlackboardData(Agent, "ResourcesStashed"), getResources, new Sequence(new Domain(ResourceStateValid, new Sequence( new GoToVoxelAct(Voxel, PlanAct.PlanType.Adjacent, Agent), new Wrap(() => DestroyResources(() => Item.Location.WorldPosition)), new Wrap(WaitForResources) { Name = "Wait for resources." }, buildAct, new CreateCraftItemAct(Voxel, Creature.AI, Item) ) )) )) | new Sequence(new Wrap(Creature.RestockAll), unreserveAct, false); } else { if (!String.IsNullOrEmpty(Item.ItemType.CraftLocation)) { Tree = new Sequence( new Wrap(() => Creature.FindAndReserve(Item.ItemType.CraftLocation, Item.ItemType.CraftLocation)), new ClearBlackboardData(Agent, "ResourcesStashed"), getResources, new Domain(ResourceStateValid, new Sequence ( new GoToTaggedObjectAct(Agent) { Tag = Item.ItemType.CraftLocation, Teleport = true, TeleportOffset = new Vector3(0.5f, 0.0f, 0), ObjectName = Item.ItemType.CraftLocation, CheckForOcclusion = true }, new Wrap(() => DestroyResources(() => Agent.Position + MathFunctions.RandVector3Cube() * 0.5f)), new Wrap(WaitForResources) { Name = "Wait for resources." }, new Wrap(() => Creature.HitAndWait(true, () => 1.0f, () => Item.Progress, () => Item.Progress += Creature.Stats.BuildSpeed / Item.ItemType.BaseCraftTime, () => Agent.Position, Noise)) { Name = "Construct object." }, unreserveAct, new Wrap(() => CreateResources(Item.SelectedResources)), new Wrap(Creature.RestockAll) )) | new Sequence(unreserveAct, new Wrap(Creature.RestockAll), false) ) | new Sequence(unreserveAct, new Wrap(Creature.RestockAll), false); } else { Tree = new Sequence( new ClearBlackboardData(Agent, "ResourcesStashed"), getResources, new Domain(ResourceStateValid, new Sequence( new Wrap(() => DestroyResources(() => Creature.Physics.Position + MathFunctions.RandVector3Cube() * 0.5f)), new Wrap(WaitForResources) { Name = "Wait for resources." }, new Wrap(() => Creature.HitAndWait(time, true, () => Creature.Physics.Position)) { Name = "Construct object." }, new Wrap(() => CreateResources(Item.SelectedResources))) ) ) | new Sequence(unreserveAct, new Wrap(Creature.RestockAll), false); } } base.Initialize(); }