Ejemplo n.º 1
0
    private void InitProjectile(int id, IPlayerPawn source, IMapProjectileLogic logic, MapProjectileCallback cb)
    {
        ClassID = (AllodsProjectile)id;
        Class   = ProjectileClassLoader.GetProjectileClassById(id);
        if (Class == null)
        {
            // make sure that at least ID is valid
            if (!Enum.IsDefined(typeof(AllodsProjectile), id))
            {
                // otherwise spam log
                Debug.LogFormat("Invalid projectile created (id={0})", id);
                return;
            }
        }

        Source = source;
        Logic  = logic;
        if (Logic != null)
        {
            Logic.SetProjectile(this);
        }
        Callback = cb;

        Width        = 1;
        Height       = 1;
        Alpha        = 1f;
        Color        = new Color(1, 1, 1, 1);
        ZOffset      = 128;
        Scale        = 1;
        DoUpdateView = true;
    }
Ejemplo n.º 2
0
        private void CreateProjectile(AllodsProjectile proj)
        {
            MapProjectile p = new MapProjectile(proj, Unit);

            p.ZOffset = 64;
            MapLogic.Instance.AddObject(p, true);
            Indicators.Add(p);
        }
Ejemplo n.º 3
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.º 4
0
    public bool Process()
    {
        if (Timer == 0)
        {
            Unit.VState       = UnitVisualState.Attacking;
            Unit.AttackFrame  = 0;
            Unit.AttackTime   = 0;
            Unit.DoUpdateView = true;
            Speed             = 0.5f;
        }

        if (Unit.Class.AttackPhases > 1)
        {
            if (Speed * Unit.AttackTime >= Unit.Class.AttackFrames[Unit.AttackFrame].Time)
            {
                //Unit.AttackFrame = ++Unit.AttackFrame % Unit.Class.AttackPhases;
                Unit.AttackFrame++;
                if (Unit.AttackFrame >= Unit.Class.AttackPhases)
                {
                    Unit.AttackFrame = Unit.Class.AttackPhases - 1;
                }
                Unit.AttackTime   = -1;
                Unit.DoUpdateView = true;
            }

            Unit.AttackTime++;
        }
        else
        {
            Unit.AttackFrame = 0;
            Unit.AttackTime  = 0;
        }

        if (Speed * Timer >= Unit.Charge && !NetworkManager.IsClient && !DamageDone)
        {
            // do damage here!
            // check if we need to fire a projectile (range)
            AllodsProjectile proj = AllodsProjectile.None; // default :D

            // check for castspell in weapon.
            // check for weapon.
            List <Spell> castspells   = new List <Spell>();
            bool         procoverride = false;
            if (Unit.GetObjectType() == MapObjectType.Human)
            {
                Item weapon = ((MapHuman)Unit).GetItemFromBody(MapUnit.BodySlot.Weapon);
                // if weapon is a staff, then castspell is called immediately.
                // otherwise castspell is only applied when the projectile hits.
                if (weapon != null && weapon.IsValid)
                {
                    foreach (ItemEffect eff in weapon.Effects)
                    {
                        if (eff.Type1 == ItemEffect.Effects.CastSpell)
                        {
                            Spell sp = new Spell(eff.Value1);
                            sp.Skill = eff.Value2;
                            sp.User  = Unit;
                            sp.Item  = weapon;
                            castspells.Add(sp);
                        }
                    }

                    if (weapon.Class.Option.Name == "Staff" || weapon.Class.Option.Name == "Shaman Staff")
                    {
                        procoverride = true;
                    }
                }
            }

            if (Unit.Interaction.GetAttackRange() > 1)
            {
                // send this projectile to clients too
                // make projectile specified in the unit class.
                proj = (AllodsProjectile)Unit.Class.Projectile;
            }

            if (!procoverride && Spell == null)
            {
                if (proj != AllodsProjectile.None)
                {
                    // following offsets are based on unit's width, height and center
                    float cX = Unit.X + Unit.Width * 0.5f + Unit.FracX;
                    float cY = Unit.Y + Unit.Height * 0.5f + Unit.FracY;

                    float tX = TargetUnit.X + TargetUnit.Width * 0.5f + TargetUnit.FracX;
                    float tY = TargetUnit.Y + TargetUnit.Height * 0.5f + TargetUnit.FracY;

                    Vector2 dir = new Vector2(tX - cX, tY - cY).normalized *((Unit.Width + Unit.Height) / 2) / 1.5f;
                    cX += dir.x;
                    cY += dir.y;

                    Server.SpawnProjectileDirectional(proj, Unit, cX, cY, 0,
                                                      tX, tY, 0,
                                                      10,
                                                      (MapProjectile fproj) =>
                    {
                        if (fproj.ProjectileX >= TargetUnit.X + TargetUnit.FracX &&
                            fproj.ProjectileY >= TargetUnit.Y + TargetUnit.FracY &&
                            fproj.ProjectileX < TargetUnit.X + TargetUnit.FracX + TargetUnit.Width &&
                            fproj.ProjectileY < TargetUnit.Y + TargetUnit.FracY + TargetUnit.Height)
                        {
                            //Debug.LogFormat("projectile hit!");
                            // done, make damage
                            if (TargetUnit.TakeDamage(DamageFlags, Unit, Damage) > 0)
                            {
                                TargetUnit.DoUpdateInfo = true;
                                TargetUnit.DoUpdateView = true;
                            }

                            // and cast spell
                            foreach (Spell spell in castspells)
                            {
                                Spells.SpellProc sp = spell.Cast(TargetUnit.X + TargetUnit.Width / 2, TargetUnit.Y + TargetUnit.Height / 2, TargetUnit);
                                if (sp != null)
                                {
                                    Unit.AddSpellEffects(sp);
                                }
                            }
                        }

                        fproj.Dispose();
                        MapLogic.Instance.Objects.Remove(fproj);
                    });
                }
                else
                {
                    if (TargetUnit.TakeDamage(DamageFlags, Unit, Damage) > 0)
                    {
                        TargetUnit.DoUpdateInfo = true;
                        TargetUnit.DoUpdateView = true;
                    }
                }
            }
            else
            {
                // cast spells directly
                // just do something atm.
                // todo: check spells that can be only casted on self (distance 0).
                if (Spell != null)
                {
                    Spells.SpellProc sp;
                    if (TargetUnit != null)
                    {
                        sp = Spell.Cast(TargetUnit.X + TargetUnit.Width / 2, TargetUnit.Y + TargetUnit.Height / 2, TargetUnit);
                    }
                    else
                    {
                        sp = Spell.Cast(TargetX, TargetY, null);
                    }
                    if (sp != null)
                    {
                        Unit.AddSpellEffects(sp);
                    }
                }
                else
                {
                    foreach (Spell spell in castspells)
                    {
                        Spells.SpellProc sp = spell.Cast(TargetUnit.X + TargetUnit.Width / 2, TargetUnit.Y + TargetUnit.Height / 2, TargetUnit);
                        if (sp != null)
                        {
                            Unit.AddSpellEffects(sp);
                        }
                    }
                }
            }

            DamageDone = true;
        }

        if (Speed * Timer >= Unit.Charge + Unit.Relax)
        {
            return(false); // end of attack
        }
        Timer++;
        return(true);
    }
Ejemplo n.º 5
0
 public MapProjectile(AllodsProjectile proj, IPlayerPawn source = null, IMapProjectileLogic logic = null, MapProjectileCallback cb = null)
 {
     InitProjectile((int)proj, source, logic, cb);
 }
Ejemplo n.º 6
0
 public static void SpawnProjectileSimple(AllodsProjectile id, IPlayerPawn source, float x, float y, float z, float animspeed = 0.5f)
 {
     SpawnProjectileSimple((int)id, source, x, y, z, animspeed);
 }
Ejemplo n.º 7
0
 public static void SpawnProjectileDirectional(AllodsProjectile id, IPlayerPawn source, float x, float y, float z, float tgx, float tgy, float tgz, float speed, MapProjectileCallback cb = null)
 {
     SpawnProjectileDirectional((int)id, source, x, y, z, tgx, tgy, tgz, speed, cb);
 }
Ejemplo n.º 8
0
 public static void SpawnProjectileHoming(AllodsProjectile id, IPlayerPawn source, float x, float y, float z, MapUnit target, float speed, MapProjectileCallback cb = null)
 {
     SpawnProjectileHoming((int)id, source, x, y, z, target, speed, cb);
 }
Ejemplo n.º 9
0
 public static void SpawnProjectileEOT(AllodsProjectile id, IPlayerPawn source, float x, float y, float z, int duration, int frequency, int startframes = 0, int endframes = 0, int zoffs = -128, MapProjectileCallback cb = null)
 {
     SpawnProjectileEOT((int)id, source, x, y, z, duration, frequency, startframes, endframes, zoffs, cb);
 }
Ejemplo n.º 10
0
 public static void SpawnProjectileSimple(AllodsProjectile id, IPlayerPawn source, float x, float y, float z, float animspeed = 0.5f, float scale = 1f, int start = 0, int end = 0)
 {
     SpawnProjectileSimple((int)id, source, x, y, z, animspeed, scale, start, end);
 }