예제 #1
0
 public void SetRootComponent(GameComponent Component)
 {
     RootComponent = Component;
 }
예제 #2
0
 public ParticleTrigger(string emitter, ComponentManager manager, string name, GameComponent parent, Matrix localTransform, Vector3 boundingBoxExtents, Vector3 boundingBoxPos) :
     base(name, parent, localTransform, boundingBoxExtents, boundingBoxPos, false)
 {
     SoundToPlay     = ContentPaths.Audio.explode;
     EmitterName     = emitter;
     TriggerOnDeath  = true;
     TriggerAmount   = 2;
     BoxTriggerTimes = 10;
     TriggerInBox    = true;
 }
예제 #3
0
        public static void GenerateCaveVegetation(VoxelChunk chunk, int x, int y, int z, int caveHeight, BiomeData biome, Vector3 vec, WorldManager world, Perlin NoiseGenerator)
        {
            var vUnder   = new VoxelHandle(chunk, new LocalVoxelCoordinate(x, y - 1, z));
            var wayUnder = new VoxelHandle(chunk, new LocalVoxelCoordinate(x, y - caveHeight, z));

            wayUnder.RawSetType(VoxelLibrary.GetVoxelType(biome.SoilLayer.VoxelType));

            wayUnder.RawSetGrass(GrassLibrary.GetGrassType(biome.GrassDecal).ID);
            foreach (VegetationData veg in biome.Vegetation)
            {
                if (!MathFunctions.RandEvent(veg.SpawnProbability))
                {
                    continue;
                }

                if (NoiseGenerator.Noise(vec.X / veg.ClumpSize, veg.NoiseOffset, vec.Y / veg.ClumpSize) < veg.ClumpThreshold)
                {
                    continue;
                }

                if (!vUnder.IsEmpty && vUnder.Type.Name == biome.SoilLayer.VoxelType)
                {
                    vUnder.RawSetType(VoxelLibrary.GetVoxelType(biome.SoilLayer.VoxelType));
                    vUnder.RawSetGrass(0);
                    float treeSize = MathFunctions.Rand() * veg.SizeVariance + veg.MeanSize;

                    WorldManager.DoLazy(() =>
                    {
                        if (!GameSettings.Default.FogofWar)
                        {
                            GameComponent entity = EntityFactory.CreateEntity <GameComponent>(veg.Name,
                                                                                              vUnder.WorldPosition + new Vector3(0.5f, 1.0f, 0.5f),
                                                                                              Blackboard.Create("Scale", treeSize));
                        }
                        else
                        {
                            world.ComponentManager.RootComponent.AddChild(new ExploredListener(
                                                                              world.ComponentManager, vUnder)
                            {
                                EntityToSpawn  = veg.Name,
                                SpawnLocation  = vUnder.WorldPosition + new Vector3(0.5f, 1.0f, 0.5f),
                                BlackboardData = Blackboard.Create("Scale", treeSize)
                            });
                        }
                    });
                }
            }

            foreach (FaunaData animal in biome.Fauna)
            {
                if (y <= 0 || !(MathFunctions.Random.NextDouble() < animal.SpawnProbability))
                {
                    continue;
                }

                FaunaData animal1 = animal;
                WorldManager.DoLazy(() =>
                {
                    if (!GameSettings.Default.FogofWar)
                    {
                        var entity = EntityFactory.CreateEntity <GameComponent>(animal1.Name,
                                                                                wayUnder.WorldPosition + Vector3.Up * 1.5f);
                    }
                    else
                    {
                        world.ComponentManager.RootComponent.AddChild(new ExploredListener
                                                                          (world.ComponentManager, new VoxelHandle(chunk, wayUnder.Coordinate.GetLocalVoxelCoordinate()))
                        {
                            EntityToSpawn = animal1.Name,
                            SpawnLocation = wayUnder.WorldPosition + Vector3.Up * 1.5f
                        });
                    }
                });
                break;
            }
        }
예제 #4
0
 public bool CanMove(GameComponent entity)
 {
     return(entity.Tags.Contains("Moveable") && !entity.IsReserved);
 }
예제 #5
0
 public GreedyPathAct(CreatureAI creature, GameComponent target, float threshold)
     : base(creature)
 {
     Target    = target;
     Threshold = threshold;
 }
예제 #6
0
 public void body_onDestroyed(GameComponent body)
 {
     ZoneBodies.Remove(body);
 }
예제 #7
0
        public TradeEnvoy SendTradeEnvoy()
        {
            if (!World.EnumerateZones().Any(room => room is BalloonPort && room.IsBuilt))
            {
                World.MakeAnnouncement(String.Format("Trade envoy from {0} left: No balloon port!", ParentFaction.Name));
                SoundManager.PlaySound(ContentPaths.Audio.Oscar.sfx_gui_negative_generic, 0.15f);
                return(null);
            }

            if (Race.HasValue(out var race))
            {
                TradeEnvoy envoy = null;

                var creatures = World.MonsterSpawner.Spawn(World.MonsterSpawner.GenerateSpawnEvent(this, World.PlayerFaction, MathFunctions.Random.Next(4) + 1, false));


                envoy = new TradeEnvoy(World.Time.CurrentDate)
                {
                    Creatures    = creatures,
                    OtherFaction = World.PlayerFaction,
                    ShouldRemove = false,
                    OwnerFaction = this,
                    TradeGoods   = ParentFaction.IsCorporate ? new ResourceSet() : (Race.HasValue(out var _race) ? _race.GenerateTradeItems(World) : new ResourceSet()),
                    TradeMoney   = new DwarfBux((decimal)MathFunctions.Rand(race.MinCash, race.MaxCash))
                };

                if (race.IsNative)
                {
                    if (Economy == null)
                    {
                        Economy = new Company(this, 1000.0m, new CompanyInformation()
                        {
                            Name = ParentFaction.Name
                        });
                    }

                    foreach (CreatureAI creature in envoy.Creatures)
                    {
                        creature.Physics.AddChild(new ResourcePack(World.ComponentManager));
                        creature.Physics.AddChild(new Flag(World.ComponentManager, Vector3.Up * 0.5f + Vector3.Backward * 0.25f, Economy.Information, new Resource("Flag")));
                    }
                }
                else
                {
                    GameComponent balloon = null;

                    var rooms = World.EnumerateZones().Where(room => room.Type.Name == "Balloon Port").ToList();

                    if (rooms.Count != 0)
                    {
                        var pos = rooms.First().GetBoundingBox().Center();
                        balloon = Balloon.CreateBalloon(pos + new Vector3(0, 1000, 0), pos + Vector3.UnitY * 15, World.ComponentManager, this);
                    }

                    if (balloon != null)
                    {
                        foreach (CreatureAI creature in creatures)
                        {
                            var tf = creature.Physics.LocalTransform;
                            tf.Translation = balloon.LocalTransform.Translation;
                            creature.Physics.LocalTransform = tf;
                        }
                    }
                    else
                    {
                        if (Economy == null)
                        {
                            Economy = new Company(this, 1000.0m, new CompanyInformation()
                            {
                                Name = ParentFaction.Name
                            });
                        }

                        foreach (CreatureAI creature in envoy.Creatures)
                        {
                            creature.Physics.AddChild(new ResourcePack(World.ComponentManager));
                            creature.Physics.AddChild(new Flag(World.ComponentManager, Vector3.Up * 0.5f + Vector3.Backward * 0.25f, Economy.Information, new Resource("Flag")));
                        }
                    }
                }

                foreach (CreatureAI creature in envoy.Creatures)
                {
                    creature.Physics.AddChild(new ResourcePack(World.ComponentManager));
                }

                envoy.DistributeGoods();
                TradeEnvoys.Add(envoy);

                World.MakeAnnouncement(new DwarfCorp.Gui.Widgets.QueuedAnnouncement
                {
                    Text        = String.Format("Trade envoy from {0} has arrived!", ParentFaction.Name),
                    ClickAction = (gui, sender) =>
                    {
                        if (envoy.Creatures.Count > 0)
                        {
                            envoy.Creatures.First().ZoomToMe();
                            World.UserInterface.MakeWorldPopup(String.Format("Traders from {0} ({1}) have entered our territory.\nThey will try to get to our balloon port to trade with us.", ParentFaction.Name, race.Name),
                                                               envoy.Creatures.First().Physics, -10);
                        }
                    },
                    ShouldKeep = () => envoy.ExpiditionState == Expedition.State.Arriving
                });

                SoundManager.PlaySound(ContentPaths.Audio.Oscar.sfx_gui_positive_generic, 0.15f);

                World.Tutorial("trade");

                if (!String.IsNullOrEmpty(race.TradeMusic))
                {
                    SoundManager.PlayMusic(race.TradeMusic);
                }

                return(envoy);
            }
            else
            {
                return(null);
            }
        }
