Ejemplo n.º 1
0
        public static DamageFlags SphereToDamageFlags(Spell sp)
        {
            DamageFlags spdf = 0;

            // set damage flags depending on spell sphere
            switch (sp.Template.Sphere)
            {
            case 1:
                spdf |= DamageFlags.Fire;
                break;

            case 2:
                spdf |= DamageFlags.Water;
                break;

            case 3:
                spdf |= DamageFlags.Air;
                break;

            case 4:
                spdf |= DamageFlags.Earth;
                break;

            case 5:
                spdf |= DamageFlags.Astral;
                break;
            }

            return(spdf);
        }
Ejemplo n.º 2
0
    // Start is called before the first frame update
    void Start()
    {
        DamageFlags currentDmgFlags = DamageFlags.IsCrt | DamageFlags.IsPoision;

        currentDmgFlags |= DamageFlags.IsWind;

        currentDmgFlags ^= DamageFlags.IsCrt;

        if ((currentDmgFlags & DamageFlags.IsWind) != 0)
        {
            Debug.Log("Wind include");
        }
        if ((currentDmgFlags & DamageFlags.IsCrt) != 0)
        {
            Debug.Log("crt include");
        }
        if ((currentDmgFlags & DamageFlags.IsPoision) != 0)
        {
            Debug.Log("Poision include");
        }
        if ((currentDmgFlags & DamageFlags.IsFire) != 0)
        {
            Debug.Log("fire include");
        }
        if ((currentDmgFlags & DamageFlags.IsIce) != 0)
        {
            Debug.Log("Ice include");
        }
    }
Ejemplo n.º 3
0
 //Standard (No or One Modifier)
 public Damage(float value, DamageType type, DamageFlags flags = DamageFlags.None)
 {
     ValidateValue(value);
     Flags = flags;
     Type  = type;
     Value = value;
 }
Ejemplo n.º 4
0
 public Damage(float amount, DamageType type, WeaponSound weaponSound, DamageFlags flags, DamageInfoFlags infoFlags)
 {
     Amount      = amount;
     Type        = type;
     WeaponSound = weaponSound;
     Flags       = flags;
     InfoFlags   = infoFlags;
     Absorbed    = 0;
 }
Ejemplo n.º 5
0
 public Damage(float amount, DamageType type, DamageFlags flags, DamageInfoFlags infoFlags)
 {
     Amount      = amount;
     Type        = type;
     Flags       = flags;
     InfoFlags   = infoFlags;
     WeaponSound = WeaponSound.None;
     Absorbed    = 0;
 }
Ejemplo n.º 6
0
    public int TakeDamage(DamageFlags flags, MapUnit source, int count)
    {
        if ((flags & DamageFlags.TerrainDamage) == 0)
        {
            return(0);
        }

        Health -= count;
        return(count);
    }
Ejemplo n.º 7
0
 public AttackAction(MapUnit unit, MapUnit targetUnit, DamageFlags damageFlags, int damage)
 {
     Unit        = unit;
     TargetUnit  = targetUnit;
     DamageFlags = damageFlags;
     Damage      = damage;
     Timer       = 0;
     Spell       = null;
     SpellID     = -1;
     TargetX     = TargetY = -1;
 }
Ejemplo n.º 8
0
    public int TakeDamage(DamageFlags flags, MapUnit source, int count)
    {
        if ((flags & DamageFlags.TerrainDamage) == 0)
        {
            return(0);
        }

        Health      -= count;
        DoUpdateInfo = true;
        DoUpdateView = true;

        return(count);
    }
Ejemplo n.º 9
0
        // this should only be called for arrows (i.e. homing projectiles), with TargetUnit set.
        protected void SpawnProjectile(AllodsProjectile type, int speed, int damage)
        {
            // following offsets are based on unit's width, height and center
            float tX, tY;

            if (TargetUnit != null)
            {
                tX = TargetUnit.X + TargetUnit.Width * 0.5f + TargetUnit.FracX;
                tY = TargetUnit.Y + TargetUnit.Height * 0.5f + TargetUnit.FracY;
            }
            else
            {
                tX = TargetX + 0.5f;
                tY = TargetY + 0.5f;
            }

            float cX, cY;

            if (Spell.User != null)
            {
                cX = Spell.User.X + Spell.User.Width * 0.5f + Spell.User.FracX;
                cY = Spell.User.Y + Spell.User.Height * 0.5f + Spell.User.FracY;
                Vector2 dir = new Vector2(tX - cX, tY - cY).normalized *((Spell.User.Width + Spell.User.Height) / 2) / 1.5f;
                cX += dir.x;
                cY += dir.y;
            }
            else
            {
                cX = tX;
                cY = tY;
            }

            Server.SpawnProjectileHoming(type, Spell.User, cX, cY, 0,
                                         TargetUnit,
                                         speed,
                                         (MapProjectile fproj) =>
            {
                //Debug.LogFormat("spell projectile hit!");
                // done, make damage
                DamageFlags spdf = SphereToDamageFlags(Spell);

                if (TargetUnit.TakeDamage(spdf, Spell.User, damage) > 0)
                {
                    TargetUnit.DoUpdateInfo = true;
                    TargetUnit.DoUpdateView = true;
                }

                fproj.Dispose();
                MapLogic.Instance.Objects.Remove(fproj);
            });
        }
