fix: Smooths out throwing explosion potions (#1303)
* Fix: The potion explodes on the user if it is thrown with not enough time. Instead, the timer is stopped, and the potion explodes instantly at the target location. * Fix: When the potion appears based on how far you throw it. * Fix: Fixes total timer amount of time.
This commit is contained in:
parent
d172b5f742
commit
7a1d5131c8
1 changed files with 76 additions and 70 deletions
|
|
@ -11,11 +11,11 @@ namespace Server.Items
|
|||
{
|
||||
private const int ExplosionRange = 2; // How long is the blast radius?
|
||||
|
||||
private static readonly bool LeveledExplosion = false; // Should explosion potions explode other nearby potions?
|
||||
private static readonly bool InstantExplosion = false; // Should explosion potions explode on impact?
|
||||
private static readonly bool RelativeLocation = false; // Is the explosion target location relative for mobiles?
|
||||
private const bool LeveledExplosion = false; // Should explosion potions explode other nearby potions?
|
||||
private const bool InstantExplosion = false; // Should explosion potions explode on impact?
|
||||
private const bool RelativeLocation = false; // Is the explosion target location relative for mobiles?
|
||||
|
||||
private TimerExecutionToken _timerToken;
|
||||
private Timer _timer;
|
||||
|
||||
public BaseExplosionPotion(PotionEffect effect) : base(0xF0D, effect)
|
||||
{
|
||||
|
|
@ -89,79 +89,20 @@ namespace Server.Items
|
|||
|
||||
from.Target = new ThrowTarget(this);
|
||||
|
||||
if (!_timerToken.Running)
|
||||
if (_timer?.Running != true)
|
||||
{
|
||||
from.SendLocalizedMessage(500236); // You should throw it now!
|
||||
|
||||
var timer = 3;
|
||||
|
||||
if (Core.ML)
|
||||
{
|
||||
// 3.6 seconds explosion delay
|
||||
Timer.StartTimer(
|
||||
TimeSpan.FromSeconds(1.0),
|
||||
TimeSpan.FromSeconds(1.25),
|
||||
5, // TODO: Should this be 4?
|
||||
() => Detonate_OnTick(from, timer--),
|
||||
out _timerToken
|
||||
);
|
||||
_timer = new DetonateTimer(this, from, TimeSpan.FromSeconds(1.0), TimeSpan.FromSeconds(1.25), 5);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 2.6 seconds explosion delay
|
||||
Timer.StartTimer(
|
||||
TimeSpan.FromSeconds(0.75),
|
||||
TimeSpan.FromSeconds(1.0),
|
||||
4,
|
||||
() => Detonate_OnTick(from, timer--),
|
||||
out _timerToken
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Detonate_OnTick(Mobile from, int timer)
|
||||
{
|
||||
if (Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var parent = FindParent(from);
|
||||
|
||||
if (timer == 0)
|
||||
{
|
||||
Point3D loc;
|
||||
Map map;
|
||||
|
||||
if (parent is Item item)
|
||||
{
|
||||
loc = item.GetWorldLocation();
|
||||
map = item.Map;
|
||||
}
|
||||
else if (parent is Mobile m)
|
||||
{
|
||||
loc = m.Location;
|
||||
map = m.Map;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
_timer = new DetonateTimer(this, from, TimeSpan.FromSeconds(0.75), TimeSpan.FromSeconds(1.0), 4);
|
||||
}
|
||||
|
||||
Explode(from, true, loc, map);
|
||||
_timerToken.Cancel();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (parent is Item item)
|
||||
{
|
||||
item.PublicOverheadMessage(MessageType.Regular, 0x22, false, timer.ToString());
|
||||
}
|
||||
else if (parent is Mobile mobile)
|
||||
{
|
||||
mobile.PublicOverheadMessage(MessageType.Regular, 0x22, false, timer.ToString());
|
||||
}
|
||||
_timer.Start();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -172,7 +113,7 @@ namespace Server.Items
|
|||
return;
|
||||
}
|
||||
|
||||
if (InstantExplosion)
|
||||
if (InstantExplosion || _timer?.Running != true)
|
||||
{
|
||||
Explode(from, true, loc, map);
|
||||
}
|
||||
|
|
@ -275,7 +216,7 @@ namespace Server.Items
|
|||
|
||||
private class ThrowTarget : Target
|
||||
{
|
||||
public ThrowTarget(BaseExplosionPotion potion) : base(12, true, TargetFlags.None) => Potion = potion;
|
||||
public ThrowTarget(BaseExplosionPotion potion) : base(Core.ML ? 12 : 10, true, TargetFlags.None) => Potion = potion;
|
||||
|
||||
public BaseExplosionPotion Potion { get; }
|
||||
|
||||
|
|
@ -325,7 +266,72 @@ namespace Server.Items
|
|||
}
|
||||
|
||||
Potion.Internalize();
|
||||
Timer.StartTimer(TimeSpan.FromSeconds(1.0), () => Potion.Reposition_OnTick(from, loc, map));
|
||||
|
||||
var delay = TimeSpan.FromSeconds(0.1 * from.GetDistanceToSqrt(loc));
|
||||
|
||||
// If the potion is about to explode, stop the timer so it doesn't explode on you, while it is mid-air
|
||||
if (Potion._timer.RemainingCount <= 1 && Potion._timer.Next <= Core.Now + delay)
|
||||
{
|
||||
Potion._timer.Stop();
|
||||
}
|
||||
|
||||
Timer.StartTimer(delay, () => Potion.Reposition_OnTick(from, loc, map));
|
||||
}
|
||||
}
|
||||
|
||||
private class DetonateTimer : Timer
|
||||
{
|
||||
private BaseExplosionPotion _potion;
|
||||
private Mobile _from;
|
||||
|
||||
public DetonateTimer(BaseExplosionPotion potion, Mobile from, TimeSpan delay, TimeSpan interval, int count) : base(delay, interval, count)
|
||||
{
|
||||
_from = from;
|
||||
_potion = potion;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
if (_potion.Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var parent = _potion.FindParent(_from);
|
||||
|
||||
if (RemainingCount == 0)
|
||||
{
|
||||
Point3D loc;
|
||||
Map map;
|
||||
|
||||
if (parent is Item item)
|
||||
{
|
||||
loc = item.GetWorldLocation();
|
||||
map = item.Map;
|
||||
}
|
||||
else if (parent is Mobile m)
|
||||
{
|
||||
loc = m.Location;
|
||||
map = m.Map;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_potion.Explode(_from, true, loc, map);
|
||||
}
|
||||
else if (RemainingCount <= 3)
|
||||
{
|
||||
if (parent is Item item)
|
||||
{
|
||||
item.PublicOverheadMessage(MessageType.Regular, 0x22, false, RemainingCount.ToString());
|
||||
}
|
||||
else if (parent is Mobile mobile)
|
||||
{
|
||||
mobile.PublicOverheadMessage(MessageType.Regular, 0x22, false, RemainingCount.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue