Core/Object: Range check, Needs tested.
Port From (https://github.com/TrinityCore/TrinityCore/commit/b717603a9b3a676e800fc401f4544735287791a9)
This commit is contained in:
@@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2012-2020 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 System;
|
||||||
|
using System.Numerics;
|
||||||
|
|
||||||
|
namespace Framework.GameMath
|
||||||
|
{
|
||||||
|
public class Box
|
||||||
|
{
|
||||||
|
public Vector3[] _edgeVector = new Vector3[3];
|
||||||
|
public Vector3 _center;
|
||||||
|
public float _area;
|
||||||
|
public float _volume;
|
||||||
|
|
||||||
|
public Box(Vector3 min, Vector3 max)
|
||||||
|
{
|
||||||
|
Vector3 bounds = new Vector3(max.X - min.X, max.Y - min.Y, max.Z - min.Z);
|
||||||
|
_edgeVector[0] = new Vector3(bounds.X, 0, 0);
|
||||||
|
_edgeVector[1] = new Vector3(0, bounds.Y, 0);
|
||||||
|
_edgeVector[2] = new Vector3(0, 0, bounds.Z);
|
||||||
|
bool finiteExtent = true;
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; ++i)
|
||||||
|
{
|
||||||
|
if (!float.IsInfinity(_edgeVector[i].Length()))
|
||||||
|
{
|
||||||
|
finiteExtent = false;
|
||||||
|
// If the extent is infinite along an axis, make the center zero to avoid NaNs
|
||||||
|
_center.SetAt(0.0f, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (finiteExtent)
|
||||||
|
{
|
||||||
|
_volume = bounds.X * bounds.Y * bounds.Z;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_volume = float.PositiveInfinity;
|
||||||
|
}
|
||||||
|
|
||||||
|
_area = 2 *
|
||||||
|
(bounds.X * bounds.Y +
|
||||||
|
bounds.Y * bounds.Z +
|
||||||
|
bounds.Z * bounds.X);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Contains(Vector3 point)
|
||||||
|
{
|
||||||
|
Vector3 u = _edgeVector[2];
|
||||||
|
Vector3 v = _edgeVector[1];
|
||||||
|
Vector3 w = _edgeVector[0];
|
||||||
|
|
||||||
|
Matrix4x4 M = new(u.X, v.X, w.X, 0.0f, u.Y, v.Y, w.Y, 0.0f, u.Z, v.Z, w.Z, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
|
// M^-1 * (point - _corner[0]) = point in unit cube's object space
|
||||||
|
// compute the inverse of M
|
||||||
|
Matrix4x4.Invert(M, out M);
|
||||||
|
Vector3 osPoint = Vector3.Transform(point - Corner(0), M);
|
||||||
|
|
||||||
|
return (osPoint.X >= 0) && (osPoint.Y >= 0) && (osPoint.Z >= 0) &&
|
||||||
|
(osPoint.X <= 1) && (osPoint.Y <= 1) && (osPoint.Z <= 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 Corner(int i)
|
||||||
|
{
|
||||||
|
switch (i)
|
||||||
|
{
|
||||||
|
case 0: return _center + (0.5f * (-_edgeVector[0] - _edgeVector[1] - _edgeVector[2]));
|
||||||
|
case 1: return _center + (0.5f * (_edgeVector[0] - _edgeVector[1] - _edgeVector[2]));
|
||||||
|
case 2: return _center + (0.5f * (-_edgeVector[0] + _edgeVector[1] - _edgeVector[2]));
|
||||||
|
case 3: return _center + (0.5f * (_edgeVector[0] + _edgeVector[1] - _edgeVector[2]));
|
||||||
|
case 4: return _center + (0.5f * (-_edgeVector[0] - _edgeVector[1] + _edgeVector[2]));
|
||||||
|
case 5: return _center + (0.5f * (_edgeVector[0] - _edgeVector[1] + _edgeVector[2]));
|
||||||
|
case 6: return _center + (0.5f * (-_edgeVector[0] + _edgeVector[1] + _edgeVector[2]));
|
||||||
|
default: return _center + (0.5f * (_edgeVector[0] + _edgeVector[1] + _edgeVector[2]));//case 7
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool isFinite()
|
||||||
|
{
|
||||||
|
return float.IsInfinity(_volume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,7 +16,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using Framework.Constants;
|
using Framework.Constants;
|
||||||
|
using Framework.GameMath;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Numerics;
|
||||||
|
|
||||||
public static class MathFunctions
|
public static class MathFunctions
|
||||||
{
|
{
|
||||||
@@ -266,4 +268,20 @@ public static class MathFunctions
|
|||||||
{
|
{
|
||||||
return (ushort)((byte)l | (ushort)h << 8);
|
return (ushort)((byte)l | (ushort)h << 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//3d math
|
||||||
|
public static Box toWorldSpace(Matrix4x4 rotation, Vector3 translation, Box box)
|
||||||
|
{
|
||||||
|
if (!box.isFinite())
|
||||||
|
return box;
|
||||||
|
|
||||||
|
box._center = new(rotation.M11 * box._center.GetAt(0) + rotation.M12 * box._center.GetAt(1) + rotation.M13 * box._center.GetAt(2) + translation.GetAt(0),
|
||||||
|
rotation.M21 * box._center.GetAt(0) + rotation.M22 * box._center.GetAt(1) + rotation.M23 * box._center.GetAt(2) + translation.GetAt(1),
|
||||||
|
rotation.M31 * box._center.GetAt(0) + rotation.M32 * box._center.GetAt(1) + rotation.M33 * box._center.GetAt(2) + translation.GetAt(2));
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; ++i)
|
||||||
|
box._edgeVector[i] = Vector3.Transform(box._edgeVector[i], rotation);
|
||||||
|
|
||||||
|
return box;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -555,7 +555,7 @@ namespace Game.Chat
|
|||||||
Map map = obj.GetMap();
|
Map map = obj.GetMap();
|
||||||
|
|
||||||
obj.Relocate(obj.GetPositionX(), obj.GetPositionY(), obj.GetPositionZ());
|
obj.Relocate(obj.GetPositionX(), obj.GetPositionY(), obj.GetPositionZ());
|
||||||
obj.SetWorldRotationAngles(oz, oy, ox);
|
obj.SetLocalRotationAngles(oz, oy, ox);
|
||||||
obj.SaveToDB();
|
obj.SaveToDB();
|
||||||
|
|
||||||
// Generate a completely new spawn with new guid
|
// Generate a completely new spawn with new guid
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
using Framework.Constants;
|
using Framework.Constants;
|
||||||
using Framework.Database;
|
using Framework.Database;
|
||||||
|
using Framework.GameMath;
|
||||||
using Game.AI;
|
using Game.AI;
|
||||||
using Game.BattleGrounds;
|
using Game.BattleGrounds;
|
||||||
using Game.Collision;
|
using Game.Collision;
|
||||||
@@ -242,7 +243,7 @@ namespace Game.Entities
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetWorldRotation(rotation.X, rotation.Y, rotation.Z, rotation.W);
|
SetLocalRotation(rotation.X, rotation.Y, rotation.Z, rotation.W);
|
||||||
GameObjectAddon gameObjectAddon = Global.ObjectMgr.GetGameObjectAddon(GetSpawnId());
|
GameObjectAddon gameObjectAddon = Global.ObjectMgr.GetGameObjectAddon(GetSpawnId());
|
||||||
|
|
||||||
// For most of gameobjects is (0, 0, 0, 1) quaternion, there are only some transports with not standard rotation
|
// For most of gameobjects is (0, 0, 0, 1) quaternion, there are only some transports with not standard rotation
|
||||||
@@ -1025,7 +1026,7 @@ namespace Game.Entities
|
|||||||
|
|
||||||
data.Id = GetEntry();
|
data.Id = GetEntry();
|
||||||
data.spawnPoint.WorldRelocate(this);
|
data.spawnPoint.WorldRelocate(this);
|
||||||
data.rotation = m_worldRotation;
|
data.rotation = m_localRotation;
|
||||||
data.spawntimesecs = (int)(m_spawnedByDefault ? m_respawnDelayTime : -m_respawnDelayTime);
|
data.spawntimesecs = (int)(m_spawnedByDefault ? m_respawnDelayTime : -m_respawnDelayTime);
|
||||||
data.animprogress = GetGoAnimProgress();
|
data.animprogress = GetGoAnimProgress();
|
||||||
data.goState = GetGoState();
|
data.goState = GetGoState();
|
||||||
@@ -1054,10 +1055,10 @@ namespace Game.Entities
|
|||||||
stmt.AddValue(index++, GetPositionY());
|
stmt.AddValue(index++, GetPositionY());
|
||||||
stmt.AddValue(index++, GetPositionZ());
|
stmt.AddValue(index++, GetPositionZ());
|
||||||
stmt.AddValue(index++, GetOrientation());
|
stmt.AddValue(index++, GetOrientation());
|
||||||
stmt.AddValue(index++, m_worldRotation.X);
|
stmt.AddValue(index++, m_localRotation.X);
|
||||||
stmt.AddValue(index++, m_worldRotation.Y);
|
stmt.AddValue(index++, m_localRotation.Y);
|
||||||
stmt.AddValue(index++, m_worldRotation.Z);
|
stmt.AddValue(index++, m_localRotation.Z);
|
||||||
stmt.AddValue(index++, m_worldRotation.W);
|
stmt.AddValue(index++, m_localRotation.W);
|
||||||
stmt.AddValue(index++, m_respawnDelayTime);
|
stmt.AddValue(index++, m_respawnDelayTime);
|
||||||
stmt.AddValue(index++, GetGoAnimProgress());
|
stmt.AddValue(index++, GetGoAnimProgress());
|
||||||
stmt.AddValue(index++, (byte)GetGoState());
|
stmt.AddValue(index++, (byte)GetGoState());
|
||||||
@@ -2207,22 +2208,22 @@ namespace Game.Entities
|
|||||||
const int PACK_YZ_MASK = (PACK_YZ << 1) - 1;
|
const int PACK_YZ_MASK = (PACK_YZ << 1) - 1;
|
||||||
const int PACK_X_MASK = (PACK_X << 1) - 1;
|
const int PACK_X_MASK = (PACK_X << 1) - 1;
|
||||||
|
|
||||||
sbyte w_sign = (sbyte)(m_worldRotation.W >= 0.0f ? 1 : -1);
|
sbyte w_sign = (sbyte)(m_localRotation.W >= 0.0f ? 1 : -1);
|
||||||
long x = (int)(m_worldRotation.X * PACK_X) * w_sign & PACK_X_MASK;
|
long x = (int)(m_localRotation.X * PACK_X) * w_sign & PACK_X_MASK;
|
||||||
long y = (int)(m_worldRotation.Y * PACK_YZ) * w_sign & PACK_YZ_MASK;
|
long y = (int)(m_localRotation.Y * PACK_YZ) * w_sign & PACK_YZ_MASK;
|
||||||
long z = (int)(m_worldRotation.Z * PACK_YZ) * w_sign & PACK_YZ_MASK;
|
long z = (int)(m_localRotation.Z * PACK_YZ) * w_sign & PACK_YZ_MASK;
|
||||||
m_packedRotation = z | (y << 21) | (x << 42);
|
m_packedRotation = z | (y << 21) | (x << 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetWorldRotation(float qx, float qy, float qz, float qw)
|
public void SetLocalRotation(float qx, float qy, float qz, float qw)
|
||||||
{
|
{
|
||||||
Quaternion rotation = new Quaternion(qx, qy, qz, qw);
|
Quaternion rotation = new Quaternion(qx, qy, qz, qw);
|
||||||
rotation = Quaternion.Multiply(rotation, 1.0f / MathF.Sqrt(Quaternion.Dot(rotation, rotation)));
|
rotation = Quaternion.Multiply(rotation, 1.0f / MathF.Sqrt(Quaternion.Dot(rotation, rotation)));
|
||||||
|
|
||||||
m_worldRotation.X = rotation.X;
|
m_localRotation.X = rotation.X;
|
||||||
m_worldRotation.Y = rotation.Y;
|
m_localRotation.Y = rotation.Y;
|
||||||
m_worldRotation.Z = rotation.Z;
|
m_localRotation.Z = rotation.Z;
|
||||||
m_worldRotation.W = rotation.W;
|
m_localRotation.W = rotation.W;
|
||||||
UpdatePackedRotation();
|
UpdatePackedRotation();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2231,12 +2232,158 @@ namespace Game.Entities
|
|||||||
SetUpdateFieldValue(m_values.ModifyValue(m_gameObjectData).ModifyValue(m_gameObjectData.ParentRotation), rotation);
|
SetUpdateFieldValue(m_values.ModifyValue(m_gameObjectData).ModifyValue(m_gameObjectData.ParentRotation), rotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetWorldRotationAngles(float z_rot, float y_rot, float x_rot)
|
public void SetLocalRotationAngles(float z_rot, float y_rot, float x_rot)
|
||||||
{
|
{
|
||||||
Quaternion quat = Quaternion.CreateFromRotationMatrix(Extensions.fromEulerAnglesZYX(z_rot, y_rot, x_rot));
|
Quaternion quat = Quaternion.CreateFromRotationMatrix(Extensions.fromEulerAnglesZYX(z_rot, y_rot, x_rot));
|
||||||
SetWorldRotation(quat.X, quat.Y, quat.Z, quat.W);
|
SetLocalRotation(quat.X, quat.Y, quat.Z, quat.W);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Quaternion GetWorldRotation()
|
||||||
|
{
|
||||||
|
Quaternion localRotation = GetLocalRotation();
|
||||||
|
|
||||||
|
Transport transport = GetTransport();
|
||||||
|
if (transport != null)
|
||||||
|
{
|
||||||
|
Quaternion worldRotation = transport.GetWorldRotation();
|
||||||
|
|
||||||
|
Quaternion worldRotationQuat = new(worldRotation.X, worldRotation.Y, worldRotation.Z, worldRotation.W);
|
||||||
|
Quaternion localRotationQuat = new(localRotation.X, localRotation.Y, localRotation.Z, localRotation.W);
|
||||||
|
|
||||||
|
Quaternion resultRotation = localRotationQuat * worldRotationQuat;
|
||||||
|
|
||||||
|
return resultRotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
return localRotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsAtInteractDistance(Player player, SpellInfo spell)
|
||||||
|
{
|
||||||
|
if (spell != null || (spell = GetSpellForLock(player)) != null)
|
||||||
|
{
|
||||||
|
float maxRange = spell.GetMaxRange(spell.IsPositive());
|
||||||
|
|
||||||
|
if (GetGoType() == GameObjectTypes.SpellFocus)
|
||||||
|
return maxRange * maxRange >= GetExactDistSq(player);
|
||||||
|
|
||||||
|
var displayInfo = CliDB.GameObjectDisplayInfoStorage.LookupByKey(GetGoInfo().displayId);
|
||||||
|
if (displayInfo != null)
|
||||||
|
return IsAtInteractDistance(player, maxRange);
|
||||||
|
}
|
||||||
|
|
||||||
|
float distance;
|
||||||
|
switch (GetGoType())
|
||||||
|
{
|
||||||
|
case GameObjectTypes.AreaDamage:
|
||||||
|
distance = 0.0f;
|
||||||
|
break;
|
||||||
|
case GameObjectTypes.QuestGiver:
|
||||||
|
case GameObjectTypes.Text:
|
||||||
|
case GameObjectTypes.FlagStand:
|
||||||
|
case GameObjectTypes.FlagDrop:
|
||||||
|
case GameObjectTypes.MiniGame:
|
||||||
|
distance = 5.5555553f;
|
||||||
|
break;
|
||||||
|
case GameObjectTypes.Binder:
|
||||||
|
distance = 10.0f;
|
||||||
|
break;
|
||||||
|
case GameObjectTypes.Chair:
|
||||||
|
case GameObjectTypes.BarberChair:
|
||||||
|
distance = 3.0f;
|
||||||
|
break;
|
||||||
|
case GameObjectTypes.FishingNode:
|
||||||
|
distance = 100.0f;
|
||||||
|
break;
|
||||||
|
case GameObjectTypes.Camera:
|
||||||
|
case GameObjectTypes.MapObject:
|
||||||
|
case GameObjectTypes.DungeonDifficulty:
|
||||||
|
case GameObjectTypes.DestructibleBuilding:
|
||||||
|
case GameObjectTypes.Door:
|
||||||
|
default:
|
||||||
|
distance = 5.0f;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Following values are not blizzlike
|
||||||
|
case GameObjectTypes.Mailbox:
|
||||||
|
// Successful mailbox interaction is rather critical to the client, failing it will start a minute-long cooldown until the next mail query may be executed.
|
||||||
|
// And since movement info update is not sent with mailbox interaction query, server may find the player outside of interaction range. Thus we increase it.
|
||||||
|
distance = 10.0f; // 5.0f is blizzlike
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return IsAtInteractDistance(player, distance);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsAtInteractDistance(Position pos, float radius)
|
||||||
|
{
|
||||||
|
var displayInfo = CliDB.GameObjectDisplayInfoStorage.LookupByKey(GetGoInfo().displayId);
|
||||||
|
if (displayInfo != null)
|
||||||
|
{
|
||||||
|
float scale = GetObjectScale();
|
||||||
|
|
||||||
|
float minX = displayInfo.GeoBoxMin.X * scale - radius;
|
||||||
|
float minY = displayInfo.GeoBoxMin.Y * scale - radius;
|
||||||
|
float minZ = displayInfo.GeoBoxMin.Z * scale - radius;
|
||||||
|
float maxX = displayInfo.GeoBoxMax.X * scale + radius;
|
||||||
|
float maxY = displayInfo.GeoBoxMax.Y * scale + radius;
|
||||||
|
float maxZ = displayInfo.GeoBoxMax.Z * scale + radius;
|
||||||
|
|
||||||
|
Quaternion localRotation = GetLocalRotation();
|
||||||
|
|
||||||
|
//Todo Test this. Needs checked.
|
||||||
|
var worldSpaceBox = MathFunctions.toWorldSpace(Matrix4x4.CreateFromQuaternion(localRotation), new Vector3(GetPositionX(), GetPositionY(), GetPositionZ()), new Box(new Vector3(minX, minY, minZ), new Vector3(maxX, maxY, maxZ)));
|
||||||
|
return worldSpaceBox.Contains(new Vector3(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetExactDist(pos) <= radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
SpellInfo GetSpellForLock(Player player)
|
||||||
|
{
|
||||||
|
if (!player)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
uint lockId = GetGoInfo().GetLockId();
|
||||||
|
if (lockId == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var lockEntry = CliDB.LockStorage.LookupByKey(lockId);
|
||||||
|
if (lockEntry == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
for (byte i = 0; i < SharedConst.MaxLockCase; ++i)
|
||||||
|
{
|
||||||
|
if (lockEntry.LockType[i] == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (lockEntry.LockType[i] == (byte)LockKeyType.Skill)
|
||||||
|
{
|
||||||
|
SpellInfo spell = Global.SpellMgr.GetSpellInfo((uint)lockEntry.Index[i], GetMap().GetDifficultyID());
|
||||||
|
if (spell != null)
|
||||||
|
return spell;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lockEntry.LockType[i] != (byte)LockKeyType.Skill)
|
||||||
|
break;
|
||||||
|
|
||||||
|
foreach (var playerSpell in player.GetSpellMap())
|
||||||
|
{
|
||||||
|
SpellInfo spell = Global.SpellMgr.GetSpellInfo(playerSpell.Key, GetMap().GetDifficultyID());
|
||||||
|
if (spell != null)
|
||||||
|
{
|
||||||
|
foreach (var effect in spell.GetEffects())
|
||||||
|
if (effect.Effect == SpellEffectName.OpenLock && effect.MiscValue == lockEntry.Index[i])
|
||||||
|
if (effect.CalcValue(player) >= lockEntry.Skill[i])
|
||||||
|
return spell;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void ModifyHealth(int change, WorldObject attackerOrHealer = null, uint spellId = 0)
|
public void ModifyHealth(int change, WorldObject attackerOrHealer = null, uint spellId = 0)
|
||||||
{
|
{
|
||||||
if (m_goValue.Building.MaxHealth == 0 || change == 0)
|
if (m_goValue.Building.MaxHealth == 0 || change == 0)
|
||||||
@@ -2729,7 +2876,8 @@ namespace Game.Entities
|
|||||||
|
|
||||||
public ulong GetSpawnId() { return m_spawnId; }
|
public ulong GetSpawnId() { return m_spawnId; }
|
||||||
|
|
||||||
public long GetPackedWorldRotation() { return m_packedRotation; }
|
public Quaternion GetLocalRotation() { return m_localRotation; }
|
||||||
|
public long GetPackedLocalRotation() { return m_packedRotation; }
|
||||||
|
|
||||||
public void SetOwnerGUID(ObjectGuid owner)
|
public void SetOwnerGUID(ObjectGuid owner)
|
||||||
{
|
{
|
||||||
@@ -2900,7 +3048,7 @@ namespace Game.Entities
|
|||||||
public uint m_groupLootTimer; // (msecs)timer used for group loot
|
public uint m_groupLootTimer; // (msecs)timer used for group loot
|
||||||
public ObjectGuid lootingGroupLowGUID; // used to find group which is looting
|
public ObjectGuid lootingGroupLowGUID; // used to find group which is looting
|
||||||
long m_packedRotation;
|
long m_packedRotation;
|
||||||
Quaternion m_worldRotation;
|
Quaternion m_localRotation;
|
||||||
public Position StationaryPosition { get; set; }
|
public Position StationaryPosition { get; set; }
|
||||||
|
|
||||||
GameObjectAI m_AI;
|
GameObjectAI m_AI;
|
||||||
|
|||||||
@@ -381,7 +381,7 @@ namespace Game.Entities
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (flags.Rotation)
|
if (flags.Rotation)
|
||||||
data.WriteInt64(ToGameObject().GetPackedWorldRotation()); // Rotation
|
data.WriteInt64(ToGameObject().GetPackedLocalRotation()); // Rotation
|
||||||
|
|
||||||
if (go)
|
if (go)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ namespace Game.Entities
|
|||||||
SetGoType(GameObjectTypes.MapObjTransport);
|
SetGoType(GameObjectTypes.MapObjTransport);
|
||||||
SetGoAnimProgress(animprogress);
|
SetGoAnimProgress(animprogress);
|
||||||
SetName(goinfo.name);
|
SetName(goinfo.name);
|
||||||
SetWorldRotation(0.0f, 0.0f, 0.0f, 1.0f);
|
SetLocalRotation(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
SetParentRotation(Quaternion.Identity);
|
SetParentRotation(Quaternion.Identity);
|
||||||
|
|
||||||
CreateModel();
|
CreateModel();
|
||||||
|
|||||||
@@ -5736,10 +5736,6 @@ namespace Game.Spells
|
|||||||
if (m_spellInfo.RangeEntry != null && m_spellInfo.RangeEntry.Flags != SpellRangeFlag.Melee && !strict)
|
if (m_spellInfo.RangeEntry != null && m_spellInfo.RangeEntry.Flags != SpellRangeFlag.Melee && !strict)
|
||||||
maxRange += Math.Min(3.0f, maxRange * 0.1f); // 10% but no more than 3.0f
|
maxRange += Math.Min(3.0f, maxRange * 0.1f); // 10% but no more than 3.0f
|
||||||
|
|
||||||
// save the original values before squaring them
|
|
||||||
float origMinRange = minRange;
|
|
||||||
float origMaxRange = maxRange;
|
|
||||||
|
|
||||||
// get square values for sqr distance checks
|
// get square values for sqr distance checks
|
||||||
minRange *= minRange;
|
minRange *= minRange;
|
||||||
maxRange *= maxRange;
|
maxRange *= maxRange;
|
||||||
@@ -5762,10 +5758,7 @@ namespace Game.Spells
|
|||||||
GameObject goTarget = m_targets.GetGOTarget();
|
GameObject goTarget = m_targets.GetGOTarget();
|
||||||
if (goTarget != null)
|
if (goTarget != null)
|
||||||
{
|
{
|
||||||
if (origMinRange > 0.0f && goTarget.IsInRange(m_caster.GetPositionX(), m_caster.GetPositionY(), m_caster.GetPositionZ(), origMinRange))
|
if (!goTarget.IsAtInteractDistance(m_caster.ToPlayer(), m_spellInfo))
|
||||||
return SpellCastResult.OutOfRange;
|
|
||||||
|
|
||||||
if (!goTarget.IsInRange(m_caster.GetPositionX(), m_caster.GetPositionY(), m_caster.GetPositionZ(), origMaxRange))
|
|
||||||
return SpellCastResult.OutOfRange;
|
return SpellCastResult.OutOfRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user