Ejemplo n.º 10
0
        protected void SpawnProjectile(MapUnit target, int damage, int color, float dst)
        {
            if (TargetUnit == null)
            {
                return;
            }

            // following offsets are based on unit's width, height and center
            float tX, tY;

            if (target != null)
            {
                tX = target.X + target.Width * 0.5f + target.FracX;
                tY = target.Y + target.Height * 0.5f + target.FracY;
            }
            else
            {
                return;
            }

            float cX, cY;

            if (Spell.User != null)
            {
                cX = Spell.User.X + Spell.User.Width * 0.5f + Spell.User.FracX;
                cY = Spell.User.Y + Spell.User.Height * 0.5f + Spell.User.FracY;
                Vector2 dir = new Vector2(tX - cX, tY - cY).normalized *((Spell.User.Width + Spell.User.Height) / 2) / 1.5f;
                cX += dir.x * dst;
                cY += dir.y * dst;
            }
            else
            {
                cX = tX;
                cY = tY;
            }

            Server.SpawnProjectileLightning(Spell.User, cX, cY, 0,
                                            target,
                                            color,
                                            (MapProjectile fproj) =>
            {
                DamageFlags spdf = SphereToDamageFlags(Spell);
                if (Spell.Item == null)
                {
                    spdf |= DamageFlags.AllowExp;
                }
                target.TakeDamage(spdf, Spell.User, damage);
            });
        }
Ejemplo n.º 11
0
    public bool Process()
    {
        if (Unit.Stats.Health <= 0)
        {
            return(false);
        }

        if (TargetUnit == Unit || !TargetUnit.IsAlive || !TargetUnit.IsLinked)
        {
            return(false);
        }

        if (!Unit.Interaction.CheckCanAttack(TargetUnit))
        {
            return(false);
        }

        // assume melee attack right now
        // check if in direct proximity
        if (Unit.Interaction.GetClosestDistanceTo(TargetUnit) <= Unit.Interaction.GetAttackRange() + 0.5f)
        {
            // in direct proximity!
            //
            Vector2i enemyCell   = TargetUnit.Interaction.GetClosestPointTo(Unit);
            int      angleNeeded = Unit.FaceCellPrecise(enemyCell.x, enemyCell.y);
            if (Unit.Angle != angleNeeded)
            {
                Unit.AddActions(new RotateAction(Unit, angleNeeded));
                return(true);
            }

            //
            //Debug.LogFormat("ID {0} ATTACKING", Unit.ID);
            int         damage = Random.Range(Unit.Stats.DamageMin, Unit.Stats.DamageMax);
            DamageFlags df     = Unit.GetDamageType();
            // we need to compare Option to set damage flags properly here
            Unit.AddActions(new AttackAction(Unit, TargetUnit, df, damage));
        }
        else
        {
            //Debug.LogFormat("ID {0} TRY WALK TO", Unit.ID);
            // make one step to the target.
            MoveState.TryWalkTo(Unit, TargetUnit.X, TargetUnit.Y, TargetUnit.Width, TargetUnit.Height, Unit.Interaction.GetAttackRange());
        }

        return(true);
    }
Ejemplo n.º 12
0
        public override bool Process()
        {
            if (!base.Process())
            {
                return(false);
            }

            Unit.Flags |= UnitFlags.Poisoned;
            if (MapLogic.Instance.LevelTime % MapLogic.TICRATE == 0)
            {
                DamageFlags spdf = Spells.SpellProc.SphereToDamageFlags(ParentProc.Spell);
                if (ParentProc.Spell.Item == null)
                {
                    spdf |= DamageFlags.AllowExp;
                }
                Unit.TakeDamage(spdf, ParentProc.Spell.User, Damage);
            }
            // This is the various effects unit can have
            return(true);
        }
