Skip to content

Commit 4e0ec47

Browse files
committed
Implement waypoint sql generation
1 parent 01c0e51 commit 4e0ec47

File tree

11 files changed

+332
-15
lines changed

11 files changed

+332
-15
lines changed

Diff for: WowPacketParser/App.config

+10-1
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,8 @@
202202
<add key="hotfix_optional_data" value="false"/>
203203
<add key="hotfixes" value="false"/>
204204

205+
<add key="creature_movement" value="false"/>
206+
205207

206208
<!--
207209
Option: ParseAllHotfixes
@@ -246,11 +248,18 @@
246248
<add key="GenerateCreateObject2SpawnsOnly" value="false"/>
247249

248250
<!--
251+
Option: SkipIntermediatePoints
252+
Description: Skips intermediate points for waypoint paths
253+
Default: "true"
254+
-->
255+
<add key="SkipIntermediatePoints" value="false"/>
256+
257+
<!--
249258
Option: SkipDuplicateSpawns
250259
Description: Skip generation of duplicate spawns (grouped by: entry, phases, position)
251260
Default: "true"
252261
-->
253-
<add key="SkipDuplicateSpawns" value="true"/>
262+
<add key="SkipDuplicateSpawns" value="true"/>
254263

255264
<!--
256265
Option: SplitSQLFile

Diff for: WowPacketParser/Enums/SQLOutput.cs

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ public enum SQLOutput
1919
creature_addon,
2020
creature_equip_template,
2121
creature_model_info,
22+
creature_movement,
2223
creature_queststarter,
2324
creature_questender,
2425
creature_template,

Diff for: WowPacketParser/Misc/Settings.cs

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public static class Settings
3131
public static readonly bool ForcePhaseZero = Conf.GetBoolean("ForcePhaseZero", false);
3232
public static readonly bool GenerateCreateObject2SpawnsOnly = Conf.GetBoolean("GenerateCreateObject2SpawnsOnly", false);
3333
public static readonly bool SkipDuplicateSpawns = Conf.GetBoolean("SkipDuplicateSpawns", false);
34+
public static readonly bool SkipIntermediatePoints = Conf.GetBoolean("SkipDuplicateSpawns", false);
3435
public static readonly string SQLFileName = Conf.GetString("SQLFileName", string.Empty);
3536
public static readonly bool SplitSQLFile = Conf.GetBoolean("SplitSQLFile", false);
3637
public static readonly bool ShowEndPrompt = Conf.GetBoolean("ShowEndPrompt", false);

Diff for: WowPacketParser/SQL/Builders/Movement.cs

