Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
367
Scripts/Services/Peerless/BasePeerless.cs
Normal file
367
Scripts/Services/Peerless/BasePeerless.cs
Normal file
@@ -0,0 +1,367 @@
|
||||
using System;
|
||||
using Server.Items;
|
||||
using Server.Spells;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class BasePeerless : BaseCreature
|
||||
{
|
||||
private PeerlessAltar m_Altar;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public PeerlessAltar Altar
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Altar;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_Altar = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanBeParagon { get { return false; } }
|
||||
public virtual bool DropPrimer { get { return Core.TOL; } }
|
||||
public virtual bool GiveMLSpecial { get { return true; } }
|
||||
|
||||
public override bool Unprovokable
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
public virtual double ChangeCombatant
|
||||
{
|
||||
get
|
||||
{
|
||||
return 0.3;
|
||||
}
|
||||
}
|
||||
|
||||
public BasePeerless(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnThink()
|
||||
{
|
||||
base.OnThink();
|
||||
|
||||
if (HasFireRing && Combatant != null && Alive && Hits > 0.8 * HitsMax && m_NextFireRing > Core.TickCount && Utility.RandomDouble() < FireRingChance)
|
||||
FireRing();
|
||||
|
||||
if (CanSpawnHelpers && Combatant != null && Alive && CanSpawnWave())
|
||||
SpawnHelpers();
|
||||
}
|
||||
|
||||
public override void OnDeath(Container c)
|
||||
{
|
||||
base.OnDeath(c);
|
||||
|
||||
if (DropPrimer)
|
||||
{
|
||||
SkillMasteryPrimer primer = SkillMasteryPrimer.GetRandom();
|
||||
List<DamageStore> rights = GetLootingRights();
|
||||
|
||||
if (rights.Count > 0)
|
||||
{
|
||||
Mobile m = rights[Utility.Random(rights.Count)].m_Mobile;
|
||||
|
||||
m.SendLocalizedMessage(1156209); // You have received a mastery primer!
|
||||
|
||||
if (m.Backpack == null || !m.Backpack.TryDropItem(m, primer, false))
|
||||
m.BankBox.DropItem(primer);
|
||||
}
|
||||
else
|
||||
{
|
||||
c.DropItem(primer);
|
||||
}
|
||||
}
|
||||
|
||||
if (GivesMLMinorArtifact && 0.5 > Utility.RandomDouble())
|
||||
{
|
||||
MondainsLegacy.DropPeerlessMinor(c);
|
||||
}
|
||||
|
||||
if (GiveMLSpecial)
|
||||
{
|
||||
if (Utility.RandomDouble() < 0.10)
|
||||
c.DropItem(new HumanFeyLeggings());
|
||||
|
||||
if (Utility.RandomDouble() < 0.025)
|
||||
c.DropItem(new CrimsonCincture());
|
||||
|
||||
if (0.05 > Utility.RandomDouble())
|
||||
{
|
||||
switch (Utility.Random(32))
|
||||
{
|
||||
case 0: c.DropItem(new AssassinChest()); break;
|
||||
case 1: c.DropItem(new AssassinArms()); break;
|
||||
case 2: c.DropItem(new AssassinLegs()); break;
|
||||
case 3: c.DropItem(new AssassinGloves()); break;
|
||||
case 4: c.DropItem(new DeathChest()); break;
|
||||
case 5: c.DropItem(new DeathArms()); break;
|
||||
case 6: c.DropItem(new DeathLegs()); break;
|
||||
case 7: c.DropItem(new DeathBoneHelm()); break;
|
||||
case 8: c.DropItem(new DeathGloves()); break;
|
||||
case 9: c.DropItem(new MyrmidonArms()); break;
|
||||
case 10: c.DropItem(new MyrmidonLegs()); break;
|
||||
case 11: c.DropItem(new MyrmidonGorget()); break;
|
||||
case 12: c.DropItem(new MyrmidonChest()); break;
|
||||
case 13: c.DropItem(new LeafweaveGloves()); break;
|
||||
case 14: c.DropItem(new LeafweaveLegs()); break;
|
||||
case 15: c.DropItem(new LeafweavePauldrons()); break;
|
||||
case 16: c.DropItem(new PaladinGloves()); break;
|
||||
case 17: c.DropItem(new PaladinGorget()); break;
|
||||
case 18: c.DropItem(new PaladinArms()); break;
|
||||
case 19: c.DropItem(new PaladinLegs()); break;
|
||||
case 20: c.DropItem(new PaladinHelm()); break;
|
||||
case 21: c.DropItem(new PaladinChest()); break;
|
||||
case 22: c.DropItem(new HunterArms()); break;
|
||||
case 23: c.DropItem(new HunterGloves()); break;
|
||||
case 24: c.DropItem(new HunterLegs()); break;
|
||||
case 25: c.DropItem(new HunterChest()); break;
|
||||
case 26: c.DropItem(new GreymistArms()); break;
|
||||
case 27: c.DropItem(new GreymistGloves()); break;
|
||||
case 28: c.DropItem(new GreymistLegs()); break;
|
||||
case 29: c.DropItem(new MalekisHonor()); break;
|
||||
case 30: c.DropItem(new Feathernock()); break;
|
||||
case 31: c.DropItem(new Swiftflight()); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_Altar != null)
|
||||
m_Altar.OnPeerlessDeath();
|
||||
}
|
||||
|
||||
public BasePeerless(AIType aiType, FightMode fightMode, int rangePerception, int rangeFight, double activeSpeed, double passiveSpeed)
|
||||
: base(aiType, fightMode, rangePerception, rangeFight, activeSpeed, passiveSpeed)
|
||||
{
|
||||
m_NextFireRing = Core.TickCount + 10000;
|
||||
m_CurrentWave = MaxHelpersWaves;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
|
||||
writer.Write((Item)m_Altar);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
m_Altar = reader.ReadItem() as PeerlessAltar;
|
||||
}
|
||||
|
||||
#region Helpers
|
||||
public virtual bool CanSpawnHelpers
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public virtual int MaxHelpersWaves
|
||||
{
|
||||
get
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
public virtual double SpawnHelpersChance
|
||||
{
|
||||
get
|
||||
{
|
||||
return 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
private int m_CurrentWave;
|
||||
|
||||
public int CurrentWave
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_CurrentWave;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_CurrentWave = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool AllHelpersDead
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_Altar != null)
|
||||
return m_Altar.AllHelpersDead();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool CanSpawnWave()
|
||||
{
|
||||
if (MaxHelpersWaves > 0 && m_CurrentWave > 0)
|
||||
{
|
||||
double hits = (Hits / (double)HitsMax);
|
||||
double waves = (m_CurrentWave / (double)(MaxHelpersWaves + 1));
|
||||
|
||||
if (hits < waves && Utility.RandomDouble() < SpawnHelpersChance)
|
||||
{
|
||||
m_CurrentWave -= 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual void SpawnHelpers()
|
||||
{
|
||||
}
|
||||
|
||||
public void SpawnHelper(BaseCreature helper, int range)
|
||||
{
|
||||
SpawnHelper(helper, GetSpawnPosition(range));
|
||||
}
|
||||
|
||||
public void SpawnHelper(BaseCreature helper, int x, int y, int z)
|
||||
{
|
||||
SpawnHelper(helper, new Point3D(x, y, z));
|
||||
}
|
||||
|
||||
public void SpawnHelper(BaseCreature helper, Point3D location)
|
||||
{
|
||||
if (helper == null)
|
||||
return;
|
||||
|
||||
helper.Home = location;
|
||||
helper.RangeHome = 4;
|
||||
|
||||
if (m_Altar != null)
|
||||
m_Altar.AddHelper(helper);
|
||||
|
||||
helper.MoveToWorld(location, Map);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public virtual void PackResources(int amount)
|
||||
{
|
||||
for (int i = 0; i < amount; i ++)
|
||||
switch ( Utility.Random(6) )
|
||||
{
|
||||
case 0:
|
||||
PackItem(new Blight());
|
||||
break;
|
||||
case 1:
|
||||
PackItem(new Scourge());
|
||||
break;
|
||||
case 2:
|
||||
PackItem(new Taint());
|
||||
break;
|
||||
case 3:
|
||||
PackItem(new Putrefaction());
|
||||
break;
|
||||
case 4:
|
||||
PackItem(new Corruption());
|
||||
break;
|
||||
case 5:
|
||||
PackItem(new Muculent());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void PackItems(Item item, int amount)
|
||||
{
|
||||
for (int i = 0; i < amount; i ++)
|
||||
PackItem(item);
|
||||
}
|
||||
|
||||
public virtual void PackTalismans(int amount)
|
||||
{
|
||||
int count = Utility.Random(amount);
|
||||
|
||||
for (int i = 0; i < count; i ++)
|
||||
PackItem(Loot.RandomTalisman());
|
||||
}
|
||||
|
||||
#region Fire Ring
|
||||
private static readonly int[] m_North = new int[]
|
||||
{
|
||||
-1, -1,
|
||||
1, -1,
|
||||
-1, 2,
|
||||
1, 2
|
||||
};
|
||||
|
||||
private static readonly int[] m_East = new int[]
|
||||
{
|
||||
-1, 0,
|
||||
2, 0
|
||||
};
|
||||
|
||||
public virtual bool HasFireRing
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public virtual double FireRingChance
|
||||
{
|
||||
get
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
private long m_NextFireRing = Core.TickCount;
|
||||
|
||||
public virtual void FireRing()
|
||||
{
|
||||
for (int i = 0; i < m_North.Length; i += 2)
|
||||
{
|
||||
Point3D p = Location;
|
||||
|
||||
p.X += m_North[i];
|
||||
p.Y += m_North[i + 1];
|
||||
|
||||
IPoint3D po = p as IPoint3D;
|
||||
|
||||
SpellHelper.GetSurfaceTop(ref po);
|
||||
|
||||
Effects.SendLocationEffect(po, Map, 0x3E27, 50);
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_East.Length; i += 2)
|
||||
{
|
||||
Point3D p = Location;
|
||||
|
||||
p.X += m_East[i];
|
||||
p.Y += m_East[i + 1];
|
||||
|
||||
IPoint3D po = p as IPoint3D;
|
||||
|
||||
SpellHelper.GetSurfaceTop(ref po);
|
||||
|
||||
Effects.SendLocationEffect(po, Map, 0x3E31, 50);
|
||||
}
|
||||
|
||||
m_NextFireRing = Core.TickCount + 10000;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
140
Scripts/Services/Peerless/ConfirmGumps.cs
Normal file
140
Scripts/Services/Peerless/ConfirmGumps.cs
Normal file
@@ -0,0 +1,140 @@
|
||||
using System;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Gumps
|
||||
{
|
||||
public class ConfirmPartyGump : Gump
|
||||
{
|
||||
private MasterKey _Key;
|
||||
|
||||
public ConfirmPartyGump(MasterKey key)
|
||||
: base(50, 50)
|
||||
{
|
||||
_Key = key;
|
||||
Closable = true;
|
||||
Disposable = true;
|
||||
Dragable = true;
|
||||
Resizable = false;
|
||||
|
||||
AddPage(0);
|
||||
AddBackground(0, 0, 245, 145, 9250);
|
||||
AddHtmlLocalized(21, 20, 203, 70, 1072525, false, false); // <CENTER>Are you sure you want to teleport <BR>your party to an unknown area?</CENTER>
|
||||
AddButton(157, 101, 247, 248, 1, GumpButtonType.Reply, 0);
|
||||
AddButton(81, 100, 241, 248, 0, GumpButtonType.Reply, 0);
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
Mobile from = sender.Mobile as Mobile;
|
||||
|
||||
switch (info.ButtonID)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
if (_Key == null || _Key.Altar == null)
|
||||
return;
|
||||
|
||||
_Key.Altar.SendConfirmations(from);
|
||||
_Key.Delete();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ConfirmEntranceGump : Gump
|
||||
{
|
||||
private Timer _Accept;
|
||||
private PeerlessAltar _Altar;
|
||||
|
||||
public ConfirmEntranceGump(PeerlessAltar altar, Mobile from)
|
||||
: base(50, 50)
|
||||
{
|
||||
from.CloseGump(typeof(ConfirmEntranceGump));
|
||||
|
||||
_Altar = altar;
|
||||
|
||||
Closable = true;
|
||||
Disposable = true;
|
||||
Dragable = true;
|
||||
Resizable = false;
|
||||
|
||||
AddPage(0);
|
||||
AddBackground(0, 0, 245, 145, 9250);
|
||||
AddHtmlLocalized(21, 20, 203, 70, 1072526, false, false); // <CENTER>Your party is teleporting to an unknown area.<BR>Do you wish to go?</CENTER>
|
||||
AddButton(157, 101, 247, 248, 1, GumpButtonType.Reply, 0);
|
||||
AddButton(81, 100, 241, 248, 0, GumpButtonType.Reply, 0);
|
||||
|
||||
_Accept = new AcceptConfirmPeerlessPartyTimer(from);
|
||||
_Accept.Start();
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
Mobile from = sender.Mobile;
|
||||
|
||||
if (_Altar == null)
|
||||
return;
|
||||
|
||||
int button = info.ButtonID;
|
||||
|
||||
switch (button)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
_Altar.Enter(from);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class AcceptConfirmPeerlessPartyTimer : Timer
|
||||
{
|
||||
private Mobile _From;
|
||||
|
||||
public AcceptConfirmPeerlessPartyTimer(Mobile from)
|
||||
: base(TimeSpan.FromSeconds(60.0), TimeSpan.FromSeconds(60.0), 1)
|
||||
{
|
||||
_From = from;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
_From.CloseGump(typeof(ConfirmEntranceGump));
|
||||
Stop();
|
||||
}
|
||||
}
|
||||
|
||||
public class ConfirmExitGump : BaseConfirmGump
|
||||
{
|
||||
public override int LabelNumber { get { return 1075026; } } // Are you sure you wish to teleport?
|
||||
|
||||
private object _Altar;
|
||||
|
||||
public ConfirmExitGump(object altar) : base()
|
||||
{
|
||||
_Altar = altar;
|
||||
}
|
||||
|
||||
public override void Confirm(Mobile from)
|
||||
{
|
||||
if (_Altar == null)
|
||||
return;
|
||||
|
||||
if (_Altar is PeerlessAltar)
|
||||
((PeerlessAltar)_Altar).Exit(from);
|
||||
}
|
||||
}
|
||||
}
|
||||
103
Scripts/Services/Peerless/MasterKey.cs
Normal file
103
Scripts/Services/Peerless/MasterKey.cs
Normal file
@@ -0,0 +1,103 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Server;
|
||||
using Server.Engines.PartySystem;
|
||||
using Server.Gumps;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class MasterKey : PeerlessKey
|
||||
{
|
||||
public override int LabelNumber { get { return 1074348; } } // master key
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public PeerlessAltar Altar { get; set; }
|
||||
|
||||
[Constructable]
|
||||
public MasterKey(int itemID)
|
||||
: base(itemID)
|
||||
{
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
public MasterKey(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (!IsChildOf(from.Backpack))
|
||||
{
|
||||
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!CanOfferConfirmation(from) && Altar == null)
|
||||
return;
|
||||
|
||||
//Altar.OnMasterKeyUse(from);
|
||||
if (Altar.Peerless == null)
|
||||
{
|
||||
from.CloseGump(typeof(ConfirmPartyGump));
|
||||
from.SendGump(new ConfirmPartyGump(this));
|
||||
}
|
||||
else
|
||||
{
|
||||
var p = Party.Get(from);
|
||||
|
||||
if (p != null)
|
||||
{
|
||||
foreach (var m in p.Members.Select(x => x.Mobile).Where(m => m.InRange(from.Location, 25)))
|
||||
{
|
||||
m.CloseGump(typeof(ConfirmEntranceGump));
|
||||
m.SendGump(new ConfirmEntranceGump(Altar, m));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.CloseGump(typeof(ConfirmEntranceGump));
|
||||
from.SendGump(new ConfirmEntranceGump(Altar, from));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
if (Altar == null)
|
||||
return;
|
||||
|
||||
Altar.MasterKeys.Remove(this);
|
||||
|
||||
if (Altar.MasterKeys.Count == 0 && Altar.Fighters.Count == 0)
|
||||
Altar.FinishSequence();
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)0); // version
|
||||
|
||||
writer.Write((Item)Altar);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Altar = reader.ReadItem() as PeerlessAltar;
|
||||
}
|
||||
|
||||
public virtual bool CanOfferConfirmation(Mobile from)
|
||||
{
|
||||
if (Altar != null && Altar.Fighters.Contains(from))
|
||||
{
|
||||
from.SendLocalizedMessage(1063296); // You may not use that teleporter at this time.
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
733
Scripts/Services/Peerless/PeerlessAltar.cs
Normal file
733
Scripts/Services/Peerless/PeerlessAltar.cs
Normal file
@@ -0,0 +1,733 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
using Server.Engines.PartySystem;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class PeerlessKeyArray
|
||||
{
|
||||
public Type Key { get; set; }
|
||||
public bool Active { get; set; }
|
||||
}
|
||||
|
||||
public abstract class PeerlessAltar : Container
|
||||
{
|
||||
public override bool IsPublicContainer { get { return true; } }
|
||||
public override bool IsDecoContainer { get { return false; } }
|
||||
|
||||
public virtual TimeSpan TimeToSlay { get { return TimeSpan.FromMinutes(90); } }
|
||||
public virtual TimeSpan DelayAfterBossSlain { get { return TimeSpan.FromMinutes(15); } }
|
||||
|
||||
public abstract int KeyCount { get; }
|
||||
public abstract MasterKey MasterKey { get; }
|
||||
|
||||
private List<PeerlessKeyArray> KeyValidation;
|
||||
|
||||
public abstract Type[] Keys { get; }
|
||||
public abstract BasePeerless Boss { get; }
|
||||
|
||||
public abstract Rectangle2D[] BossBounds { get; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public BasePeerless Peerless { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Point3D BossLocation { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Point3D TeleportDest { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Point3D ExitDest { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public DateTime Deadline { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.Counselor)]
|
||||
public bool ResetPeerless
|
||||
{
|
||||
get { return false; }
|
||||
set { if (value == true) FinishSequence(); }
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int FighterCount
|
||||
{
|
||||
get { return Fighters != null ? Fighters.Count : 0; }
|
||||
}
|
||||
|
||||
public List<Mobile> Fighters { get; set; }
|
||||
|
||||
public List<Item> MasterKeys { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Mobile Owner { get; set; }
|
||||
|
||||
/*public Mobile Summoner
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Fighters == null || Fighters.Count == 0)
|
||||
return null;
|
||||
|
||||
return Fighters[0];
|
||||
}
|
||||
}*/
|
||||
|
||||
public PeerlessAltar(int itemID)
|
||||
: base(itemID)
|
||||
{
|
||||
Movable = false;
|
||||
|
||||
Fighters = new List<Mobile>();
|
||||
MasterKeys = new List<Item>();
|
||||
}
|
||||
|
||||
public PeerlessAltar(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (from.AccessLevel > AccessLevel.Player)
|
||||
base.OnDoubleClick(from);
|
||||
}
|
||||
|
||||
public override bool CheckLift(Mobile from, Item item, ref LRReason reject)
|
||||
{
|
||||
if (from.AccessLevel > AccessLevel.Player)
|
||||
return base.CheckLift(from, item, ref reject);
|
||||
else
|
||||
reject = LRReason.CannotLift;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool OnDragDrop(Mobile from, Item dropped)
|
||||
{
|
||||
if (Owner != null && Owner != from)
|
||||
{
|
||||
if (Peerless != null && Peerless.CheckAlive())
|
||||
from.SendLocalizedMessage(1075213); // The master of this realm has already been summoned and is engaged in combat. Your opportunity will come after he has squashed the current batch of intruders!
|
||||
else
|
||||
from.SendLocalizedMessage(1072683, Owner.Name); // ~1_NAME~ has already activated the Prism, please wait...
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsKey(dropped) && MasterKeys.Count() == 0)
|
||||
{
|
||||
if (KeyValidation == null)
|
||||
{
|
||||
KeyValidation = new List<PeerlessKeyArray>();
|
||||
|
||||
Keys.ToList().ForEach(x => KeyValidation.Add(new PeerlessKeyArray { Key = x, Active = false }));
|
||||
}
|
||||
|
||||
if (KeyValidation.Any(x => x.Active == true))
|
||||
{
|
||||
if (KeyValidation.Any(x => x.Key == dropped.GetType() && x.Active == false))
|
||||
{
|
||||
KeyValidation.Find(s => s.Key == dropped.GetType()).Active = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1072682); // This is not the proper key.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Owner = from;
|
||||
KeyStartTimer(from);
|
||||
from.SendLocalizedMessage(1074575); // You have activated this object!
|
||||
KeyValidation.Find(s => s.Key == dropped.GetType()).Active = true;
|
||||
}
|
||||
|
||||
if (KeyValidation.Where(x => x.Active == true).Count() == Keys.Count())
|
||||
{
|
||||
KeyStopTimer();
|
||||
|
||||
from.SendLocalizedMessage(1072678); // You have awakened the master of this realm. You need to hurry to defeat it in time!
|
||||
BeginSequence(from);
|
||||
|
||||
for (int k = 0; k < KeyCount; k++)
|
||||
{
|
||||
from.SendLocalizedMessage(1072680); // You have been given the key to the boss.
|
||||
|
||||
MasterKey key = MasterKey;
|
||||
|
||||
if (key != null)
|
||||
{
|
||||
key.Altar = this;
|
||||
key._Map = Map;
|
||||
|
||||
if (!from.AddToBackpack(key))
|
||||
key.MoveToWorld(from.Location, from.Map);
|
||||
|
||||
MasterKeys.Add(key);
|
||||
}
|
||||
}
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(1), () => ClearContainer());
|
||||
KeyValidation = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1072682); // This is not the proper key.
|
||||
return false;
|
||||
}
|
||||
|
||||
return base.OnDragDrop(from, dropped);
|
||||
}
|
||||
|
||||
public virtual bool IsKey(Item item)
|
||||
{
|
||||
if (Keys == null || item == null)
|
||||
return false;
|
||||
|
||||
bool isKey = false;
|
||||
|
||||
// check if item is key
|
||||
for (int i = 0; i < Keys.Length && !isKey; i++)
|
||||
{
|
||||
if (Keys[i].IsAssignableFrom(item.GetType()))
|
||||
isKey = true;
|
||||
}
|
||||
|
||||
// check if item is already in container
|
||||
for (int i = 0; i < Items.Count && isKey; i++)
|
||||
{
|
||||
if (Items[i].GetType() == item.GetType())
|
||||
return false;
|
||||
}
|
||||
|
||||
return isKey;
|
||||
}
|
||||
|
||||
private Timer m_KeyResetTimer;
|
||||
|
||||
public virtual void KeyStartTimer(Mobile from)
|
||||
{
|
||||
if (m_KeyResetTimer != null)
|
||||
m_KeyResetTimer.Stop();
|
||||
|
||||
m_KeyResetTimer = Timer.DelayCall(TimeSpan.FromSeconds(30 * Keys.Count()), () =>
|
||||
{
|
||||
from.SendLocalizedMessage(1072679); // Your realm offering has reset. You will need to start over.
|
||||
|
||||
if (Owner != null)
|
||||
{
|
||||
Owner = null;
|
||||
}
|
||||
|
||||
KeyValidation = null;
|
||||
|
||||
ClearContainer();
|
||||
});
|
||||
}
|
||||
|
||||
public virtual void KeyStopTimer()
|
||||
{
|
||||
if (m_KeyResetTimer != null)
|
||||
m_KeyResetTimer.Stop();
|
||||
|
||||
m_KeyResetTimer = null;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)5); // version
|
||||
|
||||
writer.Write(Owner);
|
||||
|
||||
// version 4 remove pet table
|
||||
|
||||
// version 3 remove IsAvailable
|
||||
|
||||
// version 1
|
||||
writer.Write((bool)(m_Helpers != null));
|
||||
|
||||
if (m_Helpers != null)
|
||||
writer.WriteMobileList<BaseCreature>(m_Helpers);
|
||||
|
||||
// version 0
|
||||
writer.Write(Peerless);
|
||||
writer.Write(BossLocation);
|
||||
writer.Write(TeleportDest);
|
||||
writer.Write(ExitDest);
|
||||
|
||||
writer.Write(Deadline);
|
||||
|
||||
// serialize master keys
|
||||
writer.WriteItemList(MasterKeys);
|
||||
|
||||
// serialize fighters
|
||||
writer.WriteMobileList(Fighters);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 5:
|
||||
{
|
||||
Owner = reader.ReadMobile();
|
||||
goto case 4;
|
||||
}
|
||||
case 4:
|
||||
case 3:
|
||||
if (version < 5)
|
||||
{
|
||||
reader.ReadBool();
|
||||
}
|
||||
goto case 2;
|
||||
case 2:
|
||||
case 1:
|
||||
if (reader.ReadBool())
|
||||
m_Helpers = reader.ReadStrongMobileList<BaseCreature>();
|
||||
goto case 0;
|
||||
case 0:
|
||||
Peerless = reader.ReadMobile() as BasePeerless;
|
||||
BossLocation = reader.ReadPoint3D();
|
||||
TeleportDest = reader.ReadPoint3D();
|
||||
ExitDest = reader.ReadPoint3D();
|
||||
|
||||
Deadline = reader.ReadDateTime();
|
||||
|
||||
MasterKeys = reader.ReadStrongItemList();
|
||||
Fighters = reader.ReadStrongMobileList();
|
||||
|
||||
if (version < 4)
|
||||
{
|
||||
int count = reader.ReadInt();
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
reader.ReadMobile();
|
||||
reader.ReadStrongMobileList();
|
||||
}
|
||||
}
|
||||
|
||||
if (version < 2)
|
||||
reader.ReadBool();
|
||||
|
||||
if (Peerless == null && m_Helpers.Count > 0)
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(30), new TimerCallback(CleanupHelpers));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (Owner != null && Peerless == null)
|
||||
{
|
||||
FinishSequence();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void ClearContainer()
|
||||
{
|
||||
for (int i = Items.Count - 1; i >= 0; --i)
|
||||
{
|
||||
if (i < Items.Count)
|
||||
Items[i].Delete();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void AddFighter(Mobile fighter)
|
||||
{
|
||||
if (!Fighters.Contains(fighter))
|
||||
Fighters.Add(fighter);
|
||||
}
|
||||
|
||||
public virtual void SendConfirmations(Mobile from)
|
||||
{
|
||||
Party party = Party.Get(from);
|
||||
|
||||
if (party != null)
|
||||
{
|
||||
foreach (var m in party.Members.Select(info => info.Mobile))
|
||||
{
|
||||
if (m.InRange(from.Location, 25) && CanEnter(m))
|
||||
{
|
||||
m.SendGump(new ConfirmEntranceGump(this, from));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendGump(new ConfirmEntranceGump(this, from));
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void BeginSequence(Mobile from)
|
||||
{
|
||||
SpawnBoss();
|
||||
}
|
||||
|
||||
public virtual void SpawnBoss()
|
||||
{
|
||||
if (Peerless == null)
|
||||
{
|
||||
// spawn boss
|
||||
Peerless = Boss;
|
||||
|
||||
if (Peerless == null)
|
||||
return;
|
||||
|
||||
Peerless.Home = BossLocation;
|
||||
Peerless.RangeHome = 12;
|
||||
Peerless.MoveToWorld(BossLocation, Map);
|
||||
Peerless.Altar = this;
|
||||
|
||||
StartSlayTimer();
|
||||
}
|
||||
}
|
||||
|
||||
public void Enter(Mobile fighter)
|
||||
{
|
||||
if (CanEnter(fighter))
|
||||
{
|
||||
// teleport party member's pets
|
||||
if (fighter is PlayerMobile)
|
||||
{
|
||||
foreach (var pet in ((PlayerMobile)fighter).AllFollowers.OfType<BaseCreature>().Where(pet => pet.Alive &&
|
||||
pet.InRange(fighter.Location, 5) &&
|
||||
!(pet is BaseMount &&
|
||||
((BaseMount)pet).Rider != null) &&
|
||||
CanEnter(pet)))
|
||||
{
|
||||
pet.FixedParticles(0x376A, 9, 32, 0x13AF, EffectLayer.Waist);
|
||||
pet.PlaySound(0x1FE);
|
||||
pet.MoveToWorld(TeleportDest, Map);
|
||||
}
|
||||
}
|
||||
|
||||
// teleport party member
|
||||
fighter.FixedParticles(0x376A, 9, 32, 0x13AF, EffectLayer.Waist);
|
||||
fighter.PlaySound(0x1FE);
|
||||
fighter.MoveToWorld(TeleportDest, Map);
|
||||
|
||||
AddFighter(fighter);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool CanEnter(Mobile fighter)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual bool CanEnter(BaseCreature pet)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void FinishSequence()
|
||||
{
|
||||
StopTimers();
|
||||
|
||||
if (Owner != null)
|
||||
{
|
||||
Owner = null;
|
||||
}
|
||||
|
||||
// delete peerless
|
||||
if (Peerless != null)
|
||||
{
|
||||
if (Peerless.Corpse != null && !Peerless.Corpse.Deleted)
|
||||
Peerless.Corpse.Delete();
|
||||
|
||||
if (!Peerless.Deleted)
|
||||
Peerless.Delete();
|
||||
}
|
||||
|
||||
// teleport party to exit if not already there
|
||||
if (Fighters != null)
|
||||
{
|
||||
var fighters = new List<Mobile>(Fighters);
|
||||
|
||||
fighters.ForEach(x => Exit(x));
|
||||
|
||||
ColUtility.Free(fighters);
|
||||
}
|
||||
|
||||
// delete master keys
|
||||
if (MasterKeys != null)
|
||||
{
|
||||
var keys = new List<Item>(MasterKeys);
|
||||
|
||||
keys.ForEach(x => x.Delete());
|
||||
|
||||
ColUtility.Free(keys);
|
||||
}
|
||||
|
||||
// delete any remaining helpers
|
||||
CleanupHelpers();
|
||||
|
||||
// reset summoner, boss
|
||||
Peerless = null;
|
||||
|
||||
Deadline = DateTime.MinValue;
|
||||
|
||||
ColUtility.Free(Fighters);
|
||||
ColUtility.Free(MasterKeys);
|
||||
}
|
||||
|
||||
public virtual void Exit(Mobile fighter)
|
||||
{
|
||||
if (fighter == null)
|
||||
return;
|
||||
|
||||
// teleport fighter
|
||||
if (fighter.NetState == null && MobileIsInBossArea(fighter.LogoutLocation))
|
||||
{
|
||||
fighter.LogoutMap = this is CitadelAltar ? Map.Tokuno : this.Map;
|
||||
fighter.LogoutLocation = ExitDest;
|
||||
}
|
||||
else if (MobileIsInBossArea(fighter) && fighter.Map == this.Map)
|
||||
{
|
||||
fighter.FixedParticles(0x376A, 9, 32, 0x13AF, EffectLayer.Waist);
|
||||
fighter.PlaySound(0x1FE);
|
||||
|
||||
if (this is CitadelAltar)
|
||||
fighter.MoveToWorld(ExitDest, Map.Tokuno);
|
||||
else
|
||||
fighter.MoveToWorld(ExitDest, Map);
|
||||
}
|
||||
|
||||
// teleport his pets
|
||||
if (fighter is PlayerMobile)
|
||||
{
|
||||
foreach (var pet in ((PlayerMobile)fighter).AllFollowers.OfType<BaseCreature>().Where(pet => pet != null &&
|
||||
(pet.Alive || pet.IsBonded) &&
|
||||
pet.Map != Map.Internal &&
|
||||
MobileIsInBossArea(pet)))
|
||||
{
|
||||
if (pet is BaseMount)
|
||||
{
|
||||
BaseMount mount = (BaseMount)pet;
|
||||
|
||||
if (mount.Rider != null && mount.Rider != fighter)
|
||||
{
|
||||
mount.Rider.FixedParticles(0x376A, 9, 32, 0x13AF, EffectLayer.Waist);
|
||||
mount.Rider.PlaySound(0x1FE);
|
||||
|
||||
if (this is CitadelAltar)
|
||||
mount.Rider.MoveToWorld(ExitDest, Map.Tokuno);
|
||||
else
|
||||
mount.Rider.MoveToWorld(ExitDest, Map);
|
||||
|
||||
continue;
|
||||
}
|
||||
else if (mount.Rider != null)
|
||||
continue;
|
||||
}
|
||||
|
||||
pet.FixedParticles(0x376A, 9, 32, 0x13AF, EffectLayer.Waist);
|
||||
pet.PlaySound(0x1FE);
|
||||
|
||||
if (this is CitadelAltar)
|
||||
pet.MoveToWorld(ExitDest, Map.Tokuno);
|
||||
else
|
||||
pet.MoveToWorld(ExitDest, Map);
|
||||
}
|
||||
}
|
||||
|
||||
Fighters.Remove(fighter);
|
||||
fighter.SendLocalizedMessage(1072677); // You have been transported out of this room.
|
||||
|
||||
if (MasterKeys.Count == 0 && Fighters.Count == 0 && Owner != null)
|
||||
{
|
||||
StopTimers();
|
||||
|
||||
Owner = null;
|
||||
|
||||
if (Peerless != null)
|
||||
{
|
||||
if (Peerless.Corpse != null && !Peerless.Corpse.Deleted)
|
||||
Peerless.Corpse.Delete();
|
||||
|
||||
if (!Peerless.Deleted)
|
||||
Peerless.Delete();
|
||||
}
|
||||
|
||||
CleanupHelpers();
|
||||
|
||||
// reset summoner, boss
|
||||
Peerless = null;
|
||||
|
||||
Deadline = DateTime.MinValue;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void OnPeerlessDeath()
|
||||
{
|
||||
SendMessage(1072681); // The master of this realm has been slain! You may only stay here so long.
|
||||
|
||||
StopSlayTimer();
|
||||
|
||||
// delete master keys
|
||||
ColUtility.SafeDelete(MasterKeys);
|
||||
|
||||
ColUtility.Free(MasterKeys);
|
||||
m_DeadlineTimer = Timer.DelayCall(DelayAfterBossSlain, new TimerCallback(FinishSequence));
|
||||
}
|
||||
|
||||
public virtual bool MobileIsInBossArea(Mobile check)
|
||||
{
|
||||
return MobileIsInBossArea(check.Location);
|
||||
}
|
||||
|
||||
public virtual bool MobileIsInBossArea(Point3D loc)
|
||||
{
|
||||
if (BossBounds == null || BossBounds.Length == 0)
|
||||
return true;
|
||||
|
||||
foreach (Rectangle2D rec in BossBounds)
|
||||
{
|
||||
if (rec.Contains(loc))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual void SendMessage(int message)
|
||||
{
|
||||
Fighters.ForEach(x => x.SendLocalizedMessage(message));
|
||||
}
|
||||
|
||||
public virtual void SendMessage(int message, object param)
|
||||
{
|
||||
Fighters.ForEach(x => x.SendLocalizedMessage(message, param.ToString()));
|
||||
}
|
||||
|
||||
private Timer m_SlayTimer;
|
||||
private Timer m_DeadlineTimer;
|
||||
|
||||
public virtual void StopTimers()
|
||||
{
|
||||
StopSlayTimer();
|
||||
StopDeadlineTimer();
|
||||
}
|
||||
|
||||
public virtual void StopDeadlineTimer()
|
||||
{
|
||||
if (m_DeadlineTimer != null)
|
||||
m_DeadlineTimer.Stop();
|
||||
|
||||
m_DeadlineTimer = null;
|
||||
|
||||
if (Owner != null)
|
||||
{
|
||||
Owner = null;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void StopSlayTimer()
|
||||
{
|
||||
if (m_SlayTimer != null)
|
||||
m_SlayTimer.Stop();
|
||||
|
||||
m_SlayTimer = null;
|
||||
}
|
||||
|
||||
public virtual void StartSlayTimer()
|
||||
{
|
||||
if (m_SlayTimer != null)
|
||||
m_SlayTimer.Stop();
|
||||
|
||||
if (TimeToSlay != TimeSpan.Zero)
|
||||
Deadline = DateTime.UtcNow + TimeToSlay;
|
||||
else
|
||||
Deadline = DateTime.UtcNow + TimeSpan.FromHours(1);
|
||||
|
||||
m_SlayTimer = Timer.DelayCall(TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5), new TimerCallback(DeadlineCheck));
|
||||
m_SlayTimer.Priority = TimerPriority.OneMinute;
|
||||
}
|
||||
|
||||
public virtual void DeadlineCheck()
|
||||
{
|
||||
if (DateTime.UtcNow > Deadline)
|
||||
{
|
||||
SendMessage(1072258); // You failed to complete an objective in time!
|
||||
FinishSequence();
|
||||
return;
|
||||
}
|
||||
|
||||
TimeSpan timeLeft = Deadline - DateTime.UtcNow;
|
||||
|
||||
if (timeLeft < TimeSpan.FromMinutes(30))
|
||||
SendMessage(1075611, timeLeft.TotalSeconds);
|
||||
|
||||
Fighters.ForEach(x =>
|
||||
{
|
||||
if (x is PlayerMobile)
|
||||
{
|
||||
PlayerMobile player = (PlayerMobile)x;
|
||||
|
||||
if (player.NetState == null)
|
||||
{
|
||||
TimeSpan offline = DateTime.UtcNow - player.LastOnline;
|
||||
|
||||
if (offline > TimeSpan.FromMinutes(10))
|
||||
Exit(player);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#region Helpers
|
||||
private List<BaseCreature> m_Helpers = new List<BaseCreature>();
|
||||
|
||||
public List<BaseCreature> Helpers
|
||||
{
|
||||
get { return m_Helpers; }
|
||||
}
|
||||
|
||||
public void AddHelper(BaseCreature helper)
|
||||
{
|
||||
if (helper != null && helper.Alive && !helper.Deleted)
|
||||
m_Helpers.Add(helper);
|
||||
}
|
||||
|
||||
public bool AllHelpersDead()
|
||||
{
|
||||
for (int i = 0; i < m_Helpers.Count; i++)
|
||||
{
|
||||
BaseCreature c = m_Helpers[i];
|
||||
|
||||
if (c.Alive)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void CleanupHelpers()
|
||||
{
|
||||
for (int i = 0; i < m_Helpers.Count; i++)
|
||||
{
|
||||
BaseCreature c = m_Helpers[i];
|
||||
|
||||
if (c != null && c.Alive)
|
||||
c.Delete();
|
||||
}
|
||||
|
||||
m_Helpers.Clear();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
184
Scripts/Services/Peerless/PeerlessKey.cs
Normal file
184
Scripts/Services/Peerless/PeerlessKey.cs
Normal file
@@ -0,0 +1,184 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class PeerlessKey : Item
|
||||
{
|
||||
private int m_Lifespan;
|
||||
private Timer m_Timer;
|
||||
|
||||
private Map m_Map;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Map _Map
|
||||
{
|
||||
get { return m_Map; }
|
||||
set
|
||||
{
|
||||
m_Map = value;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public PeerlessKey(int itemID)
|
||||
: base(itemID)
|
||||
{
|
||||
LootType = LootType.Blessed;
|
||||
|
||||
if (Lifespan > 0)
|
||||
{
|
||||
m_Lifespan = Lifespan;
|
||||
StartTimer();
|
||||
}
|
||||
}
|
||||
|
||||
public PeerlessKey(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual int Lifespan { get { return 604800; } }
|
||||
public virtual bool UseSeconds { get { return false; } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int TimeLeft
|
||||
{
|
||||
get { return m_Lifespan; }
|
||||
set
|
||||
{
|
||||
m_Lifespan = value;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
if (_Map != null)
|
||||
{
|
||||
if (_Map == Map.Felucca)
|
||||
list.Add(1012001); // Felucca
|
||||
else if (_Map == Map.Trammel)
|
||||
list.Add(1012000); // Trammel
|
||||
else if (_Map == Map.Ilshenar)
|
||||
list.Add(1012002); // Ilshenar
|
||||
else if (_Map == Map.Malas)
|
||||
list.Add(1060643); // Malas
|
||||
else if (_Map == Map.Tokuno)
|
||||
list.Add(1063258); // Tokuno Islands
|
||||
}
|
||||
|
||||
if (Lifespan > 0)
|
||||
{
|
||||
if (UseSeconds)
|
||||
list.Add(1072517, m_Lifespan.ToString()); // Lifespan: ~1_val~ seconds
|
||||
else
|
||||
{
|
||||
TimeSpan t = TimeSpan.FromSeconds(TimeLeft);
|
||||
|
||||
int weeks = (int)t.Days / 7;
|
||||
int days = t.Days;
|
||||
int hours = t.Hours;
|
||||
int minutes = t.Minutes;
|
||||
|
||||
if (weeks > 1)
|
||||
list.Add(1153092, (t.Days / 7).ToString()); // Lifespan: ~1_val~ weeks
|
||||
else if (days > 1)
|
||||
list.Add(1153091, t.Days.ToString()); // Lifespan: ~1_val~ days
|
||||
else if (hours > 1)
|
||||
list.Add(1153090, t.Hours.ToString()); // Lifespan: ~1_val~ hours
|
||||
else if (minutes > 1)
|
||||
list.Add(1153089, t.Minutes.ToString()); // Lifespan: ~1_val~ minutes
|
||||
else
|
||||
list.Add(1072517, t.Seconds.ToString()); // Lifespan: ~1_val~ seconds
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void StartTimer()
|
||||
{
|
||||
if (m_Timer != null)
|
||||
return;
|
||||
|
||||
m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10), new TimerCallback(Slice));
|
||||
m_Timer.Priority = TimerPriority.OneSecond;
|
||||
}
|
||||
|
||||
public virtual void StopTimer()
|
||||
{
|
||||
if (m_Timer != null)
|
||||
m_Timer.Stop();
|
||||
|
||||
m_Timer = null;
|
||||
}
|
||||
|
||||
public virtual void Slice()
|
||||
{
|
||||
m_Lifespan -= 10;
|
||||
|
||||
InvalidateProperties();
|
||||
|
||||
if (m_Lifespan <= 0)
|
||||
Decay();
|
||||
}
|
||||
|
||||
public virtual void Decay()
|
||||
{
|
||||
if (RootParent is Mobile)
|
||||
{
|
||||
Mobile parent = (Mobile)RootParent;
|
||||
|
||||
if (Name == null)
|
||||
parent.SendLocalizedMessage(1072515, "#" + LabelNumber); // The ~1_name~ expired...
|
||||
else
|
||||
parent.SendLocalizedMessage(1072515, Name); // The ~1_name~ expired...
|
||||
|
||||
Effects.SendLocationParticles(EffectItem.Create(parent.Location, parent.Map, EffectItem.DefaultDuration), 0x3728, 8, 20, 5042);
|
||||
Effects.PlaySound(parent.Location, parent.Map, 0x201);
|
||||
}
|
||||
else
|
||||
{
|
||||
Effects.SendLocationParticles(EffectItem.Create(Location, Map, EffectItem.DefaultDuration), 0x3728, 8, 20, 5042);
|
||||
Effects.PlaySound(Location, Map, 0x201);
|
||||
}
|
||||
|
||||
StopTimer();
|
||||
Delete();
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)1); // version
|
||||
|
||||
writer.Write(m_Map);
|
||||
writer.Write((int)m_Lifespan);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
m_Map = reader.ReadMap();
|
||||
|
||||
goto case 0;
|
||||
}
|
||||
case 0:
|
||||
{
|
||||
m_Lifespan = reader.ReadInt();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
StartTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
63
Scripts/Services/Peerless/PeerlessTeleporter.cs
Normal file
63
Scripts/Services/Peerless/PeerlessTeleporter.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using Server.Gumps;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class PeerlessTeleporter : Teleporter
|
||||
{
|
||||
[Constructable]
|
||||
public PeerlessTeleporter()
|
||||
: this(null)
|
||||
{
|
||||
}
|
||||
|
||||
public PeerlessTeleporter(PeerlessAltar altar)
|
||||
: base()
|
||||
{
|
||||
Altar = altar;
|
||||
}
|
||||
|
||||
public PeerlessTeleporter(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public PeerlessAltar Altar { get; set; }
|
||||
|
||||
public override bool OnMoveOver(Mobile m)
|
||||
{
|
||||
if (m.Alive)
|
||||
{
|
||||
m.CloseGump(typeof(ConfirmExitGump));
|
||||
m.SendGump(new ConfirmExitGump(Altar));
|
||||
}
|
||||
else if (Altar != null)
|
||||
{
|
||||
Altar.Exit(m);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)0); // version
|
||||
|
||||
writer.Write((Item)Altar);
|
||||
|
||||
if (Altar != null && Altar.Map != Map)
|
||||
Map = Altar.Map;
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Altar = reader.ReadItem() as PeerlessAltar;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user