예제 #8
0
        public FireballProjectile(ComponentManager manager, Vector3 position, Vector3 initialVelocity, GameComponent target) :
            base(manager, position, initialVelocity, new Health.DamageAmount() { Amount = 15.0f, DamageType = Health.DamageType.Fire }, 0.25f, ContentPaths.Particles.fireball, "flame", ContentPaths.Audio.Oscar.sfx_ic_demon_fire_hit_1, target)
        {
            Sprite.LightsWithVoxels  = false;
            Sprite2.LightsWithVoxels = false;

            HitAnimation = Library.CreateSimpleAnimation(ContentPaths.Effects.pierce);
        }
예제 #9
0
        public override IEnumerable <Act.Status> Run()
        {
            List <ResourceAmount> foods =
                Agent.Creature.Inventory.GetResources(new Quantitiy <Resource.ResourceTags>(Resource.ResourceTags.Edible), Inventory.RestockType.Any);

            if (foods.Count == 0 && Agent.Creature.Faction == Agent.World.PlayerFaction)
            {
                Agent.SetMessage("Failed to eat. No food in inventory.");
                yield return(Act.Status.Fail);

                yield break;
            }

            FoodBody = null;
            Timer eatTimer = new Timer(3.0f, true);

            foreach (ResourceAmount resourceAmount in foods)
            {
                if (resourceAmount.Count > 0)
                {
                    List <GameComponent> bodies = Agent.Creature.Inventory.RemoveAndCreate(new ResourceAmount(resourceAmount.Type, 1),
                                                                                           Inventory.RestockType.Any);
                    var resource = Library.GetResourceType(resourceAmount.Type);
                    Agent.Creature.NoiseMaker.MakeNoise("Chew", Agent.Creature.AI.Position);
                    if (bodies.Count == 0)
                    {
                        Agent.SetMessage("Failed to eat. No food in inventory.");
                        yield return(Act.Status.Fail);
                    }
                    else
                    {
                        FoodBody = bodies[0];

                        while (!eatTimer.HasTriggered)
                        {
                            eatTimer.Update(DwarfTime.LastTime);
                            Matrix rot = Agent.Creature.Physics.LocalTransform;
                            rot.Translation         = Vector3.Zero;
                            FoodBody.LocalTransform = Agent.Creature.Physics.LocalTransform;
                            Vector3 foodPosition = Agent.Creature.Physics.Position + Vector3.Up * 0.05f + Vector3.Transform(Vector3.Forward, rot) * 0.5f;
                            FoodBody.LocalPosition = foodPosition;
                            FoodBody.PropogateTransforms();
                            FoodBody.Active = false;
                            Agent.Creature.Physics.Velocity     = Vector3.Zero;
                            Agent.Creature.CurrentCharacterMode = CharacterMode.Sitting;
                            if (MathFunctions.RandEvent(0.05f))
                            {
                                Agent.Creature.World.ParticleManager.Trigger("crumbs", foodPosition, Color.White, 3);
                            }
                            yield return(Act.Status.Running);
                        }

                        Agent.Creature.Stats.Hunger.CurrentValue += resource.FoodContent;

                        if (resource.Tags.Contains(Resource.ResourceTags.Alcohol))
                        {
                            Agent.Creature.AddThought("I had good ale recently.", new TimeSpan(0, 8, 0, 0), 10.0f);
                        }
                        else
                        {
                            Agent.Creature.AddThought("I ate good food recently.", new TimeSpan(0, 8, 0, 0), 5.0f);
                        }

                        FoodBody.GetRoot().Delete();

                        if (MustPay)
                        {
                            var depositAct = new DepositMoney(Agent, resource.MoneyValue);
                            foreach (var result in depositAct.Run())
                            {
                                if (result == Status.Running)
                                {
                                    yield return(result);
                                }
                            }
                        }

                        yield return(Act.Status.Success);
                    }
                    yield break;
                }
            }
        }
