예제 #1
0
    public bool Update()
    {
        if (TimerAtStart == -1)
        {
            TimerAtStart = MapLogic.Instance.LevelTime;
        }

        int timeOffset = MapLogic.Instance.LevelTime - TimerAtStart;

        if (timeOffset % Frequency == 0)
        {
            Projectile.CallCallback(timeOffset >= Duration);
        }

        if (timeOffset >= Duration) // die
        {
            return(false);
        }

        float ll = 0;

        // first, check start and end
        // roughly use 2 ticks per frame
        if (timeOffset > Duration - EndFrames * 2)
        {
            int endframe = (timeOffset - (Duration - EndFrames * 2)) / 2;
            Frame = Projectile.Class.Phases - EndFrames + endframe;
            ll    = 1f - (float)endframe / EndFrames;
        }
        else if (timeOffset < StartFrames * 2)
        {
            Frame = timeOffset / 2;
            ll    = (float)Frame / StartFrames;
        }
        else
        {
            Frame = (timeOffset / 2 % (Projectile.Class.Phases - (StartFrames + EndFrames))) + StartFrames;
            ll    = 0.5f + Mathf.Sin((float)timeOffset / 4 + RSeed * 2) / 4;
        }

        if (Projectile.Class.ID == (int)AllodsProjectile.FireWall && timeOffset % 2 == 0)
        {
            RSeed = UnityEngine.Random.Range(0f, 1f);
        }

        Projectile.CurrentFrame = Frame;
        Projectile.CurrentTics  = 0;
        Projectile.DoUpdateView = true;
        if (Projectile.Class.ID != (int)AllodsProjectile.FireWall)
        {
            ll = -1;
        }
        Projectile.LightLevel = (int)(256 + ll * 256f);

        if (Projectile.Class.ID == (int)AllodsProjectile.PoisonCloud)
        {
            if (timeOffset < 16)
            {
                Projectile.Alpha = (float)timeOffset / 16;
            }
            else if (timeOffset >= 16 && timeOffset < Duration - 16)
            {
                Projectile.Alpha = (1f - (float)(timeOffset - 16) / (Duration - 32)) * 0.5f + 0.5f;
            }
            else if (timeOffset >= Duration - 16)
            {
                Projectile.Alpha = 0.5f - ((float)timeOffset - (Duration - 16)) / 16 * 0.5f;
            }
            Projectile.Alpha = Projectile.Alpha * (0.5f + ((Mathf.Sin((float)timeOffset / 16 + Projectile.X * Projectile.Y + RSeed) + 0.5f) / 4));
        }

        Timer++;
        return(true);
    }
예제 #2
0
    public virtual bool Update()
    {
        // calculate target direction!
        // check if target is gone
        if (Target != null && (!Target.IsAlive || !Target.IsLinked))
        {
            Target = null;
        }

        Projectile.Alpha = 0;

        if (Target != null && SubProjectiles.Count <= 0)
        {
            // special magic for lightning
            Projectile.LightLevel = 256;
            TargetCenter          = new Vector2(Target.X + (float)Target.Width / 2 + Target.FracX, Target.Y + (float)Target.Height / 2 + Target.FracY);
            TargetAngle           = Projectile.Angle = MapObject.FaceVector(TargetCenter.x - Projectile.ProjectileX, TargetCenter.y - Projectile.ProjectileY);
            TargetDir             = new Vector2(TargetCenter.x - Projectile.ProjectileX, TargetCenter.y - Projectile.ProjectileY);
            TargetDst             = TargetDir.magnitude;
            TargetDir.Normalize();
            // spawn projectiles along the way
            Density = 0.2f;
            for (float i = 0; i < TargetDst; i += Density)
            {
                MapProjectile visProj = new MapProjectile(Color == 0 ? AllodsProjectile.Lightning : AllodsProjectile.ChainLightning);
                visProj.LightLevel   = 0;
                visProj.CurrentFrame = Color == 0 ? 0 : (5 * (Color - 1));
                visProj.SetPosition(Projectile.ProjectileX + TargetDir.x * i, Projectile.ProjectileY + TargetDir.y * i, 0); // for now
                MapLogic.Instance.Objects.Add(visProj);
                SubProjectiles.Add(visProj);
            }

            Projectile.CallCallback();
        }

        AnimTime += 0.08f;

        float   hUDiff     = MapLogic.Instance.GetHeightAt(TargetCenter.x, TargetCenter.y, 1, 1) / 32f;
        float   htOrig     = MapLogic.Instance.GetHeightAt(Projectile.ProjectileX, Projectile.ProjectileY, 1, 1) / 32f;
        float   angleToDst = Mathf.Atan2(TargetDir.y, TargetDir.x);
        float   sinScale   = TargetDst / 8 * Mathf.Sin((float)MapLogic.Instance.LevelTime / 2 * TargetDst);
        Vector2 offs       = new Vector2(0, 1);
        float   sinX       = Mathf.Cos(angleToDst) * offs.x - Mathf.Sin(angleToDst) * offs.y;
        float   sinY       = Mathf.Cos(angleToDst) * offs.y + Mathf.Sin(angleToDst) * offs.x;

        for (int i = 0; i < SubProjectiles.Count; i++)
        {
            float idst = Density * i;
            // get angle from first to second. calculate sin wave
            float baseX = Projectile.ProjectileX + TargetDir.x * idst;
            float baseY = Projectile.ProjectileY + TargetDir.y * idst;

            float         sscale = (Sin10(idst / TargetDst) * sinScale);
            MapProjectile sub    = SubProjectiles[i];
            int           cframe = (Color == 0 ? 0 : (5 * (Color - 1)));
            sub.CurrentFrame = (int)(cframe + 4 * AnimTime);
            sub.LightLevel   = 0;
            if (i % 12 == 0)
            {
                sub.LightLevel = (int)(512 * (1f - AnimTime));
            }
            float htDiff = MapLogic.Instance.GetHeightAt(baseX + sinX * sscale, baseY + sinY * sscale, 1, 1) / 32f;
            float lval   = (float)i / SubProjectiles.Count;
            float htLerp = hUDiff * lval + htOrig * (1f - lval);

            sub.SetPosition(baseX + sinX * sscale, baseY + sinY * sscale, -htDiff + htLerp);
        }

        if (AnimTime > 1)
        {
            foreach (MapProjectile sub in SubProjectiles)
            {
                sub.Dispose();
            }

            Projectile.Dispose();
            return(false);
        }

        return(true);
    }