Example #1
0
        public override void Update()
        {
            foreach (AttackerProperty attacker in attackers.Values)
            {
                // Prüfen, ob überhaupt ein Ziel existiert
                if (attacker.AttackTarget == null)
                {
                    continue;
                }

                AttackableProperty attackable = attacker.AttackTarget;

                if (Item.GetDistance(attacker.Item, attackable.Item) <=
                    attacker.AttackRange + attackable.AttackableRadius)
                {
                    // Zum ersten mal im Angriffsbereich
                    if (!attackable.AttackerItems.Contains(attacker))
                    {
                        attackable.AddAttackerItem(attacker);
                        attacker.RecoveryCounter = 0;
                    }
                    else
                    {
                        // Mit jeder weiteren Runde im Angriffsradius lädt der Recovery Counter.
                        attacker.RecoveryCounter++;
                    }

                    // Informiere Attackable über einen Angreifer
                    attackable.NoteAttackerItem(attacker);

                    // Angriff
                    if (attacker.RecoveryCounter >= attacker.AttackRecoveryTime)
                    {
                        int hitpoints = attacker.AttackStrength;
                        attackable.AttackableHealth -= hitpoints;
                        attackable.AttackerHit(attacker, hitpoints);
                        attacker.AttackHit(attackable, hitpoints);
                        attacker.RecoveryCounter = -1;
                    }
                }
                else
                {
                    // Vorher im Angriffsbereich gewesen?
                    if (attackable.AttackerItems.Contains(attacker))
                    {
                        attackable.RemoveAttackerItem(attacker);
                    }
                }
            }

            // Tote Elemente aussortieren
            foreach (AttackableProperty attackable in attackables.Values)
            {
                if (attackable.AttackableHealth <= 0)
                {
                    attackable.Kill();
                    Engine.RemoveItem(attackable.Item);
                }
            }
        }
Example #2
0
        public override void Remove(Item item)
        {
            // Entferne angreifbares Objekt
            if (item.ContainsProperty <AttackableProperty>() &&
                attackables.ContainsKey(item.Id))
            {
                // Angriffe auf ein entferntes Element stoppen
                AttackableProperty attackable = attackables[item.Id];
                foreach (AttackerProperty attacker in attackers.Values)
                {
                    if (attacker.AttackTarget == attackable)
                    {
                        attacker.StopAttack();
                    }
                }

                // entfernen
                attackables.Remove(item.Id);
            }

            // Entferne angreifendes Objekt
            if (item.ContainsProperty <AttackerProperty>() &&
                attackers.ContainsKey(item.Id))
            {
                // Angriffe stoppen
                AttackerProperty attacker = attackers[item.Id];
                attacker.StopAttack();

                // entfernen
                attackers.Remove(item.Id);
            }
        }
Example #3
0
        public DebugAttackableItem(ITypeResolver resolver, Vector2 pos)
            : base(resolver, pos, Angle.Right)
        {
            attackable = new AttackableProperty(this, 5, 100, 100);

            AddProperty(attackable);
        }
        public DebugAttackableItem(ITypeResolver resolver, Vector2 pos)
            : base(resolver, pos, Angle.Right)
        {
            attackable = new AttackableProperty(this, 5, 100, 100);

            AddProperty(attackable);
        }
Example #5
0
 public AnthillItem(SimulationContext context, AntFaction faction, Vector2 position)
     : base(context, faction, position, HillRadius, Angle.Right)
 {
     var attackable = new AttackableProperty(this);
     if (attackable != null)
     {
         attackable.OnAttackableHealthChanged += (item, value) =>
         {
             // Sollten die Hitpoints unter 0 kommen, ist der Ameisenhügel zerstört
             if (value <= 0)
                 Engine.RemoveItem(this);
         };
     }
 }
