fix: Fixes ignoring mobs, champions, party crash, slayer rarity, boat speedhack, etc (#1222)
* Movie ignore mobiles to Mobile class * Allow necromancer familiars to ignore mobiles * ChampionSpawn should not quietly fail when creating new spawn * Fix client party crash bug: 2 people partied, the leader logs out, other client is hung * Fix spellbooks creating with magery/meditation only and creating magery multiple times * Fix BaseRunicTool.GetRandomSlayer() creating more undead slayers than intended * Do not allow players to dismount each other whilst mounted * Fix AOS onwards damage increase tooltip and wrong formula in AOS * Fix monsters killing other monster revenants + animate dead should not attack player pets + other animates * Fix fire steed having loot pack added twice * Fix oaks spawn not able to create Unicorns + Kirins via Activator.CreateInstace() due to constructor having name as parametr * Fix ignoreMobiles flag not propagated to client for non-players. * Fix harrower tents not leeching from players * Fix boats speedhacking around the map * Fix bless, agility etc. not renewing duration * Fix reveal always worked * Fix empty constructor for steeds so they don't throw now.
This commit is contained in:
parent
910e06767b
commit
053dbcbad0
54 changed files with 871 additions and 454 deletions
|
|
@ -67,11 +67,12 @@ namespace Server.Multis
|
|||
private DateTime m_DecayTime;
|
||||
|
||||
private Direction m_Facing;
|
||||
private TimerExecutionToken _moveTimerToken;
|
||||
|
||||
private string m_ShipName;
|
||||
|
||||
private TimerExecutionToken _turnTimerToken;
|
||||
|
||||
private TurnTimer _turnTimer;
|
||||
private MoveTimer _moveTimer;
|
||||
|
||||
public BaseBoat() : base(0x0)
|
||||
{
|
||||
|
|
@ -125,7 +126,7 @@ namespace Server.Multis
|
|||
public Direction Moving { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool IsMoving => _moveTimerToken.Running;
|
||||
public bool IsMoving => _moveTimer?.Running == true;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Speed { get; set; }
|
||||
|
|
@ -459,8 +460,8 @@ namespace Server.Multis
|
|||
Hold?.Delete();
|
||||
PPlank?.Delete();
|
||||
SPlank?.Delete();
|
||||
_turnTimerToken.Cancel();
|
||||
_moveTimerToken.Cancel();
|
||||
_turnTimer?.Stop();
|
||||
_moveTimer?.Stop();
|
||||
|
||||
Boats.Remove(this);
|
||||
}
|
||||
|
|
@ -1091,8 +1092,10 @@ namespace Server.Multis
|
|||
Speed = FastSpeed;
|
||||
Order = single ? BoatOrder.Single : BoatOrder.Course;
|
||||
|
||||
_moveTimerToken.Cancel();
|
||||
Timer.StartTimer(FastInterval, FastInterval, StopBoat, out _moveTimerToken);
|
||||
if (!SafelyStartMoveTimer(FastInterval, single))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (message)
|
||||
{
|
||||
|
|
@ -1279,11 +1282,27 @@ namespace Server.Multis
|
|||
|
||||
if (Order != BoatOrder.Move)
|
||||
{
|
||||
_moveTimerToken.Cancel();
|
||||
_turnTimer?.Stop();
|
||||
}
|
||||
|
||||
_turnTimerToken.Cancel();
|
||||
Timer.StartTimer(TimeSpan.FromMilliseconds(500), () => Turn(offset), out _turnTimerToken);
|
||||
_turnTimer ??= new TurnTimer(offset, this, TimeSpan.FromMilliseconds(500), message);
|
||||
|
||||
if (_turnTimer.Running && _turnTimer._turn == offset)
|
||||
{
|
||||
// Dont let them spin around in circles like crazy
|
||||
return true;
|
||||
}
|
||||
|
||||
// Have they issued a new command too soon? Ignore it if so
|
||||
var turnTimerNext = (_turnTimer.Next - Core.Now).TotalMilliseconds;
|
||||
if (turnTimerNext is < 0 and > -250)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
_turnTimer._turn = offset;
|
||||
_turnTimer.Stop();
|
||||
_turnTimer.Start();
|
||||
|
||||
if (message)
|
||||
{
|
||||
|
|
@ -1295,7 +1314,7 @@ namespace Server.Multis
|
|||
|
||||
public bool Turn(int offset, bool message = true)
|
||||
{
|
||||
_turnTimerToken.Cancel();
|
||||
_turnTimer?.Stop();
|
||||
|
||||
if (CheckDecay())
|
||||
{
|
||||
|
|
@ -1347,12 +1366,51 @@ namespace Server.Multis
|
|||
m_ClientSpeed = clientSpeed;
|
||||
Order = BoatOrder.Move;
|
||||
|
||||
_moveTimerToken.Cancel();
|
||||
Timer.StartTimer(interval, single ? 1 : 0, StopBoat, out _moveTimerToken);
|
||||
SafelyStartMoveTimer(interval, single);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool SafelyStartMoveTimer(TimeSpan interval, bool single)
|
||||
{
|
||||
var singleNum = single ? 1 : 0;
|
||||
|
||||
if (_moveTimer != null)
|
||||
{
|
||||
// Do not allow them to travel faster simply by respamming the command
|
||||
if (_moveTimer.Running && _moveTimer.Interval == interval && _moveTimer.Single == singleNum)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Have they issued a new command too soon? Ignore it if so
|
||||
var moverTimerNext = (_moveTimer.Next - Core.Now).TotalMilliseconds;
|
||||
if (moverTimerNext is < 0 and > -500)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Changing the interval or flipping between commands: "Forward" and "Forward One"
|
||||
TimeSpan delay = TimeSpan.Zero;
|
||||
if (interval.TotalMilliseconds > Math.Abs(moverTimerNext))
|
||||
{
|
||||
var addedDelay = (int)(interval.TotalMilliseconds - Math.Abs(moverTimerNext));
|
||||
delay = TimeSpan.FromMilliseconds(addedDelay);
|
||||
}
|
||||
|
||||
_moveTimer.Stop();
|
||||
_moveTimer.Delay = delay;
|
||||
_moveTimer.Interval = interval;
|
||||
}
|
||||
else
|
||||
{
|
||||
_moveTimer = new MoveTimer(this, interval, interval, singleNum);
|
||||
}
|
||||
|
||||
_moveTimer.Start();
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool StopMove(bool message)
|
||||
{
|
||||
if (CheckDecay())
|
||||
|
|
@ -1360,7 +1418,7 @@ namespace Server.Multis
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!_moveTimerToken.Running)
|
||||
if (_moveTimer?.Running == false)
|
||||
{
|
||||
if (message)
|
||||
{
|
||||
|
|
@ -1373,7 +1431,7 @@ namespace Server.Multis
|
|||
Moving = Direction.North;
|
||||
Speed = 0;
|
||||
m_ClientSpeed = 0;
|
||||
_moveTimerToken.Cancel();
|
||||
_moveTimer?.Stop();
|
||||
|
||||
if (message)
|
||||
{
|
||||
|
|
@ -1891,7 +1949,7 @@ namespace Server.Multis
|
|||
continue;
|
||||
}
|
||||
|
||||
// TODO: Remove visible check and use something better, like check for spawners, or other things in the ocean we shouldn't pick up on accident
|
||||
// TODO: Remove visible check and use something better, like check for spawners, or other things in the ocean we shouldn't pick up on accident
|
||||
if (_boat.Contains(item) && item.Visible && item.Z >= _boat.Z)
|
||||
{
|
||||
_current = current;
|
||||
|
|
@ -2047,6 +2105,45 @@ namespace Server.Multis
|
|||
EventSink.WorldSave += UpdateAllComponents;
|
||||
}
|
||||
|
||||
private class TurnTimer : Timer
|
||||
{
|
||||
internal int _turn;
|
||||
private bool _message;
|
||||
private BaseBoat _boat;
|
||||
|
||||
public TurnTimer(int turn, BaseBoat boat, TimeSpan delay, bool message = true) : base(delay)
|
||||
{
|
||||
_turn = turn;
|
||||
_message = message;
|
||||
_boat = boat;
|
||||
}
|
||||
protected override void OnTick()
|
||||
{
|
||||
_boat?.Turn(_turn, _message);
|
||||
Stop();
|
||||
}
|
||||
}
|
||||
|
||||
private class MoveTimer : Timer
|
||||
{
|
||||
public TimeSpan BoatMoveDelay;
|
||||
public TimeSpan BoatMoveInterval;
|
||||
public int Single;
|
||||
private BaseBoat _boat;
|
||||
|
||||
public MoveTimer(BaseBoat boat, TimeSpan delay, TimeSpan interval, int single = 0) : base(delay, interval, single)
|
||||
{
|
||||
BoatMoveInterval = interval;
|
||||
BoatMoveDelay = delay;
|
||||
Single = single;
|
||||
_boat = boat;
|
||||
}
|
||||
protected override void OnTick()
|
||||
{
|
||||
_boat?.StopBoat();
|
||||
}
|
||||
}
|
||||
|
||||
private class DecayTimer : Timer
|
||||
{
|
||||
private readonly BaseBoat m_Boat;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue