fix: Changes Map.Sector.Mobiles to link list & Fixes various related crash bugs (#1553)
### Summary
Eliminates `IPooledEnumerable<T>` and `eable.Free()` from `Map` for mobiles. This drastically simplifies code that iterates in range, for example:
```cs
foreach (var m in m.GetMobilesInRange(5))
{
}
```
The code above no longer requires an eable and calling `Free()`.
- [X] Fixed several locations where an NPC that was damaged would cause a server crash.
- [X] Removed an unnecessary allocation in guard fake calls (NPCs calling guards on you)
- [X] Fixes damage precision loss in Poison Strike Spell
- [X] BogThing no longer attempts to "search" for boglings to eat when it is at full health
This commit is contained in:
parent
27f0cec1fa
commit
28c06c1cc0
71 changed files with 796 additions and 591 deletions
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using ModernUO.Serialization;
|
||||
using Server.Collections;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
using Server.Spells;
|
||||
|
|
@ -605,30 +606,35 @@ public partial class LeverPuzzleController : Item
|
|||
PlayerSendASCII(m_Player, 1); // A speeding rock ...
|
||||
PlaySounds(m_Player.Location, !m_Player.Female ? fs2 : ms2);
|
||||
|
||||
using var queue = PooledRefQueue<Mobile>.Create();
|
||||
var j = Utility.Random(6, 10);
|
||||
for (var i = 0; i < j; i++)
|
||||
{
|
||||
IEntity m_IEntity = new Entity(Serial.Zero, RandomPointIn(m_Player.Location, 10), m_Player.Map);
|
||||
var entity = new Entity(Serial.Zero, RandomPointIn(m_Player.Location, 10), m_Player.Map);
|
||||
|
||||
var eable = m_IEntity.Map.GetMobilesInRange(m_IEntity.Location, 2);
|
||||
var mobiles = new List<Mobile>();
|
||||
mobiles.AddRange(eable);
|
||||
|
||||
for (var k = 0; k < mobiles.Count; k++)
|
||||
// Queue the mobiles because we cannot modify while iterating through mobiles in range
|
||||
foreach (var m in entity.Map.GetMobilesInRange(entity.Location, 2))
|
||||
{
|
||||
if (IsValidDamagable(mobiles[k]) && mobiles[k] != m_Player)
|
||||
if (IsValidDamagable(m) && m != m_Player)
|
||||
{
|
||||
PlayEffect(m_Player, mobiles[k], Rock(), 8, true);
|
||||
DoDamage(mobiles[k], 25, 30, false);
|
||||
|
||||
if (mobiles[k].Player)
|
||||
{
|
||||
POHMessage(mobiles[k], 2); // OUCH!
|
||||
}
|
||||
queue.Enqueue(m);
|
||||
}
|
||||
}
|
||||
|
||||
PlayEffect(m_Player, m_IEntity, Rock(), 8, false);
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
var m = queue.Dequeue();
|
||||
|
||||
PlayEffect(m_Player, m, Rock(), 8, true);
|
||||
DoDamage(m, 25, 30, false);
|
||||
|
||||
if (m.Player)
|
||||
{
|
||||
POHMessage(m, 2); // OUCH!
|
||||
}
|
||||
}
|
||||
|
||||
PlayEffect(m_Player, entity, Rock(), 8, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Collections;
|
||||
using Server.Factions;
|
||||
using Server.Spells;
|
||||
using Server.Targeting;
|
||||
|
|
@ -90,20 +90,21 @@ namespace Server
|
|||
|
||||
private static void OnHit(Mobile from, Point3D origin, Map facet)
|
||||
{
|
||||
var eable = facet.GetMobilesInRange(origin, 12);
|
||||
var targets = new List<Mobile>();
|
||||
foreach (var m in eable)
|
||||
using var queue = PooledRefQueue<Mobile>.Create();
|
||||
foreach (var m in facet.GetMobilesInRange(origin, 12))
|
||||
{
|
||||
if (from.CanBeHarmful(m, false) &&
|
||||
m.InLOS(new Point3D(origin.X, origin.Y, origin.Z + 1)) &&
|
||||
Faction.Find(m) != null)
|
||||
{
|
||||
targets.Add(from);
|
||||
queue.Enqueue(from);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var mob in targets)
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
var mob = queue.Dequeue();
|
||||
|
||||
var damage = mob.Hits * 6 / 10;
|
||||
|
||||
if (!mob.Player && damage < 10)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue