Core: Updated to 11.2.0

Port From (https://github.com/TrinityCore/TrinityCore/commit/5cf0c6c8bb2c4e58a2d66ba5f304af34d18a4782)
This commit is contained in:
Hondacrx
2025-08-25 20:48:29 -04:00
parent d64045154a
commit aaa669210a
63 changed files with 5958 additions and 5434 deletions
+269 -190
View File
@@ -26,7 +26,6 @@ namespace Game.Entities
ObjectTypeId = TypeId.AreaTrigger;
m_updateFlag.Stationary = true;
m_updateFlag.AreaTrigger = true;
m_entityFragments.Add(EntityFragment.Tag_AreaTrigger, false);
@@ -119,7 +118,7 @@ namespace Game.Entities
SetObjectScale(1.0f);
SetDuration(duration);
_shape = GetCreateProperties().Shape;
SetShape(GetCreateProperties().Shape);
var areaTriggerData = m_values.ModifyValue(m_areaTriggerData);
if (caster != null)
@@ -176,6 +175,35 @@ namespace Game.Entities
if (GetCreateProperties() != null && GetCreateProperties().Flags.HasFlag(AreaTriggerCreatePropertiesFlag.VisualAnimIsDecay))
SetUpdateFieldValue(visualAnim.ModifyValue(visualAnim.IsDecay), true);
AreaTriggerFieldFlags fieldFlags()
{
var flags = GetCreateProperties().Flags;
AreaTriggerFieldFlags fieldFlags = AreaTriggerFieldFlags.None;
if (flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasAbsoluteOrientation))
fieldFlags |= AreaTriggerFieldFlags.AbsoluteOrientation;
if (flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasDynamicShape))
fieldFlags |= AreaTriggerFieldFlags.DynamicShape;
if (flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasAttached))
fieldFlags |= AreaTriggerFieldFlags.Attached;
if (flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasFaceMovementDir))
fieldFlags |= AreaTriggerFieldFlags.FaceMovementDir;
if (flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasFollowsTerrain))
fieldFlags |= AreaTriggerFieldFlags.FollowsTerrain;
if (flags.HasFlag(AreaTriggerCreatePropertiesFlag.AlwaysExterior))
fieldFlags |= AreaTriggerFieldFlags.AlwaysExterior;
return fieldFlags;
}
;
ReplaceAllAreaTriggerFlags(fieldFlags());
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.MovementStartTime), GameTime.GetGameTimeMS());
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.CreationTime), GameTime.GetGameTimeMS());
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.ScaleCurveId), GetCreateProperties().ScaleCurveId);
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.FacingCurveId), GetCreateProperties().FacingCurveId);
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.MorphCurveId), GetCreateProperties().MorphCurveId);
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.MoveCurveId), GetCreateProperties().MoveCurveId);
if (caster != null)
PhasingHandler.InheritPhaseShift(this, caster);
else if (IsStaticSpawn() && spawnData != null)
@@ -184,7 +212,7 @@ namespace Game.Entities
PhasingHandler.InitDbPhaseShift(GetPhaseShift(), spawnData.PhaseUseFlags, spawnData.PhaseId, spawnData.PhaseGroup);
}
if (target != null && GetCreateProperties() != null && GetCreateProperties().Flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasAttached))
if (target != null && HasAreaTriggerFlag(AreaTriggerFieldFlags.Attached))
m_movementInfo.transport.guid = target.GetGUID();
if (!IsStaticSpawn())
@@ -195,7 +223,7 @@ namespace Game.Entities
if (GetCreateProperties().OrbitInfo != null)
{
AreaTriggerOrbitInfo orbit = GetCreateProperties().OrbitInfo;
if (target != null && GetCreateProperties() != null && GetCreateProperties().Flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasAttached))
if (target != null && HasAreaTriggerFlag(AreaTriggerFieldFlags.Attached))
orbit.PathTarget = target.GetGUID();
else
orbit.Center = new(pos.posX, pos.posY, pos.posZ);
@@ -206,6 +234,10 @@ namespace Game.Entities
{
InitSplineOffsets(GetCreateProperties().SplinePoints);
}
else
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.ShapeType), (byte)AreaTriggerPathType.None);
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.Facing), _stationaryPosition.GetOrientation());
// movement on transport of areatriggers on unit is handled by themself
ITransport transport = null;
@@ -280,7 +312,6 @@ namespace Game.Entities
public override void Update(uint diff)
{
base.Update(diff);
_timeSinceCreated += diff;
if (!IsStaticSpawn())
{
@@ -291,19 +322,18 @@ namespace Game.Entities
}
else if (HasOrbit())
{
UpdateOrbitPosition(diff);
UpdateOrbitPosition();
}
else if (GetCreateProperties() != null && GetCreateProperties().Flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasAttached))
else if (HasAreaTriggerFlag(AreaTriggerFieldFlags.Attached))
{
Unit target = GetTarget();
if (target != null)
{
float orientation = 0.0f;
AreaTriggerCreateProperties createProperties = GetCreateProperties();
if (createProperties != null && createProperties.FacingCurveId != 0)
orientation = Global.DB2Mgr.GetCurveValueAt(createProperties.FacingCurveId, GetProgress());
if (m_areaTriggerData.FacingCurveId != 0)
orientation = Global.DB2Mgr.GetCurveValueAt(m_areaTriggerData.FacingCurveId, GetProgress());
if (GetCreateProperties() == null || !GetCreateProperties().Flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasAbsoluteOrientation))
if (!HasAreaTriggerFlag(AreaTriggerFieldFlags.AbsoluteOrientation))
orientation += target.GetOrientation();
GetMap().AreaTriggerRelocation(this, target.GetPositionX(), target.GetPositionY(), target.GetPositionZ(), orientation);
@@ -311,16 +341,15 @@ namespace Game.Entities
}
else if (HasSplines())
{
UpdateSplinePosition(diff);
UpdateSplinePosition(_spline);
}
else
{
AreaTriggerCreateProperties createProperties = GetCreateProperties();
if (createProperties != null && createProperties.FacingCurveId != 0)
if (m_areaTriggerData.FacingCurveId != 0)
{
float orientation = Global.DB2Mgr.GetCurveValueAt(createProperties.FacingCurveId, GetProgress());
if (GetCreateProperties() == null || !GetCreateProperties().Flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasAbsoluteOrientation))
orientation += _stationaryPosition.GetOrientation();
float orientation = Global.DB2Mgr.GetCurveValueAt(m_areaTriggerData.FacingCurveId, GetProgress());
if (!HasAreaTriggerFlag(AreaTriggerFieldFlags.AbsoluteOrientation))
orientation += m_areaTriggerData.Facing;
SetOrientation(orientation);
}
@@ -351,6 +380,14 @@ namespace Game.Entities
AddObjectToRemoveList();
}
uint GetTimeSinceCreated()
{
uint now = GameTime.GetGameTimeMS();
if (now >= m_areaTriggerData.CreationTime)
return now - m_areaTriggerData.CreationTime;
return 0;
}
void SetOverrideScaleCurve(float overrideScale)
{
SetScaleCurve(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.OverrideScaleCurve), overrideScale);
@@ -435,12 +472,8 @@ namespace Game.Entities
float scale = 1.0f;
if (m_areaTriggerData.OverrideScaleCurve.GetValue().OverrideActive)
scale *= Math.Max(GetScaleCurveValue(m_areaTriggerData.OverrideScaleCurve, m_areaTriggerData.TimeToTargetScale), 0.000001f);
else
{
AreaTriggerCreateProperties createProperties = GetCreateProperties();
if (createProperties != null && createProperties.ScaleCurveId != 0)
scale *= Math.Max(Global.DB2Mgr.GetCurveValueAt(createProperties.ScaleCurveId, GetScaleCurveProgress(m_areaTriggerData.OverrideScaleCurve, m_areaTriggerData.TimeToTargetScale)), 0.000001f);
}
else if (m_areaTriggerData.ScaleCurveId != 0)
scale *= Math.Max(Global.DB2Mgr.GetCurveValueAt(m_areaTriggerData.ScaleCurveId, GetScaleCurveProgress(m_areaTriggerData.OverrideScaleCurve, m_areaTriggerData.TimeToTargetScale)), 0.000001f);
scale *= Math.Max(GetScaleCurveValue(m_areaTriggerData.ExtraScaleCurve, m_areaTriggerData.TimeToTargetExtraScale), 0.000001f);
@@ -583,29 +616,21 @@ namespace Game.Entities
{
List<Unit> targetList = new();
switch (_shape.TriggerType)
m_areaTriggerData.ShapeData.Visit(shape =>
{
case AreaTriggerShapeType.Sphere:
SearchUnitInSphere(targetList);
break;
case AreaTriggerShapeType.Box:
SearchUnitInBox(targetList);
break;
case AreaTriggerShapeType.Polygon:
SearchUnitInPolygon(targetList);
break;
case AreaTriggerShapeType.Cylinder:
SearchUnitInCylinder(targetList);
break;
case AreaTriggerShapeType.Disk:
SearchUnitInDisk(targetList);
break;
case AreaTriggerShapeType.BoundedPlane:
SearchUnitInBoundedPlane(targetList);
break;
default:
break;
}
if (shape is AreaTriggerSphere)
SearchUnitInSphere(shape, targetList);
else if (shape is AreaTriggerBox)
SearchUnitInBox(shape, targetList);
else if (shape is AreaTriggerPolygon)
SearchUnitInPolygon(shape, targetList);
else if (shape is AreaTriggerCylinder)
SearchUnitInCylinder(shape, targetList);
else if (shape is AreaTriggerDisk)
SearchUnitInDisk(shape, targetList);
else if (shape is AreaTriggerBoundedPlane)
SearchUnitInBoundedPlane(shape, targetList);
});
if (GetTemplate() != null)
{
@@ -681,32 +706,30 @@ namespace Game.Entities
}
}
void SearchUnitInSphere(List<Unit> targetList)
void SearchUnitInSphere(AreaTriggerSphere sphere, List<Unit> targetList)
{
float progress = GetProgress();
AreaTriggerCreateProperties createProperties = GetCreateProperties();
if (createProperties != null && createProperties.MorphCurveId != 0)
progress = Global.DB2Mgr.GetCurveValueAt(createProperties.MorphCurveId, progress);
if (m_areaTriggerData.MorphCurveId != 0)
progress = Global.DB2Mgr.GetCurveValueAt(m_areaTriggerData.MorphCurveId, progress);
float scale = CalcCurrentScale();
float radius = MathFunctions.Lerp(_shape.SphereDatas.Radius, _shape.SphereDatas.RadiusTarget, progress) * scale;
float radius = MathFunctions.Lerp(sphere.Radius, sphere.RadiusTarget, progress) * scale;
SearchUnits(targetList, radius, true);
}
void SearchUnitInBox(List<Unit> targetList)
void SearchUnitInBox(AreaTriggerBox box, List<Unit> targetList)
{
float progress = GetProgress();
AreaTriggerCreateProperties createProperties = GetCreateProperties();
if (createProperties != null && createProperties.MorphCurveId != 0)
progress = Global.DB2Mgr.GetCurveValueAt(createProperties.MorphCurveId, progress);
if (m_areaTriggerData.MorphCurveId != 0)
progress = Global.DB2Mgr.GetCurveValueAt(m_areaTriggerData.MorphCurveId, progress);
unsafe
{
float scale = CalcCurrentScale();
float extentsX = MathFunctions.Lerp(_shape.BoxDatas.Extents[0], _shape.BoxDatas.ExtentsTarget[0], progress) * scale;
float extentsY = MathFunctions.Lerp(_shape.BoxDatas.Extents[1], _shape.BoxDatas.ExtentsTarget[1], progress) * scale;
float extentsZ = MathFunctions.Lerp(_shape.BoxDatas.Extents[2], _shape.BoxDatas.ExtentsTarget[2], progress) * scale;
float extentsX = MathFunctions.Lerp(box.Extents.GetValue().X, box.ExtentsTarget.GetValue().X, progress) * scale;
float extentsY = MathFunctions.Lerp(box.Extents.GetValue().Y, box.ExtentsTarget.GetValue().Y, progress) * scale;
float extentsZ = MathFunctions.Lerp(box.Extents.GetValue().Z, box.ExtentsTarget.GetValue().Z, progress) * scale;
float radius = MathF.Sqrt(extentsX * extentsX + extentsY * extentsY);
SearchUnits(targetList, radius, false);
@@ -716,14 +739,13 @@ namespace Game.Entities
}
}
void SearchUnitInPolygon(List<Unit> targetList)
void SearchUnitInPolygon(AreaTriggerPolygon polygon, List<Unit> targetList)
{
float progress = GetProgress();
AreaTriggerCreateProperties createProperties = GetCreateProperties();
if (createProperties != null && createProperties.MorphCurveId != 0)
progress = Global.DB2Mgr.GetCurveValueAt(createProperties.MorphCurveId, progress);
if (m_areaTriggerData.MorphCurveId != 0)
progress = Global.DB2Mgr.GetCurveValueAt(m_areaTriggerData.MorphCurveId, progress);
float height = MathFunctions.Lerp(_shape.PolygonDatas.Height, _shape.PolygonDatas.HeightTarget, progress);
float height = MathFunctions.Lerp(polygon.Height, polygon.HeightTarget, progress);
float minZ = GetPositionZ() - height;
float maxZ = GetPositionZ() + height;
@@ -732,17 +754,16 @@ namespace Game.Entities
targetList.RemoveAll(unit => unit.GetPositionZ() < minZ || unit.GetPositionZ() > maxZ || !unit.IsInPolygon2D(this, _polygonVertices));
}
void SearchUnitInCylinder(List<Unit> targetList)
void SearchUnitInCylinder(AreaTriggerCylinder cylinder, List<Unit> targetList)
{
float progress = GetProgress();
AreaTriggerCreateProperties createProperties = GetCreateProperties();
if (createProperties != null && createProperties.MorphCurveId != 0)
progress = Global.DB2Mgr.GetCurveValueAt(createProperties.MorphCurveId, progress);
if (m_areaTriggerData.MorphCurveId != 0)
progress = Global.DB2Mgr.GetCurveValueAt(m_areaTriggerData.MorphCurveId, progress);
float scale = CalcCurrentScale();
float radius = MathFunctions.Lerp(_shape.CylinderDatas.Radius, _shape.CylinderDatas.RadiusTarget, progress) * scale;
float height = MathFunctions.Lerp(_shape.CylinderDatas.Height, _shape.CylinderDatas.HeightTarget, progress);
if (!m_areaTriggerData.HeightIgnoresScale)
float radius = MathFunctions.Lerp(cylinder.Radius, cylinder.RadiusTarget, progress) * scale;
float height = MathFunctions.Lerp(cylinder.Height, cylinder.HeightTarget, progress);
if (!HasAreaTriggerFlag(AreaTriggerFieldFlags.HeightIgnoresScale))
height *= scale;
float minZ = GetPositionZ() - height;
@@ -753,18 +774,17 @@ namespace Game.Entities
targetList.RemoveAll(unit => unit.GetPositionZ() < minZ || unit.GetPositionZ() > maxZ);
}
void SearchUnitInDisk(List<Unit> targetList)
void SearchUnitInDisk(AreaTriggerDisk disk, List<Unit> targetList)
{
float progress = GetProgress();
AreaTriggerCreateProperties createProperties = GetCreateProperties();
if (createProperties != null && createProperties.MorphCurveId != 0)
progress = Global.DB2Mgr.GetCurveValueAt(createProperties.MorphCurveId, progress);
if (m_areaTriggerData.MorphCurveId != 0)
progress = Global.DB2Mgr.GetCurveValueAt(m_areaTriggerData.MorphCurveId, progress);
float scale = CalcCurrentScale();
float innerRadius = MathFunctions.Lerp(_shape.DiskDatas.InnerRadius, _shape.DiskDatas.InnerRadiusTarget, progress) * scale;
float outerRadius = MathFunctions.Lerp(_shape.DiskDatas.OuterRadius, _shape.DiskDatas.OuterRadiusTarget, progress) * scale;
float height = MathFunctions.Lerp(_shape.DiskDatas.Height, _shape.DiskDatas.HeightTarget, progress);
if (!m_areaTriggerData.HeightIgnoresScale)
float innerRadius = MathFunctions.Lerp(disk.InnerRadius, disk.InnerRadiusTarget, progress) * scale;
float outerRadius = MathFunctions.Lerp(disk.OuterRadius, disk.OuterRadiusTarget, progress) * scale;
float height = MathFunctions.Lerp(disk.Height, disk.HeightTarget, progress);
if (!HasAreaTriggerFlag(AreaTriggerFieldFlags.HeightIgnoresScale))
height *= scale;
float minZ = GetPositionZ() - height;
@@ -775,18 +795,17 @@ namespace Game.Entities
targetList.RemoveAll(unit => unit.IsInDist2d(this, innerRadius) || unit.GetPositionZ() < minZ || unit.GetPositionZ() > maxZ);
}
void SearchUnitInBoundedPlane(List<Unit> targetList)
void SearchUnitInBoundedPlane(AreaTriggerBoundedPlane boundedPlane, List<Unit> targetList)
{
float progress = GetProgress();
AreaTriggerCreateProperties createProperties = GetCreateProperties();
if (createProperties != null && createProperties.MorphCurveId != 0)
progress = Global.DB2Mgr.GetCurveValueAt(createProperties.MorphCurveId, progress);
if (m_areaTriggerData.MorphCurveId != 0)
progress = Global.DB2Mgr.GetCurveValueAt(m_areaTriggerData.MorphCurveId, progress);
unsafe
{
float scale = CalcCurrentScale();
float extentsX = MathFunctions.Lerp(_shape.BoundedPlaneDatas.Extents[0], _shape.BoundedPlaneDatas.ExtentsTarget[0], progress) * scale;
float extentsY = MathFunctions.Lerp(_shape.BoundedPlaneDatas.Extents[1], _shape.BoundedPlaneDatas.ExtentsTarget[1], progress) * scale;
float extentsX = MathFunctions.Lerp(boundedPlane.Extents.GetValue().X, boundedPlane.ExtentsTarget.GetValue().X, progress) * scale;
float extentsY = MathFunctions.Lerp(boundedPlane.Extents.GetValue().Y, boundedPlane.ExtentsTarget.GetValue().Y, progress) * scale;
float radius = MathF.Sqrt(extentsX * extentsX + extentsY * extentsY);
SearchUnits(targetList, radius, false);
@@ -854,8 +873,10 @@ namespace Game.Entities
}
}
SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.NumUnitsInside), _insideUnits.Count);
SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.NumPlayersInside), _insideUnits.Count(guid => guid.IsPlayer()));
if (_insideUnits.Any(guid => guid.IsPlayer()))
SetAreaTriggerFlag(AreaTriggerFieldFlags.HasPlayers);
else
RemoveAreaTriggerFlag(AreaTriggerFieldFlags.HasPlayers);
if (IsStaticSpawn())
SetActive(!_insideUnits.Empty());
@@ -902,6 +923,83 @@ namespace Game.Entities
return 0;
}
unsafe void SetShape(AreaTriggerShapeInfo shape)
{
var areaTriggerData = m_values.ModifyValue(m_areaTriggerData);
switch (shape.TriggerType)
{
case AreaTriggerShapeType.Sphere:
{
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.ShapeType), (byte)0);
var sphere = areaTriggerData.ModifyValue<AreaTriggerSphere>(m_areaTriggerData.ShapeData);
SetUpdateFieldValue(sphere.ModifyValue(sphere.Radius), shape.SphereDatas.Radius);
SetUpdateFieldValue(sphere.ModifyValue(sphere.RadiusTarget), shape.SphereDatas.RadiusTarget);
break;
}
case AreaTriggerShapeType.Box:
{
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.ShapeType), (byte)1);
var box = areaTriggerData.ModifyValue<AreaTriggerBox>(m_areaTriggerData.ShapeData);
SetUpdateFieldValue(box.ModifyValue(box.Extents), new Vector3(shape.BoxDatas.Extents[0], shape.BoxDatas.Extents[1], shape.BoxDatas.Extents[2]));
SetUpdateFieldValue(box.ModifyValue(box.ExtentsTarget), new Vector3(shape.BoxDatas.ExtentsTarget[0], shape.BoxDatas.ExtentsTarget[1], shape.BoxDatas.ExtentsTarget[2]));
break;
}
case AreaTriggerShapeType.Polygon:
{
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.ShapeType), (byte)3);
var polygon = areaTriggerData.ModifyValue<AreaTriggerPolygon>(m_areaTriggerData.ShapeData);
var vertices = polygon.ModifyValue(polygon.Vertices);
ClearDynamicUpdateFieldValues(vertices);
foreach (Vector2 vertex in shape.PolygonVertices)
AddDynamicUpdateFieldValue(vertices, vertex);
var verticesTarget = polygon.ModifyValue(polygon.VerticesTarget);
ClearDynamicUpdateFieldValues(verticesTarget);
foreach (Vector2 vertex in shape.PolygonVerticesTarget)
AddDynamicUpdateFieldValue(verticesTarget, vertex);
SetUpdateFieldValue(polygon.ModifyValue(polygon.Height), shape.PolygonDatas.Height);
SetUpdateFieldValue(polygon.ModifyValue(polygon.HeightTarget), shape.PolygonDatas.HeightTarget);
break;
}
case AreaTriggerShapeType.Cylinder:
{
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.ShapeType), (byte)4);
var cylinder = areaTriggerData.ModifyValue<AreaTriggerCylinder>(m_areaTriggerData.ShapeData);
SetUpdateFieldValue(cylinder.ModifyValue(cylinder.Radius), shape.CylinderDatas.Radius);
SetUpdateFieldValue(cylinder.ModifyValue(cylinder.RadiusTarget), shape.CylinderDatas.RadiusTarget);
SetUpdateFieldValue(cylinder.ModifyValue(cylinder.Height), shape.CylinderDatas.Height);
SetUpdateFieldValue(cylinder.ModifyValue(cylinder.HeightTarget), shape.CylinderDatas.HeightTarget);
SetUpdateFieldValue(cylinder.ModifyValue(cylinder.LocationZOffset), shape.CylinderDatas.LocationZOffset);
SetUpdateFieldValue(cylinder.ModifyValue(cylinder.LocationZOffsetTarget), shape.CylinderDatas.LocationZOffsetTarget);
break;
}
case AreaTriggerShapeType.Disk:
{
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.ShapeType), (byte)7);
var disk = areaTriggerData.ModifyValue<AreaTriggerDisk>(m_areaTriggerData.ShapeData);
SetUpdateFieldValue(disk.ModifyValue(disk.InnerRadius), shape.DiskDatas.InnerRadius);
SetUpdateFieldValue(disk.ModifyValue(disk.InnerRadiusTarget), shape.DiskDatas.InnerRadiusTarget);
SetUpdateFieldValue(disk.ModifyValue(disk.OuterRadius), shape.DiskDatas.OuterRadius);
SetUpdateFieldValue(disk.ModifyValue(disk.OuterRadiusTarget), shape.DiskDatas.OuterRadiusTarget);
SetUpdateFieldValue(disk.ModifyValue(disk.Height), shape.DiskDatas.Height);
SetUpdateFieldValue(disk.ModifyValue(disk.HeightTarget), shape.DiskDatas.HeightTarget);
SetUpdateFieldValue(disk.ModifyValue(disk.LocationZOffset), shape.DiskDatas.LocationZOffset);
SetUpdateFieldValue(disk.ModifyValue(disk.LocationZOffsetTarget), shape.DiskDatas.LocationZOffsetTarget);
break;
}
case AreaTriggerShapeType.BoundedPlane:
{
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.ShapeType), (byte)8);
var boundedPlane = areaTriggerData.ModifyValue<AreaTriggerBoundedPlane>(m_areaTriggerData.ShapeData);
SetUpdateFieldValue(boundedPlane.ModifyValue(boundedPlane.Extents), new Vector2(shape.BoundedPlaneDatas.Extents[0], shape.BoundedPlaneDatas.Extents[1]));
SetUpdateFieldValue(boundedPlane.ModifyValue(boundedPlane.ExtentsTarget), new Vector2(shape.BoundedPlaneDatas.ExtentsTarget[0], shape.BoundedPlaneDatas.ExtentsTarget[1]));
break;
}
default:
break;
}
}
float GetMaxSearchRadius()
{
return m_areaTriggerData.BoundsRadius2D * CalcCurrentScale();
@@ -909,26 +1007,25 @@ namespace Game.Entities
void UpdatePolygonVertices()
{
AreaTriggerCreateProperties createProperties = GetCreateProperties();
AreaTriggerShapeInfo shape = GetShape();
AreaTriggerPolygon shape = m_areaTriggerData.ShapeData.Get<AreaTriggerPolygon>();
float newOrientation = GetOrientation();
// No need to recalculate, orientation didn't change
if (MathFunctions.fuzzyEq(_verticesUpdatePreviousOrientation, newOrientation) && shape.PolygonVerticesTarget.Empty())
if (MathFunctions.fuzzyEq(_verticesUpdatePreviousOrientation, newOrientation) && shape.VerticesTarget.Empty())
return;
_polygonVertices.AddRange(shape.PolygonVertices.Select(p => new Position(p.X, p.Y)));
_polygonVertices.AddRange(shape.Vertices._values.Select(p => new Position(p.X, p.Y)));
if (!shape.PolygonVerticesTarget.Empty())
if (!shape.Vertices.Empty())
{
float progress = GetProgress();
if (createProperties.MorphCurveId != 0)
progress = Global.DB2Mgr.GetCurveValueAt(createProperties.MorphCurveId, progress);
if (m_areaTriggerData.MorphCurveId != 0)
progress = Global.DB2Mgr.GetCurveValueAt(m_areaTriggerData.MorphCurveId, progress);
for (var i = 0; i < _polygonVertices.Count; ++i)
{
Vector2 vertex = _polygonVertices[i];
Vector2 vertexTarget = shape.PolygonVerticesTarget[i];
Vector2 vertexTarget = shape.VerticesTarget[i];
vertex.X = MathFunctions.Lerp(vertex.X, vertexTarget.X, progress);
vertex.Y = MathFunctions.Lerp(vertex.Y, vertexTarget.Y, progress);
@@ -959,7 +1056,7 @@ namespace Game.Entities
public void UpdateShape()
{
if (_shape.IsPolygon())
if (m_areaTriggerData.ShapeData.Is<AreaTriggerPolygon>())
UpdatePolygonVertices();
}
@@ -1090,8 +1187,6 @@ namespace Game.Entities
if (splinePoints.Length < 2)
return;
_movementTime = 0;
_spline = new Spline<float>();
_spline.InitSpline(splinePoints, splinePoints.Length, EvaluationMode.Linear, _stationaryPosition.GetOrientation());
_spline.InitLengths();
@@ -1101,29 +1196,30 @@ namespace Game.Entities
speed = 1.0f;
uint timeToTarget = _spline.Length() / speed * (float)Time.InMilliseconds;
SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.TimeToTarget), timeToTarget);
if (IsInWorld)
{
if (_reachedDestination)
{
AreaTriggerRePath reshapeDest = new();
reshapeDest.TriggerGUID = GetGUID();
SendMessageToSet(reshapeDest, true);
}
var areaTriggerData = m_values.ModifyValue(m_areaTriggerData);
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.TimeToTarget), timeToTarget);
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.MovementStartTime), GameTime.GetGameTimeMS());
AreaTriggerRePath reshape = new();
reshape.TriggerGUID = GetGUID();
reshape.AreaTriggerSpline = new();
reshape.AreaTriggerSpline.ElapsedTimeForMovement = GetElapsedTimeForMovement();
reshape.AreaTriggerSpline.TimeToTarget = timeToTarget;
reshape.AreaTriggerSpline.Points = _spline;
SendMessageToSet(reshape, true);
}
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.PathType), (int)AreaTriggerPathType.Spline);
var pathData = areaTriggerData.ModifyValue<AreaTriggerSplineCalculator>(m_areaTriggerData.PathData);
SetUpdateFieldValue(pathData.ModifyValue(pathData.Catmullrom), splinePoints.Length >= 4);
var points = pathData.ModifyValue(pathData.Points);
ClearDynamicUpdateFieldValues(points);
foreach (Vector3 point in splinePoints)
AddDynamicUpdateFieldValue(points, point);
_reachedDestination = false;
}
uint GetElapsedTimeForMovement()
{
uint now = GameTime.GetGameTimeMS();
if (now >= m_areaTriggerData.MovementStartTime)
return now - m_areaTriggerData.MovementStartTime;
return 0;
}
void InitOrbit(AreaTriggerOrbitInfo orbit, float? overrideSpeed = null)
{
// Circular movement requires either a center position or an attached unit
@@ -1135,45 +1231,40 @@ namespace Game.Entities
uint timeToTarget = (uint)(orbit.Radius * 2.0f * MathF.PI * (float)Time.InMilliseconds / speed);
SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.TimeToTarget), timeToTarget);
SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.OrbitPathTarget), orbit.PathTarget.GetValueOrDefault(ObjectGuid.Empty));
var areaTriggerData = m_values.ModifyValue(m_areaTriggerData);
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.TimeToTarget), timeToTarget);
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.MovementStartTime), GameTime.GetGameTimeMS());
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.OrbitPathTarget), orbit.PathTarget.GetValueOrDefault(ObjectGuid.Empty));
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.ZOffset), orbit.ZOffset);
if (orbit.CanLoop)
SetAreaTriggerFlag(AreaTriggerFieldFlags.CanLoop);
else
RemoveAreaTriggerFlag(AreaTriggerFieldFlags.CanLoop);
_orbitInfo = new AreaTriggerOrbitInfo();
_orbitInfo.TimeToTarget = timeToTarget;
_orbitInfo.ElapsedTimeForMovement = 0;
if (IsInWorld)
{
AreaTriggerRePath reshape = new();
reshape.TriggerGUID = GetGUID();
reshape.AreaTriggerOrbit = _orbitInfo;
SendMessageToSet(reshape, true);
}
}
public bool HasOrbit()
{
return _orbitInfo != null;
SetUpdateFieldValue(areaTriggerData.ModifyValue(m_areaTriggerData.PathType), (int)AreaTriggerPathType.Orbit);
var pathData = areaTriggerData.ModifyValue<AreaTriggerOrbit>(m_areaTriggerData.PathData);
SetUpdateFieldValue(pathData.ModifyValue(pathData.CounterClockwise), orbit.CounterClockwise);
SetUpdateFieldValue(pathData.ModifyValue(pathData.Center), orbit.Center.GetValueOrDefault(new Position()));
SetUpdateFieldValue(pathData.ModifyValue(pathData.Radius), orbit.Radius);
SetUpdateFieldValue(pathData.ModifyValue(pathData.InitialAngle), orbit.InitialAngle);
SetUpdateFieldValue(pathData.ModifyValue(pathData.BlendFromRadius), orbit.BlendFromRadius);
SetUpdateFieldValue(pathData.ModifyValue(pathData.ExtraTimeForBlending), orbit.ExtraTimeForBlending);
}
Position GetOrbitCenterPosition()
{
if (!HasOrbit())
AreaTriggerOrbit orbit = m_areaTriggerData.PathData.Get<AreaTriggerOrbit>();
if (orbit == null)
return null;
if (_orbitInfo.PathTarget.HasValue)
if (!m_areaTriggerData.OrbitPathTarget.GetValue().IsEmpty())
{
WorldObject center = Global.ObjAccessor.GetWorldObject(this, _orbitInfo.PathTarget.Value);
WorldObject center = Global.ObjAccessor.GetWorldObject(this, m_areaTriggerData.OrbitPathTarget);
if (center != null)
return center;
}
if (_orbitInfo.Center.HasValue)
return new Position(_orbitInfo.Center.Value);
return null;
return new Position(orbit.Center);
}
Position CalculateOrbitPosition()
@@ -1182,26 +1273,24 @@ namespace Game.Entities
if (centerPos == null)
return GetPosition();
AreaTriggerCreateProperties createProperties = GetCreateProperties();
AreaTriggerOrbitInfo cmi = GetOrbit();
AreaTriggerOrbit cmi = m_areaTriggerData.PathData.Get<AreaTriggerOrbit>();
// AreaTrigger make exactly "Duration / TimeToTarget" loops during his life time
float pathProgress = (float)cmi.ElapsedTimeForMovement / cmi.TimeToTarget;
if (createProperties != null && createProperties.MoveCurveId != 0)
pathProgress = Global.DB2Mgr.GetCurveValueAt(createProperties.MoveCurveId, pathProgress);
float pathProgress = (float)(GetElapsedTimeForMovement() + cmi.ExtraTimeForBlending) / (float)GetTimeToTarget();
if (m_areaTriggerData.MoveCurveId != 0)
pathProgress = Global.DB2Mgr.GetCurveValueAt(m_areaTriggerData.MoveCurveId, pathProgress);
// We already made one circle and can't loop
if (!cmi.CanLoop)
if (!HasAreaTriggerFlag(AreaTriggerFieldFlags.CanLoop))
pathProgress = Math.Min(1.0f, pathProgress);
float radius = cmi.Radius;
if (MathFunctions.fuzzyNe(cmi.BlendFromRadius, radius))
if (pathProgress <= 1.0f && MathFunctions.fuzzyNe(cmi.BlendFromRadius, radius))
{
float blendCurve = (cmi.BlendFromRadius - radius) / radius;
// 4.f Defines four quarters
blendCurve = MathFunctions.RoundToInterval(ref blendCurve, 1.0f, 4.0f) / 4.0f;
float blendProgress = Math.Min(1.0f, pathProgress / blendCurve);
radius = MathFunctions.Lerp(cmi.BlendFromRadius, cmi.Radius, blendProgress);
MathFunctions.RoundToInterval(ref blendCurve, 1.0f, 4.0f);
float blendProgress = Math.Min(1.0f, pathProgress / blendCurve * 0.63661975f);
radius = MathFunctions.Lerp(cmi.BlendFromRadius, radius, blendProgress);
}
// Adapt Path progress depending of circle direction
@@ -1211,13 +1300,13 @@ namespace Game.Entities
float angle = cmi.InitialAngle + 2.0f * (float)Math.PI * pathProgress;
float x = centerPos.GetPositionX() + (radius * (float)Math.Cos(angle));
float y = centerPos.GetPositionY() + (radius * (float)Math.Sin(angle));
float z = centerPos.GetPositionZ() + cmi.ZOffset;
float z = centerPos.GetPositionZ() + m_areaTriggerData.ZOffset;
float orientation = 0.0f;
if (createProperties != null && createProperties.FacingCurveId != 0)
orientation = Global.DB2Mgr.GetCurveValueAt(createProperties.FacingCurveId, GetProgress());
if (m_areaTriggerData.FacingCurveId != 0)
orientation = Global.DB2Mgr.GetCurveValueAt(m_areaTriggerData.FacingCurveId, GetProgress());
if (GetCreateProperties() == null || !GetCreateProperties().Flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasAbsoluteOrientation))
if (!HasAreaTriggerFlag(AreaTriggerFieldFlags.AbsoluteOrientation))
{
orientation += angle;
orientation += cmi.CounterClockwise ? MathFunctions.PiOver4 : -MathFunctions.PiOver4;
@@ -1226,13 +1315,8 @@ namespace Game.Entities
return new Position(x, y, z, orientation);
}
void UpdateOrbitPosition(uint diff)
void UpdateOrbitPosition()
{
if (_orbitInfo.StartDelay > GetElapsedTimeForMovement())
return;
_orbitInfo.ElapsedTimeForMovement = (int)(GetElapsedTimeForMovement() - _orbitInfo.StartDelay);
Position pos = CalculateOrbitPosition();
GetMap().AreaTriggerRelocation(this, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation());
@@ -1240,14 +1324,12 @@ namespace Game.Entities
DebugVisualizePosition();
}
void UpdateSplinePosition(uint diff)
void UpdateSplinePosition(Spline<float> spline)
{
if (_reachedDestination)
return;
_movementTime += diff;
if (_movementTime >= GetTimeToTarget())
if (GetElapsedTimeForMovement() >= GetTimeToTarget())
{
_reachedDestination = true;
_lastSplineIndex = _spline.Last();
@@ -1262,18 +1344,18 @@ namespace Game.Entities
return;
}
float currentTimePercent = (float)_movementTime / GetTimeToTarget();
float currentTimePercent = (float)GetElapsedTimeForMovement() / GetTimeToTarget();
if (currentTimePercent <= 0.0f)
return;
AreaTriggerCreateProperties createProperties = GetCreateProperties();
if (createProperties != null && createProperties.MoveCurveId != 0)
if (m_areaTriggerData.MoveCurveId != 0)
{
float progress = Global.DB2Mgr.GetCurveValueAt(createProperties.MoveCurveId, currentTimePercent);
float progress = Global.DB2Mgr.GetCurveValueAt(m_areaTriggerData.MoveCurveId, currentTimePercent);
if (progress < 0.0f || progress > 1.0f)
{
Log.outError(LogFilter.AreaTrigger, $"AreaTrigger (Id: {GetEntry()}, AreaTriggerCreatePropertiesId: (Id: {createProperties.Id.Id}, IsCustom: {createProperties.Id.IsCustom})) has wrong progress ({progress}) caused by curve calculation (MoveCurveId: {createProperties.MoveCurveId})");
AreaTriggerCreateProperties createProperties = GetCreateProperties();
Log.outError(LogFilter.AreaTrigger, $"AreaTrigger (Id: {GetEntry()}, AreaTriggerCreatePropertiesId: (Id: {createProperties.Id.Id}, IsCustom: {createProperties.Id.IsCustom})) has wrong progress ({progress}) caused by curve calculation (MoveCurveId: {m_areaTriggerData.MoveCurveId})");
}
else
currentTimePercent = progress;
@@ -1287,10 +1369,10 @@ namespace Game.Entities
_spline.Evaluate_Percent(lastPositionIndex, percentFromLastPoint, out currentPosition);
float orientation = _stationaryPosition.GetOrientation();
if (createProperties != null && createProperties.FacingCurveId != 0)
orientation += Global.DB2Mgr.GetCurveValueAt(createProperties.FacingCurveId, GetProgress());
if (m_areaTriggerData.FacingCurveId != 0)
orientation += Global.DB2Mgr.GetCurveValueAt(m_areaTriggerData.FacingCurveId, GetProgress());
if (GetCreateProperties() != null && !GetCreateProperties().Flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasAbsoluteOrientation) && GetCreateProperties().Flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasFaceMovementDir))
if (!HasAreaTriggerFlag(AreaTriggerFieldFlags.AbsoluteOrientation) && HasAreaTriggerFlag(AreaTriggerFieldFlags.FaceMovementDir))
{
_spline.Evaluate_Derivative(lastPositionIndex, percentFromLastPoint, out Vector3 derivative);
if (derivative.X != 0.0f || derivative.Y != 0.0f)
@@ -1317,11 +1399,11 @@ namespace Game.Entities
float z = GetScaleCurveValueAtProgress(m_areaTriggerData.OverrideMoveCurveZ, progress);
float orientation = GetOrientation();
if (GetCreateProperties().FacingCurveId != 0)
if (m_areaTriggerData.FacingCurveId != 0)
{
orientation = Global.DB2Mgr.GetCurveValueAt(GetCreateProperties().FacingCurveId, GetProgress());
if (GetCreateProperties() == null || !GetCreateProperties().Flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasAbsoluteOrientation))
orientation += _stationaryPosition.GetOrientation();
orientation = Global.DB2Mgr.GetCurveValueAt(m_areaTriggerData.FacingCurveId, GetProgress());
if (HasAreaTriggerFlag(AreaTriggerFieldFlags.AbsoluteOrientation))
orientation += m_areaTriggerData.Facing;
}
GetMap().AreaTriggerRelocation(this, x, y, z, orientation);
@@ -1438,9 +1520,15 @@ namespace Game.Entities
public bool IsRemoved() { return _isRemoved; }
public uint GetSpellId() { return m_areaTriggerData.SpellID; }
public AuraEffect GetAuraEffect() { return _aurEff; }
public uint GetTimeSinceCreated() { return _timeSinceCreated; }
public void SetHeightIgnoresScale(bool heightIgnoresScale) { SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.HeightIgnoresScale), heightIgnoresScale); }
public AreaTriggerFieldFlags GetAreaTriggerFlags() { return (AreaTriggerFieldFlags)m_areaTriggerData.Flags.GetValue(); }
public bool HasAreaTriggerFlag(AreaTriggerFieldFlags flag)
{
return GetAreaTriggerFlags().HasFlag(flag);
}
public void SetAreaTriggerFlag(AreaTriggerFieldFlags flag) { SetUpdateFieldFlagValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.Flags), (uint)flag); }
public void RemoveAreaTriggerFlag(AreaTriggerFieldFlags flag) { RemoveUpdateFieldFlagValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.Flags), (uint)flag); }
public void ReplaceAllAreaTriggerFlags(AreaTriggerFieldFlags flag) { SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.Flags), (uint)flag); }
public uint GetTimeToTarget() { return m_areaTriggerData.TimeToTarget; }
public void SetTimeToTarget(uint timeToTarget) { SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.TimeToTarget), timeToTarget); }
@@ -1467,15 +1555,11 @@ namespace Game.Entities
public override ObjectGuid GetOwnerGUID() { return GetCasterGuid(); }
public ObjectGuid GetCasterGuid() { return m_areaTriggerData.Caster; }
public AreaTriggerShapeInfo GetShape() { return _shape; }
public Vector3 GetRollPitchYaw() { return _rollPitchYaw; }
public Vector3 GetTargetRollPitchYaw() { return _targetRollPitchYaw; }
public bool HasSplines() { return !_spline.Empty(); }
public Spline<float> GetSpline() { return _spline; }
public uint GetElapsedTimeForMovement() { return GetTimeSinceCreated(); } // @todo: research the right value, in sniffs both timers are nearly identical
public AreaTriggerOrbitInfo GetOrbit() { return _orbitInfo; }
bool HasOrbit() { return m_areaTriggerData.PathData.Is<AreaTriggerOrbit>(); }
public AreaTriggerOrbit GetOrbit() { return m_areaTriggerData.PathData.Get<AreaTriggerOrbit>(); }
public AreaTriggerFieldData m_areaTriggerData;
@@ -1486,21 +1570,16 @@ namespace Game.Entities
AuraEffect _aurEff;
Position _stationaryPosition;
AreaTriggerShapeInfo _shape;
int _duration;
int _totalDuration;
uint _timeSinceCreated;
float _verticesUpdatePreviousOrientation;
bool _isRemoved;
Position _rollPitchYaw;
Position _targetRollPitchYaw;
List<Position> _polygonVertices;
Spline<float> _spline;
bool _reachedDestination;
int _lastSplineIndex;
uint _movementTime;
AreaTriggerOrbitInfo _orbitInfo;
@@ -104,18 +104,6 @@ namespace Game.Entities
public AreaTriggerScaleCurvePointsTemplate CurveTemplate;
}
public struct AreaTriggerMovementScriptInfo
{
public uint SpellScriptID;
public Vector3 Center;
public void Write(WorldPacket data)
{
data.WriteUInt32(SpellScriptID);
data.WriteVector3(Center);
}
}
public struct AreaTriggerId
{
public uint Id;
@@ -204,35 +192,11 @@ namespace Game.Entities
public class AreaTriggerOrbitInfo
{
public void Write(WorldPacket data)
{
data.WriteBit(PathTarget.HasValue);
data.WriteBit(Center.HasValue);
data.WriteBit(CounterClockwise);
data.WriteBit(CanLoop);
data.WriteUInt32(TimeToTarget);
data.WriteInt32(ElapsedTimeForMovement);
data.WriteUInt32(StartDelay);
data.WriteFloat(Radius);
data.WriteFloat(BlendFromRadius);
data.WriteFloat(InitialAngle);
data.WriteFloat(ZOffset);
if (PathTarget.HasValue)
data.WritePackedGuid(PathTarget.Value);
if (Center.HasValue)
data.WriteVector3(Center.Value);
}
public ObjectGuid? PathTarget;
public Vector3? Center;
public bool CounterClockwise;
public bool CanLoop;
public uint TimeToTarget;
public int ElapsedTimeForMovement;
public uint StartDelay;
public int ExtraTimeForBlending;
public float Radius;
public float BlendFromRadius;
public float InitialAngle;
@@ -166,6 +166,7 @@ namespace Game.Entities
stats.Flags[0] = (uint)creatureDifficulty.TypeFlags;
stats.Flags[1] = creatureDifficulty.TypeFlags2;
stats.Flags[2] = creatureDifficulty.TypeFlags3;
stats.CreatureType = (sbyte)CreatureType;
stats.CreatureFamily = (int)Family;
@@ -436,6 +437,7 @@ namespace Game.Entities
public int CreatureDifficultyID;
public CreatureTypeFlags TypeFlags;
public uint TypeFlags2;
public uint TypeFlags3;
public uint LootID;
public uint PickPocketLootID;
public uint SkinLootID;
@@ -224,6 +224,12 @@ namespace Game.Entities
[FieldOffset(80)]
public craftingTable CraftingTable;
[FieldOffset(80)]
public futurePatchGameObject FuturePatchGameObject;
[FieldOffset(80)]
public assistAction AssistAction;
[FieldOffset(80)]
public raw Raw;
@@ -539,6 +545,10 @@ namespace Game.Entities
return QuestGiver.gossipID;
case GameObjectTypes.Goober:
return Goober.gossipID;
case GameObjectTypes.SpellFocus:
return SpellFocus.gossipID;
case GameObjectTypes.AssistAction:
return AssistAction.gossipID;
default:
return 0;
}
@@ -641,6 +651,8 @@ namespace Game.Entities
return Trap.cooldown;
case GameObjectTypes.Goober:
return Goober.cooldown;
case GameObjectTypes.AssistAction:
return AssistAction.cooldown;
default:
return 0;
}
@@ -1483,7 +1495,7 @@ namespace Game.Entities
public uint radius; // 4 radius, int, Min value: 0, Max value: 50, Default value: 10
public uint InteractRadiusOverride; // 5 Interact Radius Override (Yards * 100), int, Min value: 0, Max value: 2147483647, Default value: 0
public uint ItemInteractionID; // 6 Item Interaction ID, References: UiItemInteraction, NoValue = 0
public uint PlayerInteractionType; // 7 Player Interaction Type, enum { None, TradePartner, Item, Gossip, QuestGiver, Merchant, TaxiNode, Trainer, Banker, AlliedRaceDetailsGiver, GuildBanker, Registrar, Vendor, PetitionVendor, GuildTabardVendor, TalentMaster, SpecializationMaster, MailInfo, SpiritHealer, AreaSpiritHealer, Binder, Auctioneer, StableMaster, BattleMaster, Transmogrifier, LFGDungeon, VoidStorageBanker, BlackMarketAuctioneer, AdventureMap, WorldMap, GarrArchitect, GarrTradeskill, GarrMission, ShipmentCrafter, GarrRecruitment, GarrTalent, Trophy, PlayerChoice, ArtifactForge, ObliterumForge, ScrappingMachine, ContributionCollector, AzeriteRespec, IslandQueue, ItemInteraction, ChromieTime, CovenantPreview, AnimaDiversion, LegendaryCrafting, WeeklyRewards, Soulbind, CovenantSanctum, NewPlayerGuide, ItemUpgrade, AdventureJournal, Renown, AzeriteForge, PerksProgramVendor, ProfessionsCraftingOrder, Professions, ProfessionsCustomerOrder, TraitSystem, BarbersChoice, JailersTowerBuffs, MajorFactionRenown, PersonalTabardVendor, ForgeMaster, CharacterBanker, AccountBanker, ProfessionRespec, PlaceholderType71, PlaceholderType72, PlaceholderType73, PlaceholderType74, PlaceholderType75, PlaceholderType76, PlaceholderType77, }; Default: None
public uint PlayerInteractionType; // 7 Player Interaction Type, enum { None, TradePartner, Item, Gossip, QuestGiver, Merchant, TaxiNode, Trainer, Banker, AlliedRaceDetailsGiver, GuildBanker, Registrar, Vendor, PetitionVendor, GuildTabardVendor, TalentMaster, SpecializationMaster, MailInfo, SpiritHealer, AreaSpiritHealer, Binder, Auctioneer, StableMaster, BattleMaster, Transmogrifier, LFGDungeon, VoidStorageBanker, BlackMarketAuctioneer, AdventureMap, WorldMap, GarrArchitect, GarrTradeskill, GarrMission, ShipmentCrafter, GarrRecruitment, GarrTalent, Trophy, PlayerChoice, ArtifactForge, ObliterumForge, ScrappingMachine, ContributionCollector, AzeriteRespec, IslandQueue, ItemInteraction, ChromieTime, CovenantPreview, AnimaDiversion, LegendaryCrafting, WeeklyRewards, Soulbind, CovenantSanctum, NewPlayerGuide, ItemUpgrade, AdventureJournal, Renown, AzeriteForge, PerksProgramVendor, ProfessionsCraftingOrder, Professions, ProfessionsCustomerOrder, TraitSystem, BarbersChoice, JailersTowerBuffs, MajorFactionRenown, PersonalTabardVendor, ForgeMaster, CharacterBanker, AccountBanker, ProfessionRespec, PlaceholderType71, PlaceholderType72, PlaceholderType73, PlaceholderType74, PlaceholderType75, PlaceholderType76, GuildRename, PlaceholderType76, }; Default: None
}
public struct keystonereceptacle
@@ -1614,6 +1626,19 @@ namespace Game.Entities
public uint Script; // 0 Script, References: SpellScript, NoValue = 0
public uint autoClose; // 1 autoClose (ms), int, Min value: 0, Max value: 2147483647, Default value: 3000
}
public struct futurePatchGameObject
{
}
public struct assistAction
{
public uint AssistActionType; // 0 Assist Action Type, enum { None, Lounging Player, Grave Marker, Placed VO, Player Guardian, Player Slayer, Captured Buff, }; Default: None
public uint cooldown; // 1 cooldown, int, Min value: 0, Max value: 2147483647, Default value: 3000
public uint gossipID; // 2 gossipID, References: Gossip, NoValue = 0
public uint spell; // 3 spell, References: Spell, NoValue = 0
public uint playerCast; // 4 playerCast, enum { false, true, }; Default: false
}
#endregion
}
+11 -5
View File
@@ -2551,9 +2551,15 @@ namespace Game.Entities
}
eff.SetBonuses.Add(itemSetSpell);
// spell cast only if fit form requirement, in other case will cast at form change
if (itemSetSpell.ChrSpecID == 0 || (ChrSpecialization)itemSetSpell.ChrSpecID == player.GetPrimarySpecialization())
player.ApplyEquipSpell(spellInfo, null, true);
if (itemSetSpell.ChrSpecID != 0 && (ChrSpecialization)itemSetSpell.ChrSpecID != player.GetPrimarySpecialization())
continue;
if (itemSetSpell.TraitSubTreeID != 0 && itemSetSpell.TraitSubTreeID != player.m_playerData.CurrentCombatTraitConfigSubTreeID)
continue;
player.ApplyEquipSpell(spellInfo, null, true);
}
}
@@ -2592,11 +2598,10 @@ namespace Game.Entities
if (itemSetSpell.Threshold <= eff.EquippedItems.Count)
continue;
if (!eff.SetBonuses.Contains(itemSetSpell))
if (!eff.SetBonuses.Remove(itemSetSpell))
continue;
player.ApplyEquipSpell(Global.SpellMgr.GetSpellInfo(itemSetSpell.SpellID, Difficulty.None), null, false);
eff.SetBonuses.Remove(itemSetSpell);
}
if (eff.EquippedItems.Empty()) //all items of a set were removed
@@ -2618,7 +2623,8 @@ namespace Game.Entities
{
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(itemSetSpell.SpellID, Difficulty.None);
if (itemSetSpell.ChrSpecID != 0 && (ChrSpecialization)itemSetSpell.ChrSpecID != player.GetPrimarySpecialization())
if ((itemSetSpell.ChrSpecID != 0 && itemSetSpell.ChrSpecID != (ushort)player.GetPrimarySpecialization())
|| (itemSetSpell.TraitSubTreeID != 0 && itemSetSpell.TraitSubTreeID != player.m_playerData.CurrentCombatTraitConfigSubTreeID))
player.ApplyEquipSpell(spellInfo, null, false, false); // item set aura is not for current spec
else
{
@@ -15,6 +15,12 @@ namespace Game.Entities
T GetValue();
}
public interface IHasChangesMask
{
void ClearChangesMask();
UpdateMask GetUpdateMask();
}
public class UpdateFieldString : IUpdateField<string>
{
public string _value;
@@ -347,15 +353,39 @@ namespace Game.Entities
}
}
public interface IHasChangesMask
public class VariantUpdateField(int blockBit, int bit, params Type[] types)
{
void ClearChangesMask();
UpdateMask GetUpdateMask();
public object _value;
Type[] _types = types;
public int BlockBit = blockBit;
public int Bit = bit;
public bool Is<T>() { return _types.Contains(typeof(T)); }
public T Get<T>() where T : class, new()
{
if (Is<T>())
return _value as T;
return null;
}
public void Visit(Action<dynamic> visitor)
{
visitor(_value);
}
public void ConstructValue<T>() where T : class, new()
{
_value = new T();
}
}
public abstract class HasChangesMask : IHasChangesMask
{
public int _changeMask;
public static int ChangeMaskLength;
public UpdateMask _changesMask;
public int _blockBit;
public int Bit;
@@ -364,12 +394,13 @@ namespace Game.Entities
{
_blockBit = blockBit;
Bit = (int)bit;
ChangeMaskLength = changeMask;
_changesMask = new UpdateMask(changeMask);
_changeMask = changeMask;
}
public HasChangesMask(int changeMask)
{
ChangeMaskLength = changeMask;
_changesMask = new UpdateMask(changeMask);
}
@@ -433,6 +464,19 @@ namespace Game.Entities
}
}
public void ClearChangesMask(VariantUpdateField field)
{
if (typeof(IHasChangesMask).IsAssignableFrom(field._value.GetType()))
((IHasChangesMask)field._value).ClearChangesMask();
}
public dynamic ModifyValueOld(dynamic value, int bit, int blockBit)
{
_changesMask.Set(blockBit);
_changesMask.Set(bit);
return value;
}
public UpdateField<U> ModifyValue<U>(UpdateField<U> updateField) where U : new()
{
MarkChanged(updateField);
@@ -504,6 +548,18 @@ namespace Game.Entities
return new DynamicUpdateFieldSetter<U>(updateField[index], dynamicIndex);
}
public V ModifyValue<V>(VariantUpdateField field) where V : class, new()
{
if (!field.Is<V>())
field.ConstructValue<V>();
if (field.BlockBit >= 0)
_changesMask.Set(field.BlockBit);
_changesMask.Set(Bit);
return field.Get<V>();
}
public void MarkChanged<U>(UpdateField<U> updateField) where U : new()
{
_changesMask.Set(updateField.BlockBit);
@@ -560,7 +616,7 @@ namespace Game.Entities
public UpdateMask GetStaticUpdateMask()
{
return new UpdateMask(_changeMask);
return new UpdateMask(ChangeMaskLength);
}
}
File diff suppressed because it is too large Load Diff
+12 -141
View File
@@ -299,6 +299,7 @@ namespace Game.Entities
data.WriteBit(flags.NoBirthAnim);
data.WriteBit(flags.EnablePortals);
data.WriteBit(flags.PlayHoverAnim);
data.WriteBit(flags.ThisIsYou);
data.WriteBit(flags.MovementUpdate);
data.WriteBit(flags.MovementTransport);
data.WriteBit(flags.Stationary);
@@ -307,10 +308,8 @@ namespace Game.Entities
data.WriteBit(flags.Vehicle);
data.WriteBit(flags.AnimKit);
data.WriteBit(flags.Rotation);
data.WriteBit(flags.AreaTrigger);
data.WriteBit(flags.GameObject);
data.WriteBit(flags.SmoothPhasing);
data.WriteBit(flags.ThisIsYou);
data.WriteBit(flags.SceneObject);
data.WriteBit(flags.ActivePlayer);
data.WriteBit(flags.Conversation);
@@ -461,7 +460,10 @@ namespace Game.Entities
}
if (flags.CombatVictim)
data.WritePackedGuid(ToUnit().GetVictim().GetGUID()); // CombatVictim
{
Unit unit = ToUnit();
data.WritePackedGuid(unit.GetVictim().GetGUID()); // CombatVictim
}
if (flags.ServerTime)
data.WriteUInt32(GameTime.GetGameTimeMS());
@@ -481,7 +483,10 @@ namespace Game.Entities
}
if (flags.Rotation)
data.WriteInt64(ToGameObject().GetPackedLocalRotation()); // Rotation
{
GameObject gameObject = ToGameObject();
data.WriteInt64(gameObject.GetPackedLocalRotation()); // Rotation
}
if (PauseTimes != null && !PauseTimes.Empty())
foreach (var stopFrame in PauseTimes)
@@ -493,138 +498,6 @@ namespace Game.Entities
MovementExtensions.WriteTransportInfo(data, self.m_movementInfo.transport);
}
if (flags.AreaTrigger)
{
AreaTrigger areaTrigger = ToAreaTrigger();
AreaTriggerCreateProperties createProperties = areaTrigger.GetCreateProperties();
AreaTriggerShapeInfo shape = areaTrigger.GetShape();
data.WriteUInt32(areaTrigger.GetTimeSinceCreated());
data.WriteVector3(areaTrigger.GetRollPitchYaw());
switch (shape.TriggerType)
{
case AreaTriggerShapeType.Sphere:
data.WriteInt8(0);
data.WriteFloat(shape.SphereDatas.Radius);
data.WriteFloat(shape.SphereDatas.RadiusTarget);
break;
case AreaTriggerShapeType.Box:
data.WriteInt8(1);
data.WriteFloat(shape.BoxDatas.Extents[0]);
data.WriteFloat(shape.BoxDatas.Extents[1]);
data.WriteFloat(shape.BoxDatas.Extents[2]);
data.WriteFloat(shape.BoxDatas.ExtentsTarget[0]);
data.WriteFloat(shape.BoxDatas.ExtentsTarget[1]);
data.WriteFloat(shape.BoxDatas.ExtentsTarget[2]);
break;
case AreaTriggerShapeType.Polygon:
data.WriteInt8(3);
data.WriteInt32(shape.PolygonVertices.Count);
data.WriteInt32(shape.PolygonVerticesTarget.Count);
data.WriteFloat(shape.PolygonDatas.Height);
data.WriteFloat(shape.PolygonDatas.HeightTarget);
foreach (var vertice in shape.PolygonVertices)
data.WriteVector2(vertice);
foreach (var vertice in shape.PolygonVerticesTarget)
data.WriteVector2(vertice);
break;
case AreaTriggerShapeType.Cylinder:
data.WriteInt8(4);
data.WriteFloat(shape.CylinderDatas.Radius);
data.WriteFloat(shape.CylinderDatas.RadiusTarget);
data.WriteFloat(shape.CylinderDatas.Height);
data.WriteFloat(shape.CylinderDatas.HeightTarget);
data.WriteFloat(shape.CylinderDatas.LocationZOffset);
data.WriteFloat(shape.CylinderDatas.LocationZOffsetTarget);
break;
case AreaTriggerShapeType.Disk:
data.WriteInt8(7);
data.WriteFloat(shape.DiskDatas.InnerRadius);
data.WriteFloat(shape.DiskDatas.InnerRadiusTarget);
data.WriteFloat(shape.DiskDatas.OuterRadius);
data.WriteFloat(shape.DiskDatas.OuterRadiusTarget);
data.WriteFloat(shape.DiskDatas.Height);
data.WriteFloat(shape.DiskDatas.HeightTarget);
data.WriteFloat(shape.DiskDatas.LocationZOffset);
data.WriteFloat(shape.DiskDatas.LocationZOffsetTarget);
break;
case AreaTriggerShapeType.BoundedPlane:
data.WriteInt8(8);
data.WriteFloat(shape.BoundedPlaneDatas.Extents[0]);
data.WriteFloat(shape.BoundedPlaneDatas.Extents[1]);
data.WriteFloat(shape.BoundedPlaneDatas.ExtentsTarget[0]);
data.WriteFloat(shape.BoundedPlaneDatas.ExtentsTarget[1]);
break;
default:
break;
}
bool hasAbsoluteOrientation = createProperties != null && createProperties.Flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasAbsoluteOrientation);
bool hasDynamicShape = createProperties != null && createProperties.Flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasDynamicShape);
bool hasAttached = createProperties != null && createProperties.Flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasAttached);
bool hasFaceMovementDir = createProperties != null && createProperties.Flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasFaceMovementDir);
bool hasFollowsTerrain = createProperties != null && createProperties.Flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasFollowsTerrain);
bool hasAlwaysExterior = createProperties != null && createProperties.Flags.HasFlag(AreaTriggerCreatePropertiesFlag.AlwaysExterior);
bool hasUnknown1025 = false;
bool hasTargetRollPitchYaw = createProperties != null && createProperties.Flags.HasFlag(AreaTriggerCreatePropertiesFlag.HasTargetRollPitchYaw);
bool hasScaleCurveID = createProperties != null && createProperties.ScaleCurveId != 0;
bool hasMorphCurveID = createProperties != null && createProperties.MorphCurveId != 0;
bool hasFacingCurveID = createProperties != null && createProperties.FacingCurveId != 0;
bool hasMoveCurveID = createProperties != null && createProperties.MoveCurveId != 0;
bool hasMovementScript = false;
bool hasPositionalSoundKitID = false;
data.WriteBit(hasAbsoluteOrientation);
data.WriteBit(hasDynamicShape);
data.WriteBit(hasAttached);
data.WriteBit(hasFaceMovementDir);
data.WriteBit(hasFollowsTerrain);
data.WriteBit(hasAlwaysExterior);
data.WriteBit(hasUnknown1025);
data.WriteBit(hasTargetRollPitchYaw);
data.WriteBit(hasScaleCurveID);
data.WriteBit(hasMorphCurveID);
data.WriteBit(hasFacingCurveID);
data.WriteBit(hasMoveCurveID);
data.WriteBit(hasPositionalSoundKitID);
data.WriteBit(areaTrigger.HasSplines());
data.WriteBit(areaTrigger.HasOrbit());
data.WriteBit(hasMovementScript);
data.FlushBits();
if (areaTrigger.HasSplines())
AreaTriggerSplineInfo.WriteAreaTriggerSpline(data, areaTrigger.GetTimeToTarget(), areaTrigger.GetElapsedTimeForMovement(), areaTrigger.GetSpline());
if (hasTargetRollPitchYaw)
data.WriteVector3(areaTrigger.GetTargetRollPitchYaw());
if (hasScaleCurveID)
data.WriteUInt32(createProperties.ScaleCurveId);
if (hasMorphCurveID)
data.WriteUInt32(createProperties.MorphCurveId);
if (hasFacingCurveID)
data.WriteUInt32(createProperties.FacingCurveId);
if (hasMoveCurveID)
data.WriteUInt32(createProperties.MoveCurveId);
if (hasPositionalSoundKitID)
data.WriteUInt32(0);
//if (hasMovementScript)
// *data << *areaTrigger.GetMovementScript(); // AreaTriggerMovementScriptInfo
if (areaTrigger.HasOrbit())
areaTrigger.GetOrbit().Write(data);
}
if (flags.GameObject)
{
GameObject gameObject = ToGameObject();
@@ -785,7 +658,7 @@ namespace Game.Entities
Player player = ToPlayer();
bool HasSceneInstanceIDs = !player.GetSceneMgr().GetSceneTemplateByInstanceMap().Empty();
bool HasRuneState = ToUnit().GetPowerIndex(PowerType.Runes) != (int)PowerType.Max;
bool HasRuneState = player.GetPowerIndex(PowerType.Runes) != (int)PowerType.Max;
data.WriteBit(HasSceneInstanceIDs);
data.WriteBit(HasRuneState);
@@ -794,8 +667,8 @@ namespace Game.Entities
if (HasSceneInstanceIDs)
{
data.WriteInt32(player.GetSceneMgr().GetSceneTemplateByInstanceMap().Count);
foreach (var pair in player.GetSceneMgr().GetSceneTemplateByInstanceMap())
data.WriteUInt32(pair.Key);
foreach (var (sceneInstanceId, _) in player.GetSceneMgr().GetSceneTemplateByInstanceMap())
data.WriteUInt32(sceneInstanceId);
}
if (HasRuneState)
@@ -4157,7 +4030,6 @@ namespace Game.Entities
public bool Vehicle;
public bool AnimKit;
public bool Rotation;
public bool AreaTrigger;
public bool GameObject;
public bool SmoothPhasing;
public bool ThisIsYou;
@@ -4178,7 +4050,6 @@ namespace Game.Entities
Vehicle = false;
AnimKit = false;
Rotation = false;
AreaTrigger = false;
GameObject = false;
SmoothPhasing = false;
ThisIsYou = false;
+65 -102
View File
@@ -725,6 +725,25 @@ namespace Game.Entities
}
}
void _LoadCharacterBankTabSettings(SQLResult result)
{
if (!result.IsEmpty())
{
do
{
if (result.Read<byte>(0) >= (InventorySlots.BankBagEnd - InventorySlots.BankBagStart))
continue;
SetCharacterBankTabSettings(result.Read<byte>(0), result.Read<string>(1), result.Read<string>(2),
result.Read<string>(3), (BagSlotFlags)result.Read<uint>(4));
} while (result.NextRow());
}
while (m_activePlayerData.CharacterBankTabSettings.Size() < m_activePlayerData.NumCharacterBankTabs)
AddDynamicUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.CharacterBankTabSettings), new BankTabSettings());
}
void _LoadCurrency(SQLResult result)
{
if (result.IsEmpty())
@@ -1272,7 +1291,13 @@ namespace Game.Entities
});
if (activeConfig >= 0)
SetActiveCombatTraitConfigID(m_activePlayerData.TraitConfigs[activeConfig].ID);
{
TraitConfig activeTraitConfig = m_activePlayerData.TraitConfigs[activeConfig];
SetActiveCombatTraitConfigID(activeTraitConfig.ID);
int activeSubTree = activeTraitConfig.SubTrees.FindIndexIf(subTree => subTree.Active != 0);
if (activeSubTree >= 0)
SetCurrentCombatTraitConfigSubTreeID(activeTraitConfig.SubTrees[activeSubTree].TraitSubTreeID);
}
foreach (TraitConfig traitConfig in m_activePlayerData.TraitConfigs)
{
@@ -1340,55 +1365,6 @@ namespace Game.Entities
RemoveAtLoginFlag(AtLoginFlags.Resurrect);
}
void _LoadVoidStorage(SQLResult result)
{
if (result.IsEmpty())
return;
do
{
// SELECT itemId, itemEntry, slot, creatorGuid, randomBonusListId, fixedScalingLevel, artifactKnowledgeLevel, context, bonusListIDs FROM character_void_storage WHERE playerGuid = ?
ulong itemId = result.Read<ulong>(0);
uint itemEntry = result.Read<uint>(1);
byte slot = result.Read<byte>(2);
ObjectGuid creatorGuid = result.Read<ulong>(3) != 0 ? ObjectGuid.Create(HighGuid.Player, result.Read<ulong>(3)) : ObjectGuid.Empty;
uint randomBonusListId = result.Read<uint>(4);
uint fixedScalingLevel = result.Read<uint>(5);
uint artifactKnowledgeLevel = result.Read<uint>(6);
ItemContext context = (ItemContext)result.Read<byte>(7);
List<uint> bonusListIDs = new();
var bonusListIdTokens = new StringArray(result.Read<string>(8), ' ');
for (var i = 0; i < bonusListIdTokens.Length; ++i)
{
if (uint.TryParse(bonusListIdTokens[i], out uint id))
bonusListIDs.Add(id);
}
if (itemId == 0)
{
Log.outError(LogFilter.Player, "Player:_LoadVoidStorage - Player (GUID: {0}, name: {1}) has an item with an invalid id (item id: item id: {2}, entry: {3}).", GetGUID().ToString(), GetName(), itemId, itemEntry);
continue;
}
if (Global.ObjectMgr.GetItemTemplate(itemEntry) == null)
{
Log.outError(LogFilter.Player, "Player:_LoadVoidStorage - Player (GUID: {0}, name: {1}) has an item with an invalid entry (item id: item id: {2}, entry: {3}).", GetGUID().ToString(), GetName(), itemId, itemEntry);
continue;
}
if (slot >= SharedConst.VoidStorageMaxSlot)
{
Log.outError(LogFilter.Player, "Player:_LoadVoidStorage - Player (GUID: {0}, name: {1}) has an item with an invalid slot (item id: item id: {2}, entry: {3}, slot: {4}).", GetGUID().ToString(), GetName(), itemId, itemEntry, slot);
continue;
}
_voidStorageItems[slot] = new VoidStorageItem(itemId, itemEntry, creatorGuid, randomBonusListId, fixedScalingLevel, artifactKnowledgeLevel, context, bonusListIDs);
BonusData bonus = new(new ItemInstance(_voidStorageItems[slot]));
GetSession().GetCollectionMgr().AddItemAppearance(itemEntry, bonus.AppearanceModID);
}
while (result.NextRow());
}
public void _LoadMail(SQLResult mailsResult, SQLResult mailItemsResult, SQLResult artifactResult, SQLResult azeriteItemResult, SQLResult azeriteItemMilestonePowersResult, SQLResult azeriteItemUnlockedEssencesResult, SQLResult azeriteEmpoweredItemResult)
{
@@ -2762,6 +2738,26 @@ namespace Game.Entities
_playerDataFlagsNeedSave.Clear();
}
void _SaveCharacterBankTabSettings(SQLTransaction trans)
{
PreparedStatement stmt = CharacterDatabase.GetPreparedStatement(CharStatements.DEL_CHARACTER_BANK_TAB_SETTINGS);
stmt.AddValue(0, GetGUID().GetCounter());
trans.Append(stmt);
for (int i = 0; i < m_activePlayerData.CharacterBankTabSettings.Size(); ++i)
{
BankTabSettings tabSetting = m_activePlayerData.CharacterBankTabSettings[i];
stmt = CharacterDatabase.GetPreparedStatement(CharStatements.INS_CHARACTER_BANK_TAB_SETTINGS);
stmt.AddValue(0, GetGUID().GetCounter());
stmt.AddValue(1, i);
stmt.AddValue(2, tabSetting.Name);
stmt.AddValue(3, tabSetting.Icon);
stmt.AddValue(4, tabSetting.Description);
stmt.AddValue(5, tabSetting.DepositFlags);
trans.Append(stmt);
}
}
public void SaveInventoryAndGoldToDB(SQLTransaction trans)
{
_SaveInventory(trans);
@@ -2867,42 +2863,7 @@ namespace Game.Entities
}
}
}
void _SaveVoidStorage(SQLTransaction trans)
{
PreparedStatement stmt;
for (byte i = 0; i < SharedConst.VoidStorageMaxSlot; ++i)
{
if (_voidStorageItems[i] == null) // unused item
{
// DELETE FROM void_storage WHERE slot = ? AND playerGuid = ?
stmt = CharacterDatabase.GetPreparedStatement(CharStatements.DEL_CHAR_VOID_STORAGE_ITEM_BY_SLOT);
stmt.AddValue(0, i);
stmt.AddValue(1, GetGUID().GetCounter());
}
else
{
// REPLACE INTO character_void_storage (itemId, playerGuid, itemEntry, slot, creatorGuid, randomPropertyType, randomProperty, upgradeId, fixedScalingLevel, artifactKnowledgeLevel, bonusListIDs) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
stmt = CharacterDatabase.GetPreparedStatement(CharStatements.REP_CHAR_VOID_STORAGE_ITEM);
stmt.AddValue(0, _voidStorageItems[i].ItemId);
stmt.AddValue(1, GetGUID().GetCounter());
stmt.AddValue(2, _voidStorageItems[i].ItemEntry);
stmt.AddValue(3, i);
stmt.AddValue(4, _voidStorageItems[i].CreatorGuid.GetCounter());
stmt.AddValue(5, (byte)_voidStorageItems[i].RandomBonusListId);
stmt.AddValue(6, _voidStorageItems[i].FixedScalingLevel);
stmt.AddValue(7, _voidStorageItems[i].ArtifactKnowledgeLevel);
stmt.AddValue(8, (byte)_voidStorageItems[i].Context);
StringBuilder bonusListIDs = new();
foreach (uint bonusListID in _voidStorageItems[i].BonusListIDs)
bonusListIDs.AppendFormat("{0} ", bonusListID);
stmt.AddValue(9, bonusListIDs.ToString());
}
trans.Append(stmt);
}
}
void _SaveCUFProfiles(SQLTransaction trans)
{
PreparedStatement stmt;
@@ -3006,10 +2967,8 @@ namespace Game.Entities
bagSlotFlags[i] = (BagSlotFlags)result.Read<uint>(fieldIndex++);
byte bankSlots = result.Read<byte>(fieldIndex++);
BagSlotFlags[] bankBagSlotFlags = new BagSlotFlags[7];
byte bankTabs = result.Read<byte>(fieldIndex++);
BagSlotFlags bankBagFlags = (BagSlotFlags)result.Read<uint>(fieldIndex++);
for (var i = 0; i < bankBagSlotFlags.Length; ++i)
bankBagSlotFlags[i] = (BagSlotFlags)result.Read<uint>(fieldIndex++);
PlayerRestState restState = (PlayerRestState)result.Read<byte>(fieldIndex++);
PlayerFlags playerFlags = (PlayerFlags)result.Read<uint>(fieldIndex++);
@@ -3179,9 +3138,8 @@ namespace Game.Entities
ReplaceAllBagSlotFlags(bagIndex, bagSlotFlags[bagIndex]);
SetBankBagSlotCount(bankSlots);
SetCharacterBankTabCount(bankTabs);
SetBankAutoSortDisabled(bankBagFlags.HasFlag(BagSlotFlags.DisableAutoSort));
for (int bagIndex = 0; bagIndex < bankBagSlotFlags.Length; ++bagIndex)
ReplaceAllBankBagSlotFlags(bagIndex, bankBagSlotFlags[bagIndex]);
SetNativeGender(gender);
SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.Inebriation), drunk);
@@ -3608,12 +3566,11 @@ namespace Game.Entities
// must be before inventory (some items required reputation check)
reputationMgr.LoadFromDB(holder.GetResult(PlayerLoginQueryLoad.Reputation));
_LoadCharacterBankTabSettings(holder.GetResult(PlayerLoginQueryLoad.BankTabSettings));
_LoadInventory(holder.GetResult(PlayerLoginQueryLoad.Inventory), holder.GetResult(PlayerLoginQueryLoad.Artifacts), holder.GetResult(PlayerLoginQueryLoad.Azerite),
holder.GetResult(PlayerLoginQueryLoad.AzeriteMilestonePowers), holder.GetResult(PlayerLoginQueryLoad.AzeriteUnlockedEssences), holder.GetResult(PlayerLoginQueryLoad.AzeriteEmpowered), time_diff);
if (IsVoidStorageUnlocked())
_LoadVoidStorage(holder.GetResult(PlayerLoginQueryLoad.VoidStorage));
// update items with duration and realtime
UpdateItemDuration(time_diff, true);
@@ -3884,13 +3841,12 @@ namespace Game.Entities
foreach (uint bagSlotFlag in m_activePlayerData.BagSlotFlags)
stmt.AddValue(index++, bagSlotFlag);
stmt.AddValue(index++, GetBankBagSlotCount());
stmt.AddValue(index++, GetCharacterBankTabCount());
inventoryFlags = BagSlotFlags.None;
if (m_activePlayerData.BankAutoSortDisabled)
inventoryFlags |= BagSlotFlags.DisableAutoSort;
stmt.AddValue(index++, (uint)inventoryFlags);
foreach (uint bankBagSlotFlag in m_activePlayerData.BankBagSlotFlags)
stmt.AddValue(index++, bankBagSlotFlag);
stmt.AddValue(index++, m_activePlayerData.RestInfo[(int)RestTypes.XP].StateID);
stmt.AddValue(index++, m_playerData.PlayerFlags);
@@ -4019,13 +3975,12 @@ namespace Game.Entities
foreach (uint bagSlotFlag in m_activePlayerData.BagSlotFlags)
stmt.AddValue(index++, bagSlotFlag);
stmt.AddValue(index++, GetBankBagSlotCount());
stmt.AddValue(index++, GetCharacterBankTabCount());
inventoryFlags = BagSlotFlags.None;
if (m_activePlayerData.BankAutoSortDisabled)
inventoryFlags |= BagSlotFlags.DisableAutoSort;
stmt.AddValue(index++, (uint)inventoryFlags);
foreach (uint bankBagSlotFlag in m_activePlayerData.BankBagSlotFlags)
stmt.AddValue(index++, bankBagSlotFlag);
stmt.AddValue(index++, m_activePlayerData.RestInfo[(int)RestTypes.XP].StateID);
stmt.AddValue(index++, m_playerData.PlayerFlags);
@@ -4179,7 +4134,6 @@ namespace Game.Entities
_SaveCustomizations(characterTransaction);
_SaveBGData(characterTransaction);
_SaveInventory(characterTransaction);
_SaveVoidStorage(characterTransaction);
_SaveQuestStatus(characterTransaction);
_SaveDailyQuestStatus(characterTransaction);
_SaveWeeklyQuestStatus(characterTransaction);
@@ -4203,6 +4157,7 @@ namespace Game.Entities
_SaveCurrency(characterTransaction);
_SaveCUFProfiles(characterTransaction);
_SavePlayerData(characterTransaction);
_SaveCharacterBankTabSettings(characterTransaction);
if (_garrison != null)
_garrison.SaveToDB(characterTransaction);
@@ -4717,10 +4672,6 @@ namespace Game.Entities
stmt.AddValue(0, guid);
trans.Append(stmt);
stmt = CharacterDatabase.GetPreparedStatement(CharStatements.DEL_CHAR_VOID_STORAGE_ITEM_BY_CHAR_GUID);
stmt.AddValue(0, guid);
trans.Append(stmt);
stmt = CharacterDatabase.GetPreparedStatement(CharStatements.DEL_CHAR_FISHINGSTEPS);
stmt.AddValue(0, guid);
trans.Append(stmt);
@@ -4755,6 +4706,18 @@ namespace Game.Entities
stmt.AddValue(0, guid);
trans.Append(stmt);
stmt = CharacterDatabase.GetPreparedStatement(CharStatements.DEL_PLAYER_DATA_ELEMENTS_CHARACTER_BY_GUID);
stmt.AddValue(0, guid);
trans.Append(stmt);
stmt = CharacterDatabase.GetPreparedStatement(CharStatements.DEL_PLAYER_DATA_FLAGS_CHARACTER_BY_GUID);
stmt.AddValue(0, guid);
trans.Append(stmt);
stmt = CharacterDatabase.GetPreparedStatement(CharStatements.DEL_CHARACTER_BANK_TAB_SETTINGS);
stmt.AddValue(0, guid);
trans.Append(stmt);
Global.CharacterCacheStorage.DeleteCharacterCacheEntry(playerGuid, name);
break;
}
@@ -41,7 +41,6 @@ namespace Game.Entities
List<ObjectGuid> m_itemSoulboundTradeable = new();
List<ObjectGuid> m_refundableItems = new();
public List<Item> ItemUpdateQueue = new();
VoidStorageItem[] _voidStorageItems = new VoidStorageItem[SharedConst.VoidStorageMaxSlot];
Item[] m_items = new Item[(int)PlayerSlots.Count];
uint m_WeaponProficiency;
uint m_ArmorProficiency;
@@ -490,32 +489,6 @@ namespace Game.Entities
public uint leftduration;
}
public class VoidStorageItem
{
public VoidStorageItem(ulong id, uint entry, ObjectGuid creator, uint randomBonusListId, uint fixedScalingLevel, uint artifactKnowledgeLevel, ItemContext context, List<uint> bonuses)
{
ItemId = id;
ItemEntry = entry;
CreatorGuid = creator;
RandomBonusListId = randomBonusListId;
FixedScalingLevel = fixedScalingLevel;
ArtifactKnowledgeLevel = artifactKnowledgeLevel;
Context = context;
foreach (var value in bonuses)
BonusListIDs.Add(value);
}
public ulong ItemId;
public uint ItemEntry;
public ObjectGuid CreatorGuid;
public uint RandomBonusListId;
public uint FixedScalingLevel;
public uint ArtifactKnowledgeLevel;
public ItemContext Context;
public List<uint> BonusListIDs = new();
}
public class EquipmentSetInfo
{
public EquipmentSetInfo()
+60 -294
View File
@@ -1449,7 +1449,7 @@ namespace Game.Entities
return res; // return latest error if any
}
Item EquipNewItem(ushort pos, uint item, ItemContext context, bool update)
public Item EquipNewItem(ushort pos, uint item, ItemContext context, bool update)
{
Item pItem = Item.CreateItem(item, 1, context, this);
if (pItem != null)
@@ -2055,12 +2055,6 @@ namespace Game.Entities
}
}
if (IsReagentBankPos(dst) && !IsReagentBankUnlocked())
{
SendEquipError(InventoryResult.ReagentBankLocked, pSrcItem, pDstItem);
return;
}
// NOW this is or item move (swap with empty), or swap with another item (including bags in bag possitions)
// or swap empty bag with another empty or not empty bag (with items exchange)
@@ -2094,8 +2088,7 @@ namespace Game.Entities
RemoveItem(srcbag, srcslot, true);
BankItem(dest, pSrcItem, true);
if (!IsReagentBankPos(dst))
ItemRemovedQuestCheck(pSrcItem.GetEntry(), pSrcItem.GetCount());
ItemRemovedQuestCheck(pSrcItem.GetEntry(), pSrcItem.GetCount());
}
else if (IsEquipmentPos(dst))
{
@@ -2738,18 +2731,10 @@ namespace Game.Entities
if (slot >= InventorySlots.ItemStart && slot < InventorySlots.ItemStart + GetInventorySlotCount())
return true;
// bank main slots
if (slot >= InventorySlots.BankItemStart && slot < InventorySlots.BankItemEnd)
return true;
// bank bag slots
if (slot >= InventorySlots.BankBagStart && slot < InventorySlots.BankBagEnd)
return true;
// reagent bank bag slots
if (slot >= InventorySlots.ReagentStart && slot < InventorySlots.ReagentEnd)
return true;
return false;
}
@@ -4080,8 +4065,6 @@ namespace Game.Entities
return true;
if (bag >= InventorySlots.ReagentBagStart && bag < InventorySlots.ReagentBagEnd)
return true;
if (bag == InventorySlots.Bag0 && (slot >= InventorySlots.ReagentStart && slot < InventorySlots.ReagentEnd))
return true;
if (bag == InventorySlots.Bag0 && (slot >= InventorySlots.ChildEquipmentStart && slot < InventorySlots.ChildEquipmentEnd))
return true;
return false;
@@ -4168,10 +4151,6 @@ namespace Game.Entities
// prevent cheating
if ((slot >= InventorySlots.BuyBackStart && slot < InventorySlots.BuyBackEnd) || slot >= (byte)PlayerSlots.End)
return InventoryResult.WrongBagType;
// can't store anything else than crafting reagents in Reagent Bank
if (IsReagentBankPos(bag, slot) && (!IsReagentBankUnlocked() || !pProto.IsCraftingReagent()))
return InventoryResult.WrongBagType;
}
else
{
@@ -4271,14 +4250,10 @@ namespace Game.Entities
public static bool IsBankPos(byte bag, byte slot)
{
if (bag == InventorySlots.Bag0 && (slot >= InventorySlots.BankItemStart && slot < InventorySlots.BankItemEnd))
return true;
if (bag == InventorySlots.Bag0 && (slot >= InventorySlots.BankBagStart && slot < InventorySlots.BankBagEnd))
return true;
if (bag >= InventorySlots.BankBagStart && bag < InventorySlots.BankBagEnd)
return true;
if (bag == InventorySlots.Bag0 && (slot >= InventorySlots.ReagentStart && slot < InventorySlots.ReagentEnd))
return true;
return false;
}
@@ -4293,12 +4268,6 @@ namespace Game.Entities
Cypher.Assert(bag == ItemConst.NullBag && slot == ItemConst.NullSlot); // when reagentBankOnly is true then bag & slot must be hardcoded constants, not client input
}
if ((IsReagentBankPos(bag, slot) || reagentBankOnly) && !IsReagentBankUnlocked())
return InventoryResult.ReagentBankLocked;
byte slotStart = reagentBankOnly ? InventorySlots.ReagentStart : InventorySlots.BankItemStart;
byte slotEnd = reagentBankOnly ? InventorySlots.ReagentEnd : InventorySlots.BankItemEnd;
uint count = pItem.GetCount();
Log.outDebug(LogFilter.Player, "STORAGE: CanBankItem bag = {0}, slot = {1}, item = {2}, count = {3}", bag, slot, pItem.GetEntry(), count);
@@ -4334,7 +4303,7 @@ namespace Game.Entities
if (!pItem.IsBag())
return InventoryResult.WrongSlot;
if (slot - InventorySlots.BagStart >= GetBankBagSlotCount())
if (slot - InventorySlots.BagStart >= GetCharacterBankTabCount())
return InventoryResult.NoBankSlot;
res = CanUseItem(pItem, not_loading);
@@ -4363,12 +4332,7 @@ namespace Game.Entities
{
if (bag == InventorySlots.Bag0)
{
res = CanStoreItem_InInventorySlots(slotStart, slotEnd, dest, pProto, ref count, true, pItem, bag, slot);
if (res != InventoryResult.Ok)
return res;
if (count == 0)
return InventoryResult.Ok;
return InventoryResult.WrongSlot; // TODO: check if INVENTORY_SLOT_BAG_0 condition is neccessary
}
else
{
@@ -4387,12 +4351,7 @@ namespace Game.Entities
// search free slot in bag
if (bag == InventorySlots.Bag0)
{
res = CanStoreItem_InInventorySlots(slotStart, slotEnd, dest, pProto, ref count, false, pItem, bag, slot);
if (res != InventoryResult.Ok)
return res;
if (count == 0)
return InventoryResult.Ok;
return InventoryResult.WrongSlot; // TODO: check if INVENTORY_SLOT_BAG_0 condition is neccessary
}
else
{
@@ -4413,79 +4372,37 @@ namespace Game.Entities
// search stack for merge to
if (pProto.GetMaxStackSize() != 1)
{
// in slots
res = CanStoreItem_InInventorySlots(slotStart, slotEnd, dest, pProto, ref count, true, pItem, bag, slot);
// in regular bags
for (byte i = InventorySlots.BankBagStart; i < InventorySlots.BankBagEnd; i++)
{
// only consider tabs marked as reagents if requested
if (reagentBankOnly && (m_activePlayerData.CharacterBankTabSettings[i - InventorySlots.BankBagStart].DepositFlags & (int)BagSlotFlags.PriorityReagents) == 0)
continue;
res = CanStoreItem_InBag(i, dest, pProto, ref count, true, true, pItem, bag, slot);
if (res != InventoryResult.Ok)
continue;
if (count == 0)
return InventoryResult.Ok;
}
}
// search free space in regular bags
for (byte i = InventorySlots.BankBagStart; i < InventorySlots.BankBagEnd; i++)
{
// only consider tabs marked as reagents if requested
if (reagentBankOnly && (m_activePlayerData.CharacterBankTabSettings[i - InventorySlots.BankBagStart].DepositFlags & (int)BagSlotFlags.PriorityReagents) == 0)
continue;
res = CanStoreItem_InBag(i, dest, pProto, ref count, false, true, pItem, bag, slot);
if (res != InventoryResult.Ok)
return res;
continue;
if (count == 0)
return InventoryResult.Ok;
// don't try to store reagents anywhere else than in Reagent Bank if we're on it
if (!reagentBankOnly)
{
// in special bags
if (pProto.GetBagFamily() != BagFamilyMask.None)
{
for (byte i = InventorySlots.BankBagStart; i < InventorySlots.BankBagEnd; i++)
{
res = CanStoreItem_InBag(i, dest, pProto, ref count, true, false, pItem, bag, slot);
if (res != InventoryResult.Ok)
continue;
if (count == 0)
return InventoryResult.Ok;
}
}
// in regular bags
for (byte i = InventorySlots.BankBagStart; i < InventorySlots.BankBagEnd; i++)
{
res = CanStoreItem_InBag(i, dest, pProto, ref count, true, true, pItem, bag, slot);
if (res != InventoryResult.Ok)
continue;
if (count == 0)
return InventoryResult.Ok;
}
}
}
// search free place in special bag
if (!reagentBankOnly && pProto.GetBagFamily() != BagFamilyMask.None)
{
for (byte i = InventorySlots.BankBagStart; i < InventorySlots.BankBagEnd; i++)
{
res = CanStoreItem_InBag(i, dest, pProto, ref count, false, false, pItem, bag, slot);
if (res != InventoryResult.Ok)
continue;
if (count == 0)
return InventoryResult.Ok;
}
}
// search free space
res = CanStoreItem_InInventorySlots(slotStart, slotEnd, dest, pProto, ref count, false, pItem, bag, slot);
if (res != InventoryResult.Ok)
return res;
if (count == 0)
return InventoryResult.Ok;
// search free space in regular bags (don't try to store reagents anywhere else than in Reagent Bank if we're on it)
if (!reagentBankOnly)
{
for (byte i = InventorySlots.BankBagStart; i < InventorySlots.BankBagEnd; i++)
{
res = CanStoreItem_InBag(i, dest, pProto, ref count, false, true, pItem, bag, slot);
if (res != InventoryResult.Ok)
continue;
if (count == 0)
return InventoryResult.Ok;
}
}
return reagentBankOnly ? InventoryResult.ReagentBankFull : InventoryResult.BankFull;
}
@@ -4530,10 +4447,6 @@ namespace Game.Entities
if (location.HasFlag(ItemSearchLocation.Bank))
{
for (byte i = InventorySlots.BankItemStart; i < InventorySlots.BankItemEnd; ++i)
if (GetItemByPos(InventorySlots.Bag0, i) == null)
++freeSlotCount;
for (byte i = InventorySlots.BankBagStart; i < InventorySlots.BankBagEnd; ++i)
{
Bag bag = GetBagByPos(i);
@@ -4556,25 +4469,11 @@ namespace Game.Entities
if (bag.GetItemByPos(j) == null)
++freeSlotCount;
}
for (byte i = InventorySlots.ReagentStart; i < InventorySlots.ReagentEnd; ++i)
if (GetItemByPos(InventorySlots.Bag0, i) == null)
++freeSlotCount;
}
return freeSlotCount;
}
//Reagent
public static bool IsReagentBankPos(ushort pos) { return IsReagentBankPos((byte)(pos >> 8), (byte)(pos & 255)); }
public static bool IsReagentBankPos(byte bag, byte slot)
{
if (bag == InventorySlots.Bag0 && (slot >= InventorySlots.ReagentStart && slot < InventorySlots.ReagentEnd))
return true;
return false;
}
//Bags
public Bag GetBagByPos(byte bag)
{
@@ -4898,7 +4797,7 @@ namespace Game.Entities
return ItemConst.NullSlot;
}
InventoryResult CanEquipNewItem(byte slot, out ushort dest, uint item, bool swap)
public InventoryResult CanEquipNewItem(byte slot, out ushort dest, uint item, bool swap)
{
dest = 0;
Item pItem = Item.CreateItem(item, 1, ItemContext.None, this);
@@ -5253,6 +5152,14 @@ namespace Game.Entities
//Child
public static bool IsChildEquipmentPos(ushort pos) { return IsChildEquipmentPos((byte)(pos >> 8), (byte)(pos & 255)); }
public static bool IsAccountBankPos(ushort pos) { return IsBankPos((byte)(pos >> 8), (byte)(pos & 255)); }
public static bool IsAccountBankPos(byte bag, byte slot)
{
if (bag >= (int)AccountBankBagSlots.Start && bag < (int)AccountBankBagSlots.End)
return true;
return false;
}
//Artifact
void ApplyArtifactPowers(Item item, bool apply)
{
@@ -5776,34 +5683,6 @@ namespace Game.Entities
}
}
// in bank
for (byte i = InventorySlots.BankItemStart; i < InventorySlots.BankItemEnd; i++)
{
Item item = GetItemByPos(InventorySlots.Bag0, i);
if (item != null)
{
if (item.GetEntry() == itemEntry && !item.IsInTrade())
{
if (item.GetCount() + remcount <= count)
{
remcount += item.GetCount();
DestroyItem(InventorySlots.Bag0, i, update);
if (remcount >= count)
return remcount;
}
else
{
item.SetCount(item.GetCount() - count + remcount);
ItemRemovedQuestCheck(item.GetEntry(), count - remcount);
if (IsInWorld && update)
item.SendUpdateToPlayer(this);
item.SetState(ItemUpdateState.Changed, this);
return count;
}
}
}
}
// in bank bags
for (byte i = InventorySlots.BankBagStart; i < InventorySlots.BankBagEnd; i++)
{
@@ -5872,35 +5751,6 @@ namespace Game.Entities
}
}
for (byte i = InventorySlots.ReagentStart; i < InventorySlots.ReagentEnd; ++i)
{
Item item = GetItemByPos(InventorySlots.Bag0, i);
if (item != null)
{
if (item.GetEntry() == itemEntry && !item.IsInTrade())
{
if (item.GetCount() + remcount <= count)
{
// all keys can be unequipped
remcount += item.GetCount();
DestroyItem(InventorySlots.Bag0, i, update);
if (remcount >= count)
return remcount;
}
else
{
item.SetCount(item.GetCount() - count + remcount);
ItemRemovedQuestCheck(item.GetEntry(), count - remcount);
if (IsInWorld && update)
item.SendUpdateToPlayer(this);
item.SetState(ItemUpdateState.Changed, this);
return count;
}
}
}
}
for (byte i = InventorySlots.ChildEquipmentStart; i < InventorySlots.ChildEquipmentEnd; ++i)
{
Item item = GetItemByPos(InventorySlots.Bag0, i);
@@ -6014,6 +5864,27 @@ namespace Game.Entities
public byte GetBankBagSlotCount() { return m_activePlayerData.NumBankSlots; }
public void SetBankBagSlotCount(byte count) { SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.NumBankSlots), count); }
public byte GetCharacterBankTabCount() { return m_activePlayerData.NumCharacterBankTabs; }
public void SetCharacterBankTabCount(byte count) { SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.NumCharacterBankTabs), count); }
public byte GetAccountBankTabCount() { return m_activePlayerData.NumAccountBankTabs; }
public void SetAccountBankTabCount(byte count) { SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.NumAccountBankTabs), count); }
public void SetCharacterBankTabSettings(uint tabId, string name, string icon, string description, BagSlotFlags depositFlags)
{
var setter = m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.CharacterBankTabSettings, (int)tabId);
SetBankTabSettings(setter, name, icon, description, depositFlags);
}
public void SetAccountBankTabSettings(uint tabId, string name, string icon, string description, BagSlotFlags depositFlags)
{
var setter = m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.AccountBankTabSettings, (int)tabId);
SetBankTabSettings(setter, name, icon, description, depositFlags);
}
public void SetBankTabSettings(BankTabSettings bantTabSettings, string name, string icon, string description, BagSlotFlags depositFlags)
{
SetUpdateFieldValue(bantTabSettings.ModifyValue(bantTabSettings.Name), name);
SetUpdateFieldValue(bantTabSettings.ModifyValue(bantTabSettings.Icon), icon);
SetUpdateFieldValue(bantTabSettings.ModifyValue(bantTabSettings.Description), description);
SetUpdateFieldValue(bantTabSettings.ModifyValue(bantTabSettings.DepositFlags), (int)depositFlags);
}
public bool IsBackpackAutoSortDisabled() { return m_activePlayerData.BackpackAutoSortDisabled; }
public void SetBackpackAutoSortDisabled(bool disabled) { SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.BackpackAutoSortDisabled), disabled); }
@@ -6025,10 +5896,6 @@ namespace Game.Entities
public void SetBagSlotFlag(int bagIndex, BagSlotFlags flags) { SetUpdateFieldFlagValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.BagSlotFlags, bagIndex), (uint)flags); }
public void RemoveBagSlotFlag(int bagIndex, BagSlotFlags flags) { RemoveUpdateFieldFlagValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.BagSlotFlags, bagIndex), (uint)flags); }
public void ReplaceAllBagSlotFlags(int bagIndex, BagSlotFlags flags) { SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.BagSlotFlags, bagIndex), (uint)flags); }
public BagSlotFlags GetBankBagSlotFlags(int bagIndex) { return (BagSlotFlags)m_activePlayerData.BankBagSlotFlags[bagIndex]; }
public void SetBankBagSlotFlag(int bagIndex, BagSlotFlags flags) { SetUpdateFieldFlagValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.BankBagSlotFlags, bagIndex), (uint)flags); }
public void RemoveBankBagSlotFlag(int bagIndex, BagSlotFlags flags) { RemoveUpdateFieldFlagValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.BankBagSlotFlags, bagIndex), (uint)flags); }
public void ReplaceAllBankBagSlotFlags(int bagIndex, BagSlotFlags flags) { SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.BankBagSlotFlags, bagIndex), (uint)flags); }
//Loot
public ObjectGuid GetLootGUID() { return m_playerData.LootTargetGUID; }
@@ -6308,91 +6175,6 @@ namespace Game.Entities
}
}
//Void Storage
public bool IsVoidStorageUnlocked() { return HasPlayerFlag(PlayerFlags.VoidUnlocked); }
public void UnlockVoidStorage() { SetPlayerFlag(PlayerFlags.VoidUnlocked); }
public void LockVoidStorage() { RemovePlayerFlag(PlayerFlags.VoidUnlocked); }
public byte GetNextVoidStorageFreeSlot()
{
for (byte i = 0; i < SharedConst.VoidStorageMaxSlot; ++i)
if (_voidStorageItems[i] == null) // unused item
return i;
return SharedConst.VoidStorageMaxSlot;
}
public byte GetNumOfVoidStorageFreeSlots()
{
byte count = 0;
for (byte i = 0; i < SharedConst.VoidStorageMaxSlot; ++i)
if (_voidStorageItems[i] == null)
count++;
return count;
}
public byte AddVoidStorageItem(VoidStorageItem item)
{
byte slot = GetNextVoidStorageFreeSlot();
if (slot >= SharedConst.VoidStorageMaxSlot)
{
GetSession().SendVoidStorageTransferResult(VoidTransferError.Full);
return 255;
}
_voidStorageItems[slot] = item;
return slot;
}
public void DeleteVoidStorageItem(byte slot)
{
if (slot >= SharedConst.VoidStorageMaxSlot)
{
GetSession().SendVoidStorageTransferResult(VoidTransferError.InternalError1);
return;
}
_voidStorageItems[slot] = null;
}
public bool SwapVoidStorageItem(byte oldSlot, byte newSlot)
{
if (oldSlot >= SharedConst.VoidStorageMaxSlot || newSlot >= SharedConst.VoidStorageMaxSlot || oldSlot == newSlot)
return false;
_voidStorageItems.Swap(newSlot, oldSlot);
return true;
}
public VoidStorageItem GetVoidStorageItem(byte slot)
{
if (slot >= SharedConst.VoidStorageMaxSlot)
{
GetSession().SendVoidStorageTransferResult(VoidTransferError.InternalError1);
return null;
}
return _voidStorageItems[slot];
}
public VoidStorageItem GetVoidStorageItem(ulong id, out byte slot)
{
slot = 0;
for (byte i = 0; i < SharedConst.VoidStorageMaxSlot; ++i)
{
if (_voidStorageItems[i] != null && _voidStorageItems[i].ItemId == id)
{
slot = i;
return _voidStorageItems[i];
}
}
return null;
}
//Misc
void UpdateItemLevelAreaBasedScaling()
{
@@ -6469,14 +6251,6 @@ namespace Game.Entities
if (location.HasAnyFlag(ItemSearchLocation.Bank))
{
for (byte i = InventorySlots.BankItemStart; i < InventorySlots.BankItemEnd; ++i)
{
Item item = GetItemByPos(InventorySlots.Bag0, i);
if (item != null)
if (!callback(item))
return false;
}
for (byte i = InventorySlots.BankBagStart; i < InventorySlots.BankBagEnd; ++i)
{
Bag bag = GetBagByPos(i);
@@ -6509,14 +6283,6 @@ namespace Game.Entities
}
}
}
for (byte i = InventorySlots.ReagentStart; i < InventorySlots.ReagentEnd; ++i)
{
Item item = GetItemByPos(InventorySlots.Bag0, i);
if (item != null)
if (!callback(item))
return false;
}
}
return true;
+23 -1
View File
@@ -365,9 +365,20 @@ namespace Game.Entities
&& ((TraitCombatConfigFlags)(int)traitConfig.CombatConfigFlags & TraitCombatConfigFlags.ActiveForSpec) != TraitCombatConfigFlags.None;
});
if (specTraitConfigIndex >= 0)
SetActiveCombatTraitConfigID(m_activePlayerData.TraitConfigs[specTraitConfigIndex].ID);
{
TraitConfig activeTraitConfig = m_activePlayerData.TraitConfigs[specTraitConfigIndex];
SetActiveCombatTraitConfigID(activeTraitConfig.ID);
int activeSubTree = activeTraitConfig.SubTrees.FindIndexIf(subTree => subTree.Active != 0);
if (activeSubTree >= 0)
SetCurrentCombatTraitConfigSubTreeID(activeTraitConfig.SubTrees[activeSubTree].TraitSubTreeID);
else
SetCurrentCombatTraitConfigSubTreeID(0);
}
else
{
SetActiveCombatTraitConfigID(0);
SetCurrentCombatTraitConfigSubTreeID(0);
}
foreach (var talentInfo in CliDB.TalentStorage.Values)
{
@@ -1136,6 +1147,17 @@ namespace Game.Entities
}
}
if (applyTraits)
{
int activeSubTree = editedConfig.SubTrees.FindIndexIf(subTree => subTree.Active != 0);
if (activeSubTree >= 0)
SetCurrentCombatTraitConfigSubTreeID(editedConfig.SubTrees[activeSubTree].TraitSubTreeID);
else
SetCurrentCombatTraitConfigSubTreeID(0);
Item.UpdateItemSetAuras(this, false);
}
m_traitConfigStates[editedConfigId] = PlayerSpellState.Changed;
}
+3 -18
View File
@@ -143,9 +143,6 @@ namespace Game.Entities
_cinematicMgr.Dispose();
for (byte i = 0; i < SharedConst.VoidStorageMaxSlot; ++i)
_voidStorageItems[i] = null;
ClearResurrectRequestData();
WorldMgr.DecreasePlayerCount();
@@ -599,21 +596,8 @@ namespace Game.Entities
if (target == this)
{
for (byte i = EquipmentSlot.Start; i < InventorySlots.BankBagEnd; ++i)
{
if (m_items[i] == null)
continue;
m_items[i].DestroyForPlayer(target);
}
for (byte i = InventorySlots.ReagentStart; i < InventorySlots.ChildEquipmentEnd; ++i)
{
if (m_items[i] == null)
continue;
m_items[i].DestroyForPlayer(target);
}
foreach (Item item in m_items)
item?.DestroyForPlayer(target);
}
}
public override void CleanupsBeforeDelete(bool finalCleanup = true)
@@ -7697,6 +7681,7 @@ namespace Game.Entities
}
void SetActiveCombatTraitConfigID(int traitConfigId) { SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ActiveCombatTraitConfigID), (uint)traitConfigId); }
void SetCurrentCombatTraitConfigSubTreeID(int traitSubTreeId) { SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.CurrentCombatTraitConfigSubTreeID), traitSubTreeId); }
void InitPrimaryProfessions()
{
+2
View File
@@ -458,6 +458,8 @@ namespace Game.Entities
public ObjectGuid castId;
public SpellInfo Spell;
public SpellCastVisual SpellVisual;
public uint StartTimeMs;
public uint Duration;
public uint damage;
public uint originalDamage;
public SpellSchoolMask schoolMask;
+8 -1
View File
@@ -2458,7 +2458,7 @@ namespace Game.Entities
{
SetAnimTier setAnimTier = new();
setAnimTier.Unit = GetGUID();
setAnimTier.Tier = (int)animTier;
setAnimTier.Tier = (byte)animTier;
SendMessageToSet(setAnimTier, true);
}
}
@@ -2486,6 +2486,13 @@ namespace Game.Entities
RemoveDynamicUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.ChannelObjects), index);
}
public void SetChannelSpellData(uint startTimeMs, uint durationMs)
{
UnitChannel channelData = m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.ChannelData);
SetUpdateFieldValue(ref channelData.StartTimeMs, startTimeMs);
SetUpdateFieldValue(ref channelData.Duration, durationMs);
}
public sbyte GetSpellEmpowerStage() { return m_unitData.SpellEmpowerStage; }
public void SetSpellEmpowerStage(sbyte stage) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.SpellEmpowerStage), stage); }