예제 #10
0
        public IEnumerable <Status> TrackMovingTarget()
        {
            while (true)
            {
                // This is to support the case of going from one entity to another.
                if (_entity != null)
                {
                    Entity = _entity;
                }
                Creature.AI.Blackboard.Erase("EntityVoxel");
                Act.Status    status = SetTargetVoxelFromEntityAct.SetTarget("EntityVoxel", EntityName, Creature);
                GameComponent entity = Agent.Blackboard.GetData <GameComponent>(EntityName);

                if (entity == null || entity.IsDead)
                {
                    yield return(Status.Success);

                    yield break;
                }

                if (status != Status.Success)
                {
                    yield return(Act.Status.Running);
                }
                List <MoveAction> existingPath =
                    Creature.AI.Blackboard.GetData <List <MoveAction> >("PathToEntity");

                Creature.AI.Blackboard.Erase("PathToEntity");

                PlanWithGreedyFallbackAct planAct = new PlanWithGreedyFallbackAct()
                {
                    Agent    = Creature.AI,
                    PathName = "PathToEntity", VoxelName = "EntityVoxel", PlanType = PlanType, Radius = Radius, MaxTimeouts = 1
                };
                planAct.Initialize();

                bool planSucceeded = false;
                while (true)
                {
                    Act.Status planStatus = planAct.Tick();
                    LastTickedChild = planAct;
                    if (planStatus == Status.Fail)
                    {
                        yield return(Act.Status.Running);

                        break;
                    }

                    else if (planStatus == Status.Running)
                    {
                        yield return(Act.Status.Running);
                    }

                    else if (planStatus == Status.Success)
                    {
                        planSucceeded = true;
                        break;
                    }
                }

                if (!planSucceeded)
                {
                    Agent.SetMessage("Failed to reach entity. Path planning failed.");
                    yield return(Act.Status.Fail);

                    yield break;
                }

                FollowPathAct followPath = new FollowPathAct(Creature.AI, "PathToEntity")
                {
                    //BlendEnd = true,
                    //BlendStart = existingPath == null
                };
                followPath.Initialize();

                while (true)
                {
                    if (PlanType == PlanAct.PlanType.Radius && (Creature.Physics.Position - entity.Position).Length() < Radius)
                    {
                        yield return(Act.Status.Success);
                    }

                    Act.Status pathStatus = followPath.Tick();
                    LastTickedChild = followPath;
                    if (pathStatus == Status.Fail)
                    {
                        break;
                    }

                    else if (pathStatus == Status.Running)
                    {
                        yield return(Act.Status.Running);

                        List <MoveAction> path = Agent.Blackboard.GetData <List <MoveAction> >("PathToEntity");
                        if (path == null || path.Count == 0)
                        {
                            Agent.SetMessage("Failed to find path to entity.");
                            yield return(Act.Status.Fail);

                            yield break;
                        }
                        var under = VoxelHelpers.FindFirstVoxelBelowIncludingWater(new VoxelHandle(entity.World.ChunkManager, GlobalVoxelCoordinate.FromVector3(entity.Position)));

                        bool targetMoved = under == VoxelHandle.InvalidHandle || (path.Last().DestinationVoxel.WorldPosition - under.WorldPosition).Length() > Math.Max(Radius, 2) * 2;

                        if (MovingTarget && (path.Count > 0 && targetMoved))
                        {
                            break;
                        }

                        if (MovingTarget && (Creature.Physics.Position - entity.Position).Length() < 2)
                        {
                            yield return(Status.Success);

                            yield break;
                        }

                        continue;
                    }

                    else if (pathStatus == Status.Success)
                    {
                        yield return(Act.Status.Success);

                        yield break;
                    }
                }

                yield return(Act.Status.Running);
            }
        }
예제 #11
0
 public LightEmitter(string name, GameComponent parent, Matrix localTransform, Vector3 boundingBoxExtents, Vector3 boundingBoxPos, float intensity, float range) :
     base(parent.Manager, name, parent, localTransform, boundingBoxExtents, boundingBoxPos)
 {
     Light = new DynamicLight(intensity, range);
 }
예제 #12
0
        public override void Construct()
        {
            Border      = "border-one";
            Font        = "font10";
            OnConstruct = (sender) =>
            {
                sender.Root.RegisterForUpdate(sender);

                AddChild(new Widget
                {
                    AutoLayout         = AutoLayout.DockBottom,
                    MinimumSize        = new Point(0, 32),
                    Text               = "CLOSE",
                    ChangeColorOnHover = true,
                    OnClick            = (sender1, args) => sender.Close()
                });

                ComponentProperties = AddChild(new Widget
                {
                    AutoLayout  = AutoLayout.DockBottom,
                    MinimumSize = new Point(0, 128),
                });

                ListView = AddChild(new WidgetListView
                {
                    AutoLayout = AutoLayout.DockFill,
                    SelectedItemForegroundColor = new Vector4(0, 0, 0, 1),
                    ChangeColorOnSelected       = false,
                    Border     = null,
                    ItemHeight = 24
                }) as WidgetListView;

                ListView.Border = null; // Can't make WidgetListView stop defaulting its border without breaking everywhere else its used.
            };

            OnUpdate = (sender, time) =>
            {
                if (sender.Hidden)
                {
                    return;
                }
                if (SelectedEntity == null)
                {
                    SelectedComponent = null;
                    ListView.ClearItems();
                    return;
                }

                var components = SelectedEntity.EnumerateAll();

                int i = 0;
                ListView.ClearItems();
                foreach (var component in components)
                {
                    i++;
                    var tag        = component.GuiTag as Widget;
                    var lambdaCopy = component;

                    if (tag != null)
                    {
                        ListView.AddItem(tag);
                    }
                    else
                    {
                        #region Create gui row

                        tag = Root.ConstructWidget(new Widget
                        {
                            Text              = component.GetType().Name,
                            MinimumSize       = new Point(0, 16),
                            Padding           = new Margin(0, 0, 4, 4),
                            TextVerticalAlign = VerticalAlign.Center,
                            Tag = lambdaCopy
                        });

                        tag.OnClick = (sender1, args) =>
                        {
                            if (tag.IsAnyParentHidden())
                            {
                                return;
                            }
                            SelectedComponent = lambdaCopy;
                        };

                        #endregion

                        component.GuiTag = tag;
                        ListView.AddItem(tag);
                    }
                }

                ListView.Invalidate();

                if (SelectedComponent != null)
                {
                    Drawer3D.DrawBox(SelectedComponent.GetBoundingBox(), Color.White, 0.1f, true);
                    ComponentProperties.Text = SelectedComponent.GetType().Name
                                               + "\n" + SelectedComponent.Position.ToString()
                                               + "\nBB Extents: " + SelectedComponent.BoundingBoxSize.ToString()
                                               + "\nBB Offset: " + SelectedComponent.LocalBoundingBoxOffset.ToString();
                }
                else
                {
                    ComponentProperties.Text = "";
                }
            };

            base.Construct();
        }
예제 #13
0
        public static bool IsValidPlacement(
            VoxelHandle Location,
            CraftItem CraftType,
            WorldManager World,
            GameComponent PreviewBody,
            String Verb,
            String PastParticple)
        {
            if (CraftType == null)
            {
                return(false);
            }

            if (!String.IsNullOrEmpty(CraftType.CraftLocation) &&
                World.PlayerFaction.FindNearestItemWithTags(CraftType.CraftLocation, Location.WorldPosition, false, null) == null)
            {
                World.UserInterface.ShowTooltip("Can't " + Verb + ", need " + CraftType.CraftLocation);
                return(false);
            }

            foreach (var req in CraftType.Prerequisites)
            {
                switch (req)
                {
                case CraftItem.CraftPrereq.NearWall:
                {
                    var neighborFound = VoxelHelpers.EnumerateManhattanNeighbors2D(Location.Coordinate)
                                        .Select(c => new VoxelHandle(World.ChunkManager, c))
                                        .Any(v => v.IsValid && !v.IsEmpty);

                    if (!neighborFound)
                    {
                        World.UserInterface.ShowTooltip("Must be " + PastParticple + " next to wall!");
                        return(false);
                    }

                    break;
                }

                case CraftItem.CraftPrereq.OnGround:
                {
                    var below = VoxelHelpers.GetNeighbor(Location, new GlobalVoxelOffset(0, -1, 0));

                    if (!below.IsValid || below.IsEmpty)
                    {
                        World.UserInterface.ShowTooltip("Must be " + PastParticple + " on solid ground!");
                        return(false);
                    }
                    break;
                }
                }
            }

            if (PreviewBody != null)
            {
                // Just check for any intersecting body in octtree.

                var previewBox = PreviewBody.GetRotatedBoundingBox();
                var sensorBox  = previewBox;
                var sensor     = PreviewBody.GetComponent <GenericVoxelListener>();
                if (sensor != null)
                {
                    sensorBox = sensor.GetRotatedBoundingBox();
                }
                if (Debugger.Switches.DrawToolDebugInfo)
                {
                    Drawer3D.DrawBox(sensorBox, Color.Yellow, 0.1f, false);
                }

                foreach (var intersectingObject in World.EnumerateIntersectingObjects(sensorBox, CollisionType.Static))
                {
                    if (Object.ReferenceEquals(intersectingObject, sensor))
                    {
                        continue;
                    }
                    var objectRoot = intersectingObject.GetRoot() as GameComponent;
                    if (objectRoot is WorkPile)
                    {
                        continue;
                    }
                    if (objectRoot == PreviewBody)
                    {
                        continue;
                    }
                    if (objectRoot != null && objectRoot.GetRotatedBoundingBox().Intersects(previewBox))
                    {
                        World.UserInterface.ShowTooltip("Can't " + Verb + " here: intersects " + objectRoot.Name);
                        return(false);
                    }
                }

                bool intersectsWall = VoxelHelpers.EnumerateCoordinatesInBoundingBox
                                          (PreviewBody.GetRotatedBoundingBox().Expand(-0.1f)).Any(
                    v =>
                {
                    var tvh = new VoxelHandle(World.ChunkManager, v);
                    return(tvh.IsValid && !tvh.IsEmpty);
                });
                var  current    = new VoxelHandle(World.ChunkManager, GlobalVoxelCoordinate.FromVector3(PreviewBody.Position));
                bool underwater = current.IsValid && current.LiquidType != LiquidType.None;
                if (underwater)
                {
                    World.UserInterface.ShowTooltip("Can't " + Verb + " here: underwater or in lava.");
                    return(false);
                }
                if (intersectsWall && !CraftType.Prerequisites.Contains(CraftItem.CraftPrereq.NearWall))
                {
                    World.UserInterface.ShowTooltip("Can't " + Verb + " here: intersects wall.");
                    return(false);
                }
            }
            World.UserInterface.ShowTooltip("");
            return(true);
        }
예제 #14
0
        public Projectile(ComponentManager manager, Vector3 position, Vector3 initialVelocity, Health.DamageAmount damage, float size, string asset, string hitParticles, string hitNoise, GameComponent target, bool animated = false, bool singleSprite = false) :
            base(manager, "Projectile", Matrix.CreateTranslation(position), new Vector3(size, size, size), Vector3.One, 1.0f, 1.0f, 1.0f, 1.0f, new Vector3(0, -10, 0), OrientMode.Fixed)
        {
            this.AllowPhysicsSleep = false;
            Target       = target;
            HitAnimation = null;
            IsSleeping   = false;
            Velocity     = initialVelocity;
            Orientation  = OrientMode.LookAt;
            CollideMode  = Physics.CollisionMode.None;
            var spriteSheet = new SpriteSheet(asset);

            if (animated)
            {
                spriteSheet.FrameWidth  = Math.Min(spriteSheet.FrameWidth, spriteSheet.FrameHeight);
                spriteSheet.FrameHeight = spriteSheet.FrameWidth;
            }

            // Todo: Needs the cosmetic children treatement.
            if (animated)
            {
                Sprite = AddChild(new AnimatedSprite(Manager, "Sprite", Matrix.CreateRotationY((float)Math.PI * 0.5f))
                {
                    OrientationType = AnimatedSprite.OrientMode.Fixed
                }) as AnimatedSprite;

                var anim = Library.CreateSimpleAnimation(asset);
                anim.Loops = true;
                (Sprite as AnimatedSprite).AddAnimation(anim);

                if (singleSprite)
                {
                    (Sprite as AnimatedSprite).OrientationType = AnimatedSprite.OrientMode.Spherical;
                }
            }
            else
            {
                Sprite = AddChild(new SimpleSprite(Manager, "Sprite", Matrix.CreateRotationY((float)Math.PI * 0.5f), spriteSheet, new Point(0, 0))
                {
                    OrientationType = SimpleSprite.OrientMode.Fixed
                }) as SimpleSprite;
                (Sprite as SimpleSprite).AutoSetWorldSize();
                if (singleSprite)
                {
                    (Sprite as SimpleSprite).OrientationType = SimpleSprite.OrientMode.Spherical;
                }
            }

            Sprite.SetFlag(Flag.ShouldSerialize, false);

            if (!singleSprite)
            {
                if (animated)
                {
                    Sprite2 = Sprite.AddChild(new AnimatedSprite(Manager, "Sprite2",
                                                                 Matrix.CreateRotationY((float)Math.PI * 0.5f) * Matrix.CreateRotationZ((float)Math.PI * 0.5f))
                    {
                        OrientationType = AnimatedSprite.OrientMode.Fixed
                    }) as AnimatedSprite;

                    var anim = Library.CreateSimpleAnimation(asset);
                    anim.Loops = true;
                    (Sprite2 as AnimatedSprite).AddAnimation(anim);
                }
                else
                {
                    Sprite2 = AddChild(new SimpleSprite(Manager, "Sprite", Matrix.CreateRotationY((float)Math.PI * 0.5f) * Matrix.CreateRotationZ((float)Math.PI * 0.5f), spriteSheet, new Point(0, 0))
                    {
                        OrientationType = SimpleSprite.OrientMode.Fixed
                    }) as SimpleSprite;
                    (Sprite2 as SimpleSprite).AutoSetWorldSize();
                }
                Sprite2.SetFlag(Flag.ShouldSerialize, false);
            }

            Damage       = damage;
            HitParticles = AddChild(new ParticleTrigger(hitParticles, manager, "Hit Particles",
                                                        Matrix.Identity, new Vector3(size * 0.5f, size * 0.5f, size * 0.5f), Vector3.Zero)
            {
                TriggerOnDeath  = true,
                SoundToPlay     = hitNoise,
                BoxTriggerTimes = 2
            }) as ParticleTrigger;
            DamageRadius = (float)Math.Pow(size * 4, 2);
        }
예제 #15
0
 public virtual void ComponentDestroyed(GameComponent C) { }
예제 #16
0
 public virtual bool AddItem(GameComponent component)
 {
     return(Resources.AddItem(component));
 }
예제 #17
0
 public void AddBody(GameComponent body)
 {
     ZoneBodies.Add(body);
     body.OnDestroyed += () => body_onDestroyed(body);
 }
예제 #18
0
 public Grabber(string name, GameComponent parent, Matrix localTrans, Vector3 boundingboxExtents, Vector3 boundingBoxCenter) :
     base(name, parent, localTrans, boundingboxExtents, boundingBoxCenter, false)
 {
     GrabbedComponents = new List <GrabbedItem>();
     MaxGrabs          = 1;
 }
예제 #19
0
        public void CheckSurroundings(GameComponent Body, DwarfTime gameTime, ChunkManager chunks)
        {
            if (Heat > Flashpoint)
            {
                var insideBodies = World.EnumerateIntersectingObjects(Body.GetBoundingBox());

                foreach (var body in insideBodies.Where(b => b != Parent && b.Active && b.Parent == Manager.RootComponent))
                {
                    if (body.GetComponent <Flammable>().HasValue(out var flames))
                    {
                        flames.Heat += 100;
                    }
                }

                SoundManager.PlaySound(ContentPaths.Audio.fire, Body.Position, true);
            }

            float expansion = Heat > Flashpoint ? 1.0f : 0.0f;

            foreach (var coordinate in VoxelHelpers.EnumerateCoordinatesInBoundingBox(Body.BoundingBox.Expand(expansion)))
            {
                var voxel = new VoxelHandle(chunks, coordinate);
                if (!voxel.IsValid)
                {
                    continue;
                }

                if (Heat > Flashpoint && MathFunctions.RandEvent(0.5f))
                {
                    if (voxel.Type.IsFlammable)
                    {
                        if (MathFunctions.RandEvent(0.1f))
                        {
                            var existingItems = World.EnumerateIntersectingObjects(voxel.GetBoundingBox().Expand(-0.1f));


                            if (!existingItems.Any(e => e is Fire))
                            {
                                EntityFactory.CreateEntity <Fire>("Fire", voxel.GetBoundingBox().Center());
                            }
                            SoundManager.PlaySound(ContentPaths.Audio.Oscar.sfx_env_lava_spread, voxel.GetBoundingBox().Center(), true, 1.0f);
                            VoxelHelpers.KillVoxel(World, voxel);
                        }
                    }

                    if (voxel.GrassType != 0x0)
                    {
                        if (MathFunctions.RandEvent(0.1f))
                        {
                            var box = voxel.GetBoundingBox().Expand(-0.1f);
                            box.Min += Vector3.One; // Todo: Why shifting one on every axis?
                            box.Max += Vector3.One;
                            if (!World.EnumerateIntersectingObjects(box).Any(e => e is Fire))
                            {
                                EntityFactory.CreateEntity <Fire>("Fire", box.Center());
                            }
                        }

                        if (MathFunctions.RandEvent(0.5f))
                        {
                            SoundManager.PlaySound(ContentPaths.Audio.Oscar.sfx_env_lava_spread, voxel.GetBoundingBox().Center(), true, 1.0f);
                            voxel.GrassType = 0x0;
                        }
                    }
                }

                if (voxel.LiquidLevel <= 0)
                {
                    continue;
                }
                if (voxel.LiquidType == LiquidType.Lava)
                {
                    Heat += 100.0f;
                }
                else if (voxel.LiquidType == LiquidType.Water)
                {
                    Heat = Heat * 0.25f;
                }
            }
        }
예제 #20
0
 public void SetTarget(GameComponent targt)
 {
     Agent.Blackboard.SetData(TargetName, targt);
 }
예제 #21
0
파일: Box.cs 프로젝트: NakedFury/dwarfcorp
 public Box(ComponentManager manager, string name, GameComponent parent, Matrix localTransform, Vector3 boundingBoxExtents, Vector3 boundingBoxPos, string primitive, Texture2D tex) :
     base(name, parent, localTransform, boundingBoxExtents, boundingBoxPos, false)
 {
     Primitive = primitive;
     Texture   = tex;
 }
예제 #22
0
        public void GenerateCaves(VoxelChunk chunk)
        {
            Vector3      origin     = chunk.Origin;
            int          chunkSizeX = chunk.SizeX;
            int          chunkSizeY = chunk.SizeY;
            int          chunkSizeZ = chunk.SizeZ;
            BiomeData    biome      = BiomeLibrary.Biomes[Overworld.Biome.Cave];
            List <Voxel> neighbors  = new List <Voxel>();
            Voxel        vUnder     = chunk.MakeVoxel(0, 0, 0);

            for (int x = 0; x < chunkSizeX; x++)
            {
                for (int z = 0; z < chunkSizeZ; z++)
                {
                    int h = chunk.GetFilledVoxelGridHeightAt(x, chunk.SizeY - 1, z);
                    for (int i = 0; i < CaveLevels.Count; i++)
                    {
                        int y = CaveLevels[i];
                        if (y <= 0 || y >= h - 1)
                        {
                            continue;
                        }
                        Vector3 vec       = new Vector3(x, y, z) + chunk.Origin;
                        double  caveNoise = CaveNoise.GetValue((x + origin.X) * CaveNoiseScale * CaveFrequencies[i],
                                                               (y + origin.Y) * CaveNoiseScale * 3.0f, (z + origin.Z) * CaveNoiseScale * CaveFrequencies[i]);

                        double heightnoise = NoiseGenerator.Noise((x + origin.X) * NoiseScale * CaveFrequencies[i],
                                                                  (y + origin.Y) * NoiseScale * 3.0f, (z + origin.Z) * NoiseScale * CaveFrequencies[i]);

                        int caveHeight = Math.Min(Math.Max((int)(heightnoise * 5), 1), 3);

                        if (caveNoise > CaveSize)
                        {
                            bool waterFound = false;
                            for (int dy = 0; dy < caveHeight; dy++)
                            {
                                int index = chunk.Data.IndexAt(x, y - dy, z);
                                chunk.GetNeighborsManhattan(x, y - dy, z, neighbors);

                                if (neighbors.Any(v => v.WaterLevel > 0))
                                {
                                    waterFound = true;
                                }

                                if (waterFound)
                                {
                                    break;
                                }

                                chunk.Data.Types[index] = 0;
                            }

                            if (!waterFound && caveNoise > CaveSize * 1.8f && y - caveHeight > 0)
                            {
                                int indexunder = chunk.Data.IndexAt(x, y - caveHeight, z);
                                chunk.Data.Types[indexunder]      = (byte)VoxelLibrary.GetVoxelType(biome.GrassVoxel).ID;
                                chunk.Data.Health[indexunder]     = (byte)VoxelLibrary.GetVoxelType(biome.GrassVoxel).StartingHealth;
                                chunk.Data.IsExplored[indexunder] = false;
                                foreach (VegetationData veg in biome.Vegetation)
                                {
                                    if (!MathFunctions.RandEvent(veg.SpawnProbability))
                                    {
                                        continue;
                                    }

                                    if (NoiseGenerator.Noise(vec.X / veg.ClumpSize, veg.NoiseOffset, vec.Y / veg.ClumpSize) < veg.ClumpThreshold)
                                    {
                                        continue;
                                    }


                                    vUnder.GridPosition = new Vector3(x, y - 1, z);
                                    if (!vUnder.IsEmpty && vUnder.TypeName == biome.GrassVoxel)
                                    {
                                        vUnder.Type = VoxelLibrary.GetVoxelType(biome.SoilVoxel);
                                        float offset = veg.VerticalOffset;
                                        if (vUnder.RampType != RampType.None)
                                        {
                                            offset -= 0.25f;
                                        }
                                        float         treeSize = MathFunctions.Rand() * veg.SizeVariance + veg.MeanSize;
                                        GameComponent entity   = EntityFactory.CreateEntity <GameComponent>(veg.Name, chunk.Origin + new Vector3(x, y, z) + new Vector3(0, treeSize * offset, 0), Blackboard.Create("Scale", treeSize));
                                        entity.GetRootComponent().SetActiveRecursive(false);
                                        entity.GetRootComponent().SetVisibleRecursive(false);
                                        if (GameSettings.Default.FogofWar)
                                        {
                                            ExploredListener listener = new ExploredListener(
                                                PlayState.ComponentManager, entity, PlayState.ChunkManager, vUnder);
                                        }
                                    }
                                }
                            }

                            foreach (FaunaData animal in biome.Fauna)
                            {
                                if (y <= 0 || !(PlayState.Random.NextDouble() < animal.SpawnProbability))
                                {
                                    continue;
                                }


                                var entity = EntityFactory.CreateEntity <GameComponent>(animal.Name, chunk.Origin + new Vector3(x, y, z) + Vector3.Up * 1.0f);
                                entity.GetRootComponent().SetActiveRecursive(false);
                                entity.GetRootComponent().SetVisibleRecursive(false);

                                if (GameSettings.Default.FogofWar)
                                {
                                    ExploredListener listener = new ExploredListener(PlayState.ComponentManager, entity,
                                                                                     PlayState.ChunkManager, chunk.MakeVoxel(x, y, z));
                                }
                                break;
                            }
                        }
                    }
                }
            }
        }