Example #6
0
        public AnthillItem(SimulationContext context, AntFaction faction, Vector2 position)
            : base(context, faction, position, HillRadius, Angle.Right)
        {
            var attackable = new AttackableProperty(this);

            if (attackable != null)
            {
                attackable.OnAttackableHealthChanged += (item, value) =>
                {
                    // Sollten die Hitpoints unter 0 kommen, ist der Ameisenhügel zerstört
                    if (value <= 0)
                    {
                        Engine.RemoveItem(this);
                    }
                };
            }
        }
 /// <summary>
 /// Internal call to perform a hit.
 /// </summary>
 /// <param name="item">Attacked Item</param>
 /// <param name="hitpoints">Hitpoints</param>
 internal void AttackHit(AttackableProperty item, int hitpoints)
 {
     if (OnAttackHit != null)
         OnAttackHit(item.Item, hitpoints);
 }
        /// <summary>
        /// Attacks the given Item.
        /// </summary>
        /// <param name="item">Item</param>
        public void Attack(AttackableProperty item)
        {
            // Handling des alten Ziels
            if (AttackTarget != null)
            {
                // Ziel ändert sich nicht - alles gut
                if (AttackTarget == item)
                    return;

                // Altes Ziel entfernen
                StopAttack();
            }

            // Neues Ziel - Counter muss resettet werden
            RecoveryCounter = 0;

            // Prüfen, ob Attacker Teil der Simulation ist
            if (Item.Engine == null)
                throw new NotSupportedException("Attacker is not Part of the Simulation");

            // Prüfen, ob Attackable Teil der Simulation ist
            if (item.Item.Engine == null || item.Item.Engine != Item.Engine)
                throw new NotSupportedException("Attackable is not Part of the same Simulation");

            // Prüfen, ob sich das Element gerade selbst angreifen will
            if (item.Item == Item)
                throw new NotSupportedException("Item can not attack itself");

            // Ziel einfügen
            AttackTarget = item;
        }
 private void InitAttackableItem(Vector2 pos)
 {
     AttackableItem = new DebugAttackableItem(pos);
     Attackable = AttackableItem.GetProperty<AttackableProperty>();
     Engine.InsertItem(AttackableItem);
 }
 public void CleanupEngine()
 {
     AttackerItem = null;
     AttackableItem = null;
     CollectorItem = null;
     CollectableItem = null;
     Attacker = null;
     Attackable = null;
     Collector = null;
     Collectable = null;
     Map = null;
     Engine = null;
 }
Example #11
0
        /// <summary>
        /// Default Constructor for the Type Mapper.
        /// </summary>
        /// <param name="faction">Faction</param>
        /// <param name="item">Item</param>
        /// <param name="interop">UnitInterop</param>
        public InteractionInterop(Faction faction, FactionItem item, UnitInterop interop) : base(faction, item, interop)
        {
            #region Collector

            sugar = item.GetProperty <SugarCollectorProperty>();
            if (sugar == null)
            {
                throw new ArgumentException("Item does not contain SugarCollector");
            }

            apple = item.GetProperty <AppleCollectorProperty>();
            if (apple == null)
            {
                throw new ArgumentException("Item does not contain AppleCollector");
            }

            #endregion

            #region Carrier

            carrier = item.GetProperty <CarrierProperty>();
            if (carrier == null)
            {
                throw new ArgumentException("Item does not contain CarrierProperty");
            }

            #endregion

            #region Attackable

            attackable = item.GetProperty <AttackableProperty>();
            if (attackable == null)
            {
                throw new ArgumentException("Item does not contain AttackableProperty");
            }

            attackable.OnKill += i =>
            {
                if (OnKill != null)
                {
                    OnKill();
                }
            };

            attackable.OnAttackerHit += (i, value) =>
            {
                if (OnHit != null)
                {
                    OnHit(value);
                }
            };

            attackable.OnNewAttackerItem += i =>
            {
                var info = Item.GetItemInfo(i.Item);

                if (!attackerItems.Contains(info))
                {
                    attackerItems.Add(info);
                }
            };

            attackable.OnLostAttackerItem += i =>
            {
                var info = Item.GetItemInfo(i.Item);

                if (attackerItems.Contains(info))
                {
                    attackerItems.Remove(info);
                }
            };

            #endregion

            #region Attacker

            attacker = item.GetProperty <AttackerProperty>();
            if (attacker == null)
            {
                throw new ArgumentException("Item does not contain AttackerProperty");
            }

            #endregion

            // Automatic Resource Transfer on Anthill Collision.
            var collidable = item.GetProperty <CollidableProperty>();
            if (collidable == null)
            {
                throw new ArgumentException("Item does not contain AttackerProperty");
            }

            collidable.OnCollision += (i, value) =>
            {
                // Ignore if it's not a Anthill
                if (!(value is AnthillItem))
                {
                    return;
                }

                var anthill = value as AnthillItem;

                // Ignore if it's not the right faction
                if (anthill.Faction != item.Faction)
                {
                    return;
                }

                // Transfer all collectables
                Give(anthill);
            };
        }
