AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
pooltools_commandscript Class Reference
Inheritance diagram for pooltools_commandscript:
CommandScript ScriptObject

Public Member Functions

 pooltools_commandscript ()
 
ChatCommandTable GetCommands () const override
 
- Public Member Functions inherited from ScriptObject
virtual bool IsDatabaseBound () const
 
virtual bool isAfterLoadScript () const
 
virtual void checkValidity ()
 
const std::string & GetName () const
 
uint16 GetTotalAvailableHooks ()
 

Static Public Member Functions

static bool HandlePoolStart (ChatHandler *handler, std::string description)
 
static bool HandlePoolDef (ChatHandler *handler, Tail args)
 
static bool HandlePoolAdd (ChatHandler *handler, Optional< float > radiusArg)
 
static bool HandlePoolRemove (ChatHandler *handler)
 
static bool HandlePoolEnd (ChatHandler *handler)
 
static bool HandlePoolClear (ChatHandler *handler)
 

Additional Inherited Members

- Protected Member Functions inherited from CommandScript
 CommandScript (const char *name)
 
- Protected Member Functions inherited from ScriptObject
 ScriptObject (const char *name, uint16 totalAvailableHooks=0)
 
virtual ~ScriptObject ()=default
 

Detailed Description

Constructor & Destructor Documentation

◆ pooltools_commandscript()

pooltools_commandscript::pooltools_commandscript ( )
inline
59: CommandScript("pooltools_commandscript") {}
Definition CommandScript.h:25

Member Function Documentation

◆ GetCommands()

ChatCommandTable pooltools_commandscript::GetCommands ( ) const
inlineoverridevirtual

Implements CommandScript.

62 {
63 static ChatCommandTable poolToolsCommandTable =
64 {
65 { "start", HandlePoolStart, SEC_ADMINISTRATOR, Console::No },
66 { "def", HandlePoolDef, SEC_ADMINISTRATOR, Console::No },
67 { "add", HandlePoolAdd, SEC_ADMINISTRATOR, Console::No },
68 { "remove", HandlePoolRemove, SEC_ADMINISTRATOR, Console::No },
69 { "end", HandlePoolEnd, SEC_ADMINISTRATOR, Console::No },
70 { "clear", HandlePoolClear, SEC_ADMINISTRATOR, Console::No }
71 };
72
73 static ChatCommandTable commandTable =
74 {
75 { "pooltools", poolToolsCommandTable }
76 };
77 return commandTable;
78 }
@ SEC_ADMINISTRATOR
Definition Common.h:60
static bool HandlePoolEnd(ChatHandler *handler)
Definition cs_pooltools.cpp:278
static bool HandlePoolDef(ChatHandler *handler, Tail args)
Definition cs_pooltools.cpp:99
static bool HandlePoolStart(ChatHandler *handler, std::string description)
Definition cs_pooltools.cpp:80
static bool HandlePoolRemove(ChatHandler *handler)
Definition cs_pooltools.cpp:254
static bool HandlePoolClear(ChatHandler *handler)
Definition cs_pooltools.cpp:408
static bool HandlePoolAdd(ChatHandler *handler, Optional< float > radiusArg)
Definition cs_pooltools.cpp:133
std::vector< ChatCommandBuilder > ChatCommandTable
Definition ChatCommand.h:46

References HandlePoolAdd(), HandlePoolClear(), HandlePoolDef(), HandlePoolEnd(), HandlePoolRemove(), HandlePoolStart(), and SEC_ADMINISTRATOR.

◆ HandlePoolAdd()

