1
0
mirror of https://github.com/ppy/osu.git synced 2026-06-02 03:11:19 +08:00
Files
osu-lazer/osu.Game.Rulesets.Vitaru/Objects/Drawables/DrawablePatterns.cs
T
2018-03-18 22:43:16 -04:00

360 lines
12 KiB
C#

using OpenTK;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Vitaru.UI;
using osu.Game.Rulesets.Vitaru.Objects.Characters;
using System;
using osu.Game.Rulesets.Vitaru.Settings;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Extensions.Color4Extensions;
namespace osu.Game.Rulesets.Vitaru.Objects.Drawables
{
public class DrawablePattern : DrawableVitaruHitObject
{
private readonly VitaruGamemode currentGameMode = VitaruSettings.VitaruConfigManager.GetBindable<VitaruGamemode>(VitaruSetting.GameMode);
public static int PatternCount;
private readonly Pattern pattern;
private Vector2 patternStartPosition;
private Container energyCircle;
private bool loaded;
private bool started;
private bool done;
private int currentRepeat;
private Enemy enemy;
private bool prepedToPop;
private bool popped;
public DrawablePattern(Container parent, Pattern pattern) : base(pattern, parent)
{
AlwaysPresent = true;
this.pattern = pattern;
if (!pattern.IsSlider && !pattern.IsSpinner)
this.pattern.EndTime = this.pattern.StartTime + TIME_FADEOUT;
else if (pattern.IsSlider)
this.pattern.EndTime += TIME_FADEOUT;
}
protected override void LoadComplete()
{
base.LoadComplete();
PatternCount++;
if (pattern.IsSlider)
pattern.EndTime = pattern.StartTime + pattern.RepeatCount * pattern.Curve.Distance / pattern.Velocity;
LifetimeStart = pattern.StartTime - (TIME_PREEMPT + 1000f);
}
//Should be called when a DrawablePattern is getting ready to become visable as to save on resources before hand
private void load()
{
if (!loaded)
{
if (currentGameMode != VitaruGamemode.Dodge)
{
//load the enemy
ParentContainer.Add(enemy = new Enemy(ParentContainer, pattern, this)
{
Alpha = 0,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Depth = 5,
MaxHealth = pattern.EnemyHealth,
Team = 1
});
Child = energyCircle = new Container
{
Alpha = 0,
Masking = true,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(30),
CornerRadius = 30f / 2,
BorderThickness = 10,
BorderColour = pattern.ComboColour,
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both
}
},
EdgeEffect = new EdgeEffectParameters
{
Type = EdgeEffectType.Shadow,
Colour = pattern.ComboColour.Opacity(0.5f),
Radius = Width / 2,
}
};
enemy.FadeInFromZero(TIME_FADEIN);
enemy.Position = getPatternStartPosition();
enemy.MoveTo(pattern.Position, TIME_PREEMPT);
}
else
{
Child = energyCircle = new CircularContainer
{
Masking = true,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(20),
BorderThickness = 6,
BorderColour = pattern.ComboColour,
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both
}
},
EdgeEffect = new EdgeEffectParameters
{
Type = EdgeEffectType.Shadow,
Colour = pattern.ComboColour.Opacity(0.5f),
Radius = Width / 2,
}
};
}
Position = getPatternStartPosition();
this.MoveTo(pattern.Position, TIME_PREEMPT);
if (NestedHitObjects != null)
foreach (var o in NestedHitObjects)
{
var b = (DrawableBullet)o;
ParentContainer.Remove(b);
b.Dispose();
}
//Load the bullets
foreach (var o in pattern.NestedHitObjects)
{
var b = (Bullet)o;
b.ComboColour = pattern.ComboColour;
DrawableBullet drawableBullet = new DrawableBullet(ParentContainer, b, this);
ParentContainer.Add(drawableBullet);
AddNested(drawableBullet);
}
loaded = true;
}
}
private void unload()
{
if (loaded)
{
if (currentGameMode != VitaruGamemode.Dodge)
{
ParentContainer.Remove(enemy);
enemy.Dispose();
}
loaded = false;
started = false;
done = false;
}
}
private Vector2 getPatternStartPosition()
{
if (pattern.Position.X <= 384f / 2 && pattern.Position.Y <= 512f / 2)
patternStartPosition = pattern.Position - new Vector2(384f / 2, 512f / 2);
else if (pattern.Position.X > 384f / 2 && pattern.Position.Y <= 512f / 2)
patternStartPosition = new Vector2(pattern.Position.X + 384f / 2, pattern.Position.Y - 512f / 2);
else if (pattern.Position.X > 384f / 2 && pattern.Position.Y > 512f / 2)
patternStartPosition = pattern.Position + new Vector2(384f / 2, 512f / 2);
else
patternStartPosition = new Vector2(pattern.Position.X - 384f / 2, pattern.Position.Y + 512f / 2);
return patternStartPosition;
}
protected override void Update()
{
base.Update();
//Used just to keep this Update(); function clean looking
generalUpdateLogic();
if (!pattern.IsSlider && !pattern.IsSpinner && loaded)
hitcircleUpdate();
if (pattern.IsSlider && loaded)
sliderUpdate();
if (pattern.IsSpinner && loaded)
spinnerUpdate();
}
private void generalUpdateLogic()
{
if (HitObject.StartTime - TIME_PREEMPT <= Time.Current && Time.Current < pattern.EndTime + TIME_FADEOUT)
load();
else
unload();
if (currentGameMode != VitaruGamemode.Dodge && prepedToPop && HitObject.StartTime <= Time.Current)
pop();
}
/// <summary>
/// Will leave and hide
/// </summary>
private void end()
{
if (energyCircle.Alpha <= 0)
{
if (currentGameMode != VitaruGamemode.Dodge)
enemy.MoveTo(patternStartPosition, TIME_FADEOUT, Easing.InQuint);
this.MoveTo(patternStartPosition, TIME_FADEOUT, Easing.InQuint);
enemy.ScaleTo(new Vector2(0.5f), TIME_FADEOUT, Easing.InQuint);
enemy.FadeOut(TIME_FADEOUT, Easing.InQuint);
}
else
{
energyCircle.FadeOut(TIME_FADEOUT / 4);
energyCircle.ScaleTo(new Vector2(0.1f), TIME_FADEOUT / 4);
}
}
public void PrepPop()
{
if (!prepedToPop && !done)
{
double time = pattern.StartTime - Time.Current;
if (time < 0)
time = 0;
energyCircle.FadeInFromZero(time);
energyCircle.ScaleTo(Vector2.One, time);
prepedToPop = true;
}
}
private void pop()
{
if (!popped)
{
enemy.FadeOut(100);
enemy.ScaleTo(new Vector2(1.2f), 100);
popped = true;
}
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (isDisposing)
PatternCount--;
}
private void throwBullets()
{
PlaySamples();
foreach (var o in NestedHitObjects)
{
var b = (DrawableBullet)o;
if (b.Bullet.StartTime <= Time.Current)
{
b.Position = Position;
try
{
if (b.Bullet.ShootPlayer)
b.Bullet.BulletAngleRadian += pattern.PlayerRelativePositionAngle(VitaruPlayfield.VitaruPlayer.Position, b.Position) - (float)Math.PI / 2;
}
catch { b.Bullet.BulletAngleRadian = 0; }
}
}
}
/// <summary>
/// All the hitcircle stuff
/// </summary>
#region Hitcircle Stuff
private void hitcircleUpdate()
{
if (HitObject.StartTime <= Time.Current && !started)
{
started = true;
done = true;
throwBullets();
end();
}
}
#endregion
/// <summary>
/// All The Slider Stuff
/// </summary>
#region Slider Stuff
private void sliderUpdate()
{
double progress = MathHelper.Clamp((Time.Current - pattern.StartTime) / pattern.Duration, 0, 1);
int repeat = pattern.RepeatAt(progress);
progress = pattern.ProgressAt(progress);
if (HitObject.StartTime <= Time.Current && !started)
{
throwBullets();
started = true;
}
if (!done && started)
{
Position = pattern.Curve.PositionAt(progress);
if (currentGameMode != VitaruGamemode.Dodge)
enemy.Position = pattern.Curve.PositionAt(progress);
}
if (repeat > currentRepeat)
{
if (repeat < pattern.RepeatCount)
throwBullets();
currentRepeat = repeat;
}
if (pattern.EndTime <= Time.Current && started && !done)
{
end();
throwBullets();
done = true;
}
}
#endregion
/// <summary>
/// All the spinner stuff
/// </summary>
#region Spinner Stuff
private void spinnerUpdate()
{
if (pattern.StartTime <= Time.Current && !started)
{
throwBullets();
started = true;
}
if (pattern.EndTime <= Time.Current)
{
done = true;
end();
}
}
#endregion
}
}