Example #12
0
        /// <summary>
        /// Registers Ants
        /// </summary>
        /// <param name="typeMapper">Type Mapper</param>
        /// <param name="settings">Settings</param>
        private void RegisterAnt(ITypeMapper typeMapper, KeyValueStore settings)
        {
            // Ant Item
            settings.Set <AntItem>("ZickZackAngle", 10, "Correction Angle after Sprint");
            settings.Set <AntItem>("ZickZackRange", 30f, "Distance to go every Sprint");
            settings.Set <AntItem>("RotationSpeed", 20, "Maximum Rotation Angle per Round");
            settings.Set <AntItem>("DropSugar", false, "Will an Ant leave a small Sugar on Drop");
            settings.Set <AntItem>("MarkerDelay", 10, "Time in Rounds between Marker-Drops");
            typeMapper.RegisterItem <AntItem, AntState, AntInfo>(this, "Ant");

            // Walking
            settings.Set <AntItem>("MaxSpeed", 1f, "Maximum Speed of an Ant");
            typeMapper.AttachItemProperty <AntItem, WalkingProperty>(this, "Ant Walking", (i) =>
            {
                WalkingProperty property = new WalkingProperty(i);

                // Set Maximum Speed based on the current Settings
                // TODO: Check for Castes
                property.MaximumSpeed = i.Settings.GetFloat <AntItem>("MaxSpeed").Value;

                // Bind Item Orientation to Walk-Direction
                property.Direction    = i.Orientation;
                i.OrientationChanged += (item, v) => { property.Direction = v; };

                return(property);
            });

            // Collision
            settings.Set <AntItem>("Mass", 1f, "Collision Mass of an Ant");
            typeMapper.AttachItemProperty <AntItem, CollidableProperty>(this, "Ant Collidable", (i) =>
            {
                CollidableProperty property = new CollidableProperty(i);

                // Set Mass to Settings
                property.CollisionFixed = false;
                property.CollisionMass  = i.Settings.GetFloat <AntItem>("Mass").Value;

                // Bind Collision Radius to Item Radius
                property.CollisionRadius = i.Radius;
                i.RadiusChanged         += (item, v) => { property.CollisionRadius = v; };

                return(property);
            });

            // Visibility
            typeMapper.AttachItemProperty <AntItem, VisibleProperty>(this, "Ant Visible", (i) =>
            {
                VisibleProperty property = new VisibleProperty(i);

                // Bind Visibility Radius to the Item Radius
                property.VisibilityRadius = i.Radius;
                i.RadiusChanged          += (item, v) => { property.VisibilityRadius = v; };

                return(property);
            });

            // Sighting
            settings.Set <AntItem>("ViewRange", 20f, "View Range of an Ant");
            settings.Set <AntItem>("ViewAngle", 360, "View Angle of an Ant");
            typeMapper.AttachItemProperty <AntItem, SightingProperty>(this, "Ant Sighting", (i) =>
            {
                SightingProperty property = new SightingProperty(i);

                // Set View Range and Angle
                property.ViewRange = i.Settings.GetFloat <AntItem>("ViewRange").Value;
                property.ViewAngle = i.Settings.GetFloat <AntItem>("ViewAngle").Value;

                // Bind View Direction to the Item Orientation
                property.ViewDirection = i.Orientation;
                i.OrientationChanged  += (item, v) => { property.ViewDirection = v; };

                return(property);
            });

            // Sniffer
            typeMapper.AttachItemProperty <AntItem, SnifferProperty>(this, "Ant Sniffer");

            // Carrier
            settings.Set <AntItem>("CarrierStrength", 10f, "Carrier Strength of an Ant");
            typeMapper.AttachItemProperty <AntItem, CarrierProperty>(this, "Ant Carrier", (i) =>
            {
                CarrierProperty property = new CarrierProperty(i);
                property.CarrierStrength = i.Settings.GetFloat <AntItem>("CarrierStrength").Value;
                return(property);
            });

            // Attackable
            settings.Set <AntItem>("MaxHealth", 100f, "Maximum Health for an Ant");
            typeMapper.AttachItemProperty <AntItem, AttackableProperty>(this, "Ant Attackable", (i) =>
            {
                AttackableProperty property = new AttackableProperty(i);

                // Bind Attackable Radius to Item Radius
                property.AttackableRadius = i.Radius;
                i.RadiusChanged          += (item, v) => { property.AttackableRadius = v; };

                // Health
                property.AttackableMaximumHealth = settings.GetInt <AntItem>("MaxHealth").Value;
                property.AttackableHealth        = settings.GetInt <AntItem>("MaxHealth").Value;

                return(property);
            });

            // Attacker
            settings.Set <AntItem>("AttackRange", 3f, "Attack Range for a Bug");
            settings.Set <AntItem>("RecoveryTime", 2, "Recovery Time in Rounds for a Bug");
            settings.Set <AntItem>("AttackStrength", 5, "Attach Strength for a Bug");
            typeMapper.AttachItemProperty <AntItem, AttackerProperty>(this, "Ant Attacker", (i) =>
            {
                AttackerProperty property   = new AttackerProperty(i);
                property.AttackRange        = i.Settings.GetFloat <AntItem>("AttackRange").Value;
                property.AttackRecoveryTime = i.Settings.GetInt <AntItem>("RecoveryTime").Value;
                property.AttackStrength     = i.Settings.GetInt <AntItem>("AttackStrength").Value;
                return(property);
            });

            // Collector
            settings.Set <AntItem>("SugarCapacity", 5, "Maximum Capacity for Sugar");
            settings.Set <AntItem>("AppleCapacity", 2, "Maximum Capacity for Apple");
            typeMapper.AttachItemProperty <AntItem, SugarCollectorProperty>(this, "Ant Sugar Collectable", (i) =>
            {
                SugarCollectorProperty property = new SugarCollectorProperty(i);
                property.Capacity = i.Settings.GetInt <AntItem>("SugarCapacity").Value;
                return(property);
            });
            typeMapper.AttachItemProperty <AntItem, AppleCollectorProperty>(this, "Ant Apple Collectable", (i) =>
            {
                AppleCollectorProperty property = new AppleCollectorProperty(i);
                property.Capacity = i.Settings.GetInt <AntItem>("AppleCapacity").Value;
                return(property);
            }); // TODO: Optional, wenn _settings.ANT_APPLECOLLECT | _settings.ANT_APPLE_CAPACITY, 0);
        }