static bool pooltools_commandscript::HandlePoolAdd ( ChatHandler handler,
Optional< float >  radiusArg 
)
inlinestatic
134 {
135 ObjectGuid playerGuid = handler->GetPlayer()->GetGUID();
136 if (PoolSessions.find(playerGuid) == PoolSessions.end())
137 return false;
138
139 PoolSession& session = PoolSessions[playerGuid];
140 if (session.CurrentTemplate.empty())
141 {
142 handler->SendErrorMessage("Define a template first with .pooltools def");
143 return false;
144 }
145
146 Player* player = handler->GetPlayer();
147 float const radius = radiusArg.value_or(5.0f);
148
149 float searchX = player->GetPositionX();
150 float searchY = player->GetPositionY();
151 float searchZ = player->GetPositionZ();
152
153 GameObject* target = handler->GetNearbyGameObject();
154 if (radius <= 10.0f && target)
155 {
156 searchX = target->GetPositionX();
157 searchY = target->GetPositionY();
158 searchZ = target->GetPositionZ();
159 }
160
161 std::list<GameObject*> nearbyGOs;
162 Acore::GameObjectInRangeCheck check(searchX, searchY, searchZ, radius);
163 Acore::GameObjectListSearcher<Acore::GameObjectInRangeCheck> searcher(player, nearbyGOs, check);
164 Cell::VisitObjects(player, searcher, radius);
165
166 int addedCount = 0;
167 int newGroupsCount = 0;
168
169 for (GameObject* go : nearbyGOs)
170 {
171 if (go->GetDistance(searchX, searchY, searchZ) > radius)
172 continue;
173
174 bool isTemplateMatch = false;
175 for (auto const& tpl : session.CurrentTemplate)
176 {
177 if (go->GetEntry() == tpl.Entry)
178 {
179 isTemplateMatch = true;
180 break;
181 }
182 }
183 if (!isTemplateMatch)
184 continue;
185
186 uint32 const spawnId = go->GetSpawnId();
187
188 bool alreadyCaptured = false;
189 for (auto const& group : session.CapturedGroups)
190 {
191 for (auto const& obj : group.FoundObjects)
192 {
193 if (obj.second == spawnId)
194 {
195 alreadyCaptured = true;
196 break;
197 }
198 }
199 if (alreadyCaptured)
200 break;
201 }
202 if (alreadyCaptured)
203 continue;
204
205 // Clustering
206 NodeGroup* existingGroup = nullptr;
207 for (auto& group : session.CapturedGroups)
208 {
209 if (go->GetDistance(group.X, group.Y, group.Z) < 0.1f)
210 {
211 existingGroup = &group;
212 break;
213 }
214 }
215
216 if (existingGroup)
217 {
218 existingGroup->FoundObjects.push_back({ go->GetEntry(), spawnId });
219 addedCount++;
220 }
221 else
222 {
223 NodeGroup newGroup;
224 newGroup.X = go->GetPositionX();
225 newGroup.Y = go->GetPositionY();
226 newGroup.Z = go->GetPositionZ();
227 newGroup.FoundObjects.push_back({ go->GetEntry(), spawnId });
228
229 session.CapturedGroups.push_back(newGroup);
230 newGroupsCount++;
231 addedCount++;
232 }
233 }
234
235 if (addedCount == 0)
236 {
237 handler->SendErrorMessage("No new matching objects found in {}y radius.", radius);
238 return false;
239 }
240
241 handler->PSendSysMessage("|cff00ff00Scan Complete.|r Added {} objects into {} new groups.", addedCount, newGroupsCount);
242
243 if (!session.CapturedGroups.empty())
244 {
245 NodeGroup& lastGroup = session.CapturedGroups.back();
246 for (auto& p : lastGroup.FoundObjects)
247 {
248 handler->PSendSysMessage(" - Entry {} (GUID: {})", p.first, p.second);
249 }
250 }
251 return true;
252 }
std::uint32_t uint32
Definition Define.h:107
Definition GridNotifiers.h:1600
void PSendSysMessage(std::string_view str, bool escapeCharacters=false)
Definition Chat.cpp:211
void SendErrorMessage(uint32 entry)
Definition Chat.cpp:216
Player * GetPlayer() const
Definition Chat.cpp:36
GameObject * GetNearbyGameObject() const
Definition Chat.cpp:565
Definition GameObject.h:120
Definition ObjectGuid.h:118
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:113
Definition Player.h:1066
static std::map< ObjectGuid, PoolSession > PoolSessions
Definition cs_pooltools.cpp:54
Definition GridNotifiers.h:341
static void VisitObjects(WorldObject const *obj, T &visitor, float radius)
Definition CellImpl.h:165
Definition cs_pooltools.cpp:40
std::vector< std::pair< uint32, uint32 > > FoundObjects
Definition cs_pooltools.cpp:44
float Z
Definition cs_pooltools.cpp:43
float Y
Definition cs_pooltools.cpp:42
float X
Definition cs_pooltools.cpp:41
Definition cs_pooltools.cpp:48
std::vector< NodeGroup > CapturedGroups
Definition cs_pooltools.cpp:51
std::vector< PoolTemplateItem > CurrentTemplate
Definition cs_pooltools.cpp:50
float GetPositionZ() const
Definition Position.h:123
float GetPositionX() const
Definition Position.h:121
float GetPositionY() const
Definition Position.h:122

