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:
hondacrx
2020-07-23 19:01:15 -04:00
parent 58e630448d
commit ddaaae896e
9 changed files with 64 additions and 30 deletions
+8
View File
@@ -192,4 +192,12 @@ namespace Framework.Constants
Nothing = 0x00, Nothing = 0x00,
M2 = 0x01 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, ChatStrictLinkCheckingSeverity,
ChatWhisperLevelReq, ChatWhisperLevelReq,
ChatYellLevelReq, ChatYellLevelReq,
CheckGobjectLos,
CleanCharacterDb, CleanCharacterDb,
ClientCacheVersion, ClientCacheVersion,
Compression, Compression,
+9 -2
View File
@@ -494,8 +494,15 @@ namespace Game.Chat
{ {
Unit unit = handler.GetSelectedUnit(); Unit unit = handler.GetSelectedUnit();
if (unit) 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)] [Command("moveflags", RBACPermissions.CommandDebugMoveflags)]
+16 -16
View File
@@ -1806,20 +1806,6 @@ namespace Game.Entities
return thisOrTransport.IsInDist2d(objOrObjTransport, maxdist); 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) public float GetDistance(WorldObject obj)
{ {
float d = GetExactDist(obj.GetPosition()) - GetCombatReach() - obj.GetCombatReach(); 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); 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) if (IsInWorld)
{ {
@@ -1905,12 +1891,26 @@ namespace Game.Entities
else else
GetHitSpherePointFor(new Position(ox, oy, oz), out x, out y, out z); 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; 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) Position GetHitSpherePointFor(Position dest)
{ {
Vector3 vThis = new Vector3(GetPositionX(), GetPositionY(), GetPositionZ()); Vector3 vThis = new Vector3(GetPositionX(), GetPositionY(), GetPositionZ());
+8 -3
View File
@@ -2204,10 +2204,15 @@ namespace Game.Maps
return 0; 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) if (checks.HasAnyFlag(LineOfSightChecks.Vmap) && 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); 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) 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)
+3
View File
@@ -916,6 +916,9 @@ namespace Game
Values[WorldCfg.CreatureCheckInvalidPostion] = GetDefaultValue("Creature.CheckInvalidPosition", false); Values[WorldCfg.CreatureCheckInvalidPostion] = GetDefaultValue("Creature.CheckInvalidPosition", false);
Values[WorldCfg.GameobjectCheckInvalidPostion] = GetDefaultValue("GameObject.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 // call ScriptMgr if we're reloading the configuration
if (reload) if (reload)
Global.ScriptMgr.OnConfigLoad(reload); Global.ScriptMgr.OnConfigLoad(reload);
+9 -9
View File
@@ -1452,7 +1452,7 @@ namespace Game.Spells
if (unitTarget != null) if (unitTarget != null)
{ {
uint deficit = (uint)(unitTarget.GetMaxHealth() - unitTarget.GetHealth()); 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; found = obj;
maxHPDeficit = deficit; maxHPDeficit = deficit;
@@ -1467,10 +1467,10 @@ namespace Game.Spells
{ {
if (found == null) 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; 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; 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) 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; return SpellCastResult.LineOfSight;
} }
} }
@@ -4656,7 +4656,7 @@ namespace Game.Spells
m_targets.GetDstPos().GetPosition(out x, out y, out z); 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) 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; return SpellCastResult.LineOfSight;
} }
@@ -6594,7 +6594,7 @@ namespace Game.Spells
{ {
if (m_targets.GetCorpseTargetGUID().IsEmpty()) 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 true;
return false; return false;
@@ -6610,7 +6610,7 @@ namespace Game.Spells
if (!corpse.HasDynamicFlag(UnitDynFlags.Lootable)) if (!corpse.HasDynamicFlag(UnitDynFlags.Lootable))
return false; return false;
if (!corpse.IsWithinLOSInMap(m_caster, ModelIgnoreFlags.M2)) if (!corpse.IsWithinLOSInMap(m_caster, LineOfSightChecks.All, ModelIgnoreFlags.M2))
return false; return false;
break; break;
@@ -6618,7 +6618,7 @@ namespace Game.Spells
default: default:
{ {
if (losPosition != null) 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 else
{ {
// Get GO cast coordinates if original caster -> GO // Get GO cast coordinates if original caster -> GO
@@ -6627,7 +6627,7 @@ namespace Game.Spells
caster = m_caster.GetMap().GetGameObject(m_originalCasterGUID); caster = m_caster.GetMap().GetGameObject(m_originalCasterGUID);
if (!caster) if (!caster)
caster = m_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; return false;
} }
+9
View File
@@ -410,6 +410,15 @@ vmap.EnableIndoorCheck = 1
DetectPosCollision = 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 # TargetPosRecalculateRange
# Description: Max distance from movement target point (+moving unit size) and targeted # 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';