예제 #23
0
        public override IEnumerable <Status> Run()
        {
            Creature.IsCloaked = false;

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

                yield break;
            }

            Timeout.Reset();
            FailTimer.Reset();
            if (Target == null && TargetName != null)
            {
                Target = Agent.Blackboard.GetData <GameComponent>(TargetName);

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

                    yield break;
                }
            }

            if (Agent.Faction.Race.IsIntelligent)
            {
                var targetInventory = Target.GetRoot().GetComponent <Inventory>();
                if (targetInventory != null)
                {
                    targetInventory.SetLastAttacker(Agent);
                }
            }

            CharacterMode defaultCharachterMode = Creature.AI.Movement.CanFly
                ? CharacterMode.Flying
                : CharacterMode.Walking;

            bool avoided = false;

            while (true)
            {
                Timeout.Update(DwarfTime.LastTime);
                FailTimer.Update(DwarfTime.LastTime);
                if (FailTimer.HasTriggered)
                {
                    Creature.Physics.Orientation   = Physics.OrientMode.RotateY;
                    Creature.OverrideCharacterMode = false;
                    Creature.CurrentCharacterMode  = defaultCharachterMode;
                    yield return(Status.Fail);

                    yield break;
                }

                if (Timeout.HasTriggered)
                {
                    if (Training)
                    {
                        Agent.AddXP(1);
                        Creature.Physics.Orientation   = Physics.OrientMode.RotateY;
                        Creature.OverrideCharacterMode = false;
                        Creature.CurrentCharacterMode  = defaultCharachterMode;
                        yield return(Status.Success);

                        yield break;
                    }
                    else
                    {
                        Creature.Physics.Orientation   = Physics.OrientMode.RotateY;
                        Creature.OverrideCharacterMode = false;
                        Creature.CurrentCharacterMode  = defaultCharachterMode;
                        yield return(Status.Fail);

                        yield break;
                    }
                }

                if (Target == null || Target.IsDead)
                {
                    Creature.CurrentCharacterMode = defaultCharachterMode;
                    Creature.Physics.Orientation  = Physics.OrientMode.RotateY;
                    yield return(Status.Success);
                }

                // Find the location of the melee target
                Vector3 targetPos = new Vector3(Target.GlobalTransform.Translation.X,
                                                Target.GetBoundingBox().Min.Y,
                                                Target.GlobalTransform.Translation.Z);

                Vector2 diff = new Vector2(targetPos.X, targetPos.Z) - new Vector2(Creature.AI.Position.X, Creature.AI.Position.Z);

                Creature.Physics.Face(targetPos);

                bool  intersectsbounds = Creature.Physics.BoundingBox.Intersects(Target.BoundingBox);
                float dist             = diff.Length();
                // If we are really far from the target, something must have gone wrong.
                if (DefensiveStructure == null && !intersectsbounds && dist > CurrentAttack.Weapon.Range * 4)
                {
                    Creature.Physics.Orientation   = Physics.OrientMode.RotateY;
                    Creature.OverrideCharacterMode = false;
                    Creature.CurrentCharacterMode  = defaultCharachterMode;
                    yield return(Status.Fail);

                    yield break;
                }

                if (DefensiveStructure != null)
                {
                    if (Creature.Hp < LastHp)
                    {
                        float damage = LastHp - Creature.Hp;
                        Creature.Heal(Math.Min(5.0f, damage));
                        var health = DefensiveStructure.GetRoot().GetComponent <Health>();
                        if (health != null)
                        {
                            health.Damage(damage);
                            Drawer2D.DrawLoadBar(health.World.Renderer.Camera, DefensiveStructure.Position, Color.White, Color.Black, 32, 1, health.Hp / health.MaxHealth, 0.1f);
                        }
                        LastHp = Creature.Hp;
                    }

                    if (dist > CurrentAttack.Weapon.Range)
                    {
                        float sqrDist = dist * dist;
                        foreach (var threat in Creature.AI.Faction.Threats)
                        {
                            float threatDist = (threat.AI.Position - Creature.AI.Position).LengthSquared();
                            if (threatDist < sqrDist)
                            {
                                sqrDist = threatDist;
                                Target  = threat.Physics;
                                break;
                            }
                        }
                        dist = (float)Math.Sqrt(sqrDist);
                    }

                    if (dist > CurrentAttack.Weapon.Range * 4)
                    {
                        yield return(Status.Fail);

                        yield break;
                    }

                    if (DefensiveStructure.IsDead)
                    {
                        DefensiveStructure = null;
                    }
                }

                LastHp = Creature.Hp;


                // If we're out of attack range, run toward the target.
                if (DefensiveStructure == null && !Creature.AI.Movement.IsSessile && !intersectsbounds && diff.Length() > CurrentAttack.Weapon.Range)
                {
                    Creature.CurrentCharacterMode = defaultCharachterMode;
                    var greedyPath = new GreedyPathAct(Creature.AI, Target, CurrentAttack.Weapon.Range * 0.75f)
                    {
                        PathLength = 5
                    };
                    greedyPath.Initialize();

                    foreach (Act.Status stat in greedyPath.Run())
                    {
                        if (stat == Act.Status.Running)
                        {
                            yield return(Status.Running);
                        }
                        else
                        {
                            break;
                        }
                    }
                }
                // If we have a ranged weapon, try avoiding the target for a few seconds to get within range.
                else if (DefensiveStructure == null && !Creature.AI.Movement.IsSessile && !intersectsbounds && !avoided && (CurrentAttack.Weapon.Mode == Weapon.AttackMode.Ranged &&
                                                                                                                            dist < CurrentAttack.Weapon.Range * 0.15f))
                {
                    FailTimer.Reset();
                    foreach (Act.Status stat in AvoidTarget(CurrentAttack.Weapon.Range, 3.0f))
                    {
                        yield return(Status.Running);
                    }
                    avoided = true;
                }
                // Else, stop and attack
                else if ((DefensiveStructure == null && dist < CurrentAttack.Weapon.Range) ||
                         (DefensiveStructure != null && dist < CurrentAttack.Weapon.Range * 2.0))
                {
                    if (CurrentAttack.Weapon.Mode == Weapon.AttackMode.Ranged &&
                        VoxelHelpers.DoesRayHitSolidVoxel(Creature.World.ChunkManager, Creature.AI.Position, Target.Position))
                    {
                        yield return(Status.Fail);

                        yield break;
                    }

                    FailTimer.Reset();
                    avoided = false;
                    Creature.Physics.Orientation = Physics.OrientMode.Fixed;
                    Creature.Physics.Velocity    = new Vector3(Creature.Physics.Velocity.X * 0.9f, Creature.Physics.Velocity.Y, Creature.Physics.Velocity.Z * 0.9f);
                    CurrentAttack.RechargeTimer.Reset(CurrentAttack.Weapon.RechargeRate);

                    Creature.Sprite.ResetAnimations(Creature.Stats.CurrentClass.AttackMode);
                    Creature.Sprite.PlayAnimations(Creature.Stats.CurrentClass.AttackMode);
                    Creature.CurrentCharacterMode  = Creature.Stats.CurrentClass.AttackMode;
                    Creature.OverrideCharacterMode = true;
                    Timer timeout = new Timer(10.0f, true);
                    while (!CurrentAttack.Perform(Creature, Target, DwarfTime.LastTime, Creature.Stats.Strength + Creature.Stats.Size,
                                                  Creature.AI.Position, Creature.Faction.ParentFaction.Name))
                    {
                        timeout.Update(DwarfTime.LastTime);
                        if (timeout.HasTriggered)
                        {
                            break;
                        }

                        Creature.Physics.Velocity = new Vector3(Creature.Physics.Velocity.X * 0.9f, Creature.Physics.Velocity.Y, Creature.Physics.Velocity.Z * 0.9f);
                        if (Creature.AI.Movement.CanFly)
                        {
                            Creature.Physics.ApplyForce(-Creature.Physics.Gravity * 0.1f, DwarfTime.Dt);
                        }
                        yield return(Status.Running);
                    }

                    timeout.Reset();
                    while (!Agent.Creature.Sprite.AnimPlayer.IsDone())
                    {
                        timeout.Update(DwarfTime.LastTime);
                        if (timeout.HasTriggered)
                        {
                            break;
                        }
                        if (Creature.AI.Movement.CanFly)
                        {
                            Creature.Physics.ApplyForce(-Creature.Physics.Gravity * 0.1f, DwarfTime.Dt);
                        }
                        yield return(Status.Running);
                    }

                    var targetCreature = Target.GetRoot().GetComponent <CreatureAI>();
                    if (targetCreature != null && Creature.AI.FightOrFlight(targetCreature) == CreatureAI.FightOrFlightResponse.Flee)
                    {
                        yield return(Act.Status.Fail);

                        yield break;
                    }
                    Creature.CurrentCharacterMode = CharacterMode.Attacking;

                    Vector3 dogfightTarget = Vector3.Zero;
                    while (!CurrentAttack.RechargeTimer.HasTriggered && !Target.IsDead)
                    {
                        CurrentAttack.RechargeTimer.Update(DwarfTime.LastTime);
                        if (CurrentAttack.Weapon.Mode == Weapon.AttackMode.Dogfight)
                        {
                            dogfightTarget += MathFunctions.RandVector3Cube() * 0.1f;
                            Vector3 output = Creature.Controller.GetOutput(DwarfTime.Dt, dogfightTarget + Target.Position, Creature.Physics.GlobalTransform.Translation) * 0.9f;
                            Creature.Physics.ApplyForce(output - Creature.Physics.Gravity, DwarfTime.Dt);
                        }
                        else
                        {
                            Creature.Physics.Velocity = Vector3.Zero;
                            if (Creature.AI.Movement.CanFly)
                            {
                                Creature.Physics.ApplyForce(-Creature.Physics.Gravity, DwarfTime.Dt);
                            }
                        }
                        yield return(Status.Running);
                    }

                    Creature.CurrentCharacterMode = defaultCharachterMode;
                    Creature.Physics.Orientation  = Physics.OrientMode.RotateY;

                    if (Target.IsDead)
                    {
                        Target = null;
                        Agent.AddXP(10);
                        Creature.Physics.Face(Creature.Physics.Velocity + Creature.Physics.GlobalTransform.Translation);
                        Creature.Stats.NumThingsKilled++;
                        Creature.AddThought("I killed somehing!", new TimeSpan(0, 8, 0, 0), 1.0f);
                        Creature.Physics.Orientation   = Physics.OrientMode.RotateY;
                        Creature.OverrideCharacterMode = false;
                        Creature.CurrentCharacterMode  = defaultCharachterMode;
                        yield return(Status.Success);

                        break;
                    }
                }

                yield return(Status.Running);
            }
        }
