Ejemplo n.º 1
0
        public BuildRoomAct(CreatureAI agent, BuildZoneOrder buildRoom) :
            base(agent)
        {
            Name      = "Build BuildRoom " + buildRoom.ToString();
            Resources = buildRoom.ListRequiredResources();
            BuildRoom = buildRoom;
            if (BuildRoom.ResourcesReservedFor != null && BuildRoom.ResourcesReservedFor.IsDead)
            {
                BuildRoom.ResourcesReservedFor = null;
            }

            Tree = new Sequence(new Select(new Domain(buildRoom.MeetsBuildRequirements() || buildRoom.ResourcesReservedFor != null, true),
                                           new Domain(!buildRoom.MeetsBuildRequirements() && (buildRoom.ResourcesReservedFor == null || buildRoom.ResourcesReservedFor == Agent), new Sequence(new Wrap(Reserve), new GetResourcesAct(Agent, Resources))),
                                           new Domain(buildRoom.MeetsBuildRequirements() || buildRoom.ResourcesReservedFor != null, true)),
                                new Domain(() => IsRoomBuildOrder(buildRoom) && !buildRoom.IsBuilt && !buildRoom.IsDestroyed && ValidResourceState(),
                                           new Sequence(
                                               SetTargetVoxelFromRoomAct(buildRoom, "ActionVoxel"),
                                               new GoToNamedVoxelAct("ActionVoxel", PlanAct.PlanType.Adjacent, Agent),
                                               new Wrap(PutResources),
                                               new Wrap(WaitForResources)
            {
                Name = "Wait for resources..."
            },
                                               new Wrap(() => Creature.HitAndWait(true, () => 1.0f, () => buildRoom.BuildProgress,
                                                                                  () => buildRoom.BuildProgress += agent.Stats.BuildSpeed / buildRoom.VoxelOrders.Count * 0.5f,
                                                                                  () => MathFunctions.RandVector3Box(buildRoom.GetBoundingBox()), ContentPaths.Audio.Oscar.sfx_ic_dwarf_craft, () => !buildRoom.IsBuilt && !buildRoom.IsDestroyed))
            {
                Name = "Build room.."
            },
                                               new CreateRoomAct(Agent, buildRoom)
                                               , new Wrap(OnFailOrCancel))) | new Wrap(OnFailOrCancel)
                                );
        }