Ejemplo n.º 13
0
    public int TakeDamage(DamageFlags flags, MapUnit source, int count)
    {
        if ((flags & DamageFlags.Fire) == 0)
        {
            return(0);
        }

        if (SetDead(true))
        {
            // inform clients.
            if (NetworkManager.IsServer)
            {
                Server.NotifyStaticObjectDead(X, Y);
            }

            return(count);
        }

        return(0);
    }
Ejemplo n.º 14
0
        public override bool Process()
        {
            if (NetworkManager.IsClient)
            {
                return(false);
            }

            // 5x5, but remove corners
            for (int y = TargetY - 2; y <= TargetY + 2; y++)
            {
                for (int x = TargetX - 2; x <= TargetX + 2; x++)
                {
                    // check for corner tiles :)
                    if ((x == TargetX - 2 || x == TargetX + 2) && (y == TargetY - 2 || y == TargetY + 2))
                    {
                        continue;
                    }
                    if (x < 0 || y < 0 ||
                        x >= MapLogic.Instance.Width ||
                        y >= MapLogic.Instance.Height)
                    {
                        continue;
                    }

                    // check if there are FIRE effects on this cell, don't spawn fog
                    bool spawnblocked = false;
                    foreach (MapObject mo in MapLogic.Instance.Nodes[x, y].Objects)
                    {
                        if (!(mo is MapProjectile))
                        {
                            continue;
                        }

                        MapProjectile mp = (MapProjectile)mo;
                        if (mp.Class == null || mp.Class.ID != (int)AllodsProjectile.PoisonCloud)
                        {
                            continue;
                        }

                        // don't remove if on edge of fire wall
                        if (new Vector2(mp.ProjectileX - x + 0.5f, mp.ProjectileY - y + 0.5f).magnitude > 0.8f)
                        {
                            continue;
                        }

                        spawnblocked = true;
                        break;
                    }

                    if (spawnblocked)
                    {
                        continue;
                    }

                    Server.SpawnProjectileEOT(AllodsProjectile.PoisonCloud, Spell.User, x + 0.5f, y + 0.5f, 0, (int)(MapLogic.TICRATE * Spell.GetDuration()), 40, 0, 0, 16, proj =>
                    {
                        DamageFlags spdf = SphereToDamageFlags(Spell);
                        // get projectile cells
                        int axFrom = Mathf.Max(0, Mathf.FloorToInt(proj.ProjectileX));
                        int axTo   = Mathf.Min(MapLogic.Instance.Width - 1, Mathf.CeilToInt(proj.ProjectileX));
                        int ayFrom = Mathf.Max(0, Mathf.FloorToInt(proj.ProjectileY));
                        int ayTo   = Mathf.Min(MapLogic.Instance.Height - 1, Mathf.CeilToInt(proj.ProjectileY));
                        for (int py = ayFrom; py <= ayTo; py++)
                        {
                            for (int px = axFrom; px <= axTo; px++)
                            {
                                // check how much projectile is on this cell
                                float pdst = 1f - Mathf.Min(1f, new Vector2(px + 0.5f - proj.ProjectileX, py + 0.5f - proj.ProjectileY).magnitude);
                                // 0..1 effect power
                                MapNode node = MapLogic.Instance.Nodes[px, py];
                                for (int i = 0; i < node.Objects.Count; i++)
                                {
                                    MapObject mo = node.Objects[i];
                                    if (!(mo is MapUnit))
                                    {
                                        continue;
                                    }
                                    MapUnit mov = (MapUnit)mo;
                                    int dmg     = (int)(Spell.GetIndirectPower() * pdst);
                                    if (dmg <= 0)
                                    {
                                        continue;                                                                       // don't add null effects
                                    }
                                    SpellEffects.Effect eff = new SpellEffects.Poison(this, dmg, MapLogic.TICRATE * 8); // originally 8 seconds
                                    mov.AddSpellEffects(eff);
                                }
                            }
                        }
                    });
                }
            }

            return(false);
        }
Ejemplo n.º 15
0
 public override void Damage(double damage, Enums.Element element = Enums.Element.None, Enums.DamageType damageType = Enums.DamageType.Direct, DamageFlags damageFlags = DamageFlags.None, Creature attacker = null, bool onDeath = true)
 {
     return;
 }