예제 #24
0
        public void DoDamage(Creature performer, GameComponent other, float bonus)
        {
            if (!String.IsNullOrEmpty(Weapon.DiseaseToSpread))
            {
                if (other.GetRoot().GetComponent <Creature>().HasValue(out var otherCreature))
                {
                    var disease = DiseaseLibrary.GetDisease(Weapon.DiseaseToSpread);
                    if (disease != null)
                    {
                        if (MathFunctions.RandEvent(disease.LikelihoodOfSpread))
                        {
                            otherCreature.Stats.AcquireDisease(disease);
                        }
                    }
                }
            }

            var health = other.GetRoot().EnumerateAll().OfType <Health>().FirstOrDefault();

            if (health != null)
            {
                health.Damage(Weapon.DamageAmount + bonus);
                var injury = DiseaseLibrary.GetRandomInjury();

                if (MathFunctions.RandEvent(injury.LikelihoodOfSpread))
                {
                    if (other.GetRoot().GetComponent <Creature>().HasValue(out var creature))
                    {
                        creature.Stats.AcquireDisease(injury);
                    }
                }

                Vector3 knock = other.Position - performer.Physics.Position;
                knock.Normalize();
                knock *= 0.2f;
                if (other.AnimationQueue.Count == 0)
                {
                    other.AnimationQueue.Add(new KnockbackAnimation(0.15f, other.LocalTransform, knock));
                }
            }
            else
            {
                other.GetRoot().Die();
            }

            PlayNoise(other.GlobalTransform.Translation);
            if (Weapon.HitParticles != "")
            {
                performer.Manager.World.ParticleManager.Trigger(Weapon.HitParticles, other.LocalTransform.Translation, Color.White, 5);

                if (Weapon.ShootLaser)
                {
                    performer.Manager.World.ParticleManager.TriggerRay(Weapon.HitParticles, performer.AI.Position, other.LocalTransform.Translation);
                }
            }

            if (Weapon.HitAnimation != null)
            {
                IndicatorManager.DrawIndicator(Weapon.HitAnimation, other.BoundingBox.Center(), 10.0f, 1.0f, MathFunctions.RandVector2Circle(), Color.White, MathFunctions.Rand() > 0.5f);
            }

            Physics physics = other as Physics;

            if (physics != null)
            {
                Vector3 force = other.Position - performer.AI.Position;

                if (force.LengthSquared() > 0.01f)
                {
                    force.Normalize();
                    physics.ApplyForce(force * Weapon.Knockback, 1.0f);
                }
            }
        }