Ejemplo n.º 2
0
        public override void Initialize()
        {
            var unreserveAct = new Wrap(UnReserve);
            var time         = 3 * (ItemType.BaseCraftTime / Creature.AI.Stats.Intelligence);
            var getResources = new Select(new Domain(() => Des.HasResources || Des.ResourcesReservedFor != null, true),
                                          new Domain(() => !Des.HasResources && (Des.ResourcesReservedFor == Agent || Des.ResourcesReservedFor == null),
                                                     new Sequence(
                                                         new Wrap(ReserveResources),
                                                         new GetResourcesOfApparentType(Agent, RawMaterials)
            {
                BlackboardEntry = "stashed-materials"
            })
                                                     | (new Wrap(UnReserve))
                                                     & false),
                                          new Domain(() => Des.HasResources || Des.ResourcesReservedFor != null, true));

            if (!String.IsNullOrEmpty(ItemType.CraftLocation))
            {
                Tree = new Sequence(
                    new Wrap(() => Creature.FindAndReserve(ItemType.CraftLocation, "craft-location")),
                    new ClearBlackboardData(Agent, "ResourcesStashed"),
                    getResources,
                    new Domain(ResourceStateValid,
                               new Sequence(
                                   ActHelper.CreateEquipmentCheckAct(Agent, "Tool", ActHelper.EquipmentFallback.AllowDefault, "Hammer"),
                                   new GoToTaggedObjectAct(Agent)
                {
                    Teleport             = true,
                    TeleportOffset       = new Vector3(0.5f, 0.0f, 0),
                    ObjectBlackboardName = "craft-location",
                    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,         // Max Progress
                                                                      () => Des.Progress, // Current Progress
                                                                      () =>
                {                                                                         // Increment Progress
                    var location = Creature.AI.Blackboard.GetData <GameComponent>(ItemType.CraftLocation);

                    float workstationBuff = 1.0f;
                    if (location != null)
                    {
                        Creature.Physics.Face(location.Position);
                        if (location.GetComponent <SteamPipes.BuildBuff>().HasValue(out var buff))
                        {
                            workstationBuff = buff.GetBuffMultiplier();
                        }
                    }

                    // Todo: Account for environment buff & 'anvil' buff.

                    Des.Progress += (Creature.Stats.BuildSpeed * workstationBuff) / ItemType.BaseCraftTime;
                },
Ejemplo n.º 3
0
        public override void Initialize()
        {
            Act   unreserveAct = new Wrap(UnReserve);
            float time         = 3 * (Item.ItemType.Placement_PlaceTime / Creature.AI.Stats.Intelligence);
            Act   getResources = null;

            getResources = new Select(
                new Domain(() => Item.HasResources || Item.SelectedResource != null,
                           new Always(Status.Success)),
                new Domain(() => !Item.HasResources && (Item.SelectedResource == null || Item.SelectedResource.ReservedFor == Agent || Item.SelectedResource.ReservedFor == null),
                           new Sequence(
                               new Select(
                                   new Sequence(
                                       new Wrap(LocateResources),
                                       new Wrap(AcquireResources)),
                                   new Wrap(UnReserve)),
                               new Always(Status.Fail))),
                new Domain(() => Item.SelectedResource != null && (Item.HasResources || Item.SelectedResource.ReservedFor != null),
                           new Always(Status.Success)));
            Act buildAct = null;

            buildAct = new Wrap(() => Creature.HitAndWait(true, () => 1.0f,
                                                          () => Item.Progress, () => Item.Progress += (Creature.Stats.BuildSpeed * 8) / Item.ItemType.Placement_PlaceTime, // Todo: Account for creature debuffs, environment buffs
                                                          () => Item.Location.WorldPosition + Vector3.One * 0.5f, "Craft"))
            {
                Name = "Construct object."
            };

            Tree = new Select(
                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 Wrap(FinallyPlaceObject)
            {
                Name = "Place the object."
            }))))),
                new Sequence(
                    new Wrap(Creature.RestockAll),
                    unreserveAct,
                    new Always(Status.Fail)));

            base.Initialize();
        }
Ejemplo n.º 4
0
        public override IEnumerable <Status> Run()
        {
            if (!Creature.Faction.WallBuilder.IsDesignation(Voxel))
            {
                yield return(Status.Fail);

                yield break;
            }

            foreach (Status status in Creature.HitAndWait(1.0f, true))
            {
                if (status == Status.Running)
                {
                    yield return(status);
                }
            }

            Body grabbed = Creature.Inventory.RemoveAndCreate(Resource).FirstOrDefault();

            if (grabbed == null)
            {
                yield return(Status.Fail);

                yield break;
            }
            else
            {
                if (Creature.Faction.WallBuilder.IsDesignation(Voxel))
                {
                    TossMotion motion = new TossMotion(1.0f, 2.0f, grabbed.LocalTransform, Voxel.Position + new Vector3(0.5f, 0.5f, 0.5f));
                    motion.OnComplete += grabbed.Die;
                    grabbed.AnimationQueue.Add(motion);

                    WallBuilder put = Creature.Faction.WallBuilder.GetDesignation(Voxel);
                    put.Put(PlayState.ChunkManager);


                    Creature.Faction.WallBuilder.Designations.Remove(put);
                    Creature.Stats.NumBlocksPlaced++;
                    Creature.AI.AddXP(1);
                    yield return(Status.Success);
                }
                else
                {
                    Creature.Inventory.Resources.AddItem(grabbed);
                    grabbed.Die();

                    yield return(Status.Fail);
                }
            }
        }
Ejemplo n.º 5
0
        public BuildRoomAct(CreatureAI agent, BuildRoomOrder buildRoom) :
            base(agent)
        {
            Name      = "Build BuildRoom " + buildRoom.ToString();
            Resources = buildRoom.ListRequiredResources();

            Tree = new Sequence(new GetResourcesAct(Agent, Resources),
                                new Sequence(
                                    new Wrap(() => IsRoomBuildOrder(buildRoom)),
                                    SetTargetVoxelFromRoomAct(buildRoom, "TargetVoxel"),
                                    new Wrap(() => IsRoomBuildOrder(buildRoom)),
                                    new GoToVoxelAct("TargetVoxel", PlanAct.PlanType.Adjacent, Agent),
                                    new Wrap(() => IsRoomBuildOrder(buildRoom)),
                                    new Wrap(() => Creature.HitAndWait(buildRoom.VoxelOrders.Count * 0.5f / agent.Stats.BuildSpeed, true)),
                                    new Wrap(() => IsRoomBuildOrder(buildRoom)),
                                    new PlaceRoomResourcesAct(Agent, buildRoom, Resources)
                                    , new Wrap(Creature.RestockAll)) | new Wrap(Creature.RestockAll)
                                );
        }
Ejemplo n.º 6
0
        public IEnumerable <Act.Status> DoMagicResearch()
        {
            var obj = Agent.Blackboard.GetData <Body>("Research");

            if (obj == null)
            {
                yield return(Act.Status.Fail);

                yield break;
            }

            float timer = 0;

            foreach (var status in Creature.HitAndWait(false, () => { return(10.0f); }, () => { return(timer); }, () => { timer++; }, () => { return(obj.Position); }, ContentPaths.Audio.Oscar.sfx_ic_dwarf_magic_research))
            {
                yield return(Act.Status.Running);
            }
            Creature.AI.AddXP(10);
            yield return(Act.Status.Success);
        }
Ejemplo n.º 7
0
        public IEnumerable <Act.Status> DoMagicResearch()
        {
            var obj = Agent.Blackboard.GetData <GameComponent>("training-object");

            if (obj == null)
            {
                Agent.SetMessage("Failed to find magical object for research purposes.");
                yield return(Act.Status.Fail);

                yield break;
            }

            float timer = 0;

            foreach (var status in Creature.HitAndWait(false, () => { return(10.0f); }, () => { return(timer); }, () => { timer++; }, () => { return(obj.Position); }, ContentPaths.Audio.Oscar.sfx_ic_dwarf_magic_research))
            {
                yield return(Act.Status.Running);
            }
            Creature.AI.AddXP(5);
            yield return(Act.Status.Success);
        }
Ejemplo n.º 8
0
        public override IEnumerable <Status> Run()
        {
            if (!Creature.Faction.Designations.IsVoxelDesignation(Location, DesignationType.Put))
            {
                yield return(Status.Success);

                yield break;
            }

            if (!Creature.Inventory.HasResource(Resource))
            {
                yield return(Status.Fail);
            }

            foreach (var status in Creature.HitAndWait(1.0f, true, () => Location.Coordinate.ToVector3() + Vector3.One * 0.5f))
            {
                if (!Creature.Faction.Designations.IsVoxelDesignation(Location, DesignationType.Put))
                {
                    yield return(Status.Success);

                    yield break;
                }
                if (status == Status.Running)
                {
                    yield return(status);
                }
            }

            var grabbed = Creature.Inventory.RemoveAndCreate(Resource,
                                                             Inventory.RestockType.Any).FirstOrDefault();

            if (grabbed == null)
            {
                yield return(Status.Fail);

                yield break;
            }
            else
            {
                if (Creature.Faction.Designations.IsVoxelDesignation(Location, DesignationType.Put))
                {
                    // If the creature intersects the box, find a voxel adjacent to it that is free, and jump there to avoid getting crushed.
                    if (Creature.Physics.BoundingBox.Intersects(Location.GetBoundingBox()))
                    {
                        var neighbors = VoxelHelpers.EnumerateAllNeighbors(Location.Coordinate)
                                        .Select(c => new VoxelHandle(Agent.Chunks.ChunkData, c));

                        var   closest     = VoxelHandle.InvalidHandle;
                        float closestDist = float.MaxValue;
                        foreach (var voxel in neighbors)
                        {
                            if (!voxel.IsValid)
                            {
                                continue;
                            }

                            float dist = (voxel.WorldPosition - Creature.Physics.Position).LengthSquared();
                            if (dist < closestDist && voxel.IsEmpty)
                            {
                                closestDist = dist;
                                closest     = voxel;
                            }
                        }

                        if (closest.IsValid)
                        {
                            TossMotion teleport = new TossMotion(0.5f, 1.0f, Creature.Physics.GlobalTransform, closest.WorldPosition + Vector3.One * 0.5f);
                            Creature.Physics.AnimationQueue.Add(teleport);
                        }
                    }
                    TossMotion motion = new TossMotion(1.0f, 2.0f, grabbed.LocalTransform, Location.Coordinate.ToVector3() + new Vector3(0.5f, 0.5f, 0.5f));
                    grabbed.GetRoot().GetComponent <Physics>().CollideMode = Physics.CollisionMode.None;
                    grabbed.AnimationQueue.Add(motion);


                    var put = Creature.Faction.Designations.GetVoxelDesignation(Location, DesignationType.Put) as short?;
                    if (!put.HasValue)
                    {
                        yield return(Status.Fail);

                        yield break;
                    }
                    var putType = VoxelLibrary.GetVoxelType(put.Value);

                    motion.OnComplete += () =>
                    {
                        grabbed.Die();
                        PlaceVoxel(Location, putType, Creature.Manager.World);

                        Creature.Faction.Designations.RemoveVoxelDesignation(Location, DesignationType.Put);
                        Creature.Stats.NumBlocksPlaced++;
                        Creature.AI.AddXP(1);
                    };

                    yield return(Status.Success);

                    yield break;
                }
                else
                {
                    Creature.Inventory.Pickup(grabbed, Inventory.RestockType.RestockResource);
                    grabbed.Die();

                    yield return(Status.Success);
                }
            }
        }
Ejemplo n.º 9
0
        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;
                    },