Example #13
0
        /// <summary>
        /// Registers classic Bugs
        /// </summary>
        /// <param name="typeMapper">Type Mapper</param>
        /// <param name="settings">Settings</param>
        private void RegisterClassicBug(ITypeMapper typeMapper, KeyValueStore settings)
        {
            // Classic Bug
            typeMapper.RegisterItem <ClassicBugItem, BugState, BugInfo>(this, "Classic Bug");

            // Walking
            settings.Set <ClassicBugItem>("MaxSpeed", 2f, "Maximum Speed of a Classic Bug");
            typeMapper.AttachItemProperty <ClassicBugItem, WalkingProperty>(this, "Classic Bug Walking", (i) =>
            {
                WalkingProperty property = new WalkingProperty(i);

                // Set Walking Speed
                property.MaximumSpeed = i.Settings.GetFloat <ClassicBugItem>("MaxSpeed").Value;

                // Bind Direction to the Items Orientation
                property.Direction    = i.Orientation;
                i.OrientationChanged += (item, v) => { property.Direction = v; };

                return(property);
            });

            // Collision
            settings.Set <ClassicBugItem>("Mass", 10f, "Collision Mass of a Classic Bug");
            typeMapper.AttachItemProperty <ClassicBugItem, CollidableProperty>(this, "Classic Bug Collidable", (i) =>
            {
                CollidableProperty property = new CollidableProperty(i);

                // Set Collision Mass
                property.CollisionFixed = false;
                property.CollisionMass  = i.Settings.GetFloat <ClassicBugItem>("Mass").Value;

                // Bind Collision Radius to the Item Radius
                property.CollisionRadius = i.Radius;
                i.RadiusChanged         += (item, v) => { property.CollisionRadius = v; };

                return(property);
            });

            // Visibility
            typeMapper.AttachItemProperty <ClassicBugItem, VisibleProperty>(this, "Classic Bug Visible", (i) =>
            {
                VisibleProperty property = new VisibleProperty(i);

                // Bind Visibility Radius to the Item Radius
                property.VisibilityRadius = i.Radius;
                i.RadiusChanged          += (item, v) => { property.VisibilityRadius = v; };

                return(property);
            });

            // Sighting
            settings.Set <ClassicBugItem>("ViewRange", 20f, "View Range of a Classic Bug");
            settings.Set <ClassicBugItem>("ViewAngle", 360, "View Angle of a Classic Bug");
            typeMapper.AttachItemProperty <ClassicBugItem, SightingProperty>(this, "Classic Bug Sighting", (i) =>
            {
                SightingProperty property = new SightingProperty(i);

                // Set View Range and Angle
                property.ViewRange = i.Settings.GetFloat <ClassicBugItem>("ViewRange").Value;
                property.ViewAngle = i.Settings.GetFloat <ClassicBugItem>("ViewAngle").Value;

                // Bind View Direction to the Item Orientation
                property.ViewDirection = i.Orientation;
                i.OrientationChanged  += (item, v) => { property.ViewDirection = v; };

                return(property);
            });

            // Sniffer
            typeMapper.AttachItemProperty <ClassicBugItem, SnifferProperty>(this, "Classic Bug Sniffer");

            // Attackable
            settings.Set <ClassicBugItem>("MaxHealth", 1000, "Maximum Health of a Classic Bug");
            typeMapper.AttachItemProperty <ClassicBugItem, AttackableProperty>(this, "Classic Bug Attackable", (i) =>
            {
                AttackableProperty property = new AttackableProperty(i);

                // Bind Attackable Radius to Item Radius
                property.AttackableRadius = i.Radius;
                i.RadiusChanged          += (item, v) => { property.AttackableRadius = v; };

                // Health
                property.AttackableMaximumHealth = settings.GetInt <ClassicBugItem>("MaxHealth").Value;
                property.AttackableHealth        = settings.GetInt <ClassicBugItem>("MaxHealth").Value;

                return(property);
            });

            // Attacker
            settings.Set <ClassicBugItem>("AttackRange", 5f, "Attack Range for a Classic Bug");
            settings.Set <ClassicBugItem>("RecoveryTime", 5, "Recovery Time in Rounds for a Classic Bug");
            settings.Set <ClassicBugItem>("AttackStrength", 10, "Attach Strength for a Classic Bug");
            typeMapper.AttachItemProperty <ClassicBugItem, AttackerProperty>(this, "Classic Bug Attacker", (i) =>
            {
                AttackerProperty property   = new AttackerProperty(i);
                property.AttackRange        = i.Settings.GetFloat <ClassicBugItem>("AttackRange").Value;
                property.AttackRecoveryTime = i.Settings.GetInt <ClassicBugItem>("RecoveryTime").Value;
                property.AttackStrength     = i.Settings.GetInt <ClassicBugItem>("AttackStrength").Value;
                return(property);
            });
        }