References PoolSession::CapturedGroups, PoolSession::CurrentTemplate, NodeGroup::FoundObjects, Object::GetGUID(), ChatHandler::GetNearbyGameObject(), ChatHandler::GetPlayer(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), PoolSessions, ChatHandler::PSendSysMessage(), ChatHandler::SendErrorMessage(), Cell::VisitObjects(), NodeGroup::X, NodeGroup::Y, and NodeGroup::Z.

Referenced by GetCommands().

◆ HandlePoolClear()

static bool pooltools_commandscript::HandlePoolClear ( ChatHandler handler)
inlinestatic
409 {
410 PoolSessions.erase(handler->GetPlayer()->GetGUID());
411 handler->PSendSysMessage("Session cleared.");
412 return true;
413 }

References Object::GetGUID(), ChatHandler::GetPlayer(), PoolSessions, and ChatHandler::PSendSysMessage().

Referenced by GetCommands().

◆ HandlePoolDef()

static bool pooltools_commandscript::HandlePoolDef ( ChatHandler handler,
Tail  args 
)
inlinestatic
100 {
101 ObjectGuid playerGuid = handler->GetPlayer()->GetGUID();
102 if (PoolSessions.find(playerGuid) == PoolSessions.end())
103 {
104 handler->SendErrorMessage("No active session.");
105 return false;
106 }
107
108 std::vector<std::string_view> tokens = Acore::Tokenize(args, ' ', false);
109
110 if (tokens.empty() || tokens.size() % 2 != 0)
111 {
112 handler->SendErrorMessage("Invalid syntax. Usage: .pooltools def [ID] [Chance] [ID] [Chance]...");
113 return false;
114 }
115
116 std::vector<PoolTemplateItem> newTemplate;
117 for (size_t i = 0; i < tokens.size(); i += 2)
118 {
119 uint32 const entry = Acore::StringTo<uint32>(tokens[i]).value_or(0);
120 uint32 const chance = Acore::StringTo<uint32>(tokens[i + 1]).value_or(0);
121
122 if (entry == 0)
123 continue;
124
125 newTemplate.push_back({ entry, chance });
126 }
127
128 PoolSessions[playerGuid].CurrentTemplate = newTemplate;
129 handler->PSendSysMessage("Template Defined ({} items).", newTemplate.size());
130 return true;
131 }
std::vector< std::string_view > Tokenize(std::string_view str, char sep, bool keepEmpty)
Definition Tokenize.cpp:20

References Object::GetGUID(), ChatHandler::GetPlayer(), PoolSessions, ChatHandler::PSendSysMessage(), ChatHandler::SendErrorMessage(), and Acore::Tokenize().

Referenced by GetCommands().

◆ HandlePoolEnd()

static bool pooltools_commandscript::HandlePoolEnd ( ChatHandler handler)
inlinestatic
279 {
280 ObjectGuid playerGuid = handler->GetPlayer()->GetGUID();
281 auto it = PoolSessions.find(playerGuid);
282 if (it == PoolSessions.end())
283 return false;
284
285 PoolSession& session = it->second; // Use reference from iterator
286
287 auto EscapeSQL = [](std::string_view input) -> std::string {
288 std::string safe;
289 safe.reserve(input.size());
290 for (char c : input)
291 {
292 if (c == '\'')
293 safe += "\\'";
294 else
295 safe += c;
296 }
297 return safe;
298 };
299
300 bool const complexPool = (session.CurrentTemplate.size() > 1);
301
302 // SQL Variables and Header
303 LOG_DEBUG("sql.dev", "-- Pool Dump: {}", session.ZoneName);
304 LOG_DEBUG("sql.dev", "SET @mother_pool := @mother_pool+1;");
305
306 if (complexPool)
307 LOG_DEBUG("sql.dev", "SET @pool_node := @pool_node+1;");
308
309 LOG_DEBUG("sql.dev", "SET @max_limit := {};", (session.CapturedGroups.size() + 3) / 4);
310
311 // DELETEs section
312 if (!session.CapturedGroups.empty())
313 {
314 LOG_DEBUG("sql.dev", "-- Cleanup specific object links");
315 LOG_DEBUG("sql.dev", "DELETE FROM `pool_gameobject` WHERE `guid` IN (");
316
317 std::vector<std::string> guidList;
318 for (auto const& group : session.CapturedGroups)
319 for (auto const& obj : group.FoundObjects)
320 guidList.push_back(std::to_string(obj.second));
321
322 LOG_DEBUG("sql.dev", fmt::format("{}", fmt::join(guidList, ", ")));
323 LOG_DEBUG("sql.dev", ");\n");
324 }
325
326 LOG_DEBUG("sql.dev", "DELETE FROM `pool_template` WHERE `entry`=@mother_pool;");
327 LOG_DEBUG("sql.dev", "INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES (@mother_pool, @max_limit, '{} - Mother Pool');", EscapeSQL(session.ZoneName));
328
329 int groupCounter = 0;
330
331 // We can buffer the simple bulk inserts here
332 std::vector<std::string> bulkInserts;
333
334 for (auto const& group : session.CapturedGroups)
335 {
336 groupCounter++;
337
338 // Generate Description
339 std::set<std::string> uniqueNames;
340 for (auto const& obj : group.FoundObjects)
341 {
342 GameObjectTemplate const* goInfo = sObjectMgr->GetGameObjectTemplate(obj.first);
343 uniqueNames.insert(goInfo ? goInfo->name : std::to_string(obj.first));
344 }
345
346 std::string groupDesc = fmt::format("{}", fmt::join(uniqueNames, " / "));
347 std::string safeGroupDesc = EscapeSQL(groupDesc);
348
349 // Simple pooling
350 if (!complexPool)
351 {
352 for (auto const& obj : group.FoundObjects)
353 {
354 float chance = 0.0f;
355 for (auto const& tpl : session.CurrentTemplate)
356 if (tpl.Entry == obj.first)
357 chance = (float)tpl.Chance;
358
359 bulkInserts.push_back(fmt::format("({}, @mother_pool, {}, '{} - {}')",
360 obj.second, chance, EscapeSQL(session.ZoneName), safeGroupDesc));
361 }
362 }
363 // Pool_pool integration
364 else
365 {
366 LOG_DEBUG("sql.dev", "-- Group {}", groupCounter);
367 LOG_DEBUG("sql.dev", "SET @pool_node := @pool_node + 1;");
368
369 // Create the Sub-Pool Node
370 LOG_DEBUG("sql.dev", "INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES (@pool_node, 1, '{} - Node {}');", EscapeSQL(session.ZoneName), groupCounter);
371
372 // Link Node to Mother Pool
373 LOG_DEBUG("sql.dev", "INSERT INTO `pool_pool` (`pool_id`, `mother_pool`, `chance`, `description`) VALUES (@pool_node, @mother_pool, 0, '{} - {}');", EscapeSQL(session.ZoneName), safeGroupDesc);
374
375 // Link Objects to Sub-Pool Node
376 LOG_DEBUG("sql.dev", "INSERT INTO `pool_gameobject` (`guid`, `pool_entry`, `chance`, `description`) VALUES");
377
378 std::vector<std::string> nodeInserts;
379 for (auto const& obj : group.FoundObjects)
380 {
381 GameObjectTemplate const* goInfo = sObjectMgr->GetGameObjectTemplate(obj.first);
382 std::string objName = goInfo ? goInfo->name : "Unknown";
383
384 float chance = 0.0f;
385 for (auto const& tpl : session.CurrentTemplate)
386 if (tpl.Entry == obj.first) chance = (float)tpl.Chance;
387
388 nodeInserts.push_back(fmt::format("({}, @pool_node, {}, '{} - {}')",
389 obj.second, chance, EscapeSQL(session.ZoneName), EscapeSQL(objName)));
390 }
391 LOG_DEBUG("sql.dev", "{};", fmt::join(nodeInserts, ",\n"));
392 }
393 }
394
395 if (!complexPool && !bulkInserts.empty())
396 {
397 LOG_DEBUG("sql.dev", "INSERT INTO `pool_gameobject` (`guid`, `pool_entry`, `chance`, `description`) VALUES");
398 LOG_DEBUG("sql.dev", "{};", fmt::join(bulkInserts, ",\n"));
399 }
400
401 handler->PSendSysMessage("Dumped {} groups.", groupCounter);
402
403 // Cleanup
404 PoolSessions.erase(it);
405 return true;
406 }
#define LOG_DEBUG(filterType__,...)
Definition Log.h:170
#define sObjectMgr
Definition ObjectMgr.h:1686
uint32 const Entry[3]
Definition instance_blackwing_lair.cpp:73
STL namespace.
Definition GameObjectData.h:31
std::string name
Definition GameObjectData.h:35
std::string ZoneName
Definition cs_pooltools.cpp:49