Ejemplo n.º 10
0
        public override void Initialize()
        {
            Act   unreserveAct = new Wrap(UnReserve);
            float time         = 3 * (Item.ItemType.BaseCraftTime / Creature.AI.Stats.BuffedInt);
            Act   getResources = null;

            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 Sequence(new Wrap(ReserveResources), new GetResourcesAct(Agent, Item.ItemType.RequiredResources))),
                                          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)
            {
                if (!String.IsNullOrEmpty(Item.ItemType.CraftLocation))
                {
                    Tree = new Domain(IsNotCancelled, new Sequence(
                                          new Wrap(() => Creature.FindAndReserve(Item.ItemType.CraftLocation, Item.ItemType.CraftLocation)),
                                          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(Item.Location.WorldPosition)),
                                                         new Wrap(WaitForResources)
                    {
                        Name = "Wait for resources."
                    },
                                                         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", null, true)),
                                                         new CreateCraftItemAct(Voxel, Creature.AI, Item))),
                                          unreserveAct
                                          ) | new Sequence(unreserveAct, new Wrap(Creature.RestockAll), false)
                                      ) | new Sequence(unreserveAct, false);
                }
                else
                {
                    Tree = new Domain(IsNotCancelled, new Sequence(
                                          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."
                    },
                                                                      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."
                    },
                                                                      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)),
                        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),
                                       new Wrap(Creature.RestockAll)
                                   )) | new Sequence(unreserveAct, new Wrap(Creature.RestockAll), false)
                        ) | new Sequence(unreserveAct, new Wrap(Creature.RestockAll), false);
                }
                else
                {
                    Tree = new Sequence(
                        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))
                                   )
                        ) | new Sequence(unreserveAct, new Wrap(Creature.RestockAll), false);
                }
            }
            base.Initialize();
        }
Ejemplo n.º 11
0
        public override void Initialize()
        {
            Act   unreserveAct = new Wrap(() => Creature.Unreserve(ItemType.CraftLocation));
            float time         = ItemType.BaseCraftTime / Creature.AI.Stats.BuffedInt;
            Act   getResources = null;

            if (ItemType.SelectedResources == null || ItemType.SelectedResources.Count == 0)
            {
                getResources = new GetResourcesAct(Agent, ItemType.RequiredResources);
            }
            else
            {
                getResources = new GetResourcesAct(Agent, ItemType.SelectedResources);
            }

            if (ItemType.Type == CraftItem.CraftType.Object)
            {
                Tree = new Sequence(
                    new Wrap(() => Creature.FindAndReserve(ItemType.CraftLocation, ItemType.CraftLocation)),
                    getResources,
                    new Sequence
                    (
                        new GoToTaggedObjectAct(Agent)
                {
                    Tag            = ItemType.CraftLocation,
                    Teleport       = false,
                    TeleportOffset = new Vector3(1, 0, 0),
                    ObjectName     = ItemType.CraftLocation
                },
                        new Wrap(() => Creature.HitAndWait(time, true, Creature.AI.Position)),
                        new Wrap(DestroyResources),
                        unreserveAct,
                        new GoToVoxelAct(Voxel, PlanAct.PlanType.Adjacent, Agent),
                        new CreateCraftItemAct(Voxel, Creature.AI, ItemType.Name)
                    ) | new Sequence(unreserveAct, new Wrap(Creature.RestockAll), false)
                    ) | new Sequence(unreserveAct, false);
            }
            else
            {
                Tree = new Sequence(
                    new Wrap(() => Creature.FindAndReserve(ItemType.CraftLocation, ItemType.CraftLocation)),
                    getResources,
                    new Sequence
                    (
                        new GoToTaggedObjectAct(Agent)
                {
                    Tag            = ItemType.CraftLocation,
                    Teleport       = false,
                    TeleportOffset = new Vector3(1, 0, 0),
                    ObjectName     = ItemType.CraftLocation
                },
                        new Wrap(() => Creature.HitAndWait(time, true, Agent.Position)),
                        new Wrap(DestroyResources),
                        unreserveAct,
                        new Wrap(CreateResources),
                        new Wrap(Creature.RestockAll)
                    ) | new Sequence(unreserveAct, new Wrap(Creature.RestockAll), false)
                    ) | new Sequence(unreserveAct, false);
            }
            base.Initialize();
        }
Ejemplo n.º 12
0
        public override IEnumerable <Status> Run()
        {
            foreach (var res in Agent.Blackboard.GetData <List <Resource> >(ResourceBlackboardName))
            {
                if (!Creature.Inventory.Contains(res))
                {
                    yield return(Status.Fail);
                }
            }

            foreach (var status in Creature.HitAndWait(1.0f, true, () => Location.Coordinate.ToVector3() + Vector3.One * 0.5f))
            {
                if (status == Status.Running)
                {
                    yield return(status);
                }
            }

            foreach (var res in Agent.Blackboard.GetData <List <Resource> >(ResourceBlackboardName))
            {
                var grabbed = Creature.Inventory.RemoveAndCreate(res, Inventory.RestockType.Any);

                if (grabbed == null)
                {
                    yield return(Status.Fail);

                    yield break;
                }
                else
                {
                    // If the creature intersects the box, find a voxel adjacent to it that is free, and jump there to avoid getting crushed.
                    if (Creature.Physics.BoundingBox.Intersects(Location.GetBoundingBox()))
                    {
                        var neighbors = VoxelHelpers.EnumerateAllNeighbors(Location.Coordinate)
                                        .Select(c => new VoxelHandle(Agent.World.ChunkManager, c));

                        var closest     = VoxelHandle.InvalidHandle;
                        var closestDist = float.MaxValue;
                        foreach (var voxel in neighbors)
                        {
                            if (!voxel.IsValid)
                            {
                                continue;
                            }

                            float dist = (voxel.WorldPosition - Creature.Physics.Position).LengthSquared();
                            if (dist < closestDist && voxel.IsEmpty)
                            {
                                closestDist = dist;
                                closest     = voxel;
                            }
                        }

                        if (closest.IsValid)
                        {
                            TossMotion teleport = new TossMotion(0.5f, 1.0f, Creature.Physics.GlobalTransform, closest.WorldPosition + Vector3.One * 0.5f);
                            Creature.Physics.AnimationQueue.Add(teleport);
                        }
                    }

                    // Todo: Shitbox - what happens if the player saves while this animation is in progress?? How is the OnComplete restored?
                    var motion = new TossMotion(1.0f, 2.0f, grabbed.LocalTransform, Location.Coordinate.ToVector3() + new Vector3(0.5f, 0.5f, 0.5f));
                    if (grabbed.GetRoot().GetComponent <Physics>().HasValue(out var grabbedPhysics))
                    {
                        grabbedPhysics.CollideMode = Physics.CollisionMode.None;
                    }
                    grabbed.AnimationQueue.Add(motion);

                    motion.OnComplete += () => grabbed.Die();
                }

                if (Library.GetVoxelType(VoxelType).HasValue(out var vType))
                {
                    PlaceVoxel(Location, vType, Creature.Manager.World);
                }

                Creature.Stats.NumBlocksPlaced++;
                Creature.AI.AddXP(1);

                yield return(Status.Success);

                yield break;
            }
        }
Ejemplo n.º 13
0
        public override IEnumerable <Status> Run()
        {
            if (!Creature.Faction.WallBuilder.IsDesignation(Voxel))
            {
                yield return(Status.Fail);

                yield break;
            }

            foreach (Status status in Creature.HitAndWait(1.0f, true, Voxel.Position))
            {
                if (status == Status.Running)
                {
                    yield return(status);
                }
            }

            Body grabbed = Creature.Inventory.RemoveAndCreate(Resource).FirstOrDefault();

            if (grabbed == null)
            {
                yield return(Status.Fail);

                yield break;
            }
            else
            {
                if (Creature.Faction.WallBuilder.IsDesignation(Voxel))
                {
                    // If the creature intersects the box, find a voxel adjacent to it that is free, and jump there to avoid getting crushed.
                    if (Creature.Physics.BoundingBox.Intersects(Voxel.GetBoundingBox()))
                    {
                        List <Voxel> neighbors   = Voxel.Chunk.GetNeighborsEuclidean(Voxel);
                        Voxel        closest     = null;
                        float        closestDist = float.MaxValue;
                        foreach (Voxel voxel in neighbors)
                        {
                            float dist = (voxel.Position - Creature.Physics.Position).LengthSquared();
                            if (dist < closestDist && voxel.IsEmpty)
                            {
                                closestDist = dist;
                                closest     = voxel;
                            }
                        }

                        if (closest != null)
                        {
                            TossMotion teleport = new TossMotion(0.5f, 1.0f, Creature.Physics.GlobalTransform, closest.Position + Vector3.One * 0.5f);
                            Creature.Physics.AnimationQueue.Add(teleport);
                        }
                    }
                    TossMotion motion = new TossMotion(1.0f, 2.0f, grabbed.LocalTransform, Voxel.Position + new Vector3(0.5f, 0.5f, 0.5f));
                    motion.OnComplete += grabbed.Die;
                    grabbed.GetComponent <Physics>().CollideMode = Physics.CollisionMode.None;
                    grabbed.AnimationQueue.Add(motion);

                    WallBuilder put = Creature.Faction.WallBuilder.GetDesignation(Voxel);
                    put.Put(Creature.Manager.World.ChunkManager);


                    Creature.Faction.WallBuilder.Designations.Remove(put);
                    Creature.Stats.NumBlocksPlaced++;
                    Creature.AI.AddXP(1);
                    yield return(Status.Success);
                }
                else
                {
                    Creature.Inventory.Resources.AddItem(grabbed);
                    grabbed.Die();

                    yield return(Status.Fail);
                }
            }
        }