Ejemplo n.º 16
0
    public int TakeDamage(DamageFlags flags, MapUnit source, int damagecount)
    {
        if (damagecount <= 0)
        {
            return(0);
        }

        bool sourceIgnoresArmor = source != null && source.IsIgnoringArmor;

        if ((flags & DamageFlags.PhysicalDamage) != 0 && !sourceIgnoresArmor)
        {
            int ownChance = (int)(1.25f * Stats.Defence);
            int hisChance = (source != null) ? 5 + source.Stats.ToHit : ownChance;

            if (ownChance > hisChance)
            {
                if (UnityEngine.Random.Range(0, ownChance) > hisChance)
                {
                    return(0);
                }
            }

            damagecount -= Stats.Absorbtion;
            if (damagecount <= 0)
            {
                return(0);
            }
        }

        // magic resists
        if ((flags & DamageFlags.Fire) != 0)
        {
            damagecount -= damagecount * Stats.ProtectionFire / 100;
        }
        if ((flags & DamageFlags.Water) != 0)
        {
            damagecount -= damagecount * Stats.ProtectionWater / 100;
        }
        if ((flags & DamageFlags.Air) != 0)
        {
            damagecount -= damagecount * Stats.ProtectionAir / 100;
        }
        if ((flags & DamageFlags.Earth) != 0)
        {
            damagecount -= damagecount * Stats.ProtectionEarth / 100;
        }
        if ((flags & DamageFlags.Astral) != 0)
        {
            damagecount -= damagecount * Stats.ProtectionAstral / 100;
        }

        // physical resists in monsters
        if ((flags & DamageFlags.Blade) != 0)
        {
            damagecount -= damagecount * Stats.ProtectionBlade / 100;
        }
        if ((flags & DamageFlags.Axe) != 0)
        {
            damagecount -= damagecount * Stats.ProtectionAxe / 100;
        }
        if ((flags & DamageFlags.Bludgeon) != 0)
        {
            damagecount -= damagecount * Stats.ProtectionBludgeon / 100;
        }
        if ((flags & DamageFlags.Pike) != 0)
        {
            damagecount -= damagecount * Stats.ProtectionPike / 100;
        }
        if ((flags & DamageFlags.Shooting) != 0)
        {
            damagecount -= damagecount * Stats.ProtectionShooting / 100;
        }

        if (Stats.TrySetHealth(Stats.Health - damagecount))
        {
            if (NetworkManager.IsServer)
            {
                Server.NotifyDamageUnit(this, damagecount, (flags & DamageFlags.Astral) == 0);
            }
            return(damagecount);
        }

        return(0);
    }
Ejemplo n.º 17
0
    private void BecomeRagdollOnClient(Vector3 velocity, DamageFlags damageFlags, Vector3 forcePos, Vector3 force, int bone)
    {
        var ent = new ModelEntity();

        ent.Position            = Position;
        ent.Rotation            = Rotation;
        ent.Scale               = Scale;
        ent.MoveType            = MoveType.Physics;
        ent.UsePhysicsCollision = true;
        ent.EnableAllCollisions = true;
        ent.CollisionGroup      = CollisionGroup.Debris;
        ent.SetModel(GetModelName());
        ent.CopyBonesFrom(this);
        ent.CopyBodyGroups(this);
        ent.CopyMaterialGroup(this);
        ent.TakeDecalsFrom(this);
        ent.EnableHitboxes        = true;
        ent.EnableAllCollisions   = true;
        ent.SurroundingBoundsMode = SurroundingBoundsType.Physics;
        ent.RenderColorAndAlpha   = RenderColorAndAlpha;
        ent.PhysicsGroup.Velocity = velocity;

        if (Local.Pawn == this)
        {
            //ent.EnableDrawing = false; wtf
        }

        ent.SetInteractsAs(CollisionLayer.Debris);
        ent.SetInteractsWith(CollisionLayer.WORLD_GEOMETRY);
        ent.SetInteractsExclude(CollisionLayer.Player | CollisionLayer.Debris);

        foreach (var child in Children)
        {
            if (child is ModelEntity e)
            {
                var model = e.GetModelName();
                if (model != null && !model.Contains("clothes"))
                {
                    continue;
                }

                var clothing = new ModelEntity();
                clothing.SetModel(model);
                clothing.SetParent(ent, true);
                clothing.RenderColorAndAlpha = e.RenderColorAndAlpha;

                if (Local.Pawn == this)
                {
                    //	clothing.EnableDrawing = false; wtf
                }
            }
        }

        if (damageFlags.HasFlag(DamageFlags.Bullet))
        {
            if (bone >= 0)
            {
                var body = ent.GetBonePhysicsBody(bone);
                if (body != null)
                {
                    body.ApplyImpulseAt(forcePos, force * body.Mass);
                }
                else
                {
                    ent.PhysicsGroup.ApplyImpulse(force);
                }
            }
        }

        if (damageFlags.HasFlag(DamageFlags.Blast))
        {
            if (ent.PhysicsGroup != null)
            {
                ent.PhysicsGroup.AddVelocity((Position - (forcePos + Vector3.Down * 100.0f)).Normal * (force.Length * 0.2f));
                var angularDir = (Rotation.FromYaw(90) * force.WithZ(0).Normal).Normal;
                ent.PhysicsGroup.AddAngularVelocity(angularDir * (force.Length * 0.02f));
            }
        }

        Corpse = ent;

        ent.DeleteAsync(10.0f);
    }