+118
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
using System;
2+
using WowPacketParser.Enums;
3+
using WowPacketParser.Misc;
4+
using WowPacketParser.Store;
5+
using WowPacketParser.SQL;
6+
using System.Linq;
7+
8+
namespace WowPacketParser.SQL.Builders
9+
{
10+
[BuilderClass]
11+
public static class Movement
12+
{
13+
[BuilderMethod]
14+
public static string MovementData()
15+
{
16+
if (Storage.CreatureMovement.IsEmpty())
17+
return string.Empty;
18+
19+
if (!Settings.SQLOutputFlag.HasAnyFlagBit(SQLOutput.creature_movement))
20+
return string.Empty;
21+
22+
string output = "SET @MOVID = 0;\n";
23+
int pathIdCounter = 0;
24+
if (Settings.TargetedProject == TargetedProject.Cmangos)
25+
{
26+
string nodeSql = "INSERT INTO waypoint_path (PathId, Point, PositionX, PositionY, PositionZ, Orientation, WaitTime, ScriptId, Comment) VALUES\n";
27+
foreach (var data in Storage.CreatureMovement.ToList())
28+
{
29+
var creatureMovement = data.Item1;
30+
if (creatureMovement.Waypoints.Count == 0)
31+
continue;
32+
33+
string creatureName = SQLUtil.EscapeString(StoreGetters.GetName(Utilities.ObjectTypeToStore(creatureMovement.GUID.GetObjectType()), (int)creatureMovement.GUID.GetEntry()));
34+
output += "-- " + $"GUID: {creatureMovement.GUID} PathType: {creatureMovement.Type}" + "\n" + $"INSERT INTO waypoint_path_name(PathId, Name) VALUES(@MOVID + {pathIdCounter},'{creatureName}');\n" + nodeSql;
35+
36+
int pointIdCounter = 1;
37+
int actualPoint = 1;
38+
foreach (var node in creatureMovement.Waypoints)
39+
{
40+
bool finalP = creatureMovement.Destination == null && creatureMovement.Waypoints.Count == actualPoint;
41+
++actualPoint;
42+
float ori = finalP ? (creatureMovement.FinalOrientation != null ? creatureMovement.FinalOrientation.Value : 100f) : 100f;
43+
if (node.Point == false)
44+
{
45+
if (Settings.SkipIntermediatePoints == true)
46+
continue;
47+
output += "-- ";
48+
}
49+
50+
output += $"(@MOVID + {pathIdCounter}, '{pointIdCounter}', '{node.Position.X}', '{node.Position.Y}', '{node.Position.Z}', '{ori}', '0', '0', NULL)";
51+
52+
if (!finalP)
53+
output += ",\n";
54+
else
55+
output += ";\n\n";
56+
57+
++pointIdCounter;
58+
}
59+
60+
if (creatureMovement.Destination != null)
61+
{
62+
float ori = creatureMovement.FinalOrientation != null ? creatureMovement.FinalOrientation.Value : 100f;
63+
output += $"(@MOVID + {pathIdCounter}, '{pointIdCounter}', '{creatureMovement.Destination.Position.X}', '{creatureMovement.Destination.Position.Y}', '{creatureMovement.Destination.Position.Z}', '{ori}', '0', '0', NULL);\n";
64+
}
65+
66+
++pathIdCounter;
67+
}
68+
}
69+
else if (Settings.TargetedProject == TargetedProject.TrinityCore)
70+
{
71+
string nodeSql = "INSERT INTO waypoint_path_node (PathId, NodeId, PositionX, PositionY, PositionZ, Orientation, Delay) VALUES\n";
72+
foreach (var data in Storage.CreatureMovement.ToList())
73+
{
74+
var creatureMovement = data.Item1;
75+
if (creatureMovement.Waypoints.Count == 0)
76+
continue;
77+
78+
string commentInformation = $"GUID: {creatureMovement.GUID} PathType: {creatureMovement.Type}";
79+
output += "-- " + commentInformation + "\n";
80+
output += nodeSql;
81+
82+
int pointIdCounter = 1;
83+
int actualPoint = 1;
84+
foreach (var node in creatureMovement.Waypoints)
85+
{
86+
bool finalP = creatureMovement.Destination == null && creatureMovement.Waypoints.Count == actualPoint;
87+
++actualPoint;
88+
float ori = finalP ? (creatureMovement.FinalOrientation != null ? creatureMovement.FinalOrientation.Value : 100f) : 100f;
89+
if (node.Point == false)
90+
{
91+
if (Settings.SkipIntermediatePoints == true)
92+
continue;
93+
output += "-- ";
94+
}
95+
output += $"(@MOVID + {pathIdCounter}, '{pointIdCounter}', '{node.Position.X}', '{node.Position.Y}', '{node.Position.Z}', '{ori}')";
96+
97+
if (!finalP)
98+
output += ",\n";
99+
else
100+
output += ";\n\n";
101+
102+
++pointIdCounter;
103+
}
104+
105+
if (creatureMovement.Destination != null)
106+
{
107+
float ori = creatureMovement.FinalOrientation != null ? creatureMovement.FinalOrientation.Value : 100f;
108+
output += $"(@MOVID + {pathIdCounter}, '{pointIdCounter}', '{creatureMovement.Destination.Position.X}', '{creatureMovement.Destination.Position.Y}', '{creatureMovement.Destination.Position.Z}', '{ori}', '0', '0', NULL);\n\n";
109+
}
110+
111+
++pathIdCounter;
112+
}
113+
}
114+
115+
return output;
116+
}
117+
}
118+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System.Collections.Generic;
2+
using WowPacketParser.Misc;
3+
4+
namespace WowPacketParser.Store.Objects.Movement
5+
{
6+
public class CreatureMovement
7+
{
8+
public CreatureMovementFlags Type { get; set; }
9+
public WowGuid GUID { get; set; }
10+
public int PathId { get; set; }
11+
public int Id { get; set; }
12+
public List<CreatureMovementNode> Waypoints { get; set; } = new();
13+
public CreatureMovementNode? Destination { get; set; } = null;
14+
public float? FinalOrientation { get; set; } = null; // signals end of current path and wait time
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
namespace WowPacketParser.Store.Objects.Movement
2+
{
3+
public enum CreatureMovementFlags
4+
{
5+
None = 0, // pathfinding
6+
ExactPath = 1, // sent fully
7+
ExactPathFlying = 2, // sent fully + flying flag
8+
ExactPathFlyingCyclic = 3, // sent fully + flying flag + cyclic flag
9+
ExactPathAndJump = 4, // sent fully + parabolic movement at the end
10+
Invalid = 100,
11+
}
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using WowPacketParser.Misc;
2+
3+
namespace WowPacketParser.Store.Objects.Movement
4+
{
5+
public class CreatureMovementNode
6+
{
7+
public Vector3 Position { get; set; }
8+
public bool Point { get; set; }
9+
}
10+
}

Diff for: WowPacketParser/Store/Storage.cs

+4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using WowPacketParser.Enums;
44
using WowPacketParser.Misc;
55
using WowPacketParser.Store.Objects;
6+
using WowPacketParser.Store.Objects.Movement;
67

78
namespace WowPacketParser.Store
89
{
@@ -117,6 +118,9 @@ public static class Storage
117118
// Weather updates
118119
public static readonly DataBag<WeatherUpdate> WeatherUpdates = new DataBag<WeatherUpdate>(new List<SQLOutput> { SQLOutput.weather_updates });
119120

121+
// Movement
122+
public static readonly StoreBag<CreatureMovement> CreatureMovement = new StoreBag<CreatureMovement>(new List<SQLOutput> { SQLOutput.creature_movement });
123+
120124
// Npc Spell Click
121125
public static readonly StoreBag<WowGuid> NpcSpellClicks = new StoreBag<WowGuid>(new List<SQLOutput> { SQLOutput.npc_spellclick_spells });
122126
public static readonly DataBag<NpcSpellClick> SpellClicks = new DataBag<NpcSpellClick>(new List<SQLOutput> { SQLOutput.npc_spellclick_spells });

Diff for: WowPacketParserModule.V2_5_1_38707/Parsers/UpdateHandler.cs

+42-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1-
using WowPacketParser.Enums;
1+
using System.Drawing;
2+
using System.Linq;
3+
using WowPacketParser.Enums;
24
using WowPacketParser.Misc;
35
using WowPacketParser.PacketStructures;
46
using WowPacketParser.Parsing;
57
using WowPacketParser.Proto;
68
using WowPacketParser.Store;
79
using WowPacketParser.Store.Objects;
10+
using WowPacketParser.Store.Objects.Movement;
811
using WowPacketParser.Store.Objects.UpdateFields;
912
using CoreFields = WowPacketParser.Enums.Version;
1013
using CoreParsers = WowPacketParser.Parsing.Parsers;
@@ -441,14 +444,35 @@ private static MovementInfo ReadMovementUpdateBlock(Packet packet, WowGuid guid,
441444
{
442445
packet.ResetBitReader();
443446
packet.ReadInt32("ID", index);
444-
packet.ReadVector3("Destination", index);
447+
448+
CreatureMovement movement = Storage.CreatureMovement.Where(p => p.Item1.GUID == guid).SingleOrDefault()?.Item1;
449+
bool add = false;
450+
if (movement == null)
451+
{
452+
movement = new CreatureMovement()
453+
{
454+
GUID = guid
455+
};
456+
add = true;
457+
}
458+
459+
var destination = packet.ReadVector3("Destination", index);
445460

446461
var hasMovementSplineMove = packet.ReadBit("MovementSplineMove", index);
447462
if (hasMovementSplineMove)
448463
{
449464
packet.ResetBitReader();
450465

451-
packet.ReadUInt32E<SplineFlag>("SplineFlags", index);
466+
var splineFlag = packet.ReadUInt32E<SplineFlag>("SplineFlags", index);
467+
CreatureMovementFlags moveType = CreatureMovementFlags.None;
468+
469+
if (splineFlag.HasFlag(SplineFlag.EnterCycle) || splineFlag.HasFlag(SplineFlag.Cyclic))
470+
moveType = CreatureMovementFlags.ExactPathFlyingCyclic;
471+
else if (splineFlag.HasFlag(SplineFlag.Flying))
472+
moveType = CreatureMovementFlags.ExactPathFlying;
473+
else if (splineFlag.HasFlag(SplineFlag.UncompressedPath))
474+
moveType = CreatureMovementFlags.ExactPath;
475+
452476
packet.ReadInt32("Elapsed", index);
453477
packet.ReadUInt32("Duration", index);
454478
packet.ReadSingle("DurationModifier", index);
@@ -493,6 +517,7 @@ private static MovementInfo ReadMovementUpdateBlock(Packet packet, WowGuid guid,
493517
break;
494518
case 3:
495519
orientation = packet.ReadSingle("FaceDirection", index);
520+
moveType = CreatureMovementFlags.Invalid;
496521
break;
497522
default:
498523
break;
@@ -504,13 +529,23 @@ private static MovementInfo ReadMovementUpdateBlock(Packet packet, WowGuid guid,
504529
for (var i = 0; i < pointsCount; ++i)
505530
{
506531
var spot = packet.ReadVector3("Points", index, i);
532+
if (moveType != CreatureMovementFlags.Invalid)
533+
movement.Waypoints.Add(new CreatureMovementNode
534+
{
535+
Position = spot,
536+
Point = splineFlag.HasFlag(SplineFlag.EnterCycle) || splineFlag.HasFlag(SplineFlag.Cyclic)
537+
});
507538
}
508539

509540
if (hasSpellEffectExtraData)
510541
V8_0_1_27101.Parsers.MovementHandler.ReadMonsterSplineSpellEffectExtraData(packet, index);
511542

512543
if (hasJumpExtraData)
513-
V8_0_1_27101.Parsers.MovementHandler.ReadMonsterSplineJumpExtraData(packet, index);
544+
{
545+
var jumpData = V8_0_1_27101.Parsers.MovementHandler.ReadMonsterSplineJumpExtraData(packet, index);
546+
if (jumpData.StartTime > 0)
547+
moveType = CreatureMovementFlags.ExactPathAndJump;
548+
}
514549

515550
if (hasAnimationTierTransition)
516551
{
@@ -531,6 +566,9 @@ private static MovementInfo ReadMovementUpdateBlock(Packet packet, WowGuid guid,
531566
}
532567
}
533568
}
569+
570+
if (movement.Type != CreatureMovementFlags.Invalid && add)
571+
Storage.CreatureMovement.Add(movement);
534572
}
535573
}
536574

0 commit comments

Comments
 (0)