Example #14
0
        /// <summary>
        /// Registers Anthills
        /// </summary>
        /// <param name="typeMapper">Type Mapper</param>
        /// <param name="settings">Settings</param>
        private void RegisterAnthill(ITypeMapper typeMapper, KeyValueStore settings)
        {
            // Anthill
            typeMapper.RegisterItem <AnthillItem, AnthillState, AnthillInfo>(this, "Anthill");

            // Collision
            typeMapper.AttachItemProperty <AnthillItem, CollidableProperty>(this, "Anthill Collidable", (i) =>
            {
                CollidableProperty property = new CollidableProperty(i);

                // Set Collision Mass
                property.CollisionFixed = true;
                property.CollisionMass  = 0f;

                // Bind Radius to the Item Radius
                property.CollisionRadius = i.Radius;
                i.RadiusChanged         += (item, v) => { property.CollisionRadius = v; };

                return(property);
            });

            // Visibility
            typeMapper.AttachItemProperty <AnthillItem, VisibleProperty>(this, "Anthill Visible", (i) =>
            {
                VisibleProperty property = new VisibleProperty(i);

                // Bind Visibility Radius to the Item Radius
                property.VisibilityRadius = i.Radius;
                i.RadiusChanged          += (item, v) => { property.VisibilityRadius = v; };

                return(property);
            });

            // Attackable
            settings.Set <AnthillItem>("Attackable", false, "Enables the possibility to destroy Anthills");
            settings.Set <AnthillItem>("MaxHealth", 1000, "Maximum Health of an Anthill");
            settings.Set <AnthillItem>("Buildable", false, "Can an Anthill build by ants");
            typeMapper.AttachItemProperty <AnthillItem, AttackableProperty>(this, "Anthill Attackable", (i) =>
            {
                // Check Attackable Switch
                if (!i.Settings.GetBool <AnthillItem>("Attackable").Value)
                {
                    return(null);
                }

                AttackableProperty property = new AttackableProperty(i);

                // Bind Attackable Radius to Item Radius
                property.AttackableRadius = i.Radius;
                i.RadiusChanged          += (item, v) => { property.AttackableRadius = v; };

                // Health
                property.AttackableMaximumHealth = settings.GetInt <AnthillItem>("MaxHealth").Value;
                property.AttackableHealth        = settings.GetInt <AnthillItem>("MaxHealth").Value;

                return(property);
            });

            // Collectable
            typeMapper.AttachItemProperty <AnthillItem, SugarCollectableProperty>(this, "Anthill Sugarsafe"); // TODO: Radius
            typeMapper.AttachItemProperty <AnthillItem, AppleCollectableProperty>(this, "Anthill Applesafe"); // TODO: Radius
        }
Example #15
0
 public AttackableInfo(Item item, ItemProperty property, Item observer)
     : base(item, property, observer)
 {
     this.property = property as AttackableProperty;
 }