ModernUO/Projects/UOContent/Items/Addons/SolenAntHole.cs
Kamron Batman 4ddb3de026
fix(core): Fixes several serialization issues (#355)
- [X] Fixes an issue where a buffer smaller than 8 bytes would not double with enough space in some cases.
- [X] Fixes an issue with dupe copying the savebuffer reference (ugh).
- [X] Streamlines the IGenericWriter API to use better generics.
- [X] Streamlines the IGenericReader API to use better generics.
- [X] Forces `tidying` of a List/HashSet to be done externally since Writers/Readers should not have side effects.
- [X] Fixes an issue where Tidying a list didn't TrimExcess, causing memory leaks.
- [X] Reverted the meaning of `World.Running` to specifically refer to any world state post world loading.
  - NOTE: Do not use this if you want to block on world saves. Instead use checks against `WorldState.Saving` states.
- [X] Fixes an issue with serializing negative DateTime deltas.
- [X] Fixes a potential issue with serializing non-UTC DateTime.

Bumps release version
2020-12-23 07:11:41 -08:00

194 lines
5.3 KiB
C#

using System.Collections.Generic;
using Server.Mobiles;
using Server.Network;
using Server.Spells;
namespace Server.Items
{
public class SolenAntHoleComponent : AddonComponent
{
public SolenAntHoleComponent(int itemID) : base(itemID)
{
}
public SolenAntHoleComponent(Serial serial) : base(serial)
{
}
public override void OnDoubleClick(Mobile from)
{
if (from.InRange(this, 2))
{
var map = Map;
if (map == Map.Trammel || map == Map.Felucca)
{
from.MoveToWorld(new Point3D(5922, 2024, 0), map);
PublicOverheadMessage(
MessageType.Regular,
0x3B2,
true,
$"* {from.Name} dives into the hole and disappears!*"
);
}
}
else
{
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
}
}
public class SolenAntHole : BaseAddon
{
private List<Mobile> m_Spawned;
[Constructible]
public SolenAntHole()
{
m_Spawned = new List<Mobile>();
AddComponent(new AddonComponent(0x914), "dirt", 0, 0, 0, 0);
AddComponent(new SolenAntHoleComponent(0x122A), "a hole", 0x1, 0, 0, 0);
AddComponent(new AddonComponent(0x1B23), "dirt", 0x970, 1, 1, 0);
AddComponent(new AddonComponent(0xEE0), "dirt", 0, 1, 0, 0);
AddComponent(new AddonComponent(0x1B24), "dirt", 0x970, 1, -1, 0);
AddComponent(new AddonComponent(0xEE1), "dirt", 0, 0, -1, 0);
AddComponent(new AddonComponent(0x1B25), "dirt", 0x970, -1, -1, 0);
AddComponent(new AddonComponent(0xEE2), "dirt", 0, -1, 0, 0);
AddComponent(new AddonComponent(0x1B26), "dirt", 0x970, -1, 1, 0);
AddComponent(new AddonComponent(0xED3), "dirt", 0, 0, 1, 0);
}
public SolenAntHole(Serial serial) : base(serial)
{
}
public override bool ShareHue => false;
public override bool HandlesOnMovement => true;
public override void OnMovement(Mobile m, Point3D oldLocation)
{
if (!m.Player || !m.Alive || m.Hidden || !SpawnKilled())
{
return;
}
if (Utility.InRange(Location, m.Location, 3) && !Utility.InRange(Location, oldLocation, 3))
{
var count = 1 + Utility.Random(4);
for (var i = 0; i < count; i++)
{
SpawnAnt();
}
if (Utility.RandomDouble() < 0.05)
{
SpawnAnt(new Beetle());
}
}
}
public void AddComponent(AddonComponent c, string name, int hue, int x, int y, int z)
{
c.Hue = hue;
c.Name = name;
AddComponent(c, x, y, z);
}
public void SpawnAnt()
{
var random = Utility.Random(3);
var map = Map;
if (map == Map.Trammel)
{
if (random < 2)
{
SpawnAnt(new RedSolenWorker());
}
else
{
SpawnAnt(new RedSolenWarrior());
}
}
else if (map == Map.Felucca)
{
if (random < 2)
{
SpawnAnt(new BlackSolenWorker());
}
else
{
SpawnAnt(new BlackSolenWarrior());
}
}
}
public void SpawnAnt(BaseCreature ant)
{
m_Spawned.Add(ant);
var map = Map;
var p = Location;
for (var i = 0; i < 5; i++)
{
if (SpellHelper.FindValidSpawnLocation(map, ref p, false))
{
break;
}
}
ant.MoveToWorld(p, map);
ant.Home = Location;
ant.RangeHome = 10;
}
public bool SpawnKilled()
{
for (var i = m_Spawned.Count - 1; i >= 0; i--)
{
if (!m_Spawned[i].Alive || m_Spawned[i].Deleted)
{
m_Spawned.RemoveAt(i);
}
}
return m_Spawned.Count < 2;
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
writer.Write(m_Spawned);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
m_Spawned = reader.ReadEntityList<Mobile>();
}
}
}