Files
CypherCore/Source/Game/Spells/SpellCastTargets.cs
T

440 lines
14 KiB
C#

/*
* Copyright (C) 2012-2018 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.Entities;
using Game.Network.Packets;
using System;
namespace Game.Spells
{
public class SpellCastTargets
{
public SpellCastTargets()
{
m_strTarget = "";
m_src = new SpellDestination();
m_dst = new SpellDestination();
}
public SpellCastTargets(Unit caster, SpellCastRequest spellCastRequest)
{
m_targetMask = spellCastRequest.Target.Flags;
m_objectTargetGUID = spellCastRequest.Target.Unit;
m_itemTargetGUID = spellCastRequest.Target.Item;
m_strTarget = spellCastRequest.Target.Name;
m_src = new SpellDestination();
m_dst = new SpellDestination();
if (spellCastRequest.Target.SrcLocation.HasValue)
{
m_src.TransportGUID = spellCastRequest.Target.SrcLocation.Value.Transport;
Position pos;
if (!m_src.TransportGUID.IsEmpty())
pos = m_src.TransportOffset;
else
pos = m_src.Position;
pos.Relocate(spellCastRequest.Target.SrcLocation.Value.Location);
if (spellCastRequest.Target.Orientation.HasValue)
pos.SetOrientation(spellCastRequest.Target.Orientation.Value);
}
if (spellCastRequest.Target.DstLocation.HasValue)
{
m_dst.TransportGUID = spellCastRequest.Target.DstLocation.Value.Transport;
Position pos;
if (!m_dst.TransportGUID.IsEmpty())
pos = m_dst.TransportOffset;
else
pos = m_dst.Position;
pos.Relocate(spellCastRequest.Target.DstLocation.Value.Location);
if (spellCastRequest.Target.Orientation.HasValue)
pos.SetOrientation(spellCastRequest.Target.Orientation.Value);
}
SetPitch(spellCastRequest.MissileTrajectory.Pitch);
SetSpeed(spellCastRequest.MissileTrajectory.Speed);
Update(caster);
}
public void Write(SpellTargetData data)
{
data.Flags = m_targetMask;
if (m_targetMask.HasAnyFlag(SpellCastTargetFlags.Unit | SpellCastTargetFlags.CorpseAlly | SpellCastTargetFlags.Gameobject | SpellCastTargetFlags.CorpseEnemy | SpellCastTargetFlags.UnitMinipet))
data.Unit = m_objectTargetGUID;
if (m_targetMask.HasAnyFlag(SpellCastTargetFlags.Item | SpellCastTargetFlags.TradeItem) && m_itemTarget)
data.Item = m_itemTarget.GetGUID();
if (m_targetMask.HasAnyFlag(SpellCastTargetFlags.SourceLocation))
{
data.SrcLocation.HasValue = true;
TargetLocation target = new TargetLocation();
target.Transport = m_src.TransportGUID; // relative position guid here - transport for example
if (!m_src.TransportGUID.IsEmpty())
target.Location = m_src.TransportOffset;
else
target.Location = m_src.Position;
data.SrcLocation.Value = target;
}
if (Convert.ToBoolean(m_targetMask & SpellCastTargetFlags.DestLocation))
{
data.DstLocation.HasValue = true;
TargetLocation target = new TargetLocation();
target.Transport = m_dst.TransportGUID; // relative position guid here - transport for example
if (!m_dst.TransportGUID.IsEmpty())
target.Location = m_dst.TransportOffset;
else
target.Location = m_dst.Position;
data.DstLocation.Value = target;
}
if (Convert.ToBoolean(m_targetMask & SpellCastTargetFlags.String))
data.Name = m_strTarget;
}
public ObjectGuid GetOrigUnitTargetGUID()
{
switch (m_origObjectTargetGUID.GetHigh())
{
case HighGuid.Player:
case HighGuid.Vehicle:
case HighGuid.Creature:
case HighGuid.Pet:
return m_origObjectTargetGUID;
default:
return ObjectGuid.Empty;
}
}
public void SetOrigUnitTarget(Unit target)
{
if (!target)
return;
m_origObjectTargetGUID = target.GetGUID();
}
public ObjectGuid GetUnitTargetGUID()
{
if (m_objectTargetGUID.IsUnit())
return m_objectTargetGUID;
return ObjectGuid.Empty;
}
public Unit GetUnitTarget()
{
if (m_objectTarget)
return m_objectTarget.ToUnit();
return null;
}
public void SetUnitTarget(Unit target)
{
if (target == null)
return;
m_objectTarget = target;
m_objectTargetGUID = target.GetGUID();
m_targetMask |= SpellCastTargetFlags.Unit;
}
ObjectGuid GetGOTargetGUID()
{
if (m_objectTargetGUID.IsAnyTypeGameObject())
return m_objectTargetGUID;
return ObjectGuid.Empty;
}
public GameObject GetGOTarget()
{
if (m_objectTarget != null)
return m_objectTarget.ToGameObject();
return null;
}
public void SetGOTarget(GameObject target)
{
if (target == null)
return;
m_objectTarget = target;
m_objectTargetGUID = target.GetGUID();
m_targetMask |= SpellCastTargetFlags.Gameobject;
}
public ObjectGuid GetCorpseTargetGUID()
{
if (m_objectTargetGUID.IsCorpse())
return m_objectTargetGUID;
return ObjectGuid.Empty;
}
public Corpse GetCorpseTarget()
{
if (m_objectTarget != null)
return m_objectTarget.ToCorpse();
return null;
}
public WorldObject GetObjectTarget()
{
return m_objectTarget;
}
public ObjectGuid GetObjectTargetGUID()
{
return m_objectTargetGUID;
}
public void RemoveObjectTarget()
{
m_objectTarget = null;
m_objectTargetGUID.Clear();
m_targetMask &= ~(SpellCastTargetFlags.UnitMask | SpellCastTargetFlags.CorpseMask | SpellCastTargetFlags.GameobjectMask);
}
public void SetItemTarget(Item item)
{
if (item == null)
return;
m_itemTarget = item;
m_itemTargetGUID = item.GetGUID();
m_itemTargetEntry = item.GetEntry();
m_targetMask |= SpellCastTargetFlags.Item;
}
public void SetTradeItemTarget(Player caster)
{
m_itemTargetGUID = ObjectGuid.TradeItem;
m_itemTargetEntry = 0;
m_targetMask |= SpellCastTargetFlags.TradeItem;
Update(caster);
}
public void UpdateTradeSlotItem()
{
if (m_itemTarget != null && Convert.ToBoolean(m_targetMask & SpellCastTargetFlags.TradeItem))
{
m_itemTargetGUID = m_itemTarget.GetGUID();
m_itemTargetEntry = m_itemTarget.GetEntry();
}
}
public SpellDestination GetSrc()
{
return m_src;
}
public Position GetSrcPos()
{
return m_src.Position;
}
void SetSrc(float x, float y, float z)
{
m_src = new SpellDestination(x, y, z);
m_targetMask |= SpellCastTargetFlags.SourceLocation;
}
void SetSrc(Position pos)
{
m_src = new SpellDestination(pos);
m_targetMask |= SpellCastTargetFlags.SourceLocation;
}
public void SetSrc(WorldObject wObj)
{
m_src = new SpellDestination(wObj);
m_targetMask |= SpellCastTargetFlags.SourceLocation;
}
public void ModSrc(Position pos)
{
Cypher.Assert(m_targetMask.HasAnyFlag(SpellCastTargetFlags.SourceLocation));
m_src.Relocate(pos);
}
public void RemoveSrc()
{
m_targetMask &= ~SpellCastTargetFlags.SourceLocation;
}
public SpellDestination GetDst()
{
return m_dst;
}
public WorldLocation GetDstPos()
{
return m_dst.Position;
}
public void SetDst(float x, float y, float z, float orientation, uint mapId = 0xFFFFFFFF)
{
m_dst = new SpellDestination(x, y, z, orientation, mapId);
m_targetMask |= SpellCastTargetFlags.DestLocation;
}
public void SetDst(Position pos)
{
m_dst = new SpellDestination(pos);
m_targetMask |= SpellCastTargetFlags.DestLocation;
}
public void SetDst(WorldObject wObj)
{
m_dst = new SpellDestination(wObj);
m_targetMask |= SpellCastTargetFlags.DestLocation;
}
public void SetDst(SpellDestination spellDest)
{
m_dst = spellDest;
m_targetMask |= SpellCastTargetFlags.DestLocation;
}
public void SetDst(SpellCastTargets spellTargets)
{
m_dst = spellTargets.m_dst;
m_targetMask |= SpellCastTargetFlags.DestLocation;
}
public void ModDst(Position pos)
{
Cypher.Assert(m_targetMask.HasAnyFlag(SpellCastTargetFlags.DestLocation));
m_dst.Relocate(pos);
}
public void ModDst(SpellDestination spellDest)
{
Cypher.Assert(m_targetMask.HasAnyFlag(SpellCastTargetFlags.DestLocation));
m_dst = spellDest;
}
public void RemoveDst()
{
m_targetMask &= ~SpellCastTargetFlags.DestLocation;
}
public void Update(Unit caster)
{
m_objectTarget = !m_objectTargetGUID.IsEmpty() ? ((m_objectTargetGUID == caster.GetGUID()) ? caster : Global.ObjAccessor.GetWorldObject(caster, m_objectTargetGUID)) : null;
m_itemTarget = null;
if (caster is Player)
{
Player player = caster.ToPlayer();
if (m_targetMask.HasAnyFlag(SpellCastTargetFlags.Item))
m_itemTarget = player.GetItemByGuid(m_itemTargetGUID);
else if (m_targetMask.HasAnyFlag(SpellCastTargetFlags.TradeItem))
{
if (m_itemTargetGUID == ObjectGuid.TradeItem) // here it is not guid but slot. Also prevents hacking slots
{
TradeData pTrade = player.GetTradeData();
if (pTrade != null)
m_itemTarget = pTrade.GetTraderData().GetItem(TradeSlots.NonTraded);
}
}
if (m_itemTarget != null)
m_itemTargetEntry = m_itemTarget.GetEntry();
}
// update positions by transport move
if (HasSrc() && !m_src.TransportGUID.IsEmpty())
{
WorldObject transport = Global.ObjAccessor.GetWorldObject(caster, m_src.TransportGUID);
if (transport != null)
{
m_src.Position.Relocate(transport.GetPosition());
m_src.Position.RelocateOffset(m_src.TransportOffset);
}
}
if (HasDst() && !m_dst.TransportGUID.IsEmpty())
{
WorldObject transport = Global.ObjAccessor.GetWorldObject(caster, m_dst.TransportGUID);
if (transport != null)
{
m_dst.Position.Relocate(transport.GetPosition());
m_dst.Position.RelocateOffset(m_dst.TransportOffset);
}
}
}
public SpellCastTargetFlags GetTargetMask() { return m_targetMask; }
public void SetTargetMask(SpellCastTargetFlags newMask) { m_targetMask = newMask; }
public void SetTargetFlag(SpellCastTargetFlags flag) { m_targetMask |= flag; }
public ObjectGuid GetItemTargetGUID() { return m_itemTargetGUID; }
public Item GetItemTarget() { return m_itemTarget; }
public uint GetItemTargetEntry() { return m_itemTargetEntry; }
public bool HasSrc() { return Convert.ToBoolean(m_targetMask & SpellCastTargetFlags.SourceLocation); }
public bool HasDst() { return Convert.ToBoolean(m_targetMask & SpellCastTargetFlags.DestLocation); }
public bool HasTraj() { return m_speed != 0; }
public float GetPitch() { return m_pitch; }
public void SetPitch(float pitch) { m_pitch = pitch; }
float GetSpeed() { return m_speed; }
public void SetSpeed(float speed) { m_speed = speed; }
public float GetDist2d() { return m_src.Position.GetExactDist2d(m_dst.Position); }
public float GetSpeedXY() { return (float)(m_speed * Math.Cos(m_pitch)); }
public float GetSpeedZ() { return (float)(m_speed * Math.Sin(m_pitch)); }
public string GetTargetString() { return m_strTarget; }
#region Fields
SpellCastTargetFlags m_targetMask;
// objects (can be used at spell creating and after Update at casting)
WorldObject m_objectTarget;
Item m_itemTarget;
// object GUID/etc, can be used always
ObjectGuid m_origObjectTargetGUID;
ObjectGuid m_objectTargetGUID;
ObjectGuid m_itemTargetGUID;
uint m_itemTargetEntry;
SpellDestination m_src;
SpellDestination m_dst;
float m_pitch;
float m_speed;
string m_strTarget;
#endregion
}
}