Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
363
Scripts/SubSystem/VitaNex/Core/Effects/FX/BaseFX.cs
Normal file
363
Scripts/SubSystem/VitaNex/Core/Effects/FX/BaseFX.cs
Normal file
@@ -0,0 +1,363 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Server;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.FX
|
||||
{
|
||||
public static class EffectUtility
|
||||
{
|
||||
public static readonly Point3D[][] EmptyPoints = new Point3D[0][];
|
||||
}
|
||||
|
||||
public interface IEffect
|
||||
{
|
||||
IPoint3D Start { get; set; }
|
||||
Map Map { get; set; }
|
||||
Action Callback { get; set; }
|
||||
|
||||
bool Sending { get; }
|
||||
|
||||
void Send();
|
||||
}
|
||||
|
||||
public abstract class BaseEffect<TQueue, TEffectInfo> : List<TQueue>, IEffect
|
||||
where TQueue : EffectQueue<TEffectInfo>
|
||||
where TEffectInfo : EffectInfo
|
||||
{
|
||||
public bool Processing { get; protected set; }
|
||||
public int CurrentProcess { get; protected set; }
|
||||
|
||||
public TQueue CurrentQueue { get; private set; }
|
||||
|
||||
public bool Sending { get; protected set; }
|
||||
|
||||
public virtual IPoint3D Start { get; set; }
|
||||
public virtual Map Map { get; set; }
|
||||
public virtual int Repeat { get; set; }
|
||||
public virtual TimeSpan Interval { get; set; }
|
||||
public virtual Action<TEffectInfo> EffectHandler { get; set; }
|
||||
public virtual Action<TEffectInfo> EffectMutator { get; set; }
|
||||
public virtual Action Callback { get; set; }
|
||||
|
||||
public virtual bool EnableMutate { get; set; }
|
||||
public virtual bool Reversed { get; set; }
|
||||
|
||||
public abstract TEffectInfo[] Effects { get; }
|
||||
|
||||
public BaseEffect(
|
||||
IPoint3D start,
|
||||
Map map,
|
||||
int repeat = 0,
|
||||
TimeSpan? interval = null,
|
||||
Action<TEffectInfo> effectHandler = null,
|
||||
Action callback = null)
|
||||
{
|
||||
Start = start;
|
||||
Map = map;
|
||||
Repeat = Math.Max(0, repeat);
|
||||
Interval = interval ?? TimeSpan.FromMilliseconds(100);
|
||||
EffectHandler = effectHandler;
|
||||
Callback = callback;
|
||||
}
|
||||
|
||||
public abstract TQueue CreateEffectQueue(IEnumerable<TEffectInfo> queue);
|
||||
public abstract TEffectInfo CloneEffectInfo(TEffectInfo src);
|
||||
|
||||
public void Update()
|
||||
{
|
||||
this.Free(true);
|
||||
|
||||
if (Effects == null || Effects.Length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var points = GetTargetPoints(CurrentProcess);
|
||||
|
||||
if (points == null || points.Length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Capacity = points.Length;
|
||||
|
||||
this.SetAll(i => null);
|
||||
|
||||
for (var i = 0; i < points.Length; i++)
|
||||
{
|
||||
var list = points[i];
|
||||
|
||||
if (list == null || list.Length == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var fx = new TEffectInfo[list.Length][];
|
||||
|
||||
fx.SetAll(fxi => new TEffectInfo[Effects.Length]);
|
||||
|
||||
Parallel.For(
|
||||
0,
|
||||
list.Length,
|
||||
index =>
|
||||
{
|
||||
var p = list[index];
|
||||
|
||||
var pIndex = 0;
|
||||
|
||||
for (var ei = 0; ei < Effects.Length; ei++)
|
||||
{
|
||||
var e = CloneEffectInfo(Effects[ei]);
|
||||
|
||||
if (e == null || e.IsDisposed)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
e.QueueIndex = index;
|
||||
e.ProcessIndex = pIndex++;
|
||||
|
||||
e.Source = new Entity(Serial.Zero, p, Map);
|
||||
e.Map = Map;
|
||||
|
||||
if (EnableMutate)
|
||||
{
|
||||
MutateEffect(e);
|
||||
}
|
||||
|
||||
if (!e.IsDisposed)
|
||||
{
|
||||
fx[index][ei] = e;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var q = CreateEffectQueue(fx.Combine());
|
||||
|
||||
if (q.Mutator == null && EffectMutator != null)
|
||||
{
|
||||
q.Mutator = EffectMutator;
|
||||
}
|
||||
|
||||
if (q.Handler == null && EffectHandler != null)
|
||||
{
|
||||
q.Handler = EffectHandler;
|
||||
}
|
||||
|
||||
this[i] = q;
|
||||
}
|
||||
|
||||
RemoveAll(l => l == null);
|
||||
|
||||
this.Free(false);
|
||||
|
||||
if (Reversed)
|
||||
{
|
||||
Reverse();
|
||||
}
|
||||
|
||||
var idx = 0;
|
||||
|
||||
foreach (var cur in this)
|
||||
{
|
||||
if (++idx >= Count)
|
||||
{
|
||||
cur.Callback = InternalCallback;
|
||||
break;
|
||||
}
|
||||
|
||||
var next = this[idx];
|
||||
|
||||
cur.Callback = () => InternalCallback(next);
|
||||
}
|
||||
|
||||
OnUpdated();
|
||||
}
|
||||
|
||||
public virtual Point3D[][] GetTargetPoints(int dist)
|
||||
{
|
||||
return Start == null ? EffectUtility.EmptyPoints : new[] { new[] { Start.Clone3D() } };
|
||||
}
|
||||
|
||||
protected virtual void OnUpdated()
|
||||
{ }
|
||||
|
||||
public virtual void MutateEffect(TEffectInfo e)
|
||||
{ }
|
||||
|
||||
public void Send()
|
||||
{
|
||||
if (Sending)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Sending = true;
|
||||
|
||||
VitaNexCore.TryCatch(InternalSend, VitaNexCore.ToConsole);
|
||||
}
|
||||
|
||||
public virtual void OnSend()
|
||||
{ }
|
||||
|
||||
private void InternalSend()
|
||||
{
|
||||
Update();
|
||||
|
||||
if (Count == 0 || this[0] == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Processing = true;
|
||||
InternalMoveNext(this[0]);
|
||||
OnSend();
|
||||
}
|
||||
|
||||
private void InternalMoveNext(TQueue next)
|
||||
{
|
||||
CurrentQueue = next;
|
||||
CurrentQueue.Process();
|
||||
}
|
||||
|
||||
private void InternalCallback()
|
||||
{
|
||||
Sending = false;
|
||||
|
||||
if (Callback != null)
|
||||
{
|
||||
Callback();
|
||||
}
|
||||
|
||||
if (++CurrentProcess <= Repeat)
|
||||
{
|
||||
if (Interval <= TimeSpan.Zero)
|
||||
{
|
||||
Send();
|
||||
return;
|
||||
}
|
||||
|
||||
Timer.DelayCall(Interval, Send);
|
||||
return;
|
||||
}
|
||||
|
||||
CurrentProcess = 0;
|
||||
Processing = false;
|
||||
|
||||
this.Free(true);
|
||||
}
|
||||
|
||||
private void InternalCallback(TQueue next)
|
||||
{
|
||||
Processing = true;
|
||||
|
||||
if (Interval <= TimeSpan.Zero)
|
||||
{
|
||||
InternalMoveNext(next);
|
||||
return;
|
||||
}
|
||||
|
||||
Timer.DelayCall(Interval, InternalMoveNext, next);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class BaseRangedEffect<TQueue, TEffectInfo> : BaseEffect<TQueue, TEffectInfo>
|
||||
where TQueue : EffectQueue<TEffectInfo>
|
||||
where TEffectInfo : EffectInfo
|
||||
{
|
||||
public virtual int Range { get; set; }
|
||||
public virtual bool AverageZ { get; set; }
|
||||
public virtual bool LOSCheck { get; set; }
|
||||
|
||||
public BaseRangedEffect(
|
||||
IPoint3D start,
|
||||
Map map,
|
||||
int range = 5,
|
||||
int repeat = 0,
|
||||
TimeSpan? interval = null,
|
||||
Action<TEffectInfo> effectHandler = null,
|
||||
Action callback = null)
|
||||
: base(start, map, repeat, interval, effectHandler, callback)
|
||||
{
|
||||
Range = range;
|
||||
AverageZ = true;
|
||||
LOSCheck = false;
|
||||
}
|
||||
|
||||
public override Point3D[][] GetTargetPoints(int count)
|
||||
{
|
||||
return Start.ScanRangeGet(Map, Range, ComputePoint, AverageZ);
|
||||
}
|
||||
|
||||
protected virtual bool ComputePoint(ScanRangeResult r)
|
||||
{
|
||||
if (!r.Excluded && ExcludePoint(r.Current, r.Distance, Utility.GetDirection(Start, r.Current)))
|
||||
{
|
||||
r.Exclude();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected virtual bool ExcludePoint(Point3D p, int range, Direction fromCenter)
|
||||
{
|
||||
return LOSCheck && !Map.LineOfSight(p, Start);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class BaseBoundsEffect<TQueue, TEffectInfo> : BaseEffect<TQueue, TEffectInfo>
|
||||
where TQueue : EffectQueue<TEffectInfo>
|
||||
where TEffectInfo : EffectInfo
|
||||
{
|
||||
public virtual Rectangle2D Bounds { get; set; }
|
||||
public virtual bool AverageZ { get; set; }
|
||||
|
||||
public BaseBoundsEffect(
|
||||
IPoint3D start,
|
||||
Map map,
|
||||
Rectangle2D bounds,
|
||||
int repeat = 0,
|
||||
TimeSpan? interval = null,
|
||||
Action<TEffectInfo> effectHandler = null,
|
||||
Action callback = null)
|
||||
: base(start, map, repeat, interval, effectHandler, callback)
|
||||
{
|
||||
Bounds = bounds;
|
||||
AverageZ = true;
|
||||
}
|
||||
|
||||
public override Point3D[][] GetTargetPoints(int count)
|
||||
{
|
||||
var points = new List<Point3D>[Math.Max(Bounds.Width, Bounds.Height)];
|
||||
|
||||
Bounds.ForEach(
|
||||
p2d =>
|
||||
{
|
||||
var distance = (int)Math.Floor(Start.GetDistance(p2d));
|
||||
|
||||
points[distance].Add(p2d.ToPoint3D(AverageZ ? p2d.GetAverageZ(Map) : Start.Z));
|
||||
});
|
||||
|
||||
var arr = points.ToMultiArray();
|
||||
|
||||
points.Free(true);
|
||||
|
||||
return arr;
|
||||
}
|
||||
}
|
||||
}
|
||||
427
Scripts/SubSystem/VitaNex/Core/Effects/FX/ExplosionFX.cs
Normal file
427
Scripts/SubSystem/VitaNex/Core/Effects/FX/ExplosionFX.cs
Normal file
@@ -0,0 +1,427 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Server;
|
||||
using Server.Commands;
|
||||
|
||||
using VitaNex.Network;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.FX
|
||||
{
|
||||
public enum ExplodeFX
|
||||
{
|
||||
None = 0,
|
||||
Random,
|
||||
Smoke,
|
||||
Water,
|
||||
Fire,
|
||||
Earth,
|
||||
Air,
|
||||
Energy,
|
||||
Poison
|
||||
}
|
||||
|
||||
public static class ExplodeEffects
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register(
|
||||
"ExplodeFXHide",
|
||||
AccessLevel.GameMaster,
|
||||
ce =>
|
||||
{
|
||||
if (ce == null || ce.Mobile == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var m = ce.Mobile;
|
||||
|
||||
if (m.Hidden)
|
||||
{
|
||||
m.Hidden = false;
|
||||
CommandSystem.Entries["ExplodeFX"].Handler(ce);
|
||||
}
|
||||
else
|
||||
{
|
||||
CommandSystem.Entries["ExplodeFX"].Handler(ce);
|
||||
m.Hidden = true;
|
||||
}
|
||||
});
|
||||
|
||||
CommandSystem.Register(
|
||||
"ExplodeFX",
|
||||
AccessLevel.GameMaster,
|
||||
ce =>
|
||||
{
|
||||
if (ce == null || ce.Mobile == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var m = ce.Mobile;
|
||||
|
||||
if (ce.Arguments.Length < 1 || !Enum.TryParse(ce.Arguments[0], true, out ExplodeFX effect))
|
||||
{
|
||||
effect = ExplodeFX.None;
|
||||
}
|
||||
|
||||
if (ce.Arguments.Length < 2 || !Int32.TryParse(ce.Arguments[1], out var range))
|
||||
{
|
||||
range = 5;
|
||||
}
|
||||
|
||||
if (ce.Arguments.Length < 3 || !Int32.TryParse(ce.Arguments[2], out var speed))
|
||||
{
|
||||
speed = 10;
|
||||
}
|
||||
|
||||
if (ce.Arguments.Length < 4 || !Int32.TryParse(ce.Arguments[3], out var repeat))
|
||||
{
|
||||
repeat = 0;
|
||||
}
|
||||
|
||||
if (ce.Arguments.Length < 5 || !Int32.TryParse(ce.Arguments[4], out var reverse))
|
||||
{
|
||||
reverse = 0;
|
||||
}
|
||||
|
||||
range = Math.Max(0, Math.Min(100, range));
|
||||
speed = Math.Max(1, Math.Min(10, speed));
|
||||
repeat = Math.Max(0, Math.Min(100, repeat));
|
||||
reverse = Math.Max(0, Math.Min(1, reverse));
|
||||
|
||||
var e = effect.CreateInstance(
|
||||
m.Location,
|
||||
m.Map,
|
||||
range,
|
||||
repeat,
|
||||
TimeSpan.FromMilliseconds(1000 - ((speed - 1) * 100)));
|
||||
|
||||
if (e != null)
|
||||
{
|
||||
e.Reversed = (reverse > 0);
|
||||
e.Send();
|
||||
}
|
||||
else
|
||||
{
|
||||
m.SendMessage(0x55, "Usage: <effect> <range> <speed> <repeat> <reverse>");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static BaseExplodeEffect CreateInstance(
|
||||
this ExplodeFX type,
|
||||
IPoint3D start,
|
||||
Map map,
|
||||
int range = 5,
|
||||
int repeat = 0,
|
||||
TimeSpan? interval = null,
|
||||
Action<EffectInfo> effectHandler = null,
|
||||
Action callback = null)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ExplodeFX.None:
|
||||
return null;
|
||||
case ExplodeFX.Smoke:
|
||||
return new SmokeExplodeEffect(start, map, range, repeat, interval, effectHandler, callback);
|
||||
case ExplodeFX.Water:
|
||||
return new WaterRippleEffect(start, map, range, repeat, interval, effectHandler, callback);
|
||||
case ExplodeFX.Fire:
|
||||
return new FireExplodeEffect(start, map, range, repeat, interval, effectHandler, callback);
|
||||
case ExplodeFX.Earth:
|
||||
return new EarthExplodeEffect(start, map, range, repeat, interval, effectHandler, callback);
|
||||
case ExplodeFX.Air:
|
||||
return new AirExplodeEffect(start, map, range, repeat, interval, effectHandler, callback);
|
||||
case ExplodeFX.Energy:
|
||||
return new EnergyExplodeEffect(start, map, range, repeat, interval, effectHandler, callback);
|
||||
case ExplodeFX.Poison:
|
||||
return new PoisonExplodeEffect(start, map, range, repeat, interval, effectHandler, callback);
|
||||
default:
|
||||
{
|
||||
var rfx = (ExplodeFX[])Enum.GetValues(typeof(ExplodeFX));
|
||||
|
||||
do
|
||||
{
|
||||
type = rfx.GetRandom();
|
||||
}
|
||||
while (type == ExplodeFX.Random || type == ExplodeFX.None);
|
||||
|
||||
return CreateInstance(type, start, map, range, repeat, interval, effectHandler, callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace VitaNex.FX
|
||||
{
|
||||
public abstract class BaseExplodeEffect : BaseRangedEffect<EffectQueue, EffectInfo>
|
||||
{
|
||||
public BaseExplodeEffect(
|
||||
IPoint3D start,
|
||||
Map map,
|
||||
int range = 2,
|
||||
int repeat = 0,
|
||||
TimeSpan? interval = null,
|
||||
Action<EffectInfo> effectHandler = null,
|
||||
Action callback = null)
|
||||
: base(start, map, range, repeat, interval, effectHandler, callback)
|
||||
{ }
|
||||
|
||||
public override EffectQueue CreateEffectQueue(IEnumerable<EffectInfo> queue)
|
||||
{
|
||||
return new EffectQueue(queue, null, EffectHandler, false);
|
||||
}
|
||||
|
||||
public override EffectInfo CloneEffectInfo(EffectInfo src)
|
||||
{
|
||||
return new EffectInfo(null, null, src.EffectID, src.Hue, src.Speed, src.Duration, src.Render, src.Delay);
|
||||
}
|
||||
}
|
||||
|
||||
public class SmokeExplodeEffect : BaseExplodeEffect
|
||||
{
|
||||
public static EffectInfo[] Info => new[] { new EffectInfo(null, null, 14120, 0, 10, 10, EffectRender.SemiTransparent) };
|
||||
|
||||
private readonly EffectInfo[] _Effects = Info;
|
||||
|
||||
public override EffectInfo[] Effects => _Effects;
|
||||
|
||||
public SmokeExplodeEffect(
|
||||
IPoint3D start,
|
||||
Map map,
|
||||
int range = 5,
|
||||
int repeat = 0,
|
||||
TimeSpan? interval = null,
|
||||
Action<EffectInfo> effectHandler = null,
|
||||
Action callback = null)
|
||||
: base(start, map, range, repeat, interval, effectHandler, callback)
|
||||
{ }
|
||||
}
|
||||
|
||||
public class WaterRippleEffect : BaseExplodeEffect
|
||||
{
|
||||
public static EffectInfo[] Info => new[] { new EffectInfo(null, null, -1, 0, 10, 30) };
|
||||
|
||||
private readonly EffectInfo[] _Effects = Info;
|
||||
|
||||
public override EffectInfo[] Effects => _Effects;
|
||||
|
||||
public WaterRippleEffect(
|
||||
IPoint3D start,
|
||||
Map map,
|
||||
int range = 3,
|
||||
int repeat = 0,
|
||||
TimeSpan? interval = null,
|
||||
Action<EffectInfo> effectHandler = null,
|
||||
Action callback = null)
|
||||
: base(start, map, range, repeat, interval, effectHandler, callback)
|
||||
{
|
||||
EnableMutate = true;
|
||||
}
|
||||
|
||||
public override void MutateEffect(EffectInfo e)
|
||||
{
|
||||
base.MutateEffect(e);
|
||||
|
||||
if (e == null || e.EffectID != -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (Utility.GetDirection(Start, e.Source))
|
||||
{
|
||||
case Direction.Up:
|
||||
case Direction.North:
|
||||
e.EffectID = 8099;
|
||||
break;
|
||||
case Direction.Down:
|
||||
case Direction.South:
|
||||
e.EffectID = 8114;
|
||||
break;
|
||||
case Direction.Right:
|
||||
case Direction.East:
|
||||
e.EffectID = 8109;
|
||||
break;
|
||||
case Direction.Left:
|
||||
case Direction.West:
|
||||
e.EffectID = 8104;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class FireExplodeEffect : BaseExplodeEffect
|
||||
{
|
||||
public static EffectInfo[] Info => new[]
|
||||
{
|
||||
new EffectInfo(null, null, 14089, 0, 10, 20, EffectRender.SemiTransparent),
|
||||
new EffectInfo(null, null, 13401, 0, 10, 20, EffectRender.Normal, TimeSpan.FromMilliseconds(200))
|
||||
};
|
||||
|
||||
private readonly EffectInfo[] _Effects = Info;
|
||||
|
||||
public override EffectInfo[] Effects => _Effects;
|
||||
|
||||
public FireExplodeEffect(
|
||||
IPoint3D start,
|
||||
Map map,
|
||||
int range = 5,
|
||||
int repeat = 0,
|
||||
TimeSpan? interval = null,
|
||||
Action<EffectInfo> effectHandler = null,
|
||||
Action callback = null)
|
||||
: base(start, map, range, repeat, interval, effectHandler, callback)
|
||||
{ }
|
||||
}
|
||||
|
||||
public class EarthExplodeEffect : BaseExplodeEffect
|
||||
{
|
||||
public static EffectInfo[] Info => new[]
|
||||
{
|
||||
new EffectInfo(null, null, -1, 0, 10, 20),
|
||||
new EffectInfo(null, null, 14120, 0, 10, 20, EffectRender.SemiTransparent, TimeSpan.FromMilliseconds(200))
|
||||
};
|
||||
|
||||
private readonly EffectInfo[] _Effects = Info;
|
||||
|
||||
public override EffectInfo[] Effects => _Effects;
|
||||
|
||||
public EarthExplodeEffect(
|
||||
IPoint3D start,
|
||||
Map map,
|
||||
int range = 5,
|
||||
int repeat = 0,
|
||||
TimeSpan? interval = null,
|
||||
Action<EffectInfo> effectHandler = null,
|
||||
Action callback = null)
|
||||
: base(start, map, range, repeat, interval, effectHandler, callback)
|
||||
{
|
||||
EnableMutate = true;
|
||||
}
|
||||
|
||||
public override void MutateEffect(EffectInfo e)
|
||||
{
|
||||
base.MutateEffect(e);
|
||||
|
||||
if (e == null || e.EffectID != -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
e.EffectID = Utility.RandomMinMax(4963, 4973);
|
||||
e.Source = new Entity(Serial.Zero, e.Source.Location.Clone3D(zOffset: 5), e.Map);
|
||||
}
|
||||
}
|
||||
|
||||
public class AirExplodeEffect : BaseExplodeEffect
|
||||
{
|
||||
public static EffectInfo[] Info => new[]
|
||||
{
|
||||
new EffectInfo(null, null, 14217, 899, 10, 20, EffectRender.Lighten),
|
||||
new EffectInfo(null, null, 14284, 899, 10, 30, EffectRender.LightenMore, TimeSpan.FromMilliseconds(200))
|
||||
};
|
||||
|
||||
private readonly EffectInfo[] _Effects = Info;
|
||||
|
||||
public override EffectInfo[] Effects => _Effects;
|
||||
|
||||
public AirExplodeEffect(
|
||||
IPoint3D start,
|
||||
Map map,
|
||||
int range = 5,
|
||||
int repeat = 0,
|
||||
TimeSpan? interval = null,
|
||||
Action<EffectInfo> effectHandler = null,
|
||||
Action callback = null)
|
||||
: base(start, map, range, repeat, interval, effectHandler, callback)
|
||||
{ }
|
||||
}
|
||||
|
||||
public class EnergyExplodeEffect : BaseExplodeEffect
|
||||
{
|
||||
public static EffectInfo[] Info => new[]
|
||||
{
|
||||
new EffectInfo(null, null, 14170, 0, 10, 20, EffectRender.LightenMore),
|
||||
new EffectInfo(null, null, 14201, 0, 10, 30, EffectRender.Normal, TimeSpan.FromMilliseconds(200))
|
||||
};
|
||||
|
||||
private readonly EffectInfo[] _Effects = Info;
|
||||
|
||||
public override EffectInfo[] Effects => _Effects;
|
||||
|
||||
public EnergyExplodeEffect(
|
||||
IPoint3D start,
|
||||
Map map,
|
||||
int range = 5,
|
||||
int repeat = 0,
|
||||
TimeSpan? interval = null,
|
||||
Action<EffectInfo> effectHandler = null,
|
||||
Action callback = null)
|
||||
: base(start, map, range, repeat, interval, effectHandler, callback)
|
||||
{
|
||||
EnableMutate = true;
|
||||
}
|
||||
|
||||
public override void MutateEffect(EffectInfo e)
|
||||
{
|
||||
base.MutateEffect(e);
|
||||
|
||||
if (e != null && e.EffectID == 14201)
|
||||
{
|
||||
e.Source = new Entity(Serial.Zero, e.Source.Location.Clone3D(zOffset: -5), e.Map);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class PoisonExplodeEffect : BaseExplodeEffect
|
||||
{
|
||||
public static EffectInfo[] Info => new[]
|
||||
{
|
||||
new EffectInfo(null, null, 14217, 65, 10, 30, EffectRender.Darken),
|
||||
new EffectInfo(null, null, 14120, 65, 10, 30, EffectRender.Normal, TimeSpan.FromMilliseconds(200))
|
||||
};
|
||||
|
||||
private readonly EffectInfo[] _Effects = Info;
|
||||
|
||||
public override EffectInfo[] Effects => _Effects;
|
||||
|
||||
public PoisonExplodeEffect(
|
||||
IPoint3D start,
|
||||
Map map,
|
||||
int range = 5,
|
||||
int repeat = 0,
|
||||
TimeSpan? interval = null,
|
||||
Action<EffectInfo> effectHandler = null,
|
||||
Action callback = null)
|
||||
: base(start, map, range, repeat, interval, effectHandler, callback)
|
||||
{
|
||||
EnableMutate = true;
|
||||
}
|
||||
|
||||
public override void MutateEffect(EffectInfo e)
|
||||
{
|
||||
base.MutateEffect(e);
|
||||
|
||||
if (e != null)
|
||||
{
|
||||
e.Hue = Utility.RandomMinMax(550, 580);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
303
Scripts/SubSystem/VitaNex/Core/Effects/FX/SpecialFX.cs
Normal file
303
Scripts/SubSystem/VitaNex/Core/Effects/FX/SpecialFX.cs
Normal file
@@ -0,0 +1,303 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Server;
|
||||
using Server.Commands;
|
||||
|
||||
using VitaNex.Network;
|
||||
|
||||
using Geo = Server.Misc.Geometry;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.FX
|
||||
{
|
||||
public enum SpecialFX
|
||||
{
|
||||
None = 0,
|
||||
Random,
|
||||
|
||||
FirePentagram
|
||||
//-FireSpiral
|
||||
}
|
||||
|
||||
public static class SpecialEffects
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register(
|
||||
"SpecialFXHide",
|
||||
AccessLevel.GameMaster,
|
||||
ce =>
|
||||
{
|
||||
if (ce == null || ce.Mobile == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var m = ce.Mobile;
|
||||
|
||||
if (m.Hidden)
|
||||
{
|
||||
m.Hidden = false;
|
||||
CommandSystem.Entries["SpecialFX"].Handler(ce);
|
||||
}
|
||||
else
|
||||
{
|
||||
CommandSystem.Entries["SpecialFX"].Handler(ce);
|
||||
m.Hidden = true;
|
||||
}
|
||||
});
|
||||
|
||||
CommandSystem.Register(
|
||||
"SpecialFX",
|
||||
AccessLevel.GameMaster,
|
||||
ce =>
|
||||
{
|
||||
if (ce == null || ce.Mobile == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var m = ce.Mobile;
|
||||
|
||||
if (ce.Arguments.Length < 1 || !Enum.TryParse(ce.Arguments[0], true, out SpecialFX effect))
|
||||
{
|
||||
effect = SpecialFX.None;
|
||||
}
|
||||
|
||||
if (ce.Arguments.Length < 2 || !Int32.TryParse(ce.Arguments[1], out var range))
|
||||
{
|
||||
range = 5;
|
||||
}
|
||||
|
||||
if (ce.Arguments.Length < 3 || !Int32.TryParse(ce.Arguments[2], out var speed))
|
||||
{
|
||||
speed = 10;
|
||||
}
|
||||
|
||||
if (ce.Arguments.Length < 4 || !Int32.TryParse(ce.Arguments[3], out var repeat))
|
||||
{
|
||||
repeat = 0;
|
||||
}
|
||||
|
||||
if (ce.Arguments.Length < 5 || !Int32.TryParse(ce.Arguments[4], out var reverse))
|
||||
{
|
||||
reverse = 0;
|
||||
}
|
||||
|
||||
range = Math.Max(0, Math.Min(100, range));
|
||||
speed = Math.Max(1, Math.Min(10, speed));
|
||||
repeat = Math.Max(0, Math.Min(100, repeat));
|
||||
reverse = Math.Max(0, Math.Min(1, reverse));
|
||||
|
||||
var e = effect.CreateInstance(
|
||||
m.Location,
|
||||
m.Map,
|
||||
range,
|
||||
repeat,
|
||||
TimeSpan.FromMilliseconds(1000 - ((speed - 1) * 100)));
|
||||
|
||||
if (e != null)
|
||||
{
|
||||
e.Reversed = (reverse > 0);
|
||||
e.Send();
|
||||
}
|
||||
else
|
||||
{
|
||||
m.SendMessage(0x55, "Usage: <effect> <range> <speed> <repeat> <reverse>");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static BaseSpecialEffect CreateInstance(
|
||||
this SpecialFX type,
|
||||
IPoint3D start,
|
||||
Map map,
|
||||
int range = 5,
|
||||
int repeat = 0,
|
||||
TimeSpan? interval = null,
|
||||
Action<EffectInfo> effectHandler = null,
|
||||
Action callback = null)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case SpecialFX.None:
|
||||
return null;
|
||||
case SpecialFX.FirePentagram:
|
||||
return new FirePentagramEffect(start, map, range, repeat, interval, effectHandler, callback);
|
||||
/*case SpecialFX.FireSpiral:
|
||||
return new FireSpiralEffect(start, map, range, repeat, interval, effectHandler, callback);*/
|
||||
default:
|
||||
{
|
||||
var rfx = (SpecialFX[])Enum.GetValues(typeof(SpecialFX));
|
||||
|
||||
do
|
||||
{
|
||||
type = rfx.GetRandom();
|
||||
}
|
||||
while (type == SpecialFX.Random || type == SpecialFX.None);
|
||||
|
||||
return CreateInstance(type, start, map, range, repeat, interval, effectHandler, callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace VitaNex.FX
|
||||
{
|
||||
public abstract class BaseSpecialEffect : BaseRangedEffect<EffectQueue, EffectInfo>
|
||||
{
|
||||
public BaseSpecialEffect(
|
||||
IPoint3D start,
|
||||
Map map,
|
||||
int range = 2,
|
||||
int repeat = 0,
|
||||
TimeSpan? interval = null,
|
||||
Action<EffectInfo> effectHandler = null,
|
||||
Action callback = null)
|
||||
: base(start, map, range, repeat, interval, effectHandler, callback)
|
||||
{ }
|
||||
|
||||
public override EffectQueue CreateEffectQueue(IEnumerable<EffectInfo> queue)
|
||||
{
|
||||
return new EffectQueue(queue, null, EffectHandler, false);
|
||||
}
|
||||
|
||||
public override EffectInfo CloneEffectInfo(EffectInfo src)
|
||||
{
|
||||
return new EffectInfo(null, null, src.EffectID, src.Hue, src.Speed, src.Duration, src.Render, src.Delay);
|
||||
}
|
||||
}
|
||||
|
||||
public class FirePentagramEffect : BaseSpecialEffect
|
||||
{
|
||||
public static EffectInfo[] Info => new[]
|
||||
{
|
||||
new EffectInfo(null, null, 14089, 0, 10, 20, EffectRender.SemiTransparent),
|
||||
new EffectInfo(null, null, 13401, 0, 10, 20, EffectRender.Normal, TimeSpan.FromMilliseconds(200))
|
||||
};
|
||||
|
||||
private readonly EffectInfo[] _Effects = Info;
|
||||
|
||||
public override EffectInfo[] Effects => _Effects;
|
||||
|
||||
public FirePentagramEffect(
|
||||
IPoint3D start,
|
||||
Map map,
|
||||
int range = 5,
|
||||
int repeat = 0,
|
||||
TimeSpan? interval = null,
|
||||
Action<EffectInfo> effectHandler = null,
|
||||
Action callback = null)
|
||||
: base(start, map, range, repeat, interval, effectHandler, callback)
|
||||
{ }
|
||||
|
||||
private const double Section = 72;
|
||||
|
||||
private static readonly double[][] _Lines =
|
||||
{
|
||||
new[] {0, Section * 2}, new[] {Section * 2, Section * 4}, new[] {Section * 4, Section}, new[] {Section, Section * 3},
|
||||
new[] {Section * 3, 0}
|
||||
};
|
||||
|
||||
public override Point3D[][] GetTargetPoints(int count)
|
||||
{
|
||||
var points = new List<Point3D>[_Lines.Length];
|
||||
|
||||
points.SetAll(i => new List<Point3D>());
|
||||
|
||||
_Lines.For(
|
||||
(i, list) =>
|
||||
{
|
||||
var start = Start.Clone3D(
|
||||
(int)Math.Round(Range * Math.Sin(Geo.DegreesToRadians(list[0]))),
|
||||
(int)Math.Round(Range * Math.Cos(Geo.DegreesToRadians(list[0]))));
|
||||
|
||||
var end = Start.Clone3D(
|
||||
(int)Math.Round(Range * Math.Sin(Geo.DegreesToRadians(list[1]))),
|
||||
(int)Math.Round(Range * Math.Cos(Geo.DegreesToRadians(list[1]))));
|
||||
|
||||
if (AverageZ)
|
||||
{
|
||||
start = start.GetWorldTop(Map);
|
||||
end = end.GetWorldTop(Map);
|
||||
}
|
||||
|
||||
points[i].AddRange(start.GetLine3D(end, Map));
|
||||
});
|
||||
|
||||
return points.ToMultiArray();
|
||||
}
|
||||
}
|
||||
|
||||
/*public class FireSpiralEffect : BaseSpecialEffect
|
||||
{
|
||||
public static EffectInfo[] Info
|
||||
{
|
||||
get
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
new EffectInfo(null, null, 14089, 0, 10, 20, EffectRender.SemiTransparent),
|
||||
new EffectInfo(null, null, 13401, 0, 10, 20, EffectRender.Normal, TimeSpan.FromMilliseconds(200))
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private readonly EffectInfo[] _Effects = Info;
|
||||
|
||||
public override EffectInfo[] Effects { get { return _Effects; } }
|
||||
|
||||
public FireSpiralEffect(
|
||||
IPoint3D start,
|
||||
Map map,
|
||||
int range = 5,
|
||||
int repeat = 0,
|
||||
TimeSpan? interval = null,
|
||||
Action<EffectInfo> effectHandler = null,
|
||||
Action callback = null)
|
||||
: base(start, map, range, repeat, interval, effectHandler, callback)
|
||||
{ }
|
||||
|
||||
public override Point3D[][] GetTargetPoints(int count)
|
||||
{
|
||||
List<List<Point3D>> points = new List<List<Point3D>>(Range + 1);
|
||||
|
||||
points.SetAll(i => new List<Point3D>());
|
||||
|
||||
for (int r = 0; r <= Range; r++)
|
||||
{
|
||||
int bound = r * r;
|
||||
int area = (int)(Math.PI * bound);
|
||||
|
||||
int x, y;
|
||||
|
||||
for (int t = 0; t <= area; t++)
|
||||
{
|
||||
x = (int)(r * Math.Cos(t)) + Start.X;
|
||||
y = (int)(r * Math.Sin(t)) + Start.Y;
|
||||
|
||||
if (x * x + y * y <= bound)
|
||||
{
|
||||
points[r].Add(new Point3D(x, y, AverageZ ? Map.GetAverageZ(x, y) : Start.Z));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return points.ToMultiArray();
|
||||
}
|
||||
}*/
|
||||
}
|
||||
668
Scripts/SubSystem/VitaNex/Core/Effects/FX/WaveFX.cs
Normal file
668
Scripts/SubSystem/VitaNex/Core/Effects/FX/WaveFX.cs
Normal file
@@ -0,0 +1,668 @@
|
||||
#region Header
|
||||
// _,-'/-'/
|
||||
// . __,-; ,'( '/
|
||||
// \. `-.__`-._`:_,-._ _ , . ``
|
||||
// `:-._,------' ` _,`--` -: `_ , ` ,' :
|
||||
// `---..__,,--' (C) 2023 ` -'. -'
|
||||
// # Vita-Nex [http://core.vita-nex.com] #
|
||||
// {o)xxx|===============- # -===============|xxx(o}
|
||||
// # #
|
||||
#endregion
|
||||
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Server;
|
||||
using Server.Commands;
|
||||
using Server.Movement;
|
||||
|
||||
using VitaNex.Network;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex.FX
|
||||
{
|
||||
public enum WaveFX
|
||||
{
|
||||
None = 0,
|
||||
Random,
|
||||
Water,
|
||||
Fire,
|
||||
Earth,
|
||||
Air,
|
||||
Energy,
|
||||
Poison,
|
||||
Tornado
|
||||
}
|
||||
|
||||
public static class WaveEffects
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register(
|
||||
"WaveFX",
|
||||
AccessLevel.GameMaster,
|
||||
ce =>
|
||||
{
|
||||
var m = ce.Mobile;
|
||||
|
||||
if (ce.Arguments.Length < 1 || !Enum.TryParse(ce.Arguments[0], true, out WaveFX effect))
|
||||
{
|
||||
effect = WaveFX.None;
|
||||
}
|
||||
|
||||
if (ce.Arguments.Length < 2 || !Int32.TryParse(ce.Arguments[1], out var range))
|
||||
{
|
||||
range = 5;
|
||||
}
|
||||
|
||||
if (ce.Arguments.Length < 3 || !Int32.TryParse(ce.Arguments[2], out var speed))
|
||||
{
|
||||
speed = 10;
|
||||
}
|
||||
|
||||
if (ce.Arguments.Length < 4 || !Int32.TryParse(ce.Arguments[3], out var repeat))
|
||||
{
|
||||
repeat = 0;
|
||||
}
|
||||
|
||||
if (ce.Arguments.Length < 5 || !Int32.TryParse(ce.Arguments[4], out var reverse))
|
||||
{
|
||||
reverse = 0;
|
||||
}
|
||||
|
||||
range = Math.Max(0, Math.Min(100, range));
|
||||
speed = Math.Max(1, Math.Min(10, speed));
|
||||
repeat = Math.Max(0, Math.Min(100, repeat));
|
||||
reverse = Math.Max(0, Math.Min(1, reverse));
|
||||
|
||||
var e = effect.CreateInstance(
|
||||
m.Location,
|
||||
m.Map,
|
||||
m.Direction,
|
||||
range,
|
||||
repeat,
|
||||
TimeSpan.FromMilliseconds(1000 - ((speed - 1) * 100)));
|
||||
|
||||
if (e != null)
|
||||
{
|
||||
e.Reversed = (reverse > 0);
|
||||
e.Send();
|
||||
}
|
||||
else
|
||||
{
|
||||
m.SendMessage(0x55, "Usage: <effect> <range> <speed> <repeat> <reverse>");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static BaseWaveEffect CreateInstance(
|
||||
this WaveFX type,
|
||||
IPoint3D start,
|
||||
Map map,
|
||||
Direction d,
|
||||
int range = 5,
|
||||
int repeat = 0,
|
||||
TimeSpan? interval = null,
|
||||
Action<EffectInfo> effectHandler = null,
|
||||
Action callback = null)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case WaveFX.None:
|
||||
return null;
|
||||
case WaveFX.Fire:
|
||||
return new FireWaveEffect(start, map, d, range, repeat, interval, effectHandler, callback);
|
||||
case WaveFX.Water:
|
||||
return new WaterWaveEffect(start, map, d, range, repeat, interval, effectHandler, callback);
|
||||
case WaveFX.Earth:
|
||||
return new EarthWaveEffect(start, map, d, range, repeat, interval, effectHandler, callback);
|
||||
case WaveFX.Air:
|
||||
return new AirWaveEffect(start, map, d, range, repeat, interval, effectHandler, callback);
|
||||
case WaveFX.Energy:
|
||||
return new EnergyWaveEffect(start, map, d, range, repeat, interval, effectHandler, callback);
|
||||
case WaveFX.Poison:
|
||||
return new PoisonWaveEffect(start, map, d, range, repeat, interval, effectHandler, callback);
|
||||
case WaveFX.Tornado:
|
||||
return new TornadoEffect(start, map, d, range, repeat, interval, effectHandler, callback);
|
||||
default:
|
||||
{
|
||||
var rfx = (WaveFX[])Enum.GetValues(typeof(WaveFX));
|
||||
|
||||
do
|
||||
{
|
||||
type = rfx.GetRandom();
|
||||
}
|
||||
while (type == WaveFX.Random || type == WaveFX.None);
|
||||
|
||||
return CreateInstance(type, start, map, d, range, repeat, interval, effectHandler, callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class BaseWaveEffect : BaseRangedEffect<EffectQueue, EffectInfo>
|
||||
{
|
||||
public virtual Direction Direction { get; set; }
|
||||
|
||||
public BaseWaveEffect(
|
||||
IPoint3D start,
|
||||
Map map,
|
||||
Direction d,
|
||||
int range = 5,
|
||||
int repeat = 0,
|
||||
TimeSpan? interval = null,
|
||||
Action<EffectInfo> effectHandler = null,
|
||||
Action callback = null)
|
||||
: base(start, map, range, repeat, interval, effectHandler, callback)
|
||||
{
|
||||
Direction = d & Direction.ValueMask;
|
||||
}
|
||||
|
||||
public override EffectQueue CreateEffectQueue(IEnumerable<EffectInfo> queue)
|
||||
{
|
||||
return new EffectQueue(queue, null, EffectHandler, false);
|
||||
}
|
||||
|
||||
public override EffectInfo CloneEffectInfo(EffectInfo src)
|
||||
{
|
||||
return new EffectInfo(null, null, src.EffectID, src.Hue, src.Speed, src.Duration, src.Render, src.Delay);
|
||||
}
|
||||
|
||||
protected override bool ExcludePoint(Point3D p, int range, Direction fromCenter)
|
||||
{
|
||||
switch (Direction & Direction.Mask)
|
||||
{
|
||||
case Direction.Up:
|
||||
return !(fromCenter == Direction.West || fromCenter == Direction.Up || fromCenter == Direction.North);
|
||||
case Direction.North:
|
||||
return !(fromCenter == Direction.Up || fromCenter == Direction.North || fromCenter == Direction.Right);
|
||||
case Direction.Right:
|
||||
return !(fromCenter == Direction.North || fromCenter == Direction.Right || fromCenter == Direction.East);
|
||||
case Direction.East:
|
||||
return !(fromCenter == Direction.Right || fromCenter == Direction.East || fromCenter == Direction.Down);
|
||||
case Direction.Down:
|
||||
return !(fromCenter == Direction.East || fromCenter == Direction.Down || fromCenter == Direction.South);
|
||||
case Direction.South:
|
||||
return !(fromCenter == Direction.Down || fromCenter == Direction.South || fromCenter == Direction.Left);
|
||||
case Direction.Left:
|
||||
return !(fromCenter == Direction.South || fromCenter == Direction.Left || fromCenter == Direction.West);
|
||||
case Direction.West:
|
||||
return !(fromCenter == Direction.Left || fromCenter == Direction.West || fromCenter == Direction.Up);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public class WaterWaveEffect : BaseWaveEffect
|
||||
{
|
||||
public static bool DisplayElemental = true;
|
||||
|
||||
public static EffectInfo[] Info => new[]
|
||||
{
|
||||
new EffectInfo(null, null, 8459, 0, 10, 20),
|
||||
new EffectInfo(null, null, 14089, 85, 10, 30, EffectRender.SemiTransparent, TimeSpan.FromMilliseconds(200)),
|
||||
new EffectInfo(null, null, -1, 0, 10, 40, EffectRender.Normal, TimeSpan.FromMilliseconds(400))
|
||||
};
|
||||
|
||||
private readonly EffectInfo[] _Effects = Info;
|
||||
|
||||
public override EffectInfo[] Effects => _Effects;
|
||||
|
||||
public WaterWaveEffect(
|
||||
IPoint3D start,
|
||||
Map map,
|
||||
Direction d,
|
||||
int range = 5,
|
||||
int repeat = 0,
|
||||
TimeSpan? interval = null,
|
||||
Action<EffectInfo> effectHandler = null,
|
||||
Action callback = null)
|
||||
: base(start, map, d, range, repeat, interval, effectHandler, callback)
|
||||
{
|
||||
EnableMutate = true;
|
||||
}
|
||||
|
||||
public override EffectInfo CloneEffectInfo(EffectInfo src)
|
||||
{
|
||||
if (src != null && src.EffectID == 8459 && !DisplayElemental)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return base.CloneEffectInfo(src);
|
||||
}
|
||||
|
||||
public override void MutateEffect(EffectInfo e)
|
||||
{
|
||||
base.MutateEffect(e);
|
||||
|
||||
if (e == null || e.EffectID != -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (Direction)
|
||||
{
|
||||
case Direction.North:
|
||||
{
|
||||
switch (Utility.GetDirection(Start, e.Source))
|
||||
{
|
||||
case Direction.Up:
|
||||
case Direction.North:
|
||||
case Direction.Right:
|
||||
e.EffectID = 8099;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Direction.East:
|
||||
{
|
||||
switch (Utility.GetDirection(Start, e.Source))
|
||||
{
|
||||
case Direction.Down:
|
||||
case Direction.East:
|
||||
case Direction.Right:
|
||||
e.EffectID = 8109;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Direction.South:
|
||||
{
|
||||
switch (Utility.GetDirection(Start, e.Source))
|
||||
{
|
||||
case Direction.Down:
|
||||
case Direction.South:
|
||||
case Direction.Left:
|
||||
e.EffectID = 8114;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Direction.West:
|
||||
{
|
||||
switch (Utility.GetDirection(Start, e.Source))
|
||||
{
|
||||
case Direction.Up:
|
||||
case Direction.West:
|
||||
case Direction.Left:
|
||||
e.EffectID = 8104;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
switch (Utility.GetDirection(Start, e.Source))
|
||||
{
|
||||
case Direction.Up:
|
||||
case Direction.North:
|
||||
e.EffectID = 8099;
|
||||
break;
|
||||
case Direction.Right:
|
||||
case Direction.East:
|
||||
e.EffectID = 8109;
|
||||
break;
|
||||
case Direction.Down:
|
||||
case Direction.South:
|
||||
e.EffectID = 8114;
|
||||
break;
|
||||
case Direction.Left:
|
||||
case Direction.West:
|
||||
e.EffectID = 8104;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class FireWaveEffect : BaseWaveEffect
|
||||
{
|
||||
public static bool DisplayElemental = true;
|
||||
|
||||
public static EffectInfo[] Info => new[]
|
||||
{
|
||||
new EffectInfo(null, null, 8435, 0, 10, 20),
|
||||
new EffectInfo(null, null, 14089, 0, 10, 20, EffectRender.SemiTransparent, TimeSpan.FromMilliseconds(200)),
|
||||
new EffectInfo(null, null, 13401, 0, 10, 20, EffectRender.Normal, TimeSpan.FromMilliseconds(200))
|
||||
};
|
||||
|
||||
private readonly EffectInfo[] _Effects = Info;
|
||||
|
||||
public override EffectInfo[] Effects => _Effects;
|
||||
|
||||
public FireWaveEffect(
|
||||
IPoint3D start,
|
||||
Map map,
|
||||
Direction d,
|
||||
int range = 5,
|
||||
int repeat = 0,
|
||||
TimeSpan? interval = null,
|
||||
Action<EffectInfo> effectHandler = null,
|
||||
Action callback = null)
|
||||
: base(start, map, d, range, repeat, interval, effectHandler, callback)
|
||||
{
|
||||
EnableMutate = true;
|
||||
}
|
||||
|
||||
public override EffectInfo CloneEffectInfo(EffectInfo src)
|
||||
{
|
||||
if (src != null && src.EffectID == 8435 && !DisplayElemental)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return base.CloneEffectInfo(src);
|
||||
}
|
||||
}
|
||||
|
||||
public class EarthWaveEffect : BaseWaveEffect
|
||||
{
|
||||
public static bool DisplayElemental = true;
|
||||
|
||||
public static EffectInfo[] Info => new[]
|
||||
{
|
||||
new EffectInfo(null, null, 8407, 0, 10, 20),
|
||||
new EffectInfo(null, null, -1, 0, 10, 20, EffectRender.Normal, TimeSpan.FromMilliseconds(200)),
|
||||
new EffectInfo(null, null, 14120, 0, 10, 20, EffectRender.SemiTransparent, TimeSpan.FromMilliseconds(400))
|
||||
};
|
||||
|
||||
private readonly EffectInfo[] _Effects = Info;
|
||||
|
||||
public override EffectInfo[] Effects => _Effects;
|
||||
|
||||
public EarthWaveEffect(
|
||||
IPoint3D start,
|
||||
Map map,
|
||||
Direction d,
|
||||
int range = 5,
|
||||
int repeat = 0,
|
||||
TimeSpan? interval = null,
|
||||
Action<EffectInfo> effectHandler = null,
|
||||
Action callback = null)
|
||||
: base(start, map, d, range, repeat, interval, effectHandler, callback)
|
||||
{
|
||||
EnableMutate = true;
|
||||
}
|
||||
|
||||
public override EffectInfo CloneEffectInfo(EffectInfo src)
|
||||
{
|
||||
if (src != null && src.EffectID == 8407 && !DisplayElemental)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return base.CloneEffectInfo(src);
|
||||
}
|
||||
|
||||
public override void MutateEffect(EffectInfo e)
|
||||
{
|
||||
base.MutateEffect(e);
|
||||
|
||||
if (e == null || e.EffectID != -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
e.EffectID = Utility.RandomMinMax(4963, 4973);
|
||||
e.Source = new Entity(Serial.Zero, e.Source.Location.Clone3D(zOffset: 5), e.Map);
|
||||
}
|
||||
}
|
||||
|
||||
public class AirWaveEffect : BaseWaveEffect
|
||||
{
|
||||
public static bool DisplayElemental = true;
|
||||
|
||||
public static EffectInfo[] Info => new[]
|
||||
{
|
||||
new EffectInfo(null, null, 8429, 0, 10, 20),
|
||||
new EffectInfo(null, null, 14217, 899, 10, 30, EffectRender.Lighten, TimeSpan.FromMilliseconds(200)),
|
||||
new EffectInfo(null, null, 14284, 899, 10, 40, EffectRender.LightenMore, TimeSpan.FromMilliseconds(400))
|
||||
};
|
||||
|
||||
private readonly EffectInfo[] _Effects = Info;
|
||||
|
||||
public override EffectInfo[] Effects => _Effects;
|
||||
|
||||
public AirWaveEffect(
|
||||
IPoint3D start,
|
||||
Map map,
|
||||
Direction d,
|
||||
int range = 5,
|
||||
int repeat = 0,
|
||||
TimeSpan? interval = null,
|
||||
Action<EffectInfo> effectHandler = null,
|
||||
Action callback = null)
|
||||
: base(start, map, d, range, repeat, interval, effectHandler, callback)
|
||||
{
|
||||
EnableMutate = true;
|
||||
}
|
||||
|
||||
public override EffectInfo CloneEffectInfo(EffectInfo src)
|
||||
{
|
||||
if (src != null && src.EffectID == 8429 && !DisplayElemental)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return base.CloneEffectInfo(src);
|
||||
}
|
||||
}
|
||||
|
||||
public class EnergyWaveEffect : BaseWaveEffect
|
||||
{
|
||||
public static EffectInfo[] Info => new[]
|
||||
{
|
||||
new EffectInfo(null, null, 8448, 0, 10, 20),
|
||||
new EffectInfo(null, null, 14170, 0, 10, 30, EffectRender.LightenMore, TimeSpan.FromMilliseconds(200)),
|
||||
new EffectInfo(null, null, 14201, 0, 10, 40, EffectRender.Normal, TimeSpan.FromMilliseconds(400))
|
||||
};
|
||||
|
||||
private readonly EffectInfo[] _Effects = Info;
|
||||
|
||||
public override EffectInfo[] Effects => _Effects;
|
||||
|
||||
public EnergyWaveEffect(
|
||||
IPoint3D start,
|
||||
Map map,
|
||||
Direction d,
|
||||
int range = 5,
|
||||
int repeat = 0,
|
||||
TimeSpan? interval = null,
|
||||
Action<EffectInfo> effectHandler = null,
|
||||
Action callback = null)
|
||||
: base(start, map, d, range, repeat, interval, effectHandler, callback)
|
||||
{
|
||||
EnableMutate = true;
|
||||
}
|
||||
|
||||
public override void MutateEffect(EffectInfo e)
|
||||
{
|
||||
base.MutateEffect(e);
|
||||
|
||||
if (e == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (e.EffectID)
|
||||
{
|
||||
case 8448:
|
||||
e.Source = new Entity(Serial.Zero, e.Source.Location.Clone3D(zOffset: -10), e.Map);
|
||||
break;
|
||||
case 14201:
|
||||
e.Source = new Entity(Serial.Zero, e.Source.Location.Clone3D(zOffset: -5), e.Map);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class PoisonWaveEffect : BaseWaveEffect
|
||||
{
|
||||
public static EffectInfo[] Info => new[]
|
||||
{
|
||||
new EffectInfo(null, null, -1, 0, 10, 20),
|
||||
new EffectInfo(null, null, 14217, 65, 10, 30, EffectRender.Darken, TimeSpan.FromMilliseconds(200)),
|
||||
new EffectInfo(null, null, 14120, 65, 10, 40, EffectRender.Normal, TimeSpan.FromMilliseconds(400))
|
||||
};
|
||||
|
||||
private readonly EffectInfo[] _Effects = Info;
|
||||
|
||||
public override EffectInfo[] Effects => _Effects;
|
||||
|
||||
public PoisonWaveEffect(
|
||||
IPoint3D start,
|
||||
Map map,
|
||||
Direction d,
|
||||
int range = 5,
|
||||
int repeat = 0,
|
||||
TimeSpan? interval = null,
|
||||
Action<EffectInfo> effectHandler = null,
|
||||
Action callback = null)
|
||||
: base(start, map, d, range, repeat, interval, effectHandler, callback)
|
||||
{
|
||||
EnableMutate = true;
|
||||
}
|
||||
|
||||
public override void MutateEffect(EffectInfo e)
|
||||
{
|
||||
base.MutateEffect(e);
|
||||
|
||||
if (e == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (e.EffectID)
|
||||
{
|
||||
case -1:
|
||||
e.EffectID = Utility.RandomMinMax(11666, 11668);
|
||||
break;
|
||||
default:
|
||||
e.Hue = Utility.RandomMinMax(550, 580);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class TornadoEffect : BaseWaveEffect
|
||||
{
|
||||
public static EffectInfo[] Info => new[] { new EffectInfo(null, null, 14284, 899, 10, 10, EffectRender.ShadowOutline) };
|
||||
|
||||
private readonly EffectInfo[] _Effects = Info;
|
||||
|
||||
public override EffectInfo[] Effects => _Effects;
|
||||
|
||||
public int Size { get; set; }
|
||||
public int Climb { get; set; }
|
||||
public int Height { get; set; }
|
||||
|
||||
public bool CanMove { get; set; }
|
||||
|
||||
public TornadoEffect(
|
||||
IPoint3D start,
|
||||
Map map,
|
||||
Direction d,
|
||||
int range = 10,
|
||||
int repeat = 0,
|
||||
TimeSpan? interval = null,
|
||||
Action<EffectInfo> effectHandler = null,
|
||||
Action callback = null)
|
||||
: base(start, map, d, range, repeat, interval, effectHandler, callback)
|
||||
{
|
||||
EnableMutate = true;
|
||||
|
||||
Size = 5;
|
||||
Climb = 5;
|
||||
Height = 80;
|
||||
|
||||
CanMove = true;
|
||||
}
|
||||
|
||||
protected override bool ExcludePoint(Point3D p, int range, Direction fromCenter)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void MutateEffect(EffectInfo e)
|
||||
{
|
||||
base.MutateEffect(e);
|
||||
|
||||
e.Duration = 7 + (int)(Interval.TotalMilliseconds / 100.0);
|
||||
|
||||
switch (Utility.Random(3))
|
||||
{
|
||||
case 0:
|
||||
e.Render = EffectRender.Darken;
|
||||
break;
|
||||
case 1:
|
||||
e.Render = EffectRender.SemiTransparent;
|
||||
break;
|
||||
case 2:
|
||||
e.Render = EffectRender.ShadowOutline;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override Point3D[][] GetTargetPoints(int count)
|
||||
{
|
||||
var start = Start.Clone3D();
|
||||
|
||||
int x = 0, y = 0;
|
||||
|
||||
if (CanMove)
|
||||
{
|
||||
Movement.Offset(Direction, ref x, ref y);
|
||||
}
|
||||
|
||||
var end = start.Clone3D(Range * x, Range * y);
|
||||
|
||||
if (AverageZ)
|
||||
{
|
||||
start = start.GetWorldTop(Map);
|
||||
end = end.GetWorldTop(Map);
|
||||
}
|
||||
|
||||
var path = CanMove ? start.GetLine3D(end, Map, AverageZ) : new[] { start };
|
||||
var points = new List<Point3D>[path.Length];
|
||||
|
||||
points.SetAll(i => new List<Point3D>());
|
||||
|
||||
var climb = Climb;
|
||||
var size = Size;
|
||||
double height = Height;
|
||||
|
||||
Action<int> a = i =>
|
||||
{
|
||||
var step = path[i];
|
||||
|
||||
for (var z = 0; z < height; z += climb)
|
||||
{
|
||||
var mm = (int)Math.Max(0, size * (z / height));
|
||||
|
||||
points[i].AddRange(step.ScanRangeGet(Map, mm, mm, ComputePoint, false).Combine().Select(p => p.Clone3D(0, 0, z)));
|
||||
}
|
||||
};
|
||||
|
||||
if (path.Length < 10)
|
||||
{
|
||||
for (var i = 0; i < path.Length; i++)
|
||||
{
|
||||
a(i);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Parallel.For(0, path.Length, a);
|
||||
}
|
||||
|
||||
return points.FreeToMultiArray(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user