Files
Unstable Kitsune b918192e4e Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
2023-11-28 23:20:26 -05:00

257 lines
6.3 KiB
C#

using System;
using Server;
using System.Collections.Generic;
using Server.Mobiles;
using System.Linq;
using Server.Engines.Quests;
namespace Server.Items
{
public class NestWithEgg : BaseAddon
{
public TimeSpan ResetPeriod { get { return TimeSpan.FromSeconds(Utility.RandomMinMax(120, 360)); } }
public List<BaseCreature> Poachers { get; set; }
public List<Mobile> FocusList { get; set; }
public BaseCreature Hatchling { get; set; }
public Mobile Focus { get; set; }
public bool IsHatching { get; set; }
public DateTime CooldownEnds { get; set; }
public Timer DeadlineTimer { get; set; }
public AddonComponent Egg
{
get
{
return Components.FirstOrDefault(c => c.ItemID == 16831);
}
}
public bool IsInCooldown { get { return CooldownEnds != DateTime.MinValue && DateTime.UtcNow < CooldownEnds; } }
[Constructable]
public NestWithEgg()
{
AddonComponent comp = new LocalizedAddonComponent(3518, 1026869);
comp.Hue = 449;
AddComponent(comp, 0, 0, 0);
comp = new LocalizedAddonComponent(3270, 1026869);
comp.Hue = 551;
AddComponent(comp, 0, 0, 2);
comp = new LocalizedAddonComponent(3374, 1026869);
comp.Hue = 551;
AddComponent(comp, 0, 0, 2);
comp = new LocalizedAddonComponent(16831, 1112469);
AddComponent(comp, 1, 1, 15);
FocusList = new List<Mobile>();
}
public override bool HandlesOnMovement { get { return !IsInCooldown; } }
public override void OnMovement(Mobile m, Point3D oldLocation)
{
if(m is PlayerMobile && m.Location != oldLocation && m.InRange(this.Location, 3) && (!FocusList.Contains(m) || 0.015 > Utility.RandomDouble()))
{
EmptyNestQuest quest = QuestHelper.GetQuest((PlayerMobile)m, typeof(EmptyNestQuest)) as EmptyNestQuest;
if(quest != null && !quest.Completed)
{
if(Focus == null)
{
Focus = m;
m.RevealingAction();
SpawnPoachers(m);
DeadlineTimer = Timer.DelayCall(TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5), () =>
{
DeadlineTimer.Stop();
if(Poachers != null && Poachers.Count > 0)
Delete();
else
{
Focus = null;
Hatchling = null;
CooldownEnds = DateTime.MinValue;
}
});
DeadlineTimer.Start();
}
else if(IsInCooldown)
{
CooldownEnds = DateTime.UtcNow + TimeSpan.FromMinutes(2);
}
}
}
}
public void SpawnPoachers(Mobile m)
{
Map map = m.Map;
if(map == null || map == Map.Internal)
return;
if(Poachers == null)
Poachers = new List<BaseCreature>();
for(int i = 0; i < 3; i++)
{
Poacher p = new Poacher(this);
Point3D pnt = m.Location;
for(int j = 0; j < 10; j++)
{
int x = Utility.RandomMinMax(m.X - 2, m.X + 2);
int y = Utility.RandomMinMax(m.Y - 2, m.Y + 2);
int z = map.GetAverageZ(x, y);
if(map.CanSpawnMobile(x, y, z))
{
pnt = new Point3D(x, y, z);
break;
}
}
p.MoveToWorld(pnt, map);
Poachers.Add(p);
}
Poachers.ForEach(poacher => poacher.Combatant = m);
}
public void OnPoacherKilled(BaseCreature bc)
{
if(Poachers != null && Poachers.Contains(bc))
{
Poachers.Remove(bc);
if(Poachers.Count == 0)
{
if(!IsHatching)
{
IsHatching = true;
ColUtility.Free(Poachers);
Timer.DelayCall(TimeSpan.FromSeconds(Utility.RandomMinMax(15, 30)), () =>
{
Hatchling = new DragonTurtleHatchling();
Hatchling.MoveToWorld(this.Location, this.Map);
Hatchling.Tamable = false;
SpawnPoachers(Hatchling);
if(Egg != null)
Egg.Visible = false;
});
}
else
{
if(Hatchling.Alive)
{
CooldownEnds = DateTime.UtcNow + ResetPeriod;
Timer.DelayCall(TimeSpan.FromSeconds(1), OnComplete, new object[] { Hatchling, Focus } );
if(!FocusList.Contains(Focus))
FocusList.Add(Focus);
}
else
Delete();
if(DeadlineTimer != null)
{
DeadlineTimer.Stop();
DeadlineTimer = null;
}
Hatchling = null;
Focus = null;
ColUtility.Free(Poachers);
Poachers = null;
}
}
}
}
private void OnComplete(object o)
{
object[] objs = o as object[];
BaseCreature hatchling = objs[0] as BaseCreature;
Mobile focus = objs[1] as Mobile;
if(hatchling != null)
{
focus.PublicOverheadMessage(Server.Network.MessageType.Regular, 0x35, 1156496); // *The Hatchling safely burrows into the sand*
Timer.DelayCall(TimeSpan.FromSeconds(1), hatchling.Delete);
}
if(focus != null && focus is PlayerMobile)
{
EmptyNestQuest quest = QuestHelper.GetQuest((PlayerMobile)focus, typeof(EmptyNestQuest)) as EmptyNestQuest;
if(quest != null)
{
quest.Update(hatchling);
// Quest Complete and crap can be handled in update
}
}
Timer.DelayCall(TimeSpan.FromMinutes(1), () =>
{
if(Egg != null && !Egg.Visible)
Egg.Visible = true;
});
IsHatching = false;
}
public override void Delete()
{
base.Delete();
if (DeadlineTimer != null)
{
DeadlineTimer.Stop();
DeadlineTimer = null;
}
if (Poachers != null)
ColUtility.Free(Poachers);
}
public NestWithEgg(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);
writer.Write(Hatchling);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
Hatchling = reader.ReadMobile() as BaseCreature;
if(Hatchling != null)
Hatchling.Delete();
if(Egg != null && !Egg.Visible)
Egg.Visible = true;
FocusList = new List<Mobile>();
}
}
}