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); }
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); }