Ejemplo n.º 18
0
        public virtual void ShootBullet(float spread, float force, float damage, float bulletSize, string impactEffect = null, DamageFlags damageType = DamageFlags.Bullet)
        {
            Vector3 forward = Owner.EyeRotation.Forward;

            forward += (Vector3.Random + Vector3.Random + Vector3.Random + Vector3.Random) * spread * 0.25f;
            forward  = forward.Normal;

            foreach (TraceResult trace in TraceBullet(Owner.EyePosition, Owner.EyePosition + forward * BulletRange, bulletSize))
            {
                Vector3 endPos = trace.EndPosition + trace.Direction * bulletSize;

                if (string.IsNullOrEmpty(impactEffect))
                {
                    trace.Surface.DoBulletImpact(trace);
                }
                else
                {
                    Particles.Create(impactEffect, endPos)?.SetForward(0, trace.Normal);
                }

                if (!IsServer || !trace.Entity.IsValid())
                {
                    continue;
                }

                using (Prediction.Off())
                {
                    DealDamage(trace.Entity, trace.EndPosition, forward * 100f * force, damage, damageType, trace);
                }
            }
        }
Ejemplo n.º 19
0
        public virtual void DealDamage(Entity target, Vector3 position, Vector3 force, float damage, DamageFlags damageType, TraceResult?traceResult = null)
        {
            DamageInfo damageInfo = new DamageInfo()
                                    .WithPosition(position)
                                    .WithFlag(damageType)
                                    .WithForce(force)
                                    .WithAttacker(Owner)
                                    .WithWeapon(this);

            if (traceResult != null)
            {
                damageInfo.UsingTraceResult((TraceResult)traceResult);
            }

            damageInfo.Damage = damage;

            target.TakeDamage(damageInfo);
        }
Ejemplo n.º 20
0
 public Damage SetModifiers(DamageFlags flag)
 {
     return(new Damage(Value, Type, flag));
 }