References PoolSession::CapturedGroups, PoolSession::CurrentTemplate, Object::GetGUID(), ChatHandler::GetPlayer(), LOG_DEBUG, GameObjectTemplate::name, PoolSessions, ChatHandler::PSendSysMessage(), sObjectMgr, and PoolSession::ZoneName.

Referenced by GetCommands().

◆ HandlePoolRemove()

static bool pooltools_commandscript::HandlePoolRemove ( ChatHandler handler)
inlinestatic
255 {
256 ObjectGuid const playerGuid = handler->GetPlayer()->GetGUID();
257 if (PoolSessions.find(playerGuid) == PoolSessions.end())
258 {
259 handler->SendErrorMessage("No active session.");
260 return false;
261 }
262
263 PoolSession& session = PoolSessions[playerGuid];
264
265 if (session.CapturedGroups.empty())
266 {
267 handler->SendErrorMessage("No groups captured.");
268 return false;
269 }
270
271 NodeGroup removed = session.CapturedGroups.back();
272 session.CapturedGroups.pop_back();
273
274 handler->PSendSysMessage("|cffff0000Undo Successful.|r Removed last group containing {} objects.", removed.FoundObjects.size());
275 return true;
276 }

References PoolSession::CapturedGroups, NodeGroup::FoundObjects, Object::GetGUID(), ChatHandler::GetPlayer(), PoolSessions, ChatHandler::PSendSysMessage(), and ChatHandler::SendErrorMessage().

Referenced by GetCommands().

◆ HandlePoolStart()

static bool pooltools_commandscript::HandlePoolStart ( ChatHandler handler,
std::string  description 
)
inlinestatic
81 {
82 ObjectGuid const playerGuid = handler->GetPlayer()->GetGUID();
83
84 if (PoolSessions.find(playerGuid) != PoolSessions.end())
85 {
86 handler->SendErrorMessage("Session already active. Use .pooltools clear first.");
87 return false;
88 }
89
90 PoolSession session;
91 session.ZoneName = description;
92
93 PoolSessions[playerGuid] = session;
94
95 handler->PSendSysMessage("|cff00ff00Pool Session Started.|r Description: {}", description);
96 return true;
97 }

References Object::GetGUID(), ChatHandler::GetPlayer(), PoolSessions, ChatHandler::PSendSysMessage(), ChatHandler::SendErrorMessage(), and PoolSession::ZoneName.

Referenced by GetCommands().


The documentation for this class was generated from the following file: