SpeedHandling System
Doing testings - making things ready for my beta, i found a problem in the mobiles speed handling:
Server handles in a poor way changing of Maluses on a Player-Mobile, just overriding the current Speed sending the SpeedControl Packet.
This can cause serious problems if you are, for example, flying and get under sleep effect.
Normal runuo does this :
- SpeedControl.Mount - Set flying
- SpeedControl.Walk - Set sleeping
- SpeedControl.Disable - Sleep expires -> NO MORE MOUNTSPEED.
I know runuo does not supports SA, But i think this can be reproduced with the other things that use SpeedControl packet.
Notice: this solution can be used only by people who know what they are doing
Here's my solution to the problem:
In Mobile.cs
And in another file i called SpeedHandler.cs
then just simply change any
to
Any suggestion would be welcome
Doing testings - making things ready for my beta, i found a problem in the mobiles speed handling:
Server handles in a poor way changing of Maluses on a Player-Mobile, just overriding the current Speed sending the SpeedControl Packet.
This can cause serious problems if you are, for example, flying and get under sleep effect.
Normal runuo does this :
- SpeedControl.Mount - Set flying
- SpeedControl.Walk - Set sleeping
- SpeedControl.Disable - Sleep expires -> NO MORE MOUNTSPEED.
I know runuo does not supports SA, But i think this can be reproduced with the other things that use SpeedControl packet.
Notice: this solution can be used only by people who know what they are doing
Here's my solution to the problem:
In Mobile.cs
Code:
#region SA
private RunningFlags m_RunningFlags = RunningFlags.None;
protected bool GetRunningFlag(RunningFlags flag)
{
return ((m_RunningFlags & flag) != 0);
}
protected void SetRunningFlag(RunningFlags flag, bool on)
{
m_RunningFlags = (on ? m_RunningFlags | flag : m_RunningFlags & ~flag);
}
public void SwitchSpeedControl(RunningFlags flag, bool active)
{
if (GetRunningFlag(flag) == active)
return;//Flag is already at that status, no mod needed
SetRunningFlag(flag, active);
if (active)
{
Packet p = SpeedHandler.GetSpeedType(flag);//Override current SpeedControl
if (p == null)
return;
if (p == SpeedControl.MountSpeed && GetWalkingFlag())//We cannot override any WALKING Malus
{
//Console.WriteLine("Malus not overridden");
return;
}
else
Send(p);
return;
}
else
{
bool restore = false;
RunningFlags torestore = RunningFlags.None;
foreach (RunningFlags f in Enum.GetValues(typeof(RunningFlags)))
{
if (f == RunningFlags.None)
continue;
if (GetRunningFlag(f))
{
torestore = f;
//Console.WriteLine(f.ToString());
restore = true;
break;
}
}
if (restore)
{
//Console.WriteLine("Passive restoring");
Packet p = SpeedHandler.GetSpeedType(torestore);//Restore any overridden SpeedControl
if (p != null)
{
if (p == SpeedControl.MountSpeed && GetWalkingFlag())//Check if there are Malus Controls
Send(SpeedControl.WalkSpeed);
else
Send(p);
}
}
else
Send(SpeedControl.Disable);
}
}
public bool GetWalkingFlag()
{
foreach (RunningFlags f in Enum.GetValues(typeof(RunningFlags)))
{
if (f == RunningFlags.None)
continue;
if (GetRunningFlag(f) && SpeedHandler.GetSpeedType(f) == SpeedControl.WalkSpeed)
return true;
}
return false;
}
#endregion
And in another file i called SpeedHandler.cs
Code:
using Server.Network;
using System;
namespace Server
{
[Flags]
public enum RunningFlags
{
None = 0x00000000,
Flying = 0x00000001,
Sleep = 0x00000002,
ReaperForm = 0x00000004,
//WalkAnimalForm = 0x00000008,
StoneForm = 0x00000010,
TwistedWeald = 0x00000020,
Grizzle = 0x00000040,
SpeedBoost = 0x00000080,
AnimalForm = 0x00000100,
//Requiem - CUSTOM
Bola = 0x00000200,
TPBlocked = 0x00000400,
GuerrieroStile = 0x00000800,
}
public class SpeedHandler
{
public static Packet GetSpeedType(RunningFlags flag)
{
RunningFlags fl = flag;
Packet modspeed = null;
switch (fl)
{
case RunningFlags.Flying:
case RunningFlags.AnimalForm:
case RunningFlags.SpeedBoost:
modspeed = SpeedControl.MountSpeed; break;
case RunningFlags.Grizzle:
case RunningFlags.ReaperForm:
case RunningFlags.Sleep:
case RunningFlags.StoneForm:
case RunningFlags.TwistedWeald:
//case RunningFlags.WalkAnimalForm:
//Requiem
case RunningFlags.Bola:
case RunningFlags.GuerrieroStile:
case RunningFlags.TPBlocked:
modspeed = SpeedControl.WalkSpeed; break;
default: break;
}
return modspeed;
}
}
}
then just simply change any
Code:
pm.Send(SpeedControl.Something)
Code:
pm.SwitchSpeedControl(RunningFlags.CurrentFlag, AmIActivatingTheFlag?)
Any suggestion would be welcome