Ejemplo n.º 21
0
        public override bool Process()
        {
            if (NetworkManager.IsClient)
            {
                return(false);
            }

            // we need to spawn several EoT projectiles at the destination
            // 5x2

            float   sourceX   = Spell.User.X + Spell.User.FracX + Spell.User.Width / 2f;
            float   sourceY   = Spell.User.Y + Spell.User.FracY + Spell.User.Height / 2f;
            Vector2 direction = new Vector2(TargetX + 0.5f - sourceX, TargetY + 0.5f - sourceY);
            float   angle     = Mathf.Atan2(direction.y, direction.x) - (Mathf.PI / 180) * 90;

            for (int x = -2; x <= 2; x++)
            {
                for (int y = 0; y < 2; y++)
                {
                    // rotate x and y
                    float fx = x;
                    float fy = y;
                    float rx = Mathf.Cos(angle) * x - Mathf.Sin(angle) * y;
                    float ry = Mathf.Cos(angle) * y + Mathf.Sin(angle) * x;
                    Server.SpawnProjectileEOT(AllodsProjectile.FireWall, Spell.User, TargetX + rx + 0.5f, TargetY + ry + 0.5f, 0, (int)(MapLogic.TICRATE * Spell.GetDuration()), 10, 4, 4, 16, proj =>
                    {
                        DamageFlags spdf = SphereToDamageFlags(Spell);
                        if (Spell.Item == null)
                        {
                            spdf |= DamageFlags.AllowExp;
                        }
                        // get projectile cells
                        int axFrom = Mathf.Max(0, Mathf.FloorToInt(proj.ProjectileX));
                        int axTo   = Mathf.Min(MapLogic.Instance.Width - 1, Mathf.CeilToInt(proj.ProjectileX));
                        int ayFrom = Mathf.Max(0, Mathf.FloorToInt(proj.ProjectileY));
                        int ayTo   = Mathf.Min(MapLogic.Instance.Height - 1, Mathf.CeilToInt(proj.ProjectileY));
                        for (int py = ayFrom; py <= ayTo; py++)
                        {
                            for (int px = axFrom; px <= axTo; px++)
                            {
                                // check how much projectile is on this cell
                                float pdst = 1f - Mathf.Min(1f, new Vector2(px + 0.5f - proj.ProjectileX, py + 0.5f - proj.ProjectileY).magnitude);
                                // 0..1 effect power
                                MapNode node = MapLogic.Instance.Nodes[px, py];
                                for (int i = 0; i < node.Objects.Count; i++)
                                {
                                    MapObject mo = node.Objects[i];
                                    if (!(mo is IVulnerable))
                                    {
                                        // aoe fire effect: remove cloud effects if any
                                        if (!(mo is MapProjectile))
                                        {
                                            continue;
                                        }

                                        MapProjectile mp = (MapProjectile)mo;
                                        if (mp.Class == null || mp.Class.ID != (int)AllodsProjectile.PoisonCloud)
                                        {
                                            continue;
                                        }

                                        // don't remove if on edge of fire wall
                                        if (new Vector2(mp.ProjectileX - proj.ProjectileX, mp.ProjectileY - proj.ProjectileY).magnitude > 0.8f)
                                        {
                                            continue;
                                        }

                                        mp.Dispose();
                                        i--;
                                        continue;
                                    }
                                    else
                                    {
                                        IVulnerable mov = (IVulnerable)mo;
                                        int dmg         = (int)(Spell.GetDamage() * pdst);
                                        mov.TakeDamage(spdf, Spell.User, dmg);
                                    }
                                }
                            }
                        }
                    });
                }
            }

            return(false);
        }
Ejemplo n.º 22
0
        public override bool Process()
        {
            if (NetworkManager.IsClient)
            {
                return(false);
            }

            int ballDamage = 16;

            // here SpawnProjectile is basically duplicated. except some functions that aren't needed.
            // following offsets are based on unit's width, height and center
            float tX, tY;

            tX = TargetX + 0.5f;
            tY = TargetY + 0.5f;

            float cX, cY;

            if (Spell.User != null)
            {
                cX = Spell.User.X + Spell.User.Width * 0.5f + Spell.User.FracX;
                cY = Spell.User.Y + Spell.User.Height * 0.5f + Spell.User.FracY;
                Vector2 dir = new Vector2(tX - cX, tY - cY).normalized *((Spell.User.Width + Spell.User.Height) / 2) / 1.5f;
                cX += dir.x;
                cY += dir.y;
            }
            else
            {
                cX = tX;
                cY = tY;
            }

            Server.SpawnProjectileDirectional(AllodsProjectile.FireBall, Spell.User, cX, cY, 0,
                                              tX, tY, 0,
                                              10,
                                              (MapProjectile fproj) =>
            {
                //Debug.LogFormat("spell projectile hit!");
                // done, make damage
                DamageFlags spdf = SphereToDamageFlags(Spell);

                // spawn explosion. serverside, since projectile hit callback is serverside as well.
                Server.SpawnProjectileSimple(AllodsProjectile.Explosion, null, fproj.ProjectileX, fproj.ProjectileY, fproj.ProjectileZ);

                // apply damage over 3x3 cells around the fireball
                for (int y = fproj.Y - 1; y <= fproj.Y + 1; y++)
                {
                    for (int x = fproj.X - 1; x <= fproj.X + 1; x++)
                    {
                        if (x < 0 || y < 0 || x >= MapLogic.Instance.Width || y >= MapLogic.Instance.Height)
                        {
                            continue;
                        }

                        int dmg = (int)((2f - (new Vector2(x - fproj.X, y - fproj.Y).magnitude)) * ballDamage);
                        // damage in the center is approximately 1.4 or 1.6
                        MapNode node = MapLogic.Instance.Nodes[x, y];
                        for (int i = 0; i < node.Objects.Count; i++)
                        {
                            MapObject mo = node.Objects[i];
                            if (!(mo is IVulnerable))
                            {
                                continue;
                            }
                            IVulnerable mov = (IVulnerable)mo;
                            mov.TakeDamage(spdf, Spell.User, dmg);
                            mo.DoUpdateInfo = true;
                            mo.DoUpdateView = true;
                            //Debug.LogFormat("{0} <- {1}", mo, dmg);
                        }
                    }
                }

                fproj.Dispose();
                MapLogic.Instance.Objects.Remove(fproj);
            });

            return(false);
        }
Ejemplo n.º 23
0
        public virtual void Damage(double dmg, Character attacker = null, int sound = 0, DamageType damageType = DamageType.RawDamage, DamageFlags flags = DamageFlags.None)
        {
            if (LifeStatus != LifeStatus.Alive)
            {
                return;
            }

            RemoveStatus("Morph");

            var realDamage = dmg;

            if ((flags & DamageFlags.CanBeAbsorbed) == DamageFlags.CanBeAbsorbed)
            {
                if (AbsorbingAbsoluteDamage)
                {
                    CurrentAbsoluteDamageAbsorbed += dmg;
                    if (MaximumAbsoluteDamageAbsorbed <= CurrentAbsoluteDamageAbsorbed)
                    {
                        RemoveStatus("AbsoluteAbsorb");
                    }
                    realDamage = 0;
                    SpellAnimation(AbsoluteAbsorbAnimation, 100);
                }
                else if (AbsorbingPhysicalDamage && damageType == DamageType.Physical)
                {
                    CurrentPhysicalDamageAbsorbed += dmg;
                    if (MaximumPhysicalDamageAbsorbed <= CurrentPhysicalDamageAbsorbed)
                    {
                        RemoveStatus("PhysicalAbsorb");
                    }
                    realDamage = 0;
                    SpellAnimation(PhysicalAbsorbAnimation, 100);
                }
                else if (AbsorbingMagicalDamage && damageType == DamageType.Magical)
                {
                    CurrentMagicalDamageAbsorbed += dmg;
                    if (MaximumMagicalDamageAbsorbed <= CurrentMagicalDamageAbsorbed)
                    {
                        RemoveStatus("MagicalAbsorb");
                    }
                    realDamage = 0;
                    SpellAnimation(MagicalAbsorbAnimation, 100);
                }
            }

            if (damageType == DamageType.Physical)
            {
                realDamage *= ArmorProtection * (1d - PhysicalProtection);
            }
            else if (damageType == DamageType.Magical)
            {
                realDamage -= (realDamage * (MagicResistance / 100d));
                realDamage *= (1d - MagicalProtection);
            }

            if (Map.Flags.HasFlag(MapFlags.PlayerKill))
            {
                dmg *= 0.75;
            }

            if (attacker != null)
            {
                if (!Enemies.Contains(attacker))
                {
                    Enemies.Add(attacker);
                }
                if (!attacker.Enemies.Contains(this))
                {
                    attacker.Enemies.Add(this);
                }
                LastAttacker = attacker;
            }

            if ((flags & DamageFlags.CanBeRedirected) == DamageFlags.CanBeRedirected)
            {
                if (RedirectingPhysicalDamage && damageType == DamageType.Physical)
                {
                    if (PhysicalRedirectTarget != null && PhysicalRedirectTarget != this && WithinRange(PhysicalRedirectTarget, 12))
                    {
                        var yourDamage = realDamage * PhysicalRedirectPercent;
                        realDamage -= yourDamage;
                        PhysicalRedirectTarget.Damage(yourDamage, null, 0, DamageType.RawDamage, DamageFlags.None);
                    }
                    if (--PhysicalRedirectCount == 0)
                    {
                        RemoveStatus("PhysicalRedirect");
                    }
                }

                if (RedirectingMagicalDamage && damageType == DamageType.Magical)
                {
                    if (MagicalRedirectTarget != null && MagicalRedirectTarget != this && WithinRange(MagicalRedirectTarget, 12))
                    {
                        var yourDamage = realDamage * MagicalRedirectPercent;
                        realDamage -= yourDamage;
                        MagicalRedirectTarget.Damage(yourDamage, null, 0, DamageType.RawDamage, DamageFlags.None);
                    }
                    if (--MagicalRedirectCount == 0)
                    {
                        RemoveStatus("MagicalRedirect");
                    }
                }
            }

            if ((flags & DamageFlags.CanBeConvertedToManaDamage) == DamageFlags.CanBeConvertedToManaDamage)
            {
                if (ConvertingPhysicalDamageToManaDamage && damageType == DamageType.Physical)
                {
                    CurrentMP -= (long)realDamage;
                    if (CurrentMP < 0)
                    {
                        CurrentMP = 0;
                    }
                    CurrentPhysicalDamageConvertedToManaDamage += dmg;
                    if (MaximumPhysicalDamageConvertedToManaDamage <= CurrentPhysicalDamageConvertedToManaDamage)
                    {
                        RemoveStatus("PhysicalConvertToMana");
                    }
                    realDamage = 0;
                    SpellAnimation(PhysicalConvertToManaAnimation, 100);
                }
                if (ConvertingMagicalDamageToManaDamage && damageType == DamageType.Magical)
                {
                    CurrentMP -= (long)realDamage;
                    if (CurrentMP < 0)
                    {
                        CurrentMP = 0;
                    }
                    CurrentMagicalDamageConvertedToManaDamage += dmg;
                    if (MaximumMagicalDamageConvertedToManaDamage <= CurrentPhysicalDamageConvertedToManaDamage)
                    {
                        RemoveStatus("MagicalConvertToMana");
                    }
                    realDamage = 0;
                    SpellAnimation(MagicalConvertToManaAnimation, 100);
                }
            }

            CurrentHP -= (long)realDamage;

            if (CurrentHP < 0)
            {
                CurrentHP = 0;
            }

            if (attacker != null)
            {
                if (Attackers.ContainsKey(attacker))
                {
                    Attackers[attacker] += realDamage;
                }
                else
                {
                    Attackers.Add(attacker, realDamage);
                }
            }

            double percent = Math.Floor((double)CurrentHP / (double)MaximumHP * 100.0);

            if (percent < 0)
            {
                percent = 0;
            }

            if (percent > 100)
            {
                percent = 100;
            }

            var dot = (flags & DamageFlags.DamageOverTime) == DamageFlags.DamageOverTime;
            var id  = (attacker != null) ? attacker.ID : ID;

            foreach (Character c in Map.Objects)
            {
                if (WithinRange(c, 12) && (c is Player))
                {
                    var packet = new ServerPacket(0x13);
                    packet.WriteUInt32(id);
                    packet.WriteUInt32(ID);
                    packet.WriteByte(dot);
                    packet.WriteByte((byte)percent);
                    packet.WriteUInt32((uint)realDamage);
                    packet.WriteByte((byte)sound);
                    (c as Player).Client.Enqueue(packet);
                }
            }
        }
Ejemplo n.º 24
0
 public void TookDamage(DamageFlags damageFlags, Vector3 forcePos, Vector3 force)
 {
 }
Ejemplo n.º 25
0
        public static bool DealDamage(Entity victim, Entity attacker, float damage, DamageFlags flags = DamageFlags.None)
        {
            if (damage <= 0f)
            {
                return(false);
            }

            if (victim == null)
            {
                throw new NullReferenceException("Cannot deal damage to null victim");
            }

            CombatSnapshot.Builder snapshotBuilder = new CombatSnapshot.Builder()
            {
                Victim   = victim,
                Attacker = attacker
            };

            victim.combatTimer = COMBAT_TIMER_MAX;
            if (attacker != null)
            {
                attacker.combatTimer = COMBAT_TIMER_MAX;
            }

            bool hitShield  = false;
            bool victimDied = false;

            if (!victim.Invincible)
            {
                //not ignoring shield, hit it
                if (victim.Shield > 0f && (DamageFlags.IgnoreShield & flags) != DamageFlags.IgnoreShield)
                {
                    hitShield = true;
                    float preDmgShield = victim.Shield;
                    victim.Shield -= damage;
                    if (victim.Shield < 0f)
                    {
                        damage       -= preDmgShield;
                        victim.Shield = 0f;
                        victim.OnShieldDepleted(victim);
                        snapshotBuilder.ShieldDamage = preDmgShield;
                    }
                    else
                    {
                        snapshotBuilder.ShieldDamage = damage;
                    }

                    victim.ShieldRegenDelay = victim.ShieldRegenDelayMax.GetValue();
                }

                //either the shield wasn't hit, or pierce is set
                if (!hitShield || (DamageFlags.PierceShield & flags) == DamageFlags.PierceShield)
                {
                    victim.Health -= damage;
                    if (victim.Health < 0f)
                    {
                        victim.Health = 0f;
                        victimDied    = victim.OnDeath(victim);
                    }
                    snapshotBuilder.HealthDamage = damage;
                }
            }

            //TODO some event calls
            snapshotBuilder.VictimDied = victimDied;


            return(victimDied);
        }