So, I came in trying to fix gameobject LoS. So I restructured some stuff.
Port From (https://github.com/TrinityCore/TrinityCore/commit/5392212799b669d91c80cf0e9539a3aaa2abbe79)
This commit is contained in:
@@ -192,4 +192,12 @@ namespace Framework.Constants
|
||||
Nothing = 0x00,
|
||||
M2 = 0x01
|
||||
}
|
||||
|
||||
public enum LineOfSightChecks
|
||||
{
|
||||
Vmap = 0x1, // check static floor layout data
|
||||
Gobject = 0x2, // check dynamic game object data
|
||||
|
||||
All = Vmap | Gobject
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1109,6 +1109,7 @@ namespace Framework.Constants
|
||||
ChatStrictLinkCheckingSeverity,
|
||||
ChatWhisperLevelReq,
|
||||
ChatYellLevelReq,
|
||||
CheckGobjectLos,
|
||||
CleanCharacterDb,
|
||||
ClientCacheVersion,
|
||||
Compression,
|
||||
|
||||
@@ -494,8 +494,15 @@ namespace Game.Chat
|
||||
{
|
||||
Unit unit = handler.GetSelectedUnit();
|
||||
if (unit)
|
||||
handler.SendSysMessage("Unit {0} (GuidLow: {1}) is {2}in LoS", unit.GetName(), unit.GetGUID().ToString(), handler.GetSession().GetPlayer().IsWithinLOSInMap(unit) ? "" : "not ");
|
||||
return true;
|
||||
{
|
||||
Player player = handler.GetSession().GetPlayer();
|
||||
handler.SendSysMessage($"Checking LoS {player.GetName()} -> {unit.GetName()}:");
|
||||
handler.SendSysMessage($" VMAP LoS: {(player.IsWithinLOSInMap(unit, LineOfSightChecks.Vmap) ? "clear" : "obstructed")}");
|
||||
handler.SendSysMessage($" GObj LoS: {(player.IsWithinLOSInMap(unit, LineOfSightChecks.Gobject) ? "clear" : "obstructed")}");
|
||||
handler.SendSysMessage($"{unit.GetName()} is {(player.IsWithinLOSInMap(unit) ? "" : "not ")}in line of sight of {player.GetName()}.");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
[Command("moveflags", RBACPermissions.CommandDebugMoveflags)]
|
||||
|
||||
@@ -1806,20 +1806,6 @@ namespace Game.Entities
|
||||
return thisOrTransport.IsInDist2d(objOrObjTransport, maxdist);
|
||||
}
|
||||
|
||||
public bool IsWithinLOSInMap(WorldObject obj, ModelIgnoreFlags ignoreFlags = ModelIgnoreFlags.Nothing)
|
||||
{
|
||||
if (!IsInMap(obj))
|
||||
return false;
|
||||
|
||||
float x, y, z;
|
||||
if (obj.IsTypeId(TypeId.Player))
|
||||
obj.GetPosition(out x, out y, out z);
|
||||
else
|
||||
obj.GetHitSpherePointFor(GetPosition(), out x, out y, out z);
|
||||
|
||||
return IsWithinLOS(x, y, z, ignoreFlags);
|
||||
}
|
||||
|
||||
public float GetDistance(WorldObject obj)
|
||||
{
|
||||
float d = GetExactDist(obj.GetPosition()) - GetCombatReach() - obj.GetCombatReach();
|
||||
@@ -1895,7 +1881,7 @@ namespace Game.Entities
|
||||
return obj && IsInMap(obj) && IsInPhase(obj) && _IsWithinDist(obj, dist2compare, is3D, incOwnRadius, incTargetRadius);
|
||||
}
|
||||
|
||||
public bool IsWithinLOS(float ox, float oy, float oz, ModelIgnoreFlags ignoreFlags = ModelIgnoreFlags.Nothing)
|
||||
public bool IsWithinLOS(float ox, float oy, float oz, LineOfSightChecks checks = LineOfSightChecks.All, ModelIgnoreFlags ignoreFlags = ModelIgnoreFlags.Nothing)
|
||||
{
|
||||
if (IsInWorld)
|
||||
{
|
||||
@@ -1905,12 +1891,26 @@ namespace Game.Entities
|
||||
else
|
||||
GetHitSpherePointFor(new Position(ox, oy, oz), out x, out y, out z);
|
||||
|
||||
return GetMap().IsInLineOfSight(GetPhaseShift(), x, y, z + 2.0f, ox, oy, oz + 2.0f, ignoreFlags);
|
||||
return GetMap().IsInLineOfSight(GetPhaseShift(), x, y, z + 2.0f, ox, oy, oz + 2.0f, checks, ignoreFlags);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool IsWithinLOSInMap(WorldObject obj, LineOfSightChecks checks = LineOfSightChecks.All, ModelIgnoreFlags ignoreFlags = ModelIgnoreFlags.Nothing)
|
||||
{
|
||||
if (!IsInMap(obj))
|
||||
return false;
|
||||
|
||||
float x, y, z;
|
||||
if (obj.IsTypeId(TypeId.Player))
|
||||
obj.GetPosition(out x, out y, out z);
|
||||
else
|
||||
obj.GetHitSpherePointFor(GetPosition(), out x, out y, out z);
|
||||
|
||||
return IsWithinLOS(x, y, z, checks, ignoreFlags);
|
||||
}
|
||||
|
||||
Position GetHitSpherePointFor(Position dest)
|
||||
{
|
||||
Vector3 vThis = new Vector3(GetPositionX(), GetPositionY(), GetPositionZ());
|
||||
|
||||
@@ -2204,10 +2204,15 @@ namespace Game.Maps
|
||||
return 0;
|
||||
}
|
||||
|
||||
public bool IsInLineOfSight(PhaseShift phaseShift, float x1, float y1, float z1, float x2, float y2, float z2, ModelIgnoreFlags ignoreFlags)
|
||||
public bool IsInLineOfSight(PhaseShift phaseShift, float x1, float y1, float z1, float x2, float y2, float z2, LineOfSightChecks checks, ModelIgnoreFlags ignoreFlags)
|
||||
{
|
||||
return Global.VMapMgr.IsInLineOfSight(PhasingHandler.GetTerrainMapId(phaseShift, this, x1, y1), x1, y1, z1, x2, y2, z2, ignoreFlags)
|
||||
&& _dynamicTree.IsInLineOfSight(new Vector3(x1, y1, z1), new Vector3(x2, y2, z2), phaseShift);
|
||||
if (checks.HasAnyFlag(LineOfSightChecks.Vmap) && Global.VMapMgr.IsInLineOfSight(PhasingHandler.GetTerrainMapId(phaseShift, this, x1, y1), x1, y1, z1, x2, y2, z2, ignoreFlags))
|
||||
return false;
|
||||
|
||||
if (WorldConfig.GetBoolValue(WorldCfg.CheckGobjectLos) && checks.HasAnyFlag(LineOfSightChecks.Gobject) && _dynamicTree.IsInLineOfSight(new Vector3(x1, y1, z1), new Vector3(x2, y2, z2), phaseShift))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool GetObjectHitPos(PhaseShift phaseShift, float x1, float y1, float z1, float x2, float y2, float z2, out float rx, out float ry, out float rz, float modifyDist)
|
||||
|
||||
@@ -916,6 +916,9 @@ namespace Game
|
||||
Values[WorldCfg.CreatureCheckInvalidPostion] = GetDefaultValue("Creature.CheckInvalidPosition", false);
|
||||
Values[WorldCfg.GameobjectCheckInvalidPostion] = GetDefaultValue("GameObject.CheckInvalidPosition", false);
|
||||
|
||||
// Whether to use LoS from game objects
|
||||
Values[WorldCfg.CheckGobjectLos] = GetDefaultValue("CheckGameObjectLoS", true);
|
||||
|
||||
// call ScriptMgr if we're reloading the configuration
|
||||
if (reload)
|
||||
Global.ScriptMgr.OnConfigLoad(reload);
|
||||
|
||||
@@ -1452,7 +1452,7 @@ namespace Game.Spells
|
||||
if (unitTarget != null)
|
||||
{
|
||||
uint deficit = (uint)(unitTarget.GetMaxHealth() - unitTarget.GetHealth());
|
||||
if ((deficit > maxHPDeficit || found == null) && target.IsWithinDist(unitTarget, jumpRadius) && target.IsWithinLOSInMap(unitTarget, ModelIgnoreFlags.M2))
|
||||
if ((deficit > maxHPDeficit || found == null) && target.IsWithinDist(unitTarget, jumpRadius) && target.IsWithinLOSInMap(unitTarget, LineOfSightChecks.All, ModelIgnoreFlags.M2))
|
||||
{
|
||||
found = obj;
|
||||
maxHPDeficit = deficit;
|
||||
@@ -1467,10 +1467,10 @@ namespace Game.Spells
|
||||
{
|
||||
if (found == null)
|
||||
{
|
||||
if ((!isBouncingFar || target.IsWithinDist(obj, jumpRadius)) && target.IsWithinLOSInMap(obj, ModelIgnoreFlags.M2))
|
||||
if ((!isBouncingFar || target.IsWithinDist(obj, jumpRadius)) && target.IsWithinLOSInMap(obj, LineOfSightChecks.All, ModelIgnoreFlags.M2))
|
||||
found = obj;
|
||||
}
|
||||
else if (target.GetDistanceOrder(obj, found) && target.IsWithinLOSInMap(obj, ModelIgnoreFlags.M2))
|
||||
else if (target.GetDistanceOrder(obj, found) && target.IsWithinLOSInMap(obj, LineOfSightChecks.All, ModelIgnoreFlags.M2))
|
||||
found = obj;
|
||||
}
|
||||
}
|
||||
@@ -4643,7 +4643,7 @@ namespace Game.Spells
|
||||
}
|
||||
|
||||
if (!m_spellInfo.HasAttribute(SpellAttr2.CanTargetNotInLos) && !Global.DisableMgr.IsDisabledFor(DisableType.Spell, m_spellInfo.Id, null, DisableFlags.SpellLOS)
|
||||
&& !unitTarget.IsWithinLOSInMap(losTarget, ModelIgnoreFlags.M2))
|
||||
&& !unitTarget.IsWithinLOSInMap(losTarget, LineOfSightChecks.All, ModelIgnoreFlags.M2))
|
||||
return SpellCastResult.LineOfSight;
|
||||
}
|
||||
}
|
||||
@@ -4656,7 +4656,7 @@ namespace Game.Spells
|
||||
m_targets.GetDstPos().GetPosition(out x, out y, out z);
|
||||
|
||||
if (!m_spellInfo.HasAttribute(SpellAttr2.CanTargetNotInLos) && !Global.DisableMgr.IsDisabledFor(DisableType.Spell, m_spellInfo.Id, null, DisableFlags.SpellLOS)
|
||||
&& !m_caster.IsWithinLOS(x, y, z, ModelIgnoreFlags.M2))
|
||||
&& !m_caster.IsWithinLOS(x, y, z, LineOfSightChecks.All, ModelIgnoreFlags.M2))
|
||||
return SpellCastResult.LineOfSight;
|
||||
}
|
||||
|
||||
@@ -6594,7 +6594,7 @@ namespace Game.Spells
|
||||
{
|
||||
if (m_targets.GetCorpseTargetGUID().IsEmpty())
|
||||
{
|
||||
if (target.IsWithinLOSInMap(m_caster, ModelIgnoreFlags.M2) && target.HasUnitFlag(UnitFlags.Skinnable))
|
||||
if (target.IsWithinLOSInMap(m_caster, LineOfSightChecks.All, ModelIgnoreFlags.M2) && target.HasUnitFlag(UnitFlags.Skinnable))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@@ -6610,7 +6610,7 @@ namespace Game.Spells
|
||||
if (!corpse.HasDynamicFlag(UnitDynFlags.Lootable))
|
||||
return false;
|
||||
|
||||
if (!corpse.IsWithinLOSInMap(m_caster, ModelIgnoreFlags.M2))
|
||||
if (!corpse.IsWithinLOSInMap(m_caster, LineOfSightChecks.All, ModelIgnoreFlags.M2))
|
||||
return false;
|
||||
|
||||
break;
|
||||
@@ -6618,7 +6618,7 @@ namespace Game.Spells
|
||||
default:
|
||||
{
|
||||
if (losPosition != null)
|
||||
return target.IsWithinLOS(losPosition.GetPositionX(), losPosition.GetPositionY(), losPosition.GetPositionZ(), ModelIgnoreFlags.M2);
|
||||
return target.IsWithinLOS(losPosition.GetPositionX(), losPosition.GetPositionY(), losPosition.GetPositionZ(), LineOfSightChecks.All, ModelIgnoreFlags.M2);
|
||||
else
|
||||
{
|
||||
// Get GO cast coordinates if original caster -> GO
|
||||
@@ -6627,7 +6627,7 @@ namespace Game.Spells
|
||||
caster = m_caster.GetMap().GetGameObject(m_originalCasterGUID);
|
||||
if (!caster)
|
||||
caster = m_caster;
|
||||
if (target != m_caster && !target.IsWithinLOSInMap(caster, ModelIgnoreFlags.M2))
|
||||
if (target != m_caster && !target.IsWithinLOSInMap(caster, LineOfSightChecks.All, ModelIgnoreFlags.M2))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -410,6 +410,15 @@ vmap.EnableIndoorCheck = 1
|
||||
|
||||
DetectPosCollision = 1
|
||||
|
||||
#
|
||||
# CheckGameObjectLoS
|
||||
# Description: Include dynamic game objects (doors, chests etc.) in line of sight checks.
|
||||
# This increases CPU usage somewhat.
|
||||
# Default: 1 - (Enabled)
|
||||
# 0 - (Disabled, may break some boss encounters)
|
||||
|
||||
CheckGameObjectLoS = 1
|
||||
|
||||
#
|
||||
# TargetPosRecalculateRange
|
||||
# Description: Max distance from movement target point (+moving unit size) and targeted
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_sapphiron_frost_breath';
|
||||
Reference in New Issue
Block a user