예제 #25
0
        public override Feasibility IsFeasible(Creature agent)
        {
            GameComponent closestItem = agent.Faction.FindNearestItemWithTags("Bed", agent.AI.Position, true, agent.AI);

            return((closestItem != null && !agent.AI.Stats.Health.IsSatisfied()) || agent.AI.Stats.Health.IsCritical() ? Feasibility.Feasible : Feasibility.Infeasible);
        }
예제 #26
0
        public bool Perform(Creature performer, GameComponent other, DwarfTime time, float bonus, Vector3 pos, string faction)
        {
            if (!performer.Sprite.AnimPlayer.HasValidAnimation() ||
                performer.Sprite.AnimPlayer.CurrentFrame != Weapon.TriggerFrame)
            {
                HasTriggered = false;
                return(false);
            }

            if (HasTriggered)
            {
                return(true);
            }

            HasTriggered = true;
            switch (Weapon.Mode)
            {
            case Weapon.AttackMode.Melee:
            case Weapon.AttackMode.Dogfight:
            {
                DoDamage(performer, other, bonus);
                break;
            }

            case Weapon.AttackMode.Area:
            {
                var box = new BoundingBox(performer.AI.Position - Vector3.One * Weapon.Range, performer.AI.Position + Vector3.One * Weapon.Range);

                foreach (var body in performer.World.EnumerateIntersectingObjects(box, CollisionType.Both).Where(b => b.IsRoot()))
                {
                    if (body.GetRoot().GetComponent <CreatureAI>().HasValue(out var creature))
                    {
                        if (creature.Faction == performer.Faction)
                        {
                            continue;
                        }

                        if (performer.World.Overworld.GetPolitics(creature.Faction.ParentFaction, performer.Faction.ParentFaction).GetCurrentRelationship() != Relationship.Hateful)
                        {
                            continue;
                        }

                        DoDamage(performer, body, bonus);
                    }
                    else
                    {
                        if (body.GetRoot().GetComponent <Health>().HasValue(out var health))
                        {
                            DoDamage(performer, body, bonus);
                        }

                        continue;
                    }
                }
                break;
            }

            case Weapon.AttackMode.Ranged:
            {
                PlayNoise(other.GlobalTransform.Translation);
                LaunchProjectile(pos, other.Position, other);

                var injury = DiseaseLibrary.GetRandomInjury();

                if (MathFunctions.RandEvent(injury.LikelihoodOfSpread))
                {
                    if (other.GetRoot().GetComponent <Creature>().HasValue(out var creature))
                    {
                        creature.Stats.AcquireDisease(injury);
                    }
                }
                break;
            }
            }

            return(true);
        }
예제 #27
0
        public Body FindNearestItemWithTags(string tag, Vector3 location, bool filterReserved, GameComponent queryObject)
        {
            Body  closestItem = null;
            float closestDist = float.MaxValue;

            foreach (Body i in OwnedObjects)
            {
                if (i == null || i.IsDead || (i.IsReserved && filterReserved && i.ReservedFor != queryObject) || !(i.Tags.Any(t => tag == t)))
                {
                    continue;
                }
                float d = (i.GlobalTransform.Translation - location).LengthSquared();
                if (!(d < closestDist))
                {
                    continue;
                }
                closestDist = d;
                closestItem = i;
            }

            return(closestItem);
        }
예제 #28
0
 public virtual void ComponentCreated(GameComponent C) { }
예제 #29
0
        public KillEntityAct(GameComponent entity, CreatureAI creature) :
            base(creature)
        {
            Entity = entity;
            Name   = "Kill Entity";

            // Get the closest structure that we might defend from.
            closestDefensiveStructure = creature.Faction.OwnedObjects.Where(b => !b.IsReserved && b.Tags.Contains("Defensive")).OrderBy(b => (b.Position - Entity.Position).LengthSquared()).FirstOrDefault();

            // Do not attempt to defend from faraway structures
            if (closestDefensiveStructure != null)
            {
                float distToStructure = (closestDefensiveStructure.Position - creature.Position).Length();
                float distToEntity    = (Entity.Position - creature.Position).Length();

                if (distToStructure > 1.5f * distToEntity || distToStructure > 12.0f)
                {
                    closestDefensiveStructure = null;
                }
            }

            PlanAct.PlanType planType = PlanAct.PlanType.Adjacent;
            float            radius   = 0.0f;

            if (creature.Creature.Attacks[0].Weapon.Mode == Weapon.AttackMode.Ranged)
            {
                planType = PlanAct.PlanType.Radius;
                radius   = creature.Creature.Attacks[0].Weapon.Range;
            }

            if (creature.Movement.IsSessile)
            {
                Tree =
                    new Domain(() => Verify(creature),
                               new Sequence
                               (
                                   new AttackAct(Agent, entity)
                               ) | new Wrap(() => OnAttackEnd(creature))
                               );
            }
            else
            {
                if (creature.Creature.Attacks[0].Weapon.Mode != Weapon.AttackMode.Ranged ||
                    closestDefensiveStructure == null || (closestDefensiveStructure.Position - creature.Position).Length() > 20.0f)
                {
                    Tree =
                        new Domain(() => Verify(creature),
                                   new Sequence
                                   (
                                       new GoToEntityAct(entity, creature)
                    {
                        MovingTarget = true,
                        PlanType     = planType,
                        Radius       = radius
                    } | new Wrap(() => OnAttackEnd(creature)),
                                       new AttackAct(Agent, entity),
                                       new Wrap(() => OnAttackEnd(creature))
                                   ));
                }
                else
                {
                    closestDefensiveStructure.ReservedFor = creature;
                    Tree =
                        new Domain(() => Verify(creature),
                                   new Sequence
                                   (
                                       new GoToEntityAct(closestDefensiveStructure, creature)
                    {
                        PlanType = PlanAct.PlanType.Into,
                    } | new Wrap(() => OnAttackEnd(creature)),
                                       new TeleportAct(Creature.AI)
                    {
                        Location = closestDefensiveStructure.GetRotatedBoundingBox().Center(), Type = TeleportAct.TeleportType.Lerp
                    },
                                       new AttackAct(Agent, entity)
                    {
                        DefensiveStructure = closestDefensiveStructure
                    },
                                       new Wrap(() => OnAttackEnd(creature))
                                   ));
                }
            }
        }
예제 #30
0
 public void RemoveComponent(GameComponent component)
 {
     RemovalMutex.WaitOne();
     Removals.Add(component);
     RemovalMutex.ReleaseMutex();
 }