mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-28 08:06:23 +00:00
Merge branch 'master' into Playerbot
This commit is contained in:
@@ -36,10 +36,10 @@ typedef std::set<WGWorkshop*> Workshop;
|
||||
typedef std::set<Group*> GroupSet;
|
||||
//typedef std::set<WintergraspCapturePoint *> CapturePointSet; unused ?
|
||||
|
||||
const uint32 VehNumWorldState[2] = { 3680, 3490 };
|
||||
const uint32 MaxVehNumWorldState[2] = { 3681, 3491 };
|
||||
const uint32 ClockWorldState[2] = { 3781, 4354 };
|
||||
const uint32 WintergraspFaction[3] = { 1, 2, 35 };
|
||||
uint32 const VehNumWorldState[2] = { 3680, 3490 };
|
||||
uint32 const MaxVehNumWorldState[2] = { 3681, 3491 };
|
||||
uint32 const ClockWorldState[2] = { 3781, 4354 };
|
||||
uint32 const WintergraspFaction[3] = { 1, 2, 35 };
|
||||
float const WintergraspStalkerPos[4] = { 4948.985f, 2937.789f, 550.5172f, 1.815142f };
|
||||
|
||||
enum WintergraspSpells
|
||||
@@ -235,13 +235,14 @@ struct BfWGCoordGY
|
||||
TeamId startcontrol;
|
||||
};
|
||||
|
||||
const uint32 WGQuest[2][6] =
|
||||
uint32 const WGQuest[2][6] =
|
||||
{
|
||||
{ 13186, 13181, 13222, 13538, 13177, 13179 },
|
||||
{ 13185, 13183, 13223, 13539, 13178, 13180 },
|
||||
};
|
||||
|
||||
// 7 in sql, 7 in header
|
||||
const BfWGCoordGY WGGraveyard[BATTLEFIELD_WG_GRAVEYARD_MAX] =
|
||||
BfWGCoordGY const WGGraveyard[BATTLEFIELD_WG_GRAVEYARD_MAX] =
|
||||
{
|
||||
{ 5104.750f, 2300.940f, 368.579f, 0.733038f, 1329, BATTLEFIELD_WG_GY_WORKSHOP_NE, BATTLEFIELD_WG_GOSSIPTEXT_GY_NE, TEAM_NEUTRAL },
|
||||
{ 5099.120f, 3466.036f, 368.484f, 5.317802f, 1330, BATTLEFIELD_WG_GY_WORKSHOP_NW, BATTLEFIELD_WG_GOSSIPTEXT_GY_NW, TEAM_NEUTRAL },
|
||||
@@ -480,12 +481,12 @@ protected:
|
||||
ObjectGuid m_titansRelic;
|
||||
};
|
||||
|
||||
const uint8 WG_MAX_OBJ = 32;
|
||||
const uint8 WG_MAX_TURRET = 16;
|
||||
const uint8 WG_MAX_KEEP_NPC = 45;
|
||||
const uint8 WG_MAX_OUTSIDE_NPC = 14;
|
||||
const uint8 WG_OUTSIDE_ALLIANCE_NPC = 7;
|
||||
const uint8 WG_MAX_TELEPORTER = 12;
|
||||
uint8 const WG_MAX_OBJ = 32;
|
||||
uint8 const WG_MAX_TURRET = 16;
|
||||
uint8 const WG_MAX_KEEP_NPC = 45;
|
||||
uint8 const WG_MAX_OUTSIDE_NPC = 14;
|
||||
uint8 const WG_OUTSIDE_ALLIANCE_NPC = 7;
|
||||
uint8 const WG_MAX_TELEPORTER = 12;
|
||||
|
||||
enum WintergraspGameObjectBuildingType
|
||||
{
|
||||
@@ -614,7 +615,7 @@ struct WintergraspBuildingSpawnData
|
||||
uint32 destroyText;
|
||||
};
|
||||
|
||||
const WintergraspBuildingSpawnData WGGameObjectBuilding[WG_MAX_OBJ] =
|
||||
WintergraspBuildingSpawnData const WGGameObjectBuilding[WG_MAX_OBJ] =
|
||||
{
|
||||
// Wall (Not spawned in db)
|
||||
// Entry WS X Y Z O type NameID
|
||||
@@ -662,28 +663,28 @@ const WintergraspBuildingSpawnData WGGameObjectBuilding[WG_MAX_OBJ] =
|
||||
{ 191810, 3773, 5397.11f, 2841.54f, 425.899f, 3.14159f, BATTLEFIELD_WG_OBJECTTYPE_DOOR_LAST, 0, 0 },
|
||||
};
|
||||
|
||||
const Position WGTurret[WG_MAX_TURRET] =
|
||||
Position const WGTurret[WG_MAX_TURRET] =
|
||||
{
|
||||
{ 5391.19f, 3060.8f, 419.616f, 1.69557f },
|
||||
{ 5266.75f, 2976.5f, 421.067f, 3.20354f },
|
||||
{ 5234.86f, 2948.8f, 420.88f, 1.61311f },
|
||||
{ 5323.05f, 2923.7f, 421.645f, 1.5817f },
|
||||
{ 5363.82f, 2923.87f, 421.709f, 1.60527f },
|
||||
{ 5264.04f, 2861.34f, 421.587f, 3.21142f },
|
||||
{ 5264.68f, 2819.78f, 421.656f, 3.15645f },
|
||||
{ 5322.16f, 2756.69f, 421.646f, 4.69978f },
|
||||
{ 5363.78f, 2756.77f, 421.629f, 4.78226f },
|
||||
{ 5236.2f, 2732.68f, 421.649f, 4.72336f },
|
||||
{ 5265.02f, 2704.63f, 421.7f, 3.12507f },
|
||||
{ 5350.87f, 2616.03f, 421.243f, 4.72729f },
|
||||
{ 5390.95f, 2615.5f, 421.126f, 4.6409f },
|
||||
{ 5148.8f, 2820.24f, 421.621f, 3.16043f },
|
||||
{ 5147.98f, 2861.93f, 421.63f, 3.18792f },
|
||||
{ 5352.22f, 3061.46f, 421.102f, 1.52235f }
|
||||
{ 5391.08251953125f, 3061.720947265625f, 419.699462890625f, 1.570796370506286621f }, // VerifiedBuild 51666
|
||||
{ 5265.90966796875f, 2976.45849609375f, 421.149261474609375f, 2.984513044357299804f }, // VerifiedBuild 51666
|
||||
{ 5234.7861328125f, 2948.731689453125f, 420.96331787109375f, 1.623156189918518066f }, // VerifiedBuild 51666
|
||||
{ 5322.8662109375f, 2923.34326171875f, 421.7288818359375f, 1.466076612472534179f }, // VerifiedBuild 51666
|
||||
{ 5363.857421875f, 2923.782470703125f, 421.79150390625f, 1.48352980613708496f }, // VerifiedBuild 51666
|
||||
{ 5264.23583984375f, 2861.381103515625f, 421.66876220703125f, 3.124139308929443359f }, // VerifiedBuild 51666
|
||||
{ 5264.58544921875f, 2819.799560546875f, 421.738494873046875f, 3.106686115264892578f }, // VerifiedBuild 51666
|
||||
{ 5322.18408203125f, 2756.658203125f, 421.72845458984375f, 4.520402908325195312f }, // VerifiedBuild 51666
|
||||
{ 5363.7685546875f, 2756.81689453125f, 421.712127685546875f, 4.572762489318847656f }, // VerifiedBuild 51666
|
||||
{ 5236.1044921875f, 2732.7265625f, 421.73175048828125f, 4.642575740814208984f }, // VerifiedBuild 51666
|
||||
{ 5264.88720703125f, 2704.792236328125f, 421.782623291015625f, 3.211405754089355468f }, // VerifiedBuild 51666
|
||||
{ 5350.78125f, 2615.8466796875f, 421.32568359375f, 4.747295379638671875f }, // VerifiedBuild 51666
|
||||
{ 5390.77490234375f, 2615.3251953125f, 421.208984375f, 4.607669353485107421f }, // VerifiedBuild 51666
|
||||
{ 5148.5634765625f, 2820.538330078125f, 421.70361328125f, 3.368485450744628906f }, // VerifiedBuild 51666
|
||||
{ 5147.75f, 2861.8681640625f, 421.713165283203125f, 3.141592741012573242f }, // VerifiedBuild 51666
|
||||
{ 5352.21923828125f, 3061.62158203125f, 421.184600830078125f, 1.675516128540039062f } // VerifiedBuild 51666
|
||||
};
|
||||
|
||||
// Here there is all npc keeper spawn point
|
||||
const WintergraspObjectPositionData WGKeepNPC[WG_MAX_KEEP_NPC] =
|
||||
WintergraspObjectPositionData const WGKeepNPC[WG_MAX_KEEP_NPC] =
|
||||
{
|
||||
// X Y Z O horde alliance
|
||||
// North East
|
||||
@@ -742,7 +743,7 @@ const WintergraspObjectPositionData WGKeepNPC[WG_MAX_KEEP_NPC] =
|
||||
{ 5316.770996f, 2619.430176f, 409.027740f, 5.363431f, BATTLEFIELD_WG_NPC_GUARD_H, BATTLEFIELD_WG_NPC_GUARD_A } // Standing Guard
|
||||
};
|
||||
|
||||
const WintergraspObjectPositionData WGOutsideNPC[WG_MAX_OUTSIDE_NPC] =
|
||||
WintergraspObjectPositionData const WGOutsideNPC[WG_MAX_OUTSIDE_NPC] =
|
||||
{
|
||||
{ 5032.04f, 3681.79f, 362.980f, 4.210f, BATTLEFIELD_WG_NPC_VIERON_BLAZEFEATHER, 0 },
|
||||
{ 5020.71f, 3626.19f, 360.150f, 4.640f, BATTLEFIELD_WG_NPC_HOODOO_MASTER_FU_JIN, 0 },
|
||||
@@ -769,7 +770,7 @@ struct WintergraspTeleporterData
|
||||
float o;
|
||||
};
|
||||
|
||||
const WintergraspTeleporterData WGPortalDefenderData[WG_MAX_TELEPORTER] =
|
||||
WintergraspTeleporterData const WGPortalDefenderData[WG_MAX_TELEPORTER] =
|
||||
{
|
||||
// Player teleporter
|
||||
{ 190763, 5153.41f, 2901.35f, 409.191f, -0.069f },
|
||||
@@ -805,9 +806,10 @@ struct WintergraspTowerData
|
||||
};
|
||||
|
||||
uint8 const WG_MAX_ATTACKTOWERS = 3;
|
||||
|
||||
// 192414 : 0 in sql, 1 in header
|
||||
// 192278 : 0 in sql, 3 in header
|
||||
const WintergraspTowerData AttackTowers[WG_MAX_ATTACKTOWERS] =
|
||||
WintergraspTowerData const AttackTowers[WG_MAX_ATTACKTOWERS] =
|
||||
{
|
||||
// West tower
|
||||
{
|
||||
@@ -921,9 +923,9 @@ struct WintergraspTowerCannonData
|
||||
Position TurretTop[5];
|
||||
};
|
||||
|
||||
const uint8 WG_MAX_TOWER_CANNON = 7;
|
||||
uint8 const WG_MAX_TOWER_CANNON = 7;
|
||||
|
||||
const WintergraspTowerCannonData TowerCannon[WG_MAX_TOWER_CANNON] =
|
||||
WintergraspTowerCannonData const TowerCannon[WG_MAX_TOWER_CANNON] =
|
||||
{
|
||||
{
|
||||
190221,
|
||||
@@ -937,8 +939,8 @@ const WintergraspTowerCannonData TowerCannon[WG_MAX_TOWER_CANNON] =
|
||||
},
|
||||
2,
|
||||
{
|
||||
{ 5255.88f, 3047.63f, 438.499f, 3.13677f },
|
||||
{ 5280.9f, 3071.32f, 438.499f, 1.62879f },
|
||||
{ 5254.158203125f, 3047.79541015625f, 438.58270263671875f, 3.141592741012573242f }, // VerifiedBuild 51666
|
||||
{ 5280.96923828125f, 3073.374267578125f, 438.58270263671875f, 1.65806281566619873f }, // VerifiedBuild 51666
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0 },
|
||||
@@ -956,8 +958,8 @@ const WintergraspTowerCannonData TowerCannon[WG_MAX_TOWER_CANNON] =
|
||||
},
|
||||
2,
|
||||
{
|
||||
{ 5138.59f, 2935.16f, 439.845f, 3.11723f },
|
||||
{ 5163.06f, 2959.52f, 439.846f, 1.47258f },
|
||||
{ 5136.8427734375f, 2935.2646484375f, 439.929718017578125f, 3.106686115264892578f }, // VerifiedBuild 51666
|
||||
{ 5163.5087890625f, 2960.82080078125f, 439.929718017578125f, 1.605702877044677734f }, // VerifiedBuild 51666
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0 },
|
||||
@@ -975,8 +977,8 @@ const WintergraspTowerCannonData TowerCannon[WG_MAX_TOWER_CANNON] =
|
||||
},
|
||||
2,
|
||||
{
|
||||
{ 5163.84f, 2723.74f, 439.844f, 4.7115f },
|
||||
{ 5139.69f, 2747.4f, 439.844f, 3.17221f },
|
||||
{ 5163.86279296875f, 2721.9326171875f, 439.927734375f, 4.642575740814208984f }, // VerifiedBuild 51666
|
||||
{ 5137.888671875f, 2747.526611328125f, 439.927734375f, 3.159045934677124023f }, // VerifiedBuild 51666
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0 },
|
||||
@@ -994,8 +996,8 @@ const WintergraspTowerCannonData TowerCannon[WG_MAX_TOWER_CANNON] =
|
||||
},
|
||||
2,
|
||||
{
|
||||
{ 5278.21f, 2607.23f, 439.755f, 4.71944f },
|
||||
{ 5255.01f, 2631.98f, 439.755f, 3.15257f },
|
||||
{ 5278.27001953125f, 2605.745361328125f, 439.837890625f, 4.817108631134033203f }, // VerifiedBuild 51666
|
||||
{ 5252.43603515625f, 2632.1494140625f, 439.837890625f, 3.193952560424804687f }, // VerifiedBuild 51666
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0 },
|
||||
@@ -1003,58 +1005,58 @@ const WintergraspTowerCannonData TowerCannon[WG_MAX_TOWER_CANNON] =
|
||||
},
|
||||
{
|
||||
190356,
|
||||
2,
|
||||
4,
|
||||
{
|
||||
{4537.380371f, 3599.531738f, 402.886993f, 3.998462f},
|
||||
{4581.497559f, 3604.087158f, 402.886963f, 5.651723f},
|
||||
{0, 0, 0, 0},
|
||||
{0, 0, 0, 0},
|
||||
{0, 0, 0, 0},
|
||||
{ 4538.8867f, 3601.4148f, 402.886993f, 3.998462f }, // VerifiedBuild 0
|
||||
{ 4579.6943f, 3605.6738f, 402.886993f, 5.651723f }, // VerifiedBuild 0
|
||||
{ 4534.7104f, 3642.0645f, 402.886993f, 2.455163f }, // VerifiedBuild 0
|
||||
{ 4575.2915f, 3646.363f, 402.886993f, 0.884366f }, // VerifiedBuild 0
|
||||
{ 0, 0, 0, 0 },
|
||||
},
|
||||
2,
|
||||
4,
|
||||
{
|
||||
{4469.448242f, 1966.623779f, 465.647217f, 1.153573f},
|
||||
{4581.895996f, 3626.438477f, 426.539062f, 0.117806f},
|
||||
{0, 0, 0, 0},
|
||||
{0, 0, 0, 0},
|
||||
{0, 0, 0, 0},
|
||||
{ 4583.152f, 3626.6692f, 426.539062f, 0.117806f }, // VerifiedBuild 0
|
||||
{ 4559.8447f, 3598.097f, 426.539062f, 4.780807f }, // VerifiedBuild 0
|
||||
{ 4531.4473f, 3621.2424f, 426.539062f, 3.268910f }, // VerifiedBuild 0
|
||||
{ 4554.4956f, 3649.5588f, 426.539062f, 1.657981f }, // VerifiedBuild 0
|
||||
{ 0, 0, 0, 0 },
|
||||
},
|
||||
},
|
||||
{
|
||||
190357,
|
||||
2,
|
||||
4,
|
||||
{
|
||||
{ 4421.640137f, 2799.935791f, 412.630920f, 5.459298f },
|
||||
{ 4420.263184f, 2845.340332f, 412.630951f, 0.742197f },
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 4419.017578125f, 2802.616455078125f, 412.71405029296875f, 5.550147056579589843f }, // VerifiedBuild 51666
|
||||
{ 4418.22314453125f, 2843.650146484375f, 412.71405029296875f, 0.820304751396179199f }, // VerifiedBuild 51666
|
||||
{ 4377.2593f, 2842.6213f, 412.71405029296875f, 2.376623f }, // VerifiedBuild 0
|
||||
{ 4377.91943359375f, 2801.678955078125f, 412.71405029296875f, 3.979350566864013671f }, // VerifiedBuild 51666
|
||||
{ 0, 0, 0, 0 },
|
||||
},
|
||||
3,
|
||||
4,
|
||||
{
|
||||
{ 4423.430664f, 2822.762939f, 436.283142f, 6.223487f },
|
||||
{ 4397.825684f, 2847.629639f, 436.283325f, 1.579430f },
|
||||
{ 4398.814941f, 2797.266357f, 436.283051f, 4.703747f },
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 4424.33642578125f, 2822.9638671875f, 436.36627197265625f, 6.161012172698974609f }, // VerifiedBuild 51666
|
||||
{ 4397.763f, 2848.164f, 436.36627197265625f, 1.579430f }, // VerifiedBuild 0
|
||||
{ 4398.64404296875f, 2796.262939453125f, 436.36627197265625f, 4.78220224380493164f }, // VerifiedBuild 51666
|
||||
{ 4372.1884765625f, 2822.0888671875f, 436.36627197265625f, 3.263765573501586914f }, // VerifiedBuild 51666
|
||||
{ 0, 0, 0, 0 },
|
||||
},
|
||||
},
|
||||
{
|
||||
190358,
|
||||
2,
|
||||
4,
|
||||
{
|
||||
{ 4448.138184f, 1974.998779f, 441.995911f, 1.967238f },
|
||||
{ 4486.3257f, 1954.6545f, 442.0783f, 0.349065840244293212f },
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 4448.80712890625f, 1971.795166015625f, 442.07830810546875f, 2.0245819091796875f }, // VerifiedBuild 51666
|
||||
{ 4486.32568359375f, 1954.654541015625f, 442.07830810546875f, 0.349065840244293212f }, // VerifiedBuild 51666
|
||||
{ 4469.431640625f, 1917.064208984375f, 442.07830810546875f, 5.078907966613769531f }, // VerifiedBuild 51666
|
||||
{ 4431.83056640625f, 1934.13720703125f, 442.07830810546875f, 3.647738218307495117f }, // VerifiedBuild 51666
|
||||
{ 0, 0, 0, 0 },
|
||||
},
|
||||
2,
|
||||
4,
|
||||
{
|
||||
{ 4469.448242f, 1966.623779f, 465.647217f, 1.153573f },
|
||||
{ 4481.996582f, 1933.658325f, 465.647186f, 5.873029f },
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 4469.7724609375f, 1967.2432861328125f, 465.73052978515625f, 1.221730470657348632f }, // VerifiedBuild 51666
|
||||
{ 4482.228515625f, 1933.906494140625f, 465.73052978515625f, 5.951572895050048828f }, // VerifiedBuild 51666
|
||||
{ 4436.2080078125f, 1954.7906494140625f, 465.73052978515625f, 2.740166902542114257f }, // VerifiedBuild 51666
|
||||
{ 4448.705078125f, 1921.1121826171875f, 465.73052978515625f, 4.398229598999023437f }, // VerifiedBuild 51666
|
||||
{ 0, 0, 0, 0 },
|
||||
},
|
||||
},
|
||||
@@ -1074,7 +1076,7 @@ struct WGWorkshopData
|
||||
uint8 takenText;
|
||||
};
|
||||
|
||||
const WGWorkshopData WorkshopsData[WG_MAX_WORKSHOP] =
|
||||
WGWorkshopData const WorkshopsData[WG_MAX_WORKSHOP] =
|
||||
{
|
||||
// NE
|
||||
{BATTLEFIELD_WG_WORKSHOP_NE, WORLDSTATE_WORKSHOP_NE, BATTLEFIELD_WG_TEXT_WORKSHOP_NE_ATTACK, BATTLEFIELD_WG_TEXT_WORKSHOP_NE_TAKEN},
|
||||
|
||||
@@ -2738,17 +2738,17 @@ bool WorldObject::GetClosePoint(float& x, float& y, float& z, float size, float
|
||||
return true;
|
||||
}
|
||||
|
||||
Position WorldObject::GetNearPosition(float dist, float angle, bool disableWarning)
|
||||
Position WorldObject::GetNearPosition(float dist, float angle)
|
||||
{
|
||||
Position pos = GetPosition();
|
||||
MovePosition(pos, dist, angle, disableWarning);
|
||||
MovePosition(pos, dist, angle);
|
||||
return pos;
|
||||
}
|
||||
|
||||
Position WorldObject::GetRandomNearPosition(float radius, bool disableWarning)
|
||||
Position WorldObject::GetRandomNearPosition(float radius)
|
||||
{
|
||||
Position pos = GetPosition();
|
||||
MovePosition(pos, radius * (float) rand_norm(), (float) rand_norm() * static_cast<float>(2 * M_PI), disableWarning);
|
||||
MovePosition(pos, radius * (float) rand_norm(), (float) rand_norm() * static_cast<float>(2 * M_PI));
|
||||
return pos;
|
||||
}
|
||||
|
||||
@@ -2786,7 +2786,7 @@ void WorldObject::GetChargeContactPoint(WorldObject const* obj, float& x, float&
|
||||
return (m_valuesCount > UNIT_FIELD_COMBATREACH) ? m_floatValues[UNIT_FIELD_COMBATREACH] : DEFAULT_WORLD_OBJECT_SIZE * GetObjectScale();
|
||||
}
|
||||
|
||||
void WorldObject::MovePosition(Position& pos, float dist, float angle, bool disableWarning)
|
||||
void WorldObject::MovePosition(Position& pos, float dist, float angle)
|
||||
{
|
||||
angle += GetOrientation();
|
||||
float destx, desty, destz, ground, floor;
|
||||
@@ -2796,9 +2796,7 @@ void WorldObject::MovePosition(Position& pos, float dist, float angle, bool disa
|
||||
// Prevent invalid coordinates here, position is unchanged
|
||||
if (!Acore::IsValidMapCoord(destx, desty))
|
||||
{
|
||||
if (!disableWarning)
|
||||
LOG_FATAL("entities.object", "WorldObject::MovePosition invalid coordinates X: {} and Y: {} were passed!", destx, desty);
|
||||
|
||||
LOG_FATAL("entities.object", "WorldObject::MovePosition invalid coordinates X: {} and Y: {} were passed!", destx, desty);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -425,13 +425,13 @@ public:
|
||||
void GetNearPoint(WorldObject const* searcher, float& x, float& y, float& z, float searcher_size, float distance2d, float absAngle, float controlZ = 0, Position const* startPos = nullptr) const;
|
||||
void GetVoidClosePoint(float& x, float& y, float& z, float size, float distance2d = 0, float relAngle = 0, float controlZ = 0) const;
|
||||
bool GetClosePoint(float& x, float& y, float& z, float size, float distance2d = 0, float angle = 0, WorldObject const* forWho = nullptr, bool force = false) const;
|
||||
void MovePosition(Position& pos, float dist, float angle, bool disableWarning = false);
|
||||
Position GetNearPosition(float dist, float angle, bool disableWarning = false);
|
||||
void MovePosition(Position& pos, float dist, float angle);
|
||||
Position GetNearPosition(float dist, float angle);
|
||||
void MovePositionToFirstCollision(Position& pos, float dist, float angle);
|
||||
Position GetFirstCollisionPosition(float startX, float startY, float startZ, float destX, float destY);
|
||||
Position GetFirstCollisionPosition(float destX, float destY, float destZ);
|
||||
Position GetFirstCollisionPosition(float dist, float angle);
|
||||
Position GetRandomNearPosition(float radius, bool disableWarning = false);
|
||||
Position GetRandomNearPosition(float radius);
|
||||
|
||||
void GetContactPoint(WorldObject const* obj, float& x, float& y, float& z, float distance2d = CONTACT_DISTANCE) const;
|
||||
void GetChargeContactPoint(WorldObject const* obj, float& x, float& y, float& z, float distance2d = CONTACT_DISTANCE) const;
|
||||
@@ -611,6 +611,10 @@ public:
|
||||
[[nodiscard]] virtual float GetStationaryZ() const { return GetPositionZ(); }
|
||||
[[nodiscard]] virtual float GetStationaryO() const { return GetOrientation(); }
|
||||
|
||||
[[nodiscard]] float GetMapWaterOrGroundLevel(Position pos, float* ground = nullptr) const
|
||||
{
|
||||
return GetMapWaterOrGroundLevel(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), ground);
|
||||
};
|
||||
[[nodiscard]] float GetMapWaterOrGroundLevel(float x, float y, float z, float* ground = nullptr) const;
|
||||
[[nodiscard]] float GetMapHeight(float x, float y, float z, bool vmap = true, float distanceToSearch = 50.0f) const; // DEFAULT_HEIGHT_SEARCH in map.h
|
||||
|
||||
|
||||
@@ -4809,6 +4809,12 @@ void SpellMgr::LoadSpellInfoCorrections()
|
||||
spellInfo->AttributesEx5 |= SPELL_ATTR5_ALLOW_ACTION_DURING_CHANNEL;
|
||||
});
|
||||
|
||||
// Fatal Attraction
|
||||
ApplySpellFix({ 40869 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo(TARGET_DEST_CASTER); // target set by script
|
||||
});
|
||||
|
||||
// Fatal Attraction
|
||||
ApplySpellFix({ 40870 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "WardenModuleMac.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
#include <openssl/crypto.h>
|
||||
|
||||
WardenMac::WardenMac() : Warden()
|
||||
{
|
||||
@@ -152,8 +153,8 @@ void WardenMac::HandleHashResult(ByteBuffer& buff)
|
||||
|
||||
//const uint8 validHash[20] = { 0x56, 0x8C, 0x05, 0x4C, 0x78, 0x1A, 0x97, 0x2A, 0x60, 0x37, 0xA2, 0x29, 0x0C, 0x22, 0xB5, 0x25, 0x71, 0xA0, 0x6F, 0x4E };
|
||||
|
||||
// Verify key
|
||||
if (memcmp(buff.contents() + 1, sha1.GetDigest().data(), 20) != 0)
|
||||
// Verify key using constant-time comparison
|
||||
if (CRYPTO_memcmp(buff.contents() + 1, sha1.GetDigest().data(), 20) != 0)
|
||||
{
|
||||
LOG_DEBUG("warden", "Request hash reply: failed");
|
||||
ApplyPenalty(0, "Request hash reply: failed");
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "World.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
#include <openssl/crypto.h>
|
||||
|
||||
// GUILD is the shortest string that has no client validation (RAID only sends if in a raid group)
|
||||
static constexpr char _luaEvalPrefix[] = "local S,T,R=SendAddonMessage,function()";
|
||||
@@ -230,8 +231,8 @@ void WardenWin::HandleHashResult(ByteBuffer& buff)
|
||||
{
|
||||
buff.rpos(buff.wpos());
|
||||
|
||||
// Verify key
|
||||
if (memcmp(buff.contents() + 1, Module.ClientKeySeedHash, Acore::Crypto::Constants::SHA1_DIGEST_LENGTH_BYTES) != 0)
|
||||
// Verify key using constant-time comparison
|
||||
if (CRYPTO_memcmp(buff.contents() + 1, Module.ClientKeySeedHash, Acore::Crypto::Constants::SHA1_DIGEST_LENGTH_BYTES) != 0)
|
||||
{
|
||||
LOG_DEBUG("warden", "Request hash reply: failed");
|
||||
ApplyPenalty(0, "Request hash reply: failed");
|
||||
@@ -650,7 +651,7 @@ void WardenWin::HandleData(ByteBuffer& buff)
|
||||
WardenCheckResult const* rs = sWardenCheckMgr->GetWardenResultById(checkId);
|
||||
|
||||
std::vector<uint8> result = rs->Result.ToByteVector(0, false);
|
||||
if (memcmp(buff.contents() + buff.rpos(), result.data(), rd->Length) != 0)
|
||||
if (CRYPTO_memcmp(buff.contents() + buff.rpos(), result.data(), rd->Length) != 0)
|
||||
{
|
||||
LOG_DEBUG("warden", "RESULT MEM_CHECK fail CheckId {} account Id {}", checkId, _session->GetAccountId());
|
||||
checkFailed = checkId;
|
||||
@@ -668,7 +669,7 @@ void WardenWin::HandleData(ByteBuffer& buff)
|
||||
case MODULE_CHECK:
|
||||
{
|
||||
uint8 const byte = 0xE9;
|
||||
if (memcmp(buff.contents() + buff.rpos(), &byte, sizeof(uint8)) != 0)
|
||||
if (CRYPTO_memcmp(buff.contents() + buff.rpos(), &byte, sizeof(uint8)) != 0)
|
||||
{
|
||||
if (type == PAGE_CHECK_A || type == PAGE_CHECK_B)
|
||||
{
|
||||
@@ -731,7 +732,7 @@ void WardenWin::HandleData(ByteBuffer& buff)
|
||||
}
|
||||
|
||||
WardenCheckResult const* rs = sWardenCheckMgr->GetWardenResultById(checkId);
|
||||
if (memcmp(buff.contents() + buff.rpos(), rs->Result.ToByteArray<20>(false).data(), Acore::Crypto::Constants::SHA1_DIGEST_LENGTH_BYTES) != 0) // SHA1
|
||||
if (CRYPTO_memcmp(buff.contents() + buff.rpos(), rs->Result.ToByteArray<20>(false).data(), Acore::Crypto::Constants::SHA1_DIGEST_LENGTH_BYTES) != 0)
|
||||
{
|
||||
LOG_DEBUG("warden", "RESULT MPQ_CHECK fail, CheckId {} account Id {}", checkId, _session->GetAccountId());
|
||||
checkFailed = checkId;
|
||||
|
||||
@@ -1310,6 +1310,7 @@ void World::SetInitialWorldSettings()
|
||||
!MapMgr::ExistMapAndVMap(530, 10349.6f, -6357.29f) ||
|
||||
!MapMgr::ExistMapAndVMap(530, -3961.64f, -13931.2f))))
|
||||
{
|
||||
LOG_ERROR("server.loading", "Failed to find map files for starting areas");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1456,14 +1456,10 @@ public:
|
||||
{
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(7355);
|
||||
if (!spellInfo)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Player* caster = handler->GetSession()->GetPlayer())
|
||||
{
|
||||
Spell::SendCastResult(caster, spellInfo, 0, SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW);
|
||||
}
|
||||
if (player)
|
||||
Spell::SendCastResult(player, spellInfo, 0, SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -146,9 +146,9 @@ struct boss_sacrolash : public BossAI
|
||||
DoCastVictim(SPELL_CONFOUNDING_BLOW);
|
||||
}, 20s, 25s);
|
||||
|
||||
ScheduleTimedEvent(20s, [&] {
|
||||
me->SummonCreature(NPC_SHADOW_IMAGE, me->GetPosition(), TEMPSUMMON_TIMED_DESPAWN, 12000);
|
||||
}, 6s);
|
||||
ScheduleTimedEvent(8s, 16s, [&] {
|
||||
me->SummonCreature(NPC_SHADOW_IMAGE, me->GetPosition(), TEMPSUMMON_TIMED_DESPAWN, 10000);
|
||||
}, 8s, 12s);
|
||||
|
||||
scheduler.Schedule(36s, GROUP_SPECIAL_ABILITY, [this](TaskContext context) {
|
||||
Unit* target = SelectTarget(SelectTargetMethod::MaxThreat, 1, 100.0f);
|
||||
@@ -253,9 +253,9 @@ struct boss_alythess : public BossAI
|
||||
DoCastVictim(SPELL_BLAZE);
|
||||
}, 3800ms);
|
||||
|
||||
ScheduleTimedEvent(15s, [&] {
|
||||
ScheduleTimedEvent(21s, 34s, [&] {
|
||||
DoCastSelf(SPELL_PYROGENICS);
|
||||
}, 15s);
|
||||
}, 21s, 34s);
|
||||
|
||||
ScheduleTimedEvent(10s, 15s, [&] {
|
||||
me->CastCustomSpell(SPELL_FLAME_SEAR, SPELLVALUE_MAX_TARGETS, urand(4, 5), me, TRIGGERED_NONE);
|
||||
|
||||
@@ -107,7 +107,8 @@ const Position RightSideLanes[3] =
|
||||
|
||||
const Position RightSide = { 1458.5555f, 502.1995f, 59.899513f, 1.605702f };
|
||||
const Position LeftSide = { 1469.0642f, 729.5854f, 59.823853f, 4.6774f };
|
||||
const Position LandingPos = { 1476.77f, 665.094f, 20.6423f };
|
||||
const Position LandingRightPos = { 1476.77f, 665.094f, 20.6423f };
|
||||
const Position LandingLeftPos = { 1469.93f, 557.009f, 22.631699f };
|
||||
|
||||
class CorruptTriggers : public BasicEvent
|
||||
{
|
||||
@@ -212,18 +213,18 @@ struct boss_felmyst : public BossAI
|
||||
DoCastVictim(SPELL_CLEAVE);
|
||||
}, 7500ms);
|
||||
|
||||
ScheduleTimedEvent(12s, [&] {
|
||||
DoCastVictim(SPELL_CORROSION);
|
||||
}, 20s);
|
||||
|
||||
ScheduleTimedEvent(18s, [&] {
|
||||
ScheduleTimedEvent(13s, 30s, [&] {
|
||||
Talk(YELL_BREATH);
|
||||
DoCastSelf(SPELL_GAS_NOVA);
|
||||
}, 20s);
|
||||
DoCastVictim(SPELL_CORROSION);
|
||||
}, 30s, 39s);
|
||||
|
||||
ScheduleTimedEvent(25s, [&] {
|
||||
ScheduleTimedEvent(18s, 43s, [&] {
|
||||
DoCastSelf(SPELL_GAS_NOVA);
|
||||
}, 18s, 43s);
|
||||
|
||||
ScheduleTimedEvent(26s, 53s, [&] {
|
||||
DoCastRandomTarget(SPELL_ENCAPSULATE_CHANNEL, 0, 50.0f);
|
||||
}, 25s);
|
||||
}, 26s, 53s);
|
||||
|
||||
me->m_Events.AddEventAtOffset([&] {
|
||||
Talk(YELL_TAKEOFF);
|
||||
@@ -285,21 +286,25 @@ struct boss_felmyst : public BossAI
|
||||
|
||||
scheduler.Schedule(27s, GROUP_BREATH, [this](TaskContext)
|
||||
{
|
||||
me->GetMotionMaster()->MovePoint(POINT_AIR_UP, RightSide);
|
||||
if (me->GetDistance(LeftSide) < me->GetDistance(RightSide))
|
||||
me->GetMotionMaster()->MovePoint(POINT_AIR_UP, LeftSide);
|
||||
else
|
||||
me->GetMotionMaster()->MovePoint(POINT_AIR_UP, RightSide);
|
||||
});
|
||||
break;
|
||||
case POINT_AIR_UP:
|
||||
me->m_Events.AddEventAtOffset([&] {
|
||||
bool isRightSide = me->FindNearestCreature(NPC_WORLD_TRIGGER_RIGHT, 30.0f);
|
||||
if (_strafeCount >= 3)
|
||||
{
|
||||
_strafeCount = 0;
|
||||
me->GetMotionMaster()->MoveLand(POINT_GROUND, LandingPos);
|
||||
me->GetMotionMaster()->MoveLand(POINT_GROUND, isRightSide ? LandingRightPos : LandingLeftPos);
|
||||
return;
|
||||
}
|
||||
|
||||
++_strafeCount;
|
||||
_currentLane = urand(0, 2);
|
||||
if (me->FindNearestCreature(NPC_WORLD_TRIGGER_RIGHT, 30.0f))
|
||||
if (isRightSide)
|
||||
me->GetMotionMaster()->MovePoint(POINT_LANE, RightSideLanes[_currentLane], false);
|
||||
else
|
||||
me->GetMotionMaster()->MovePoint(POINT_LANE, LeftSideLanes[_currentLane], false);
|
||||
|
||||
@@ -61,7 +61,7 @@ struct boss_muru : public BossAI
|
||||
void Reset() override
|
||||
{
|
||||
BossAI::Reset();
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetVisible(true);
|
||||
me->m_Events.KillAllEvents(false);
|
||||
@@ -352,6 +352,29 @@ class spell_entropius_negative_energy_periodic : public AuraScript
|
||||
}
|
||||
};
|
||||
|
||||
class spell_muru_blackhole : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_muru_blackhole);
|
||||
|
||||
void ChangeSummonPos(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
if (!GetCaster())
|
||||
return;
|
||||
|
||||
WorldLocation summonPos = *GetExplTargetDest();
|
||||
float destZ = summonPos.GetPositionZ() - GetCaster()->GetMapWaterOrGroundLevel(GetCaster()->GetPosition());
|
||||
Position offset = { 0.0f, 0.0f, -destZ, 0.0f};
|
||||
summonPos.RelocateOffset(offset);
|
||||
SetExplTargetDest(summonPos);
|
||||
GetHitDest()->RelocateOffset(offset);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHit += SpellEffectFn(spell_muru_blackhole::ChangeSummonPos, EFFECT_0, SPELL_EFFECT_SUMMON);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_muru()
|
||||
{
|
||||
RegisterSunwellPlateauCreatureAI(boss_muru);
|
||||
@@ -363,4 +386,5 @@ void AddSC_boss_muru()
|
||||
RegisterSpellScript(spell_entropius_void_zone_visual_aura);
|
||||
RegisterSpellScript(spell_entropius_black_hole_effect);
|
||||
RegisterSpellScript(spell_entropius_negative_energy_periodic);
|
||||
RegisterSpellScript(spell_muru_blackhole);
|
||||
}
|
||||
|
||||
@@ -250,9 +250,44 @@ private:
|
||||
ObjectGuid _protectorGUID;
|
||||
};
|
||||
|
||||
enum SunwellTeleportSpells
|
||||
{
|
||||
SPELL_TELEPORT_TO_APEX_POINT = 46881,
|
||||
SPELL_TELEPORT_TO_WITCHS_SANCTUM = 46883,
|
||||
SPELL_TELEPORT_TO_SUNWELL_PLATEAU = 46884,
|
||||
};
|
||||
class spell_sunwell_teleport : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_sunwell_teleport);
|
||||
public:
|
||||
spell_sunwell_teleport(uint32 triggeredSpellId) : SpellScript(), _triggeredSpellId(triggeredSpellId) { }
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ _triggeredSpellId });
|
||||
}
|
||||
|
||||
void HandleScript(SpellEffIndex effIndex)
|
||||
{
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
if (Player* target = GetHitPlayer())
|
||||
target->CastSpell(target, _triggeredSpellId, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_sunwell_teleport::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
private:
|
||||
uint32 _triggeredSpellId;
|
||||
};
|
||||
|
||||
void AddSC_instance_sunwell_plateau()
|
||||
{
|
||||
new instance_sunwell_plateau();
|
||||
RegisterSpellScript(spell_cataclysm_breath);
|
||||
RegisterSunwellPlateauCreatureAI(npc_sunblade_scout);
|
||||
RegisterSpellScriptWithArgs(spell_sunwell_teleport, "spell_teleport_to_apex_point", SPELL_TELEPORT_TO_APEX_POINT);
|
||||
RegisterSpellScriptWithArgs(spell_sunwell_teleport, "spell_teleport_to_witchs_sanctum", SPELL_TELEPORT_TO_WITCHS_SANCTUM);
|
||||
RegisterSpellScriptWithArgs(spell_sunwell_teleport, "spell_teleport_to_sunwell_plateau", SPELL_TELEPORT_TO_SUNWELL_PLATEAU);
|
||||
}
|
||||
|
||||
@@ -160,9 +160,10 @@ static PlayerAbilityStruct PlayerAbility[13][3] =
|
||||
{
|
||||
// 0 UNK class (should never be set)
|
||||
{
|
||||
{ 0, ABILITY_TARGET_SELF, 0ms},
|
||||
{ 0, ABILITY_TARGET_SELF, 0ms},
|
||||
{ 0, ABILITY_TARGET_SELF, 0ms}
|
||||
// Warrior as fallback behavior if for some reason UNK class
|
||||
{ SPELL_WR_SPELL_REFLECT, ABILITY_TARGET_SELF, 10000ms },
|
||||
{ SPELL_WR_WHIRLWIND, ABILITY_TARGET_SELF, 10000ms },
|
||||
{ SPELL_WR_MORTAL_STRIKE, ABILITY_TARGET_VICTIM, 6000ms }
|
||||
},
|
||||
// 1 warrior
|
||||
{ { SPELL_WR_SPELL_REFLECT, ABILITY_TARGET_SELF, 10000ms },
|
||||
@@ -212,9 +213,10 @@ static PlayerAbilityStruct PlayerAbility[13][3] =
|
||||
},
|
||||
// 10 UNK class (should never be set)
|
||||
{
|
||||
{ 0, ABILITY_TARGET_SELF, 0ms},
|
||||
{ 0, ABILITY_TARGET_SELF, 0ms},
|
||||
{ 0, ABILITY_TARGET_SELF, 0ms}
|
||||
// Warrior as fallback behavior if for some reason UNK class
|
||||
{ SPELL_WR_SPELL_REFLECT, ABILITY_TARGET_SELF, 10000ms },
|
||||
{ SPELL_WR_WHIRLWIND, ABILITY_TARGET_SELF, 10000ms },
|
||||
{ SPELL_WR_MORTAL_STRIKE, ABILITY_TARGET_VICTIM, 6000ms }
|
||||
},
|
||||
// 11 druid
|
||||
{ { SPELL_DR_LIFEBLOOM, ABILITY_TARGET_HEAL, 10000ms },
|
||||
|
||||
@@ -39,6 +39,7 @@ enum ForestFrog
|
||||
SPELL_SUMMON_AMANI_CHARM_CHEST_2 = 43756, // Amani Charm Box (186734)
|
||||
SPELL_SUMMON_MONEY_BAG = 43774, // Money Bag (186736)
|
||||
SPELL_STEALTH_ = 34189,
|
||||
SPELL_FIXATE = 43360,
|
||||
|
||||
// Creatures
|
||||
NPC_FOREST_FROG = 24396,
|
||||
@@ -884,6 +885,26 @@ class spell_summon_amanishi_sentries : public SpellScript
|
||||
}
|
||||
};
|
||||
|
||||
class spell_call_of_the_beast : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_call_of_the_beast);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_FIXATE });
|
||||
}
|
||||
|
||||
void HandleEffect(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
GetHitUnit()->CastSpell(GetHitUnit(), SPELL_FIXATE, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_call_of_the_beast::HandleEffect, EFFECT_0, SPELL_EFFECT_APPLY_AURA);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_zulaman()
|
||||
{
|
||||
RegisterZulAmanCreatureAI(npc_forest_frog);
|
||||
@@ -896,4 +917,5 @@ void AddSC_zulaman()
|
||||
RegisterZulAmanCreatureAI(npc_amanishi_scout);
|
||||
RegisterSpellScript(spell_alert_drums);
|
||||
RegisterSpellScript(spell_summon_amanishi_sentries);
|
||||
RegisterSpellScript(spell_call_of_the_beast);
|
||||
}
|
||||
|
||||
@@ -102,7 +102,11 @@ struct boss_mother_shahraz : public BossAI
|
||||
|
||||
ScheduleTimedEvent(50s, [&] {
|
||||
Talk(SAY_SPELL);
|
||||
me->CastCustomSpell(SPELL_FATAL_ATTRACTION, SPELLVALUE_MAX_TARGETS, 3, me, false);
|
||||
// weights for 1, 2, or 3 targets
|
||||
static double chances[] = {5.0, 15.0, 80.0};
|
||||
uint32 selectedIndex = urandweighted(3, chances);
|
||||
uint32 numTargets = selectedIndex + 1;
|
||||
me->CastCustomSpell(SPELL_FATAL_ATTRACTION, SPELLVALUE_MAX_TARGETS, numTargets, me, false);
|
||||
}, 1min);
|
||||
|
||||
me->m_Events.AddEventAtOffset([&] {
|
||||
@@ -197,26 +201,91 @@ class spell_mother_shahraz_saber_lash_aura : public AuraScript
|
||||
}
|
||||
};
|
||||
|
||||
const Position validTeleportStairsPos[9] =
|
||||
constexpr float minTeleportDistSq = 30.f * 30.f;
|
||||
constexpr float maxTeleportDistSq = 50.f * 50.f;
|
||||
|
||||
const Position teleportPositions[79] =
|
||||
{
|
||||
//Platform teleports
|
||||
|
||||
{945.00f, 149.17f, 197.07483},
|
||||
{956.92f, 153.20f, 197.07483},
|
||||
{933.69f, 154.15f, 197.07483},
|
||||
|
||||
//Floor teleports
|
||||
|
||||
{966.87f, 184.45f, 192.84f},
|
||||
{927.22f, 187.04f, 192.84f},
|
||||
{922.54f, 110.09f, 192.84f},
|
||||
{958.01f, 110.47f, 192.84f},
|
||||
{939.95f, 108.29f, 192.84f},
|
||||
{945.68f, 205.74f, 192.84f}
|
||||
};
|
||||
|
||||
constexpr float minTeleportDist = 30.f;
|
||||
constexpr float maxTeleportDist = 50.f;
|
||||
{918.581, 110.065, 192.849},
|
||||
{943.493, 108.279, 192.847},
|
||||
{964.335, 109.774, 192.836},
|
||||
{971.987, 148.678, 192.820},
|
||||
{956.107, 146.804, 197.075},
|
||||
{934.990, 144.492, 197.075},
|
||||
{916.477, 143.932, 192.829},
|
||||
{921.147, 167.942, 192.827},
|
||||
{925.678, 184.302, 192.838},
|
||||
{940.993, 181.637, 192.463},
|
||||
{948.525, 193.635, 191.906},
|
||||
{965.403, 179.717, 192.832},
|
||||
{966.440, 197.428, 192.840},
|
||||
{959.519, 218.769, 192.846},
|
||||
{943.849, 208.796, 191.209},
|
||||
{931.741, 199.204, 192.846},
|
||||
{931.808, 220.284, 192.845},
|
||||
{945.203, 232.269, 191.208},
|
||||
{966.960, 236.315, 192.842},
|
||||
{966.079, 258.634, 192.822},
|
||||
{945.193, 252.556, 191.208},
|
||||
{924.433, 235.585, 192.842},
|
||||
{919.422, 250.186, 192.820},
|
||||
{923.024, 271.408, 192.368},
|
||||
{928.982, 283.581, 192.368},
|
||||
{923.807, 302.435, 192.854},
|
||||
{925.547, 316.368, 192.830},
|
||||
{922.124, 330.724, 192.842},
|
||||
{926.061, 343.538, 192.848},
|
||||
{947.211, 351.582, 191.208},
|
||||
{965.287, 351.110, 192.850},
|
||||
{964.311, 340.715, 192.850},
|
||||
{971.435, 328.932, 192.850},
|
||||
{979.385, 318.413, 192.843},
|
||||
{962.361, 304.283, 192.839},
|
||||
{964.359, 287.723, 192.835},
|
||||
{961.600, 270.791, 192.829},
|
||||
{945.802, 267.542, 191.208},
|
||||
{948.130, 284.002, 191.208},
|
||||
{940.823, 299.090, 191.208},
|
||||
{949.039, 314.410, 191.208},
|
||||
{941.133, 334.733, 191.208},
|
||||
{956.045, 329.034, 192.834},
|
||||
{956.605, 247.336, 192.828},
|
||||
{931.937, 244.108, 192.819},
|
||||
{938.510, 158.778, 197.075},
|
||||
{928.364, 208.923, 192.847},
|
||||
{962.436, 205.330, 192.847},
|
||||
{955.670, 346.279, 192.849},
|
||||
{931.286, 324.910, 192.819},
|
||||
{962.375, 317.202, 192.838},
|
||||
{956.159, 292.589, 192.834},
|
||||
{934.550, 274.786, 192.368},
|
||||
{921.056, 287.731, 192.368},
|
||||
{956.248, 262.074, 192.829},
|
||||
{955.738, 231.656, 192.836},
|
||||
{934.566, 231.991, 192.838},
|
||||
{956.050, 198.811, 192.841},
|
||||
{939.707, 193.020, 191.923},
|
||||
{940.500, 259.348, 191.208},
|
||||
{948.237, 304.773, 191.208},
|
||||
{923.764, 176.246, 192.832},
|
||||
{960.474, 187.324, 192.833},
|
||||
{968.408, 168.684, 192.825},
|
||||
{967.788, 126.891, 192.822},
|
||||
{930.301, 118.605, 192.847},
|
||||
{952.902, 159.420, 197.075},
|
||||
{931.728, 291.711, 192.368},
|
||||
{950.031, 276.024, 191.208},
|
||||
{943.486, 243.084, 191.208},
|
||||
{950.499, 223.192, 191.208},
|
||||
{940.605, 218.999, 191.208},
|
||||
{949.264, 183.562, 192.380},
|
||||
{950.100, 207.404, 191.241},
|
||||
{969.982, 187.897, 192.837},
|
||||
{931.661, 185.178, 192.831},
|
||||
{924.498, 193.739, 192.847},
|
||||
{966.774, 226.680, 192.847},
|
||||
{953.118, 121.170, 192.822},
|
||||
};
|
||||
|
||||
class spell_mother_shahraz_fatal_attraction : public SpellScript
|
||||
{
|
||||
@@ -234,43 +303,20 @@ class spell_mother_shahraz_fatal_attraction : public SpellScript
|
||||
|
||||
void SetDest(SpellDestination& dest)
|
||||
{
|
||||
Position finalDest;
|
||||
|
||||
// Check if the boss is near stairs to avoid players falling through the platform with random teleports.
|
||||
if (GetCaster()->GetPositionY() < 194.f)
|
||||
finalDest = validTeleportStairsPos[urand(0, 8)];
|
||||
else
|
||||
Position casterPos = GetCaster()->GetPosition();
|
||||
std::vector<Position> validTeleportPositions;
|
||||
std::copy_if(std::begin(teleportPositions), std::end(teleportPositions), std::back_inserter(validTeleportPositions),
|
||||
[&](Position const& pos) {
|
||||
float distanceSq = pos.GetExactDist2dSq(casterPos);
|
||||
return minTeleportDistSq <= distanceSq && distanceSq <= maxTeleportDistSq;
|
||||
});
|
||||
if (validTeleportPositions.empty())
|
||||
{
|
||||
finalDest = GetCaster()->GetNearPosition(frand(minTeleportDist, maxTeleportDist), static_cast<float>(rand_norm()) * static_cast<float>(2 * M_PI), true);
|
||||
|
||||
// Maybe not necessary but just in case to avoid LOS issues with an object
|
||||
if (!GetCaster()->IsWithinLOS(finalDest.GetPositionX(), finalDest.GetPositionY(), finalDest.GetPositionZ()))
|
||||
finalDest = GetCaster()->GetNearPosition(frand(minTeleportDist, maxTeleportDist), static_cast<float>(rand_norm()) * static_cast<float>(2 * M_PI), true);
|
||||
|
||||
/* @note: To avoid teleporting players near a walls, we will define a safe area.
|
||||
* As the boss have an area boudary around y: 320.f. We will limit the safe area to this value, avoiding wird issues.
|
||||
* x limit: 932.f/960.f | y limit: 224.f/320.f
|
||||
*/
|
||||
if (finalDest.m_positionX < 932.f)
|
||||
finalDest.m_positionX = 932.f;
|
||||
else if (finalDest.m_positionX > 960.f)
|
||||
finalDest.m_positionX = 960.f;
|
||||
|
||||
if (finalDest.m_positionY < 224.f)
|
||||
finalDest.m_positionY = 224.f;
|
||||
else if (finalDest.m_positionY > 320.f)
|
||||
finalDest.m_positionY = 320.f;
|
||||
|
||||
// After relocate a finalDest outside the safe area, we need to recheck the distance with the boss
|
||||
if (GetCaster()->GetExactDist2d(finalDest) < minTeleportDist)
|
||||
{
|
||||
if (finalDest.m_positionX == 932.f || finalDest.m_positionX == 960.f)
|
||||
finalDest.m_positionY = finalDest.m_positionY + (minTeleportDist - GetCaster()->GetExactDist2d(finalDest));
|
||||
else if (finalDest.m_positionY == 224.f || finalDest.m_positionY == 320.f)
|
||||
finalDest.m_positionX = finalDest.m_positionX + (minTeleportDist - GetCaster()->GetExactDist2d(finalDest));
|
||||
}
|
||||
}
|
||||
|
||||
LOG_ERROR("scripts", "spell_mother_shahraz_fatal_attraction: No valid teleport positions found (Map: {} X: {} Y: {} Z: {})",
|
||||
GetCaster()->GetMap()->GetId(), GetCaster()->GetPositionX(), GetCaster()->GetPositionY(), GetCaster()->GetPositionZ());
|
||||
return;
|
||||
}
|
||||
Position finalDest = validTeleportPositions[urand(0, validTeleportPositions.size() - 1)];
|
||||
dest.Relocate(finalDest);
|
||||
}
|
||||
|
||||
@@ -283,7 +329,7 @@ class spell_mother_shahraz_fatal_attraction : public SpellScript
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mother_shahraz_fatal_attraction::FilterTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_mother_shahraz_fatal_attraction::SetDest, EFFECT_1, TARGET_DEST_CASTER_RANDOM);
|
||||
OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_mother_shahraz_fatal_attraction::SetDest, EFFECT_1, TARGET_DEST_CASTER);
|
||||
OnEffectHitTarget += SpellEffectFn(spell_mother_shahraz_fatal_attraction::HandleTeleportUnits, EFFECT_1, SPELL_EFFECT_TELEPORT_UNITS);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user