using System;
using Server;
using Server.Mobiles;
using System.Collections;
using System.Collections.Generic;
using Server.Spells;
namespace Server.Items
{
public class FireTotem : Item
{
public Mobile m_Owner;
public EffectTimer m_Timer;
public static TimeSpan TickDuration = TimeSpan.FromSeconds(3.0);
public DateTime m_Expiration = DateTime.UtcNow;
public static int Range = 15;
[Constructable]
public FireTotem( Mobile owner, double duration ) : base()
{
Name = "fire totem";
Weight = 2.0;
Movable = false;
m_Owner = owner;
m_Expiration = DateTime.UtcNow + TimeSpan.FromSeconds(duration);
Movable = false;
if (m_Timer == null)
m_Timer = new EffectTimer(this);
m_Timer.Start();
}
public static bool PlayerCanDamage(Mobile from, Mobile target)
{
if (from == null)
return false;
if (target == null)
return false;
if (!target.Alive || target.IsDeadBondedPet)
return false;
if (!target.CanBeDamaged())
return false;
if (!from.CanBeHarmful(target))
return false;
int NotorietyResult = Notoriety.Compute(from, target);
if (NotorietyResult == Notoriety.CanBeAttacked)
return true;
if (NotorietyResult == Notoriety.Criminal)
return true;
if (NotorietyResult == Notoriety.Murderer)
return true;
return false;
}
public class EffectTimer : Timer
{
public FireTotem m_FireTotem;
public EffectTimer(FireTotem FireTotem): base(TimeSpan.Zero, TickDuration)
{
m_FireTotem = FireTotem;
Priority = TimerPriority.TwoFiftyMS;
}
protected override void OnTick()
{
if (m_FireTotem == null)
{
Stop();
return;
}
if (m_FireTotem.Deleted)
{
Stop();
return;
}
if (DateTime.UtcNow >= m_FireTotem.m_Expiration)
{
m_FireTotem.Delete();
return;
}
Queue m_Queue = new Queue();
var nearbyMobiles = m_FireTotem.Map.GetMobilesInRange(m_FireTotem.Location, Range);
foreach (Mobile mobile in nearbyMobiles)
{
if (mobile == null) continue;
if (mobile.AccessLevel > AccessLevel.Player) continue;
if (mobile.Hidden) continue;
if (!m_FireTotem.Map.LineOfSight(m_FireTotem.Location, mobile.Location)) continue;
if (PlayerCanDamage(m_FireTotem.m_Owner, mobile))
m_Queue.Enqueue(mobile);
}
Point3D location = m_FireTotem.Location;
Map map = m_FireTotem.Map;
if (m_Queue.Count > 0)
Effects.PlaySound(location, map, 0x226);
while (m_Queue.Count > 0)
{
Mobile mobile = (Mobile)m_Queue.Dequeue();
if (mobile == null)
continue;
IEntity startLocation = new Entity(Serial.Zero, new Point3D(location.X, location.Y, location.Z + 10), map);
IEntity endLocation = new Entity(Serial.Zero, new Point3D(mobile.Location.X, mobile.Location.Y, mobile.Location.Z + 5), map);
Effects.SendMovingEffect(startLocation, endLocation, 0x36D4, 8, 0, false, false, 0, 0);
double targetDistance = Utility.GetDistanceToSqrt(startLocation.Location, endLocation.Location);
double destinationDelay = (double)targetDistance * .06;
Timer.DelayCall(TimeSpan.FromSeconds(destinationDelay), delegate
{
if (mobile == null)
return;
int damage = Utility.RandomMinMax(10, 20);
mobile.PlaySound(0x359);
new Blood().MoveToWorld(mobile.Location, mobile.Map);
AOS.Damage(mobile, damage, 100, 0, 0, 0, 0);
});
}
}
}
public override void OnAfterDelete()
{
if (m_Timer != null)
{
m_Timer.Stop();
m_Timer = null;
}
base.OnAfterDelete();
}
public FireTotem(Serial serial): base(serial)
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 );
writer.Write(m_Expiration);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize( reader );
int version = reader.ReadInt();
if (version >= 0)
{
m_Expiration = reader.ReadDateTime();
}
if (m_Expiration <= DateTime.UtcNow)
Delete();
else
{
if (m_Timer == null)
m_Timer = new EffectTimer(this);
m_Timer.Start();
}
}
}
}