fix: Fixes NPC slowness. (#955)
* Adds the following configurations: * `movement.delay.npcMinDelay` - 0.1 - Pets or Non-monster NPCs * `movement.delay.npcMaxDelay` - 0.4 - Pets or Non-monster NPCs * `movement.delay.monsterMinDelay` - 0.4 - Non-pet Monsters or NPC vs Player Combat * `movement.delay.monsterMaxDelay` - 0.8 - Non-pet Monsters or NPC vs Player Combat * `movement.delay.monsterMinDex` - 150 - Dex maximum for delay by dex * `movement.delay.MinDex` - 190 - Dex maximum for delay by dex
This commit is contained in:
parent
44bd129734
commit
bdee7bc671
357 changed files with 767 additions and 962 deletions
|
|
@ -1,6 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Server.ContextMenus;
|
||||
using Server.Engines.Quests;
|
||||
using Server.Engines.Quests.Necro;
|
||||
|
|
@ -810,31 +809,45 @@ namespace Server.Mobiles
|
|||
switch (Action)
|
||||
{
|
||||
case ActionType.Wander:
|
||||
m_Mobile.OnActionWander();
|
||||
return DoActionWander();
|
||||
{
|
||||
m_Mobile.OnActionWander();
|
||||
return DoActionWander();
|
||||
}
|
||||
|
||||
case ActionType.Combat:
|
||||
m_Mobile.OnActionCombat();
|
||||
return DoActionCombat();
|
||||
{
|
||||
m_Mobile.OnActionCombat();
|
||||
return DoActionCombat();
|
||||
}
|
||||
|
||||
case ActionType.Guard:
|
||||
m_Mobile.OnActionGuard();
|
||||
return DoActionGuard();
|
||||
{
|
||||
m_Mobile.OnActionGuard();
|
||||
return DoActionGuard();
|
||||
}
|
||||
|
||||
case ActionType.Flee:
|
||||
m_Mobile.OnActionFlee();
|
||||
return DoActionFlee();
|
||||
{
|
||||
m_Mobile.OnActionFlee();
|
||||
return DoActionFlee();
|
||||
}
|
||||
|
||||
case ActionType.Interact:
|
||||
m_Mobile.OnActionInteract();
|
||||
return DoActionInteract();
|
||||
{
|
||||
m_Mobile.OnActionInteract();
|
||||
return DoActionInteract();
|
||||
}
|
||||
|
||||
case ActionType.Backoff:
|
||||
m_Mobile.OnActionBackoff();
|
||||
return DoActionBackoff();
|
||||
{
|
||||
m_Mobile.OnActionBackoff();
|
||||
return DoActionBackoff();
|
||||
}
|
||||
|
||||
default:
|
||||
return false;
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -843,42 +856,54 @@ namespace Server.Mobiles
|
|||
switch (Action)
|
||||
{
|
||||
case ActionType.Wander:
|
||||
m_Mobile.Warmode = false;
|
||||
m_Mobile.Combatant = null;
|
||||
m_Mobile.FocusMob = null;
|
||||
m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed;
|
||||
break;
|
||||
{
|
||||
m_Mobile.Warmode = false;
|
||||
m_Mobile.Combatant = null;
|
||||
m_Mobile.FocusMob = null;
|
||||
m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed;
|
||||
break;
|
||||
}
|
||||
|
||||
case ActionType.Combat:
|
||||
m_Mobile.Warmode = true;
|
||||
m_Mobile.FocusMob = null;
|
||||
m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed;
|
||||
break;
|
||||
{
|
||||
m_Mobile.Warmode = true;
|
||||
m_Mobile.FocusMob = null;
|
||||
m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed;
|
||||
break;
|
||||
}
|
||||
|
||||
case ActionType.Guard:
|
||||
m_Mobile.Warmode = true;
|
||||
m_Mobile.FocusMob = null;
|
||||
m_Mobile.Combatant = null;
|
||||
m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed;
|
||||
m_NextStopGuard = Core.TickCount + (int)TimeSpan.FromSeconds(10).TotalMilliseconds;
|
||||
m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed;
|
||||
break;
|
||||
{
|
||||
m_Mobile.Warmode = true;
|
||||
m_Mobile.FocusMob = null;
|
||||
m_Mobile.Combatant = null;
|
||||
m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed;
|
||||
m_NextStopGuard = Core.TickCount + (int)TimeSpan.FromSeconds(10).TotalMilliseconds;
|
||||
m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed;
|
||||
break;
|
||||
}
|
||||
|
||||
case ActionType.Flee:
|
||||
m_Mobile.Warmode = true;
|
||||
m_Mobile.FocusMob = null;
|
||||
m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed;
|
||||
break;
|
||||
{
|
||||
m_Mobile.Warmode = true;
|
||||
m_Mobile.FocusMob = null;
|
||||
m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed;
|
||||
break;
|
||||
}
|
||||
|
||||
case ActionType.Interact:
|
||||
m_Mobile.Warmode = false;
|
||||
m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed;
|
||||
break;
|
||||
{
|
||||
m_Mobile.Warmode = false;
|
||||
m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed;
|
||||
break;
|
||||
}
|
||||
|
||||
case ActionType.Backoff:
|
||||
m_Mobile.Warmode = false;
|
||||
m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed;
|
||||
break;
|
||||
{
|
||||
m_Mobile.Warmode = false;
|
||||
m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1012,12 +1037,7 @@ namespace Server.Mobiles
|
|||
|
||||
public virtual bool Obey()
|
||||
{
|
||||
if (m_Mobile.Deleted)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return m_Mobile.ControlOrder switch
|
||||
var shouldObey = !m_Mobile.Deleted && m_Mobile.ControlOrder switch
|
||||
{
|
||||
OrderType.None => DoOrderNone(),
|
||||
OrderType.Come => DoOrderCome(),
|
||||
|
|
@ -1034,6 +1054,15 @@ namespace Server.Mobiles
|
|||
OrderType.Transfer => DoOrderTransfer(),
|
||||
_ => false
|
||||
};
|
||||
|
||||
if (shouldObey)
|
||||
{
|
||||
// TODO: This might cause the movement timer to reset too often if someone is spamming commands.
|
||||
// Test this thoroughly.
|
||||
m_Mobile.ResetSpeeds();
|
||||
}
|
||||
|
||||
return shouldObey;
|
||||
}
|
||||
|
||||
public virtual void OnCurrentOrderChanged()
|
||||
|
|
@ -1046,104 +1075,128 @@ namespace Server.Mobiles
|
|||
switch (m_Mobile.ControlOrder)
|
||||
{
|
||||
case OrderType.None:
|
||||
m_Mobile.ControlMaster.RevealingAction();
|
||||
m_Mobile.Home = m_Mobile.Location;
|
||||
m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed;
|
||||
m_Mobile.PlaySound(m_Mobile.GetIdleSound());
|
||||
m_Mobile.Warmode = false;
|
||||
m_Mobile.Combatant = null;
|
||||
break;
|
||||
{
|
||||
m_Mobile.ControlMaster.RevealingAction();
|
||||
m_Mobile.Home = m_Mobile.Location;
|
||||
m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed;
|
||||
m_Mobile.PlaySound(m_Mobile.GetIdleSound());
|
||||
m_Mobile.Warmode = false;
|
||||
m_Mobile.Combatant = null;
|
||||
break;
|
||||
}
|
||||
|
||||
case OrderType.Come:
|
||||
m_Mobile.ControlMaster.RevealingAction();
|
||||
m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed;
|
||||
m_Mobile.PlaySound(m_Mobile.GetIdleSound());
|
||||
m_Mobile.Warmode = false;
|
||||
m_Mobile.Combatant = null;
|
||||
break;
|
||||
{
|
||||
m_Mobile.ControlMaster.RevealingAction();
|
||||
m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed;
|
||||
m_Mobile.PlaySound(m_Mobile.GetIdleSound());
|
||||
m_Mobile.Warmode = false;
|
||||
m_Mobile.Combatant = null;
|
||||
break;
|
||||
}
|
||||
|
||||
case OrderType.Drop:
|
||||
m_Mobile.ControlMaster.RevealingAction();
|
||||
m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed;
|
||||
m_Mobile.PlaySound(m_Mobile.GetIdleSound());
|
||||
m_Mobile.Warmode = true;
|
||||
m_Mobile.Combatant = null;
|
||||
break;
|
||||
{
|
||||
m_Mobile.ControlMaster.RevealingAction();
|
||||
m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed;
|
||||
m_Mobile.PlaySound(m_Mobile.GetIdleSound());
|
||||
m_Mobile.Warmode = true;
|
||||
m_Mobile.Combatant = null;
|
||||
break;
|
||||
}
|
||||
|
||||
case OrderType.Friend:
|
||||
case OrderType.Unfriend:
|
||||
m_Mobile.ControlMaster.RevealingAction();
|
||||
break;
|
||||
{
|
||||
m_Mobile.ControlMaster.RevealingAction();
|
||||
break;
|
||||
}
|
||||
|
||||
case OrderType.Guard:
|
||||
m_Mobile.ControlMaster.RevealingAction();
|
||||
m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed;
|
||||
m_Mobile.PlaySound(m_Mobile.GetIdleSound());
|
||||
m_Mobile.Warmode = true;
|
||||
m_Mobile.Combatant = null;
|
||||
var petname = $"{m_Mobile.Name}";
|
||||
m_Mobile.ControlMaster.SendLocalizedMessage(1049671, petname); // ~1_PETNAME~ is now guarding you.
|
||||
break;
|
||||
{
|
||||
m_Mobile.ControlMaster.RevealingAction();
|
||||
m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed;
|
||||
m_Mobile.PlaySound(m_Mobile.GetIdleSound());
|
||||
m_Mobile.Warmode = true;
|
||||
m_Mobile.Combatant = null;
|
||||
var petname = $"{m_Mobile.Name}";
|
||||
m_Mobile.ControlMaster.SendLocalizedMessage(1049671, petname); // ~1_PETNAME~ is now guarding you.
|
||||
break;
|
||||
}
|
||||
|
||||
case OrderType.Attack:
|
||||
m_Mobile.ControlMaster.RevealingAction();
|
||||
m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed;
|
||||
m_Mobile.PlaySound(m_Mobile.GetIdleSound());
|
||||
{
|
||||
m_Mobile.ControlMaster.RevealingAction();
|
||||
m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed;
|
||||
m_Mobile.PlaySound(m_Mobile.GetIdleSound());
|
||||
|
||||
m_Mobile.Warmode = true;
|
||||
m_Mobile.Combatant = null;
|
||||
break;
|
||||
m_Mobile.Warmode = true;
|
||||
m_Mobile.Combatant = null;
|
||||
break;
|
||||
}
|
||||
|
||||
case OrderType.Patrol:
|
||||
m_Mobile.ControlMaster.RevealingAction();
|
||||
m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed;
|
||||
m_Mobile.PlaySound(m_Mobile.GetIdleSound());
|
||||
m_Mobile.Warmode = false;
|
||||
m_Mobile.Combatant = null;
|
||||
break;
|
||||
{
|
||||
m_Mobile.ControlMaster.RevealingAction();
|
||||
m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed;
|
||||
m_Mobile.PlaySound(m_Mobile.GetIdleSound());
|
||||
m_Mobile.Warmode = false;
|
||||
m_Mobile.Combatant = null;
|
||||
break;
|
||||
}
|
||||
|
||||
case OrderType.Release:
|
||||
m_Mobile.ControlMaster.RevealingAction();
|
||||
m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed;
|
||||
m_Mobile.PlaySound(m_Mobile.GetIdleSound());
|
||||
m_Mobile.Warmode = false;
|
||||
m_Mobile.Combatant = null;
|
||||
break;
|
||||
{
|
||||
m_Mobile.ControlMaster.RevealingAction();
|
||||
m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed;
|
||||
m_Mobile.PlaySound(m_Mobile.GetIdleSound());
|
||||
m_Mobile.Warmode = false;
|
||||
m_Mobile.Combatant = null;
|
||||
break;
|
||||
}
|
||||
|
||||
case OrderType.Stay:
|
||||
m_Mobile.ControlMaster.RevealingAction();
|
||||
m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed;
|
||||
m_Mobile.PlaySound(m_Mobile.GetIdleSound());
|
||||
m_Mobile.Warmode = false;
|
||||
m_Mobile.Combatant = null;
|
||||
break;
|
||||
{
|
||||
m_Mobile.ControlMaster.RevealingAction();
|
||||
m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed;
|
||||
m_Mobile.PlaySound(m_Mobile.GetIdleSound());
|
||||
m_Mobile.Warmode = false;
|
||||
m_Mobile.Combatant = null;
|
||||
break;
|
||||
}
|
||||
|
||||
case OrderType.Stop:
|
||||
m_Mobile.ControlMaster.RevealingAction();
|
||||
m_Mobile.Home = m_Mobile.Location;
|
||||
m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed;
|
||||
m_Mobile.PlaySound(m_Mobile.GetIdleSound());
|
||||
m_Mobile.Warmode = false;
|
||||
m_Mobile.Combatant = null;
|
||||
break;
|
||||
{
|
||||
m_Mobile.ControlMaster.RevealingAction();
|
||||
m_Mobile.Home = m_Mobile.Location;
|
||||
m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed;
|
||||
m_Mobile.PlaySound(m_Mobile.GetIdleSound());
|
||||
m_Mobile.Warmode = false;
|
||||
m_Mobile.Combatant = null;
|
||||
break;
|
||||
}
|
||||
|
||||
case OrderType.Follow:
|
||||
m_Mobile.ControlMaster.RevealingAction();
|
||||
m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed;
|
||||
m_Mobile.PlaySound(m_Mobile.GetIdleSound());
|
||||
{
|
||||
m_Mobile.ControlMaster.RevealingAction();
|
||||
m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed;
|
||||
m_Mobile.PlaySound(m_Mobile.GetIdleSound());
|
||||
|
||||
m_Mobile.Warmode = false;
|
||||
m_Mobile.Combatant = null;
|
||||
break;
|
||||
m_Mobile.Warmode = false;
|
||||
m_Mobile.Combatant = null;
|
||||
break;
|
||||
}
|
||||
|
||||
case OrderType.Transfer:
|
||||
m_Mobile.ControlMaster.RevealingAction();
|
||||
m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed;
|
||||
m_Mobile.PlaySound(m_Mobile.GetIdleSound());
|
||||
{
|
||||
m_Mobile.ControlMaster.RevealingAction();
|
||||
m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed;
|
||||
m_Mobile.PlaySound(m_Mobile.GetIdleSound());
|
||||
|
||||
m_Mobile.Warmode = false;
|
||||
m_Mobile.Combatant = null;
|
||||
break;
|
||||
m_Mobile.Warmode = false;
|
||||
m_Mobile.Combatant = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1824,32 +1877,50 @@ namespace Server.Mobiles
|
|||
switch (iRndMove)
|
||||
{
|
||||
case 0:
|
||||
DoMove(Direction.Up);
|
||||
break;
|
||||
{
|
||||
DoMove(Direction.Up);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
DoMove(Direction.North);
|
||||
break;
|
||||
{
|
||||
DoMove(Direction.North);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
DoMove(Direction.Left);
|
||||
break;
|
||||
{
|
||||
DoMove(Direction.Left);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
DoMove(Direction.West);
|
||||
break;
|
||||
{
|
||||
DoMove(Direction.West);
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
DoMove(Direction.Down);
|
||||
break;
|
||||
{
|
||||
DoMove(Direction.Down);
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
DoMove(Direction.South);
|
||||
break;
|
||||
{
|
||||
DoMove(Direction.South);
|
||||
break;
|
||||
}
|
||||
case 7:
|
||||
DoMove(Direction.Right);
|
||||
break;
|
||||
{
|
||||
DoMove(Direction.Right);
|
||||
break;
|
||||
}
|
||||
case 8:
|
||||
DoMove(Direction.East);
|
||||
break;
|
||||
{
|
||||
DoMove(Direction.East);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
DoMove(m_Mobile.Direction);
|
||||
break;
|
||||
{
|
||||
DoMove(m_Mobile.Direction);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1857,100 +1928,24 @@ namespace Server.Mobiles
|
|||
|
||||
public double TransformMoveDelay(double delay)
|
||||
{
|
||||
var isPassive = delay == m_Mobile.PassiveSpeed;
|
||||
var isControlled = m_Mobile.Controlled || m_Mobile.Summoned;
|
||||
double max = m_Mobile.IsMonster ? SpeedInfo.MaxMonsterDelay : SpeedInfo.MaxDelay;
|
||||
|
||||
if (delay == 0.2)
|
||||
if (!m_Mobile.IsDeadPet && (m_Mobile.ReduceSpeedWithDamage || m_Mobile.IsSubdued))
|
||||
{
|
||||
delay = 0.3;
|
||||
}
|
||||
else if (delay == 0.25)
|
||||
{
|
||||
delay = 0.45;
|
||||
}
|
||||
else if (delay == 0.3)
|
||||
{
|
||||
delay = 0.6;
|
||||
}
|
||||
else if (delay == 0.4)
|
||||
{
|
||||
delay = 0.9;
|
||||
}
|
||||
else if (delay == 0.5)
|
||||
{
|
||||
delay = 1.05;
|
||||
}
|
||||
else if (delay == 0.6)
|
||||
{
|
||||
delay = 1.2;
|
||||
}
|
||||
else if (delay == 0.8)
|
||||
{
|
||||
delay = 1.5;
|
||||
}
|
||||
double offset = m_Mobile.StamMax <= 0 ? 1.0 : m_Mobile.Stam / (double)m_Mobile.StamMax;
|
||||
|
||||
if (isPassive)
|
||||
{
|
||||
delay += 0.2;
|
||||
}
|
||||
|
||||
if (!isControlled)
|
||||
{
|
||||
delay += 0.1;
|
||||
}
|
||||
else if (m_Mobile.Controlled)
|
||||
{
|
||||
if (m_Mobile.ControlOrder == OrderType.Follow && m_Mobile.ControlTarget == m_Mobile.ControlMaster)
|
||||
if (offset < 1.0)
|
||||
{
|
||||
delay *= 0.5;
|
||||
delay += (max - delay) * (1.0 - offset);
|
||||
}
|
||||
|
||||
delay -= 0.075;
|
||||
}
|
||||
|
||||
if (m_Mobile.ReduceSpeedWithDamage || m_Mobile.IsSubdued)
|
||||
{
|
||||
var offset = (double)m_Mobile.Hits / m_Mobile.HitsMax;
|
||||
|
||||
if (offset < 0.0)
|
||||
{
|
||||
offset = 0.0;
|
||||
}
|
||||
else if (offset > 1.0)
|
||||
{
|
||||
offset = 1.0;
|
||||
}
|
||||
|
||||
offset = 1.0 - offset;
|
||||
|
||||
delay += offset * 0.8;
|
||||
}
|
||||
|
||||
if (delay < 0.0)
|
||||
{
|
||||
delay = 0.0;
|
||||
}
|
||||
|
||||
if (double.IsNaN(delay))
|
||||
{
|
||||
using (var op = new StreamWriter("nan_transform.txt", true))
|
||||
{
|
||||
op.WriteLine(
|
||||
$"NaN in TransformMoveDelay: {Core.Now}, {GetType()}, {m_Mobile?.GetType()}, {m_Mobile.HitsMax}"
|
||||
);
|
||||
}
|
||||
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
return delay;
|
||||
return Math.Min(delay, max);
|
||||
}
|
||||
|
||||
public virtual bool CheckMove() => Core.TickCount - NextMove >= 0;
|
||||
|
||||
public virtual bool DoMove(Direction d) => DoMove(d, false);
|
||||
|
||||
public virtual bool DoMove(Direction d, bool badStateOk)
|
||||
public virtual bool DoMove(Direction d, bool badStateOk = false)
|
||||
{
|
||||
var res = DoMoveImpl(d);
|
||||
|
||||
|
|
@ -2712,7 +2707,7 @@ namespace Server.Mobiles
|
|||
public virtual void OnCurrentSpeedChanged()
|
||||
{
|
||||
m_Timer.Stop();
|
||||
m_Timer.Delay = TimeSpan.FromSeconds(Utility.RandomDouble());
|
||||
m_Timer.Delay = TimeSpan.FromMilliseconds(Utility.Random(128) * 8);
|
||||
m_Timer.Interval = TimeSpan.FromSeconds(Math.Max(0.0, m_Mobile.CurrentSpeed));
|
||||
m_Timer.Start();
|
||||
}
|
||||
|
|
@ -2740,70 +2735,72 @@ namespace Server.Mobiles
|
|||
|
||||
public override void OnClick()
|
||||
{
|
||||
if (!m_Mobile.Deleted && m_Mobile.Controlled && m_From.CheckAlive())
|
||||
if (m_Mobile.Deleted || !m_Mobile.Controlled || !m_From.CheckAlive())
|
||||
{
|
||||
if (m_Mobile.IsDeadPet && m_Order is OrderType.Guard or OrderType.Attack or OrderType.Transfer or OrderType.Drop)
|
||||
{
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var isOwner = m_From == m_Mobile.ControlMaster;
|
||||
var isFriend = !isOwner && m_Mobile.IsPetFriend(m_From);
|
||||
if (m_Mobile.IsDeadPet && m_Order is OrderType.Guard or OrderType.Attack or OrderType.Transfer or OrderType.Drop)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isOwner && !isFriend)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var isOwner = m_From == m_Mobile.ControlMaster;
|
||||
var isFriend = !isOwner && m_Mobile.IsPetFriend(m_From);
|
||||
|
||||
if (isFriend && m_Order != OrderType.Follow && m_Order != OrderType.Stay && m_Order != OrderType.Stop)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!isOwner && !isFriend)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (m_Order)
|
||||
{
|
||||
case OrderType.Follow:
|
||||
case OrderType.Attack:
|
||||
case OrderType.Transfer:
|
||||
case OrderType.Friend:
|
||||
case OrderType.Unfriend:
|
||||
if (isFriend && m_Order != OrderType.Follow && m_Order != OrderType.Stay && m_Order != OrderType.Stop)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (m_Order)
|
||||
{
|
||||
case OrderType.Follow:
|
||||
case OrderType.Attack:
|
||||
case OrderType.Transfer:
|
||||
case OrderType.Friend:
|
||||
case OrderType.Unfriend:
|
||||
{
|
||||
if (m_Order == OrderType.Transfer && m_From.HasTrade)
|
||||
{
|
||||
if (m_Order == OrderType.Transfer && m_From.HasTrade)
|
||||
{
|
||||
m_From.SendLocalizedMessage(1010507); // You cannot transfer a pet with a trade pending
|
||||
}
|
||||
else if (m_Order == OrderType.Friend && m_From.HasTrade)
|
||||
{
|
||||
m_From.SendLocalizedMessage(1070947); // You cannot friend a pet with a trade pending
|
||||
}
|
||||
else
|
||||
{
|
||||
m_AI.BeginPickTarget(m_From, m_Order);
|
||||
}
|
||||
|
||||
break;
|
||||
m_From.SendLocalizedMessage(1010507); // You cannot transfer a pet with a trade pending
|
||||
}
|
||||
case OrderType.Release:
|
||||
else if (m_Order == OrderType.Friend && m_From.HasTrade)
|
||||
{
|
||||
if (m_Mobile.Summoned)
|
||||
{
|
||||
goto default;
|
||||
}
|
||||
|
||||
m_From.SendGump(new ConfirmReleaseGump(m_From, m_Mobile));
|
||||
|
||||
break;
|
||||
m_From.SendLocalizedMessage(1070947); // You cannot friend a pet with a trade pending
|
||||
}
|
||||
default:
|
||||
else
|
||||
{
|
||||
if (m_Mobile.CheckControlChance(m_From))
|
||||
{
|
||||
m_Mobile.ControlOrder = m_Order;
|
||||
}
|
||||
|
||||
break;
|
||||
m_AI.BeginPickTarget(m_From, m_Order);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case OrderType.Release:
|
||||
{
|
||||
if (m_Mobile.Summoned)
|
||||
{
|
||||
goto default;
|
||||
}
|
||||
|
||||
m_From.SendGump(new ConfirmReleaseGump(m_From, m_Mobile));
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (m_Mobile.CheckControlChance(m_From))
|
||||
{
|
||||
m_Mobile.ControlOrder = m_Order;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2904,14 +2901,10 @@ namespace Server.Mobiles
|
|||
{
|
||||
var args = $"{to.Name}\t{from.Name}\t ";
|
||||
|
||||
from.SendLocalizedMessage(
|
||||
1043248,
|
||||
args
|
||||
); // The pet refuses to be transferred because it will not obey ~1_NAME~.~3_BLANK~
|
||||
to.SendLocalizedMessage(
|
||||
1043249,
|
||||
args
|
||||
); // The pet will not accept you as a master because it does not trust you.~3_BLANK~
|
||||
// The pet refuses to be transferred because it will not obey ~1_NAME~.~3_BLANK~
|
||||
from.SendLocalizedMessage(1043248, args);
|
||||
// The pet will not accept you as a master because it does not trust you.~3_BLANK~
|
||||
to.SendLocalizedMessage(1043249, args);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -2919,14 +2912,10 @@ namespace Server.Mobiles
|
|||
{
|
||||
var args = $"{to.Name}\t{from.Name}\t ";
|
||||
|
||||
from.SendLocalizedMessage(
|
||||
1043250,
|
||||
args
|
||||
); // The pet refuses to be transferred because it will not obey you sufficiently.~3_BLANK~
|
||||
to.SendLocalizedMessage(
|
||||
1043251,
|
||||
args
|
||||
); // The pet will not accept you as a master because it does not trust ~2_NAME~.~3_BLANK~
|
||||
// The pet refuses to be transferred because it will not obey you sufficiently.~3_BLANK~
|
||||
from.SendLocalizedMessage(1043250, args);
|
||||
// The pet will not accept you as a master because it does not trust ~2_NAME~.~3_BLANK~
|
||||
to.SendLocalizedMessage(1043251, args);
|
||||
}
|
||||
else if (accepted && to.Followers + m_Creature.ControlSlots > to.FollowersMax)
|
||||
{
|
||||
|
|
@ -2986,10 +2975,8 @@ namespace Server.Mobiles
|
|||
var args = $"{from.Name}\t{m_Creature.Name}\t{to.Name}";
|
||||
|
||||
from.SendLocalizedMessage(1043253, args); // You have transferred your pet to ~3_GETTER~.
|
||||
to.SendLocalizedMessage(
|
||||
1043252,
|
||||
args
|
||||
); // ~1_NAME~ has transferred the allegiance of ~2_PET_NAME~ to you.
|
||||
// ~1_NAME~ has transferred the allegiance of ~2_PET_NAME~ to you.
|
||||
to.SendLocalizedMessage(1043252, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3004,7 +2991,7 @@ namespace Server.Mobiles
|
|||
|
||||
public AITimer(BaseAI owner)
|
||||
: base(
|
||||
TimeSpan.FromSeconds(Utility.RandomDouble()),
|
||||
TimeSpan.FromSeconds(Utility.Random(128) * 8),
|
||||
TimeSpan.FromSeconds(Math.Max(0.0, owner.m_Mobile.CurrentSpeed))
|
||||
)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue