Scripts/Commands: Convert argument parsing of .npc commands
(And I snuck some chat command cleanup in there, more de-cluttering!) (cherry picked from commit 88d446dadf65bf47c72d3042834281233b1174ac)
This commit is contained in:
@@ -25,8 +25,8 @@ if not getcwd().endswith('src'):
|
||||
print('(Invoke as \'python ../contrib/enumutils_describe.py\')')
|
||||
exit(1)
|
||||
|
||||
EnumPattern = compile(r'//\s*EnumUtils: DESCRIBE THIS\s+enum\s+([0-9A-Za-z]+)[^\n]*\s*{([^}]+)};')
|
||||
EnumValuesPattern = compile(r'\s+.+?(,|$)[^\n]*')
|
||||
EnumPattern = compile(r'//\s*EnumUtils: DESCRIBE THIS(?:\s*\(in ([^\)]+)\))?\s+enum\s+([0-9A-Za-z]+)[^\n]*\s*{([^}]+)};')
|
||||
EnumValuesPattern = compile(r'\s+\S.+?(,|$)[^\n]*')
|
||||
EnumValueNamePattern = compile(r'^\s*([a-zA-Z0-9_]+)', flags=MULTILINE)
|
||||
EnumValueSkipLinePattern = compile(r'^\s*//')
|
||||
EnumValueCommentPattern = compile(r'//,?[ \t]*([^\n]+)$')
|
||||
@@ -52,9 +52,10 @@ def processFile(path, filename):
|
||||
|
||||
enums = []
|
||||
for enum in EnumPattern.finditer(file):
|
||||
name = enum.group(1)
|
||||
prefix = enum.group(1) or ''
|
||||
name = enum.group(2)
|
||||
values = []
|
||||
for value in EnumValuesPattern.finditer(enum.group(2)):
|
||||
for value in EnumValuesPattern.finditer(enum.group(3)):
|
||||
valueData = value.group(0)
|
||||
|
||||
valueNameMatch = EnumValueNamePattern.search(valueData)
|
||||
@@ -89,7 +90,7 @@ def processFile(path, filename):
|
||||
|
||||
values.append((valueName, valueTitle, valueDescription))
|
||||
|
||||
enums.append((name, values))
|
||||
enums.append((prefix + name, prefix, values))
|
||||
print('%s.h: Enum %s parsed with %d values' % (filename, name, len(values)))
|
||||
|
||||
if not enums:
|
||||
@@ -110,7 +111,7 @@ def processFile(path, filename):
|
||||
output.write('\n')
|
||||
output.write('namespace Trinity::Impl::EnumUtilsImpl\n')
|
||||
output.write('{\n')
|
||||
for name, values in enums:
|
||||
for name, prefix, values in enums:
|
||||
tag = ('data for enum \'%s\' in \'%s.h\' auto-generated' % (name, filename))
|
||||
output.write('\n')
|
||||
output.write('/*' + ('*'*(len(tag)+2)) + '*\\\n')
|
||||
@@ -122,7 +123,7 @@ def processFile(path, filename):
|
||||
output.write(' switch (value)\n')
|
||||
output.write(' {\n')
|
||||
for label, title, description in values:
|
||||
output.write(' case %s: return { %s, %s, %s };\n' % (label, strescape(label), strescape(title), strescape(description)))
|
||||
output.write(' case %s: return { %s, %s, %s };\n' % (prefix + label, strescape(label), strescape(title), strescape(description)))
|
||||
output.write(' default: throw std::out_of_range("value");\n')
|
||||
output.write(' }\n')
|
||||
output.write('}\n')
|
||||
@@ -135,8 +136,8 @@ def processFile(path, filename):
|
||||
output.write('{\n')
|
||||
output.write(' switch (index)\n')
|
||||
output.write(' {\n')
|
||||
for i in range(len(values)):
|
||||
output.write(' case %d: return %s;\n' % (i, values[i][0]))
|
||||
for (i, (label, title, description)) in enumerate(values):
|
||||
output.write(' case %d: return %s;\n' % (i, prefix + label))
|
||||
output.write(' default: throw std::out_of_range("index");\n')
|
||||
output.write(' }\n')
|
||||
output.write('}\n')
|
||||
@@ -146,8 +147,8 @@ def processFile(path, filename):
|
||||
output.write('{\n')
|
||||
output.write(' switch (value)\n')
|
||||
output.write(' {\n')
|
||||
for i in range(len(values)):
|
||||
output.write(' case %s: return %d;\n' % (values[i][0], i))
|
||||
for (i, (label, title, description)) in enumerate(values):
|
||||
output.write(' case %s: return %d;\n' % (prefix + label, i))
|
||||
output.write(' default: throw std::out_of_range("value");\n')
|
||||
output.write(' }\n')
|
||||
output.write('}\n')
|
||||
|
||||
@@ -68,13 +68,14 @@ class TC_GAME_API CreatureAI : public UnitAI
|
||||
Creature* DoSummonFlyer(uint32 entry, WorldObject* obj, float flightZ, float radius = 5.0f, Milliseconds despawnTime = 30s, TempSummonType summonType = TEMPSUMMON_CORPSE_TIMED_DESPAWN);
|
||||
|
||||
public:
|
||||
// EnumUtils: DESCRIBE THIS (in CreatureAI::)
|
||||
enum EvadeReason
|
||||
{
|
||||
EVADE_REASON_NO_HOSTILES, // the creature's threat list is empty
|
||||
EVADE_REASON_BOUNDARY, // the creature has moved outside its evade boundary
|
||||
EVADE_REASON_NO_PATH, // the creature was unable to reach its target for over 5 seconds
|
||||
EVADE_REASON_SEQUENCE_BREAK, // this is a boss and the pre-requisite encounters for engaging it are not defeated yet
|
||||
EVADE_REASON_OTHER
|
||||
EVADE_REASON_OTHER, // anything else
|
||||
};
|
||||
|
||||
explicit CreatureAI(Creature* creature, uint32 scriptId = {});
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "CreatureAI.h"
|
||||
#include "Define.h"
|
||||
#include "SmartEnum.h"
|
||||
#include <stdexcept>
|
||||
|
||||
namespace Trinity::Impl::EnumUtilsImpl
|
||||
{
|
||||
|
||||
/****************************************************************************\
|
||||
|* data for enum 'CreatureAI::EvadeReason' in 'CreatureAI.h' auto-generated *|
|
||||
\****************************************************************************/
|
||||
template <>
|
||||
TC_API_EXPORT EnumText EnumUtils<CreatureAI::EvadeReason>::ToString(CreatureAI::EvadeReason value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case CreatureAI::EVADE_REASON_NO_HOSTILES: return { "EVADE_REASON_NO_HOSTILES", "EVADE_REASON_NO_HOSTILES", "the creature's threat list is empty" };
|
||||
case CreatureAI::EVADE_REASON_BOUNDARY: return { "EVADE_REASON_BOUNDARY", "EVADE_REASON_BOUNDARY", "the creature has moved outside its evade boundary" };
|
||||
case CreatureAI::EVADE_REASON_NO_PATH: return { "EVADE_REASON_NO_PATH", "EVADE_REASON_NO_PATH", "the creature was unable to reach its target for over 5 seconds" };
|
||||
case CreatureAI::EVADE_REASON_SEQUENCE_BREAK: return { "EVADE_REASON_SEQUENCE_BREAK", "EVADE_REASON_SEQUENCE_BREAK", "this is a boss and the pre-requisite encounters for engaging it are not defeated yet" };
|
||||
case CreatureAI::EVADE_REASON_OTHER: return { "EVADE_REASON_OTHER", "EVADE_REASON_OTHER", "anything else" };
|
||||
default: throw std::out_of_range("value");
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
TC_API_EXPORT size_t EnumUtils<CreatureAI::EvadeReason>::Count() { return 5; }
|
||||
|
||||
template <>
|
||||
TC_API_EXPORT CreatureAI::EvadeReason EnumUtils<CreatureAI::EvadeReason>::FromIndex(size_t index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: return CreatureAI::EVADE_REASON_NO_HOSTILES;
|
||||
case 1: return CreatureAI::EVADE_REASON_BOUNDARY;
|
||||
case 2: return CreatureAI::EVADE_REASON_NO_PATH;
|
||||
case 3: return CreatureAI::EVADE_REASON_SEQUENCE_BREAK;
|
||||
case 4: return CreatureAI::EVADE_REASON_OTHER;
|
||||
default: throw std::out_of_range("index");
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
TC_API_EXPORT size_t EnumUtils<CreatureAI::EvadeReason>::ToIndex(CreatureAI::EvadeReason value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case CreatureAI::EVADE_REASON_NO_HOSTILES: return 0;
|
||||
case CreatureAI::EVADE_REASON_BOUNDARY: return 1;
|
||||
case CreatureAI::EVADE_REASON_NO_PATH: return 2;
|
||||
case CreatureAI::EVADE_REASON_SEQUENCE_BREAK: return 3;
|
||||
case CreatureAI::EVADE_REASON_OTHER: return 4;
|
||||
default: throw std::out_of_range("value");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,32 +44,6 @@ namespace Trinity::Impl::ChatCommands
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... Ts>
|
||||
struct SingleConsumer<Trinity::ChatCommands::Variant<Ts...>>
|
||||
{
|
||||
using V = std::variant<Ts...>;
|
||||
static constexpr size_t N = std::variant_size_v<V>;
|
||||
|
||||
template <size_t I>
|
||||
static Optional<std::string_view> TryAtIndex(Trinity::ChatCommands::Variant<Ts...>& val, [[maybe_unused]] std::string_view args)
|
||||
{
|
||||
if constexpr (I < N)
|
||||
{
|
||||
if (Optional<std::string_view> next = SingleConsumer<std::variant_alternative_t<I, V>>::TryConsumeTo(val.template emplace<I>(), args))
|
||||
return next;
|
||||
else
|
||||
return TryAtIndex<I+1>(val, args);
|
||||
}
|
||||
else
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
static Optional<std::string_view> TryConsumeTo(Trinity::ChatCommands::Variant<Ts...>& val, std::string_view args)
|
||||
{
|
||||
return TryAtIndex<0>(val, args);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
for backwards compatibility, consumes the rest of the string
|
||||
new code should use the Tail/WTail tags defined in ChatCommandTags
|
||||
|
||||
@@ -51,7 +51,7 @@ Optional<std::string_view> Trinity::Impl::ChatCommands::ArgInfo<CurrencyTypesEnt
|
||||
Optional<std::string_view> next = SingleConsumer<decltype(val)>::TryConsumeTo(val, args);
|
||||
if (next)
|
||||
data = val.visit(CurrencyTypesVisitor());
|
||||
return args;
|
||||
return next;
|
||||
}
|
||||
|
||||
struct GameTeleVisitor
|
||||
@@ -69,6 +69,21 @@ Optional<std::string_view> Trinity::Impl::ChatCommands::ArgInfo<GameTele const*>
|
||||
return next;
|
||||
}
|
||||
|
||||
struct ItemTemplateVisitor
|
||||
{
|
||||
using value_type = ItemTemplate const*;
|
||||
value_type operator()(Hyperlink<item> item) const { return item->Item; }
|
||||
value_type operator()(uint32 item) const { return sObjectMgr->GetItemTemplate(item); }
|
||||
};
|
||||
Optional<std::string_view> Trinity::Impl::ChatCommands::ArgInfo<ItemTemplate const*>::TryConsume(ItemTemplate const*& data, std::string_view args)
|
||||
{
|
||||
Variant<Hyperlink<item>, uint32> val;
|
||||
Optional<std::string_view> next = SingleConsumer<decltype(val)>::TryConsumeTo(val, args);
|
||||
if (next)
|
||||
data = val.visit(ItemTemplateVisitor());
|
||||
return next;
|
||||
}
|
||||
|
||||
struct SpellInfoVisitor
|
||||
{
|
||||
using value_type = SpellInfo const*;
|
||||
|
||||
@@ -33,22 +33,22 @@ struct GameTele;
|
||||
namespace Trinity::Impl::ChatCommands
|
||||
{
|
||||
|
||||
/************************** ARGUMENT HANDLERS *******************************************\
|
||||
|* Define how to extract contents of a certain requested type from a string *|
|
||||
|* Must implement the following: *|
|
||||
|* - TryConsume: T&, std::string_view -> Optional<std::string_view> *|
|
||||
|* returns nullopt if no match, otherwise tail of argument string *|
|
||||
|* - if nullopt is returned, state of T& is indeterminate *|
|
||||
|* - otherwise, T& should be initialized to the intended return value *|
|
||||
|* *|
|
||||
\****************************************************************************************/
|
||||
template <typename T, typename = void>
|
||||
struct ArgInfo { static_assert(Trinity::dependant_false_v<T>, "Invalid command parameter type - see ChatCommandArgs.h for possible types"); };
|
||||
/************************** ARGUMENT HANDLERS *******************************************\
|
||||
|* Define how to extract contents of a certain requested type from a string *|
|
||||
|* Must implement the following: *|
|
||||
|* - TryConsume: T&, std::string_view -> Optional<std::string_view> *|
|
||||
|* returns nullopt if no match, otherwise tail of argument string *|
|
||||
|* - if nullopt is returned, state of T& is indeterminate *|
|
||||
|* - otherwise, T& should be initialized to the intended return value *|
|
||||
|* *|
|
||||
\****************************************************************************************/
|
||||
template <typename T, typename = void>
|
||||
struct ArgInfo { static_assert(Trinity::dependant_false_v<T>, "Invalid command parameter type - see ChatCommandArgs.h for possible types"); };
|
||||
|
||||
// catch-all for number types
|
||||
template <typename T>
|
||||
struct ArgInfo<T, std::enable_if_t<std::is_integral_v<T> || std::is_floating_point_v<T>>>
|
||||
{
|
||||
// catch-all for number types
|
||||
template <typename T>
|
||||
struct ArgInfo<T, std::enable_if_t<std::is_integral_v<T> || std::is_floating_point_v<T>>>
|
||||
{
|
||||
static Optional<std::string_view> TryConsume(T& val, std::string_view args)
|
||||
{
|
||||
auto [token, tail] = tokenize(args);
|
||||
@@ -68,12 +68,12 @@ struct ArgInfo<T, std::enable_if_t<std::is_integral_v<T> || std::is_floating_poi
|
||||
|
||||
return tail;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// string_view
|
||||
template <>
|
||||
struct ArgInfo<std::string_view, void>
|
||||
{
|
||||
// string_view
|
||||
template <>
|
||||
struct ArgInfo<std::string_view, void>
|
||||
{
|
||||
static Optional<std::string_view> TryConsume(std::string_view& val, std::string_view args)
|
||||
{
|
||||
auto [token, next] = tokenize(args);
|
||||
@@ -82,12 +82,12 @@ struct ArgInfo<std::string_view, void>
|
||||
val = token;
|
||||
return next;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// string
|
||||
template <>
|
||||
struct ArgInfo<std::string, void>
|
||||
{
|
||||
// string
|
||||
template <>
|
||||
struct ArgInfo<std::string, void>
|
||||
{
|
||||
static Optional<std::string_view> TryConsume(std::string& val, std::string_view args)
|
||||
{
|
||||
std::string_view view;
|
||||
@@ -96,12 +96,12 @@ struct ArgInfo<std::string, void>
|
||||
val.assign(view);
|
||||
return next;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// wstring
|
||||
template <>
|
||||
struct ArgInfo<std::wstring, void>
|
||||
{
|
||||
// wstring
|
||||
template <>
|
||||
struct ArgInfo<std::wstring, void>
|
||||
{
|
||||
static Optional<std::string_view> TryConsume(std::wstring& val, std::string_view args)
|
||||
{
|
||||
std::string_view utf8view;
|
||||
@@ -112,12 +112,12 @@ struct ArgInfo<std::wstring, void>
|
||||
else
|
||||
return std::nullopt;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// enum
|
||||
template <typename T>
|
||||
struct ArgInfo<T, std::enable_if_t<std::is_enum_v<T>>>
|
||||
{
|
||||
// enum
|
||||
template <typename T>
|
||||
struct ArgInfo<T, std::enable_if_t<std::is_enum_v<T>>>
|
||||
{
|
||||
static std::map<std::string, Optional<T>> MakeSearchMap()
|
||||
{
|
||||
std::map<std::string, Optional<T>> map;
|
||||
@@ -194,21 +194,22 @@ struct ArgInfo<T, std::enable_if_t<std::is_enum_v<T>>>
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// a container tag
|
||||
template <typename T>
|
||||
struct ArgInfo<T, std::enable_if_t<std::is_base_of_v<ContainerTag, T>>>
|
||||
{
|
||||
// a container tag
|
||||
template <typename T>
|
||||
struct ArgInfo<T, std::enable_if_t<std::is_base_of_v<ContainerTag, T>>>
|
||||
{
|
||||
static Optional<std::string_view> TryConsume(T& tag, std::string_view args)
|
||||
{
|
||||
return tag.TryConsume(args);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct ArgInfo<std::vector<T>, void>
|
||||
{
|
||||
// non-empty vector
|
||||
template <typename T>
|
||||
struct ArgInfo<std::vector<T>, void>
|
||||
{
|
||||
static Optional<std::string_view> TryConsume(std::vector<T>& val, std::string_view args)
|
||||
{
|
||||
val.clear();
|
||||
@@ -223,11 +224,12 @@ struct ArgInfo<std::vector<T>, void>
|
||||
val.pop_back();
|
||||
return next;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template <typename T, size_t N>
|
||||
struct ArgInfo<std::array<T, N>, void>
|
||||
{
|
||||
// fixed-size array
|
||||
template <typename T, size_t N>
|
||||
struct ArgInfo<std::array<T, N>, void>
|
||||
{
|
||||
static Optional<std::string_view> TryConsume(std::array<T, N>& val, std::string_view args)
|
||||
{
|
||||
Optional<std::string_view> next = args;
|
||||
@@ -236,35 +238,69 @@ struct ArgInfo<std::array<T, N>, void>
|
||||
return std::nullopt;
|
||||
return next;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// AchievementEntry* from numeric id or link
|
||||
template <>
|
||||
struct TC_GAME_API ArgInfo<AchievementEntry const*>
|
||||
{
|
||||
// variant
|
||||
template <typename... Ts>
|
||||
struct ArgInfo<Trinity::ChatCommands::Variant<Ts...>>
|
||||
{
|
||||
using V = std::variant<Ts...>;
|
||||
static constexpr size_t N = std::variant_size_v<V>;
|
||||
|
||||
template <size_t I>
|
||||
static Optional<std::string_view> TryAtIndex(Trinity::ChatCommands::Variant<Ts...>& val, [[maybe_unused]] std::string_view args)
|
||||
{
|
||||
if constexpr (I < N)
|
||||
{
|
||||
if (Optional<std::string_view> next = ArgInfo<std::variant_alternative_t<I, V>>::TryConsume(val.template emplace<I>(), args))
|
||||
return next;
|
||||
else
|
||||
return TryAtIndex<I + 1>(val, args);
|
||||
}
|
||||
else
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
static Optional<std::string_view> TryConsume(Trinity::ChatCommands::Variant<Ts...>& val, std::string_view args)
|
||||
{
|
||||
return TryAtIndex<0>(val, args);
|
||||
}
|
||||
};
|
||||
|
||||
// AchievementEntry* from numeric id or link
|
||||
template <>
|
||||
struct TC_GAME_API ArgInfo<AchievementEntry const*>
|
||||
{
|
||||
static Optional<std::string_view> TryConsume(AchievementEntry const*&, std::string_view);
|
||||
};
|
||||
};
|
||||
|
||||
// CurrencyTypesEntry* from numeric id or link
|
||||
template <>
|
||||
struct TC_GAME_API ArgInfo<CurrencyTypesEntry const*>
|
||||
{
|
||||
// CurrencyTypesEntry* from numeric id or link
|
||||
template <>
|
||||
struct TC_GAME_API ArgInfo<CurrencyTypesEntry const*>
|
||||
{
|
||||
static Optional<std::string_view> TryConsume(CurrencyTypesEntry const*&, std::string_view);
|
||||
};
|
||||
};
|
||||
|
||||
// GameTele* from string name or link
|
||||
template <>
|
||||
struct TC_GAME_API ArgInfo<GameTele const*>
|
||||
{
|
||||
// GameTele* from string name or link
|
||||
template <>
|
||||
struct TC_GAME_API ArgInfo<GameTele const*>
|
||||
{
|
||||
static Optional<std::string_view> TryConsume(GameTele const*&, std::string_view);
|
||||
};
|
||||
};
|
||||
|
||||
// SpellInfo const* from spell id or link
|
||||
template <>
|
||||
struct TC_GAME_API ArgInfo<SpellInfo const*>
|
||||
{
|
||||
// ItemTemplate* from numeric id or link
|
||||
template <>
|
||||
struct TC_GAME_API ArgInfo<ItemTemplate const*>
|
||||
{
|
||||
static Optional<std::string_view> TryConsume(ItemTemplate const*&, std::string_view);
|
||||
};
|
||||
|
||||
// SpellInfo const* from spell id or link
|
||||
template <>
|
||||
struct TC_GAME_API ArgInfo<SpellInfo const*>
|
||||
{
|
||||
static Optional<std::string_view> TryConsume(SpellInfo const*&, std::string_view);
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,12 @@ namespace Trinity::Impl::ChatCommands
|
||||
static constexpr bool value = (std::is_assignable_v<T&, Ts> && ...);
|
||||
};
|
||||
|
||||
template <typename... Ts>
|
||||
struct are_all_assignable<void, Ts...>
|
||||
{
|
||||
static constexpr bool value = false;
|
||||
};
|
||||
|
||||
template <std::size_t index, typename T1, typename... Ts>
|
||||
struct get_nth : get_nth<index-1, Ts...> { };
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace Trinity::ChatCommands
|
||||
|
||||
static bool Match(char const* pos)
|
||||
{
|
||||
if (*(pos++) != c1)
|
||||
if (std::toupper(*(pos++)) != std::toupper(c1))
|
||||
return false;
|
||||
else if constexpr (sizeof...(chars) > 0)
|
||||
return ExactSequence<chars...>::Match(pos);
|
||||
@@ -151,10 +151,6 @@ namespace Trinity::ChatCommands
|
||||
using namespace ::Trinity::Hyperlinks::LinkTags;
|
||||
}
|
||||
|
||||
/************************** VARIANT TAG LOGIC *********************************\
|
||||
|* This has some special handling over in ChatCommand.h *|
|
||||
\******************************************************************************/
|
||||
|
||||
namespace Trinity::Impl
|
||||
{
|
||||
template <typename T>
|
||||
|
||||
@@ -263,7 +263,7 @@ namespace Trinity::Hyperlinks
|
||||
make_base_tag(gameobject, ObjectGuid::LowType);
|
||||
make_base_tag(gameobject_entry, uint32);
|
||||
make_base_tag(itemset, uint32);
|
||||
make_base_tag(player, std::string const&);
|
||||
make_base_tag(player, std::string_view);
|
||||
make_base_tag(skill, uint32);
|
||||
make_base_tag(taxinode, uint32);
|
||||
make_base_tag(tele, uint32);
|
||||
|
||||
@@ -22034,7 +22034,7 @@ void Player::StopCastingCharm()
|
||||
}
|
||||
}
|
||||
|
||||
void Player::Say(std::string const& text, Language language, WorldObject const* /*= nullptr*/)
|
||||
void Player::Say(std::string_view text, Language language, WorldObject const* /*= nullptr*/)
|
||||
{
|
||||
std::string _text(text);
|
||||
sScriptMgr->OnPlayerChat(this, CHAT_MSG_SAY, language, _text);
|
||||
@@ -22060,7 +22060,7 @@ void Player::Say(uint32 textId, WorldObject const* target /*= nullptr*/)
|
||||
Talk(textId, CHAT_MSG_SAY, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), target);
|
||||
}
|
||||
|
||||
void Player::Yell(std::string const& text, Language language, WorldObject const* /*= nullptr*/)
|
||||
void Player::Yell(std::string_view text, Language language, WorldObject const* /*= nullptr*/)
|
||||
{
|
||||
std::string _text(text);
|
||||
sScriptMgr->OnPlayerChat(this, CHAT_MSG_YELL, language, _text);
|
||||
@@ -22073,7 +22073,7 @@ void Player::Yell(uint32 textId, WorldObject const* target /*= nullptr*/)
|
||||
Talk(textId, CHAT_MSG_YELL, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL), target);
|
||||
}
|
||||
|
||||
void Player::TextEmote(std::string const& text, WorldObject const* /*= nullptr*/, bool /*= false*/)
|
||||
void Player::TextEmote(std::string_view text, WorldObject const* /*= nullptr*/, bool /*= false*/)
|
||||
{
|
||||
std::string _text(text);
|
||||
sScriptMgr->OnPlayerChat(this, CHAT_MSG_EMOTE, LANG_UNIVERSAL, _text);
|
||||
@@ -22101,7 +22101,7 @@ void Player::TextEmote(uint32 textId, WorldObject const* target /*= nullptr*/, b
|
||||
Talk(textId, CHAT_MSG_EMOTE, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), target);
|
||||
}
|
||||
|
||||
void Player::Whisper(std::string const& text, Language language, Player* target, bool /*= false*/)
|
||||
void Player::Whisper(std::string_view text, Language language, Player* target, bool /*= false*/)
|
||||
{
|
||||
ASSERT(target);
|
||||
|
||||
|
||||
@@ -1224,16 +1224,16 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
|
||||
void SetBattlePetData(BattlePets::BattlePet const* pet = nullptr);
|
||||
|
||||
/// Handles said message in regular chat based on declared language and in config pre-defined Range.
|
||||
void Say(std::string const& text, Language language, WorldObject const* = nullptr) override;
|
||||
void Say(std::string_view text, Language language, WorldObject const* = nullptr) override;
|
||||
void Say(uint32 textId, WorldObject const* target = nullptr) override;
|
||||
/// Handles yelled message in regular chat based on declared language and in config pre-defined Range.
|
||||
void Yell(std::string const& text, Language language, WorldObject const* = nullptr) override;
|
||||
void Yell(std::string_view text, Language language, WorldObject const* = nullptr) override;
|
||||
void Yell(uint32 textId, WorldObject const* target = nullptr) override;
|
||||
/// Outputs an universal text which is supposed to be an action.
|
||||
void TextEmote(std::string const& text, WorldObject const* = nullptr, bool = false) override;
|
||||
void TextEmote(std::string_view text, WorldObject const* = nullptr, bool = false) override;
|
||||
void TextEmote(uint32 textId, WorldObject const* target = nullptr, bool isBossEmote = false) override;
|
||||
/// Handles whispers from Addons and players based on sender, receiver's guid and language.
|
||||
void Whisper(std::string const& text, Language language, Player* receiver, bool = false) override;
|
||||
void Whisper(std::string_view text, Language language, Player* receiver, bool = false) override;
|
||||
void Whisper(uint32 textId, Player* target, bool isBossWhisper = false) override;
|
||||
void WhisperAddon(std::string const& text, std::string const& prefix, bool isLogged, Player* receiver);
|
||||
|
||||
|
||||
@@ -13160,7 +13160,7 @@ bool Unit::IsHighestExclusiveAuraEffect(SpellInfo const* spellInfo, AuraType aur
|
||||
return true;
|
||||
}
|
||||
|
||||
void Unit::Talk(std::string const& text, ChatMsg msgType, Language language, float textRange, WorldObject const* target)
|
||||
void Unit::Talk(std::string_view text, ChatMsg msgType, Language language, float textRange, WorldObject const* target)
|
||||
{
|
||||
Trinity::CustomChatTextBuilder builder(this, msgType, text, language, target);
|
||||
Trinity::LocalizedDo<Trinity::CustomChatTextBuilder> localizer(builder);
|
||||
@@ -13168,22 +13168,22 @@ void Unit::Talk(std::string const& text, ChatMsg msgType, Language language, flo
|
||||
Cell::VisitWorldObjects(this, worker, textRange);
|
||||
}
|
||||
|
||||
void Unit::Say(std::string const& text, Language language, WorldObject const* target /*= nullptr*/)
|
||||
void Unit::Say(std::string_view text, Language language, WorldObject const* target /*= nullptr*/)
|
||||
{
|
||||
Talk(text, CHAT_MSG_MONSTER_SAY, language, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), target);
|
||||
}
|
||||
|
||||
void Unit::Yell(std::string const& text, Language language, WorldObject const* target /*= nullptr*/)
|
||||
void Unit::Yell(std::string_view text, Language language, WorldObject const* target /*= nullptr*/)
|
||||
{
|
||||
Talk(text, CHAT_MSG_MONSTER_YELL, language, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL), target);
|
||||
}
|
||||
|
||||
void Unit::TextEmote(std::string const& text, WorldObject const* target /*= nullptr*/, bool isBossEmote /*= false*/)
|
||||
void Unit::TextEmote(std::string_view text, WorldObject const* target /*= nullptr*/, bool isBossEmote /*= false*/)
|
||||
{
|
||||
Talk(text, isBossEmote ? CHAT_MSG_RAID_BOSS_EMOTE : CHAT_MSG_MONSTER_EMOTE, LANG_UNIVERSAL, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), target);
|
||||
}
|
||||
|
||||
void Unit::Whisper(std::string const& text, Language language, Player* target, bool isBossWhisper /*= false*/)
|
||||
void Unit::Whisper(std::string_view text, Language language, Player* target, bool isBossWhisper /*= false*/)
|
||||
{
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
@@ -1833,11 +1833,11 @@ class TC_GAME_API Unit : public WorldObject
|
||||
bool IsHighestExclusiveAura(Aura const* aura, bool removeOtherAuraApplications = false);
|
||||
bool IsHighestExclusiveAuraEffect(SpellInfo const* spellInfo, AuraType auraType, int32 effectAmount, uint32 auraEffectMask, bool removeOtherAuraApplications = false);
|
||||
|
||||
virtual void Talk(std::string const& text, ChatMsg msgType, Language language, float textRange, WorldObject const* target);
|
||||
virtual void Say(std::string const& text, Language language, WorldObject const* target = nullptr);
|
||||
virtual void Yell(std::string const& text, Language language, WorldObject const* target = nullptr);
|
||||
virtual void TextEmote(std::string const& text, WorldObject const* target = nullptr, bool isBossEmote = false);
|
||||
virtual void Whisper(std::string const& text, Language language, Player* target, bool isBossWhisper = false);
|
||||
virtual void Talk(std::string_view text, ChatMsg msgType, Language language, float textRange, WorldObject const* target);
|
||||
virtual void Say(std::string_view text, Language language, WorldObject const* target = nullptr);
|
||||
virtual void Yell(std::string_view text, Language language, WorldObject const* target = nullptr);
|
||||
virtual void TextEmote(std::string_view text, WorldObject const* target = nullptr, bool isBossEmote = false);
|
||||
virtual void Whisper(std::string_view text, Language language, Player* target, bool isBossWhisper = false);
|
||||
virtual void Talk(uint32 textId, ChatMsg msgType, float textRange, WorldObject const* target);
|
||||
virtual void Say(uint32 textId, WorldObject const* target = nullptr);
|
||||
virtual void Yell(uint32 textId, WorldObject const* target = nullptr);
|
||||
|
||||
@@ -78,28 +78,28 @@ template class TC_GAME_API HashMapHolder<Transport>;
|
||||
|
||||
namespace PlayerNameMapHolder
|
||||
{
|
||||
typedef std::unordered_map<std::string, Player*> MapType;
|
||||
static MapType PlayerNameMap;
|
||||
typedef std::unordered_map<std::string, Player*> MapType;
|
||||
static MapType PlayerNameMap;
|
||||
|
||||
void Insert(Player* p)
|
||||
{
|
||||
void Insert(Player* p)
|
||||
{
|
||||
PlayerNameMap[p->GetName()] = p;
|
||||
}
|
||||
}
|
||||
|
||||
void Remove(Player* p)
|
||||
{
|
||||
void Remove(Player* p)
|
||||
{
|
||||
PlayerNameMap.erase(p->GetName());
|
||||
}
|
||||
}
|
||||
|
||||
Player* Find(std::string const& name)
|
||||
{
|
||||
Player* Find(std::string_view name)
|
||||
{
|
||||
std::string charName(name);
|
||||
if (!normalizePlayerName(charName))
|
||||
return nullptr;
|
||||
|
||||
auto itr = PlayerNameMap.find(charName);
|
||||
return (itr != PlayerNameMap.end()) ? itr->second : nullptr;
|
||||
}
|
||||
}
|
||||
} // namespace PlayerNameMapHolder
|
||||
|
||||
WorldObject* ObjectAccessor::GetWorldObject(WorldObject const& p, ObjectGuid const& guid)
|
||||
@@ -264,7 +264,7 @@ Player* ObjectAccessor::FindPlayer(ObjectGuid const& guid)
|
||||
return player && player->IsInWorld() ? player : nullptr;
|
||||
}
|
||||
|
||||
Player* ObjectAccessor::FindPlayerByName(std::string const& name)
|
||||
Player* ObjectAccessor::FindPlayerByName(std::string_view name)
|
||||
{
|
||||
Player* player = PlayerNameMapHolder::Find(name);
|
||||
if (!player || !player->IsInWorld())
|
||||
@@ -284,7 +284,7 @@ Player* ObjectAccessor::FindConnectedPlayer(ObjectGuid const& guid)
|
||||
return HashMapHolder<Player>::Find(guid);
|
||||
}
|
||||
|
||||
Player* ObjectAccessor::FindConnectedPlayerByName(std::string const& name)
|
||||
Player* ObjectAccessor::FindConnectedPlayerByName(std::string_view name)
|
||||
{
|
||||
return PlayerNameMapHolder::Find(name);
|
||||
}
|
||||
|
||||
@@ -81,12 +81,12 @@ namespace ObjectAccessor
|
||||
// these functions return objects if found in whole world
|
||||
// ACCESS LIKE THAT IS NOT THREAD SAFE
|
||||
TC_GAME_API Player* FindPlayer(ObjectGuid const&);
|
||||
TC_GAME_API Player* FindPlayerByName(std::string const& name);
|
||||
TC_GAME_API Player* FindPlayerByName(std::string_view name);
|
||||
TC_GAME_API Player* FindPlayerByLowGUID(ObjectGuid::LowType lowguid);
|
||||
|
||||
// this returns Player even if he is not in world, for example teleporting
|
||||
TC_GAME_API Player* FindConnectedPlayer(ObjectGuid const&);
|
||||
TC_GAME_API Player* FindConnectedPlayerByName(std::string const& name);
|
||||
TC_GAME_API Player* FindConnectedPlayerByName(std::string_view name);
|
||||
|
||||
// when using this, you must use the hashmapholder's lock
|
||||
TC_GAME_API HashMapHolder<Player>::MapType const& GetPlayers();
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#define SPEED_CHARGE 42.0f // assume it is 25 yard per 0.6 second
|
||||
|
||||
// EnumUtils: DESCRIBE THIS
|
||||
enum MovementGeneratorType : uint8
|
||||
{
|
||||
IDLE_MOTION_TYPE = 0, // IdleMovementGenerator.h
|
||||
@@ -45,7 +46,7 @@ enum MovementGeneratorType : uint8
|
||||
EFFECT_MOTION_TYPE = 16,
|
||||
SPLINE_CHAIN_MOTION_TYPE = 17, // SplineChainMovementGenerator.h
|
||||
FORMATION_MOTION_TYPE = 18, // FormationMovementGenerator.h
|
||||
MAX_MOTION_TYPE // limit
|
||||
MAX_MOTION_TYPE // SKIP
|
||||
};
|
||||
|
||||
enum MovementGeneratorMode : uint8
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "MovementDefines.h"
|
||||
#include "Define.h"
|
||||
#include "SmartEnum.h"
|
||||
#include <stdexcept>
|
||||
|
||||
namespace Trinity::Impl::EnumUtilsImpl
|
||||
{
|
||||
|
||||
/*******************************************************************************\
|
||||
|* data for enum 'MovementGeneratorType' in 'MovementDefines.h' auto-generated *|
|
||||
\*******************************************************************************/
|
||||
template <>
|
||||
TC_API_EXPORT EnumText EnumUtils<MovementGeneratorType>::ToString(MovementGeneratorType value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case IDLE_MOTION_TYPE: return { "IDLE_MOTION_TYPE", "IDLE_MOTION_TYPE", "IdleMovementGenerator.h" };
|
||||
case RANDOM_MOTION_TYPE: return { "RANDOM_MOTION_TYPE", "RANDOM_MOTION_TYPE", "RandomMovementGenerator.h" };
|
||||
case WAYPOINT_MOTION_TYPE: return { "WAYPOINT_MOTION_TYPE", "WAYPOINT_MOTION_TYPE", "WaypointMovementGenerator.h" };
|
||||
case MAX_DB_MOTION_TYPE: return { "MAX_DB_MOTION_TYPE", "MAX_DB_MOTION_TYPE", "Below motion types can't be set in DB." };
|
||||
case CONFUSED_MOTION_TYPE: return { "CONFUSED_MOTION_TYPE", "CONFUSED_MOTION_TYPE", "ConfusedMovementGenerator.h" };
|
||||
case CHASE_MOTION_TYPE: return { "CHASE_MOTION_TYPE", "CHASE_MOTION_TYPE", "ChaseMovementGenerator.h" };
|
||||
case HOME_MOTION_TYPE: return { "HOME_MOTION_TYPE", "HOME_MOTION_TYPE", "HomeMovementGenerator.h" };
|
||||
case FLIGHT_MOTION_TYPE: return { "FLIGHT_MOTION_TYPE", "FLIGHT_MOTION_TYPE", "FlightPathMovementGenerator.h" };
|
||||
case POINT_MOTION_TYPE: return { "POINT_MOTION_TYPE", "POINT_MOTION_TYPE", "PointMovementGenerator.h" };
|
||||
case FLEEING_MOTION_TYPE: return { "FLEEING_MOTION_TYPE", "FLEEING_MOTION_TYPE", "FleeingMovementGenerator.h" };
|
||||
case DISTRACT_MOTION_TYPE: return { "DISTRACT_MOTION_TYPE", "DISTRACT_MOTION_TYPE", "IdleMovementGenerator.h" };
|
||||
case ASSISTANCE_MOTION_TYPE: return { "ASSISTANCE_MOTION_TYPE", "ASSISTANCE_MOTION_TYPE", "PointMovementGenerator.h" };
|
||||
case ASSISTANCE_DISTRACT_MOTION_TYPE: return { "ASSISTANCE_DISTRACT_MOTION_TYPE", "ASSISTANCE_DISTRACT_MOTION_TYPE", "IdleMovementGenerator.h" };
|
||||
case TIMED_FLEEING_MOTION_TYPE: return { "TIMED_FLEEING_MOTION_TYPE", "TIMED_FLEEING_MOTION_TYPE", "FleeingMovementGenerator.h" };
|
||||
case FOLLOW_MOTION_TYPE: return { "FOLLOW_MOTION_TYPE", "FOLLOW_MOTION_TYPE", "FollowMovementGenerator.h" };
|
||||
case ROTATE_MOTION_TYPE: return { "ROTATE_MOTION_TYPE", "ROTATE_MOTION_TYPE", "IdleMovementGenerator.h" };
|
||||
case EFFECT_MOTION_TYPE: return { "EFFECT_MOTION_TYPE", "EFFECT_MOTION_TYPE", "" };
|
||||
case SPLINE_CHAIN_MOTION_TYPE: return { "SPLINE_CHAIN_MOTION_TYPE", "SPLINE_CHAIN_MOTION_TYPE", "SplineChainMovementGenerator.h" };
|
||||
case FORMATION_MOTION_TYPE: return { "FORMATION_MOTION_TYPE", "FORMATION_MOTION_TYPE", "FormationMovementGenerator.h" };
|
||||
default: throw std::out_of_range("value");
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
TC_API_EXPORT size_t EnumUtils<MovementGeneratorType>::Count() { return 19; }
|
||||
|
||||
template <>
|
||||
TC_API_EXPORT MovementGeneratorType EnumUtils<MovementGeneratorType>::FromIndex(size_t index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: return IDLE_MOTION_TYPE;
|
||||
case 1: return RANDOM_MOTION_TYPE;
|
||||
case 2: return WAYPOINT_MOTION_TYPE;
|
||||
case 3: return MAX_DB_MOTION_TYPE;
|
||||
case 4: return CONFUSED_MOTION_TYPE;
|
||||
case 5: return CHASE_MOTION_TYPE;
|
||||
case 6: return HOME_MOTION_TYPE;
|
||||
case 7: return FLIGHT_MOTION_TYPE;
|
||||
case 8: return POINT_MOTION_TYPE;
|
||||
case 9: return FLEEING_MOTION_TYPE;
|
||||
case 10: return DISTRACT_MOTION_TYPE;
|
||||
case 11: return ASSISTANCE_MOTION_TYPE;
|
||||
case 12: return ASSISTANCE_DISTRACT_MOTION_TYPE;
|
||||
case 13: return TIMED_FLEEING_MOTION_TYPE;
|
||||
case 14: return FOLLOW_MOTION_TYPE;
|
||||
case 15: return ROTATE_MOTION_TYPE;
|
||||
case 16: return EFFECT_MOTION_TYPE;
|
||||
case 17: return SPLINE_CHAIN_MOTION_TYPE;
|
||||
case 18: return FORMATION_MOTION_TYPE;
|
||||
default: throw std::out_of_range("index");
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
TC_API_EXPORT size_t EnumUtils<MovementGeneratorType>::ToIndex(MovementGeneratorType value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case IDLE_MOTION_TYPE: return 0;
|
||||
case RANDOM_MOTION_TYPE: return 1;
|
||||
case WAYPOINT_MOTION_TYPE: return 2;
|
||||
case MAX_DB_MOTION_TYPE: return 3;
|
||||
case CONFUSED_MOTION_TYPE: return 4;
|
||||
case CHASE_MOTION_TYPE: return 5;
|
||||
case HOME_MOTION_TYPE: return 6;
|
||||
case FLIGHT_MOTION_TYPE: return 7;
|
||||
case POINT_MOTION_TYPE: return 8;
|
||||
case FLEEING_MOTION_TYPE: return 9;
|
||||
case DISTRACT_MOTION_TYPE: return 10;
|
||||
case ASSISTANCE_MOTION_TYPE: return 11;
|
||||
case ASSISTANCE_DISTRACT_MOTION_TYPE: return 12;
|
||||
case TIMED_FLEEING_MOTION_TYPE: return 13;
|
||||
case FOLLOW_MOTION_TYPE: return 14;
|
||||
case ROTATE_MOTION_TYPE: return 15;
|
||||
case EFFECT_MOTION_TYPE: return 16;
|
||||
case SPLINE_CHAIN_MOTION_TYPE: return 17;
|
||||
case FORMATION_MOTION_TYPE: return 18;
|
||||
default: throw std::out_of_range("value");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -71,7 +71,7 @@ namespace Trinity
|
||||
class CustomChatTextBuilder
|
||||
{
|
||||
public:
|
||||
CustomChatTextBuilder(WorldObject const* obj, ChatMsg msgType, std::string const& text, Language language = LANG_UNIVERSAL, WorldObject const* target = nullptr)
|
||||
CustomChatTextBuilder(WorldObject const* obj, ChatMsg msgType, std::string_view text, Language language = LANG_UNIVERSAL, WorldObject const* target = nullptr)
|
||||
: _source(obj), _msgType(msgType), _text(text), _language(language), _target(target) { }
|
||||
|
||||
ChatPacketSender* operator()(LocaleConstant locale) const;
|
||||
|
||||
@@ -45,13 +45,15 @@ EndScriptData */
|
||||
#include <sstream>
|
||||
#include <typeinfo>
|
||||
|
||||
// definitions are over in cs_npc.cpp
|
||||
bool HandleNpcSpawnGroup(ChatHandler* handler, char const* args);
|
||||
bool HandleNpcDespawnGroup(ChatHandler* handler, char const* args);
|
||||
|
||||
using namespace Trinity::ChatCommands;
|
||||
using GameObjectSpawnId = Variant<Hyperlink<gameobject>, ObjectGuid::LowType>;
|
||||
using GameObjectEntry = Variant<Hyperlink<gameobject_entry>, uint32>;
|
||||
|
||||
// definitions are over in cs_npc.cpp
|
||||
bool HandleNpcSpawnGroup(ChatHandler* handler, std::vector<Variant<uint32, ExactSequence<'f','o','r','c','e'>, ExactSequence<'i','g','n','o','r','e','r','e','s','p','a','w','n'>>> const& opts);
|
||||
bool HandleNpcDespawnGroup(ChatHandler* handler, std::vector<Variant<uint32, ExactSequence<'r','e','m','o','v','e','r','e','s','p','a','w','n','t','i','m','e'>>> const& opts);
|
||||
|
||||
class gobject_commandscript : public CommandScript
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -48,87 +48,14 @@ EndScriptData */
|
||||
#include <boost/core/demangle.hpp>
|
||||
#include <typeinfo>
|
||||
|
||||
bool HandleNpcSpawnGroup(ChatHandler* handler, char const* args)
|
||||
{
|
||||
if (!*args)
|
||||
return false;
|
||||
|
||||
bool ignoreRespawn = false;
|
||||
bool force = false;
|
||||
uint32 groupId = 0;
|
||||
|
||||
// Decode arguments
|
||||
char* arg = strtok((char*)args, " ");
|
||||
while (arg)
|
||||
{
|
||||
std::string thisArg = arg;
|
||||
std::transform(thisArg.begin(), thisArg.end(), thisArg.begin(), ::tolower);
|
||||
if (thisArg == "ignorerespawn")
|
||||
ignoreRespawn = true;
|
||||
else if (thisArg == "force")
|
||||
force = true;
|
||||
else if (thisArg.empty() || !(std::count_if(thisArg.begin(), thisArg.end(), ::isdigit) == (int)thisArg.size()))
|
||||
return false;
|
||||
else
|
||||
groupId = atoi(thisArg.c_str());
|
||||
|
||||
arg = strtok(nullptr, " ");
|
||||
}
|
||||
|
||||
Player* player = handler->GetSession()->GetPlayer();
|
||||
|
||||
std::vector <WorldObject*> creatureList;
|
||||
if (!player->GetMap()->SpawnGroupSpawn(groupId, ignoreRespawn, force, &creatureList))
|
||||
{
|
||||
handler->PSendSysMessage(LANG_SPAWNGROUP_BADGROUP, groupId);
|
||||
handler->SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
handler->PSendSysMessage(LANG_SPAWNGROUP_SPAWNCOUNT, creatureList.size());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HandleNpcDespawnGroup(ChatHandler* handler, char const* args)
|
||||
{
|
||||
if (!*args)
|
||||
return false;
|
||||
|
||||
bool deleteRespawnTimes = false;
|
||||
uint32 groupId = 0;
|
||||
|
||||
// Decode arguments
|
||||
char* arg = strtok((char*)args, " ");
|
||||
while (arg)
|
||||
{
|
||||
std::string thisArg = arg;
|
||||
std::transform(thisArg.begin(), thisArg.end(), thisArg.begin(), ::tolower);
|
||||
if (thisArg == "removerespawntime")
|
||||
deleteRespawnTimes = true;
|
||||
else if (thisArg.empty() || !(std::count_if(thisArg.begin(), thisArg.end(), ::isdigit) == (int)thisArg.size()))
|
||||
return false;
|
||||
else
|
||||
groupId = atoi(thisArg.c_str());
|
||||
|
||||
arg = strtok(nullptr, " ");
|
||||
}
|
||||
|
||||
Player* player = handler->GetSession()->GetPlayer();
|
||||
|
||||
size_t n = 0;
|
||||
if (!player->GetMap()->SpawnGroupDespawn(groupId, deleteRespawnTimes, &n))
|
||||
{
|
||||
handler->PSendSysMessage(LANG_SPAWNGROUP_BADGROUP, groupId);
|
||||
handler->SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
handler->PSendSysMessage("Despawned a total of %zu objects.", n);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
using namespace Trinity::ChatCommands;
|
||||
using CreatureSpawnId = Variant<Hyperlink<creature>, ObjectGuid::LowType>;
|
||||
using CreatureEntry = Variant<Hyperlink<creature_entry>, uint32>;
|
||||
|
||||
// shared with cs_gobject.cpp, definitions are at the bottom of this file
|
||||
bool HandleNpcSpawnGroup(ChatHandler* handler, std::vector<Variant<uint32, ExactSequence<'f','o','r','c','e'>, ExactSequence<'i','g','n','o','r','e','r','e','s','p','a','w','n'>>> const& opts);
|
||||
bool HandleNpcDespawnGroup(ChatHandler* handler, std::vector<Variant<uint32, ExactSequence<'r','e','m','o','v','e','r','e','s','p','a','w','n','t','i','m','e'>>> const& opts);
|
||||
|
||||
class npc_commandscript : public CommandScript
|
||||
{
|
||||
public:
|
||||
@@ -199,16 +126,8 @@ public:
|
||||
}
|
||||
|
||||
//add spawn of creature
|
||||
static bool HandleNpcAddCommand(ChatHandler* handler, char const* args)
|
||||
static bool HandleNpcAddCommand(ChatHandler* handler, CreatureEntry id)
|
||||
{
|
||||
if (!*args)
|
||||
return false;
|
||||
|
||||
char* charID = handler->extractKeyFromLink((char*)args, "Hcreature_entry");
|
||||
if (!charID)
|
||||
return false;
|
||||
|
||||
uint32 id = atoul(charID);
|
||||
if (!sObjectMgr->GetCreatureTemplate(id))
|
||||
return false;
|
||||
|
||||
@@ -254,38 +173,15 @@ public:
|
||||
}
|
||||
|
||||
//add item in vendorlist
|
||||
static bool HandleNpcAddVendorItemCommand(ChatHandler* handler, char const* args)
|
||||
static bool HandleNpcAddVendorItemCommand(ChatHandler* handler, ItemTemplate const* item, Optional<uint32> mc, Optional<uint32> it, Optional<uint32> ec, Optional<std::string_view> bonusListIDs)
|
||||
{
|
||||
if (!*args)
|
||||
return false;
|
||||
|
||||
const uint8 type = 1; // FIXME: make type (1 item, 2 currency) an argument
|
||||
|
||||
char* pitem = handler->extractKeyFromLink((char*)args, "Hitem");
|
||||
if (!pitem)
|
||||
if (!item)
|
||||
{
|
||||
handler->SendSysMessage(LANG_COMMAND_NEEDITEMSEND);
|
||||
handler->SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 itemId = atoull(pitem);
|
||||
if (!itemId)
|
||||
return false;
|
||||
|
||||
char* fmaxcount = strtok(nullptr, " "); //add maxcount, default: 0
|
||||
uint32 maxcount = 0;
|
||||
if (fmaxcount)
|
||||
maxcount = atoul(fmaxcount);
|
||||
|
||||
char* fincrtime = strtok(nullptr, " "); //add incrtime, default: 0
|
||||
uint32 incrtime = 0;
|
||||
if (fincrtime)
|
||||
incrtime = atoul(fincrtime);
|
||||
|
||||
char* fextendedcost = strtok(nullptr, " "); //add ExtendedCost, default: 0
|
||||
uint32 extendedcost = fextendedcost ? atoul(fextendedcost) : 0;
|
||||
char const* fbonuslist = strtok(nullptr, " ");
|
||||
Creature* vendor = handler->getSelectedCreature();
|
||||
if (!vendor)
|
||||
{
|
||||
@@ -294,6 +190,10 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 itemId = item->GetId();
|
||||
uint32 maxcount = mc.value_or(0);
|
||||
uint32 incrtime = it.value_or(0);
|
||||
uint32 extendedcost = ec.value_or(0);
|
||||
uint32 vendor_entry = vendor->GetEntry();
|
||||
|
||||
VendorItem vItem;
|
||||
@@ -301,10 +201,10 @@ public:
|
||||
vItem.maxcount = maxcount;
|
||||
vItem.incrtime = incrtime;
|
||||
vItem.ExtendedCost = extendedcost;
|
||||
vItem.Type = type;
|
||||
vItem.Type = ITEM_VENDOR_TYPE_ITEM;
|
||||
|
||||
if (fbonuslist)
|
||||
for (std::string_view token : Trinity::Tokenize(fbonuslist, ';', false))
|
||||
if (bonusListIDs)
|
||||
for (std::string_view token : Trinity::Tokenize(*bonusListIDs, ';', false))
|
||||
if (Optional<int32> bonusListID = Trinity::StringTo<int32>(token))
|
||||
vItem.BonusListIDs.push_back(*bonusListID);
|
||||
|
||||
@@ -323,16 +223,8 @@ public:
|
||||
}
|
||||
|
||||
//add move for creature
|
||||
static bool HandleNpcAddMoveCommand(ChatHandler* handler, char const* args)
|
||||
static bool HandleNpcAddMoveCommand(ChatHandler* handler, CreatureSpawnId lowGuid)
|
||||
{
|
||||
if (!*args)
|
||||
return false;
|
||||
|
||||
char* guidStr = strtok((char*)args, " ");
|
||||
char* waitStr = strtok((char*)nullptr, " ");
|
||||
|
||||
ObjectGuid::LowType lowGuid = atoull(guidStr);
|
||||
|
||||
// attempt check creature existence by DB data
|
||||
CreatureData const* data = sObjectMgr->GetCreatureData(lowGuid);
|
||||
if (!data)
|
||||
@@ -342,11 +234,6 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
int wait = waitStr ? atoi(waitStr) : 0;
|
||||
|
||||
if (wait < 0)
|
||||
wait = 0;
|
||||
|
||||
// Update movement type
|
||||
WorldDatabasePreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_CREATURE_MOVEMENT_TYPE);
|
||||
|
||||
@@ -360,7 +247,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool HandleNpcSetAllowMovementCommand(ChatHandler* handler, char const* /*args*/)
|
||||
static bool HandleNpcSetAllowMovementCommand(ChatHandler* handler)
|
||||
{
|
||||
if (sWorld->getAllowMovement())
|
||||
{
|
||||
@@ -375,12 +262,8 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool HandleNpcSetEntryCommand(ChatHandler* handler, char const* args)
|
||||
static bool HandleNpcSetEntryCommand(ChatHandler* handler, CreatureEntry newEntryNum)
|
||||
{
|
||||
if (!*args)
|
||||
return false;
|
||||
|
||||
uint32 newEntryNum = atoul(args);
|
||||
if (!newEntryNum)
|
||||
return false;
|
||||
|
||||
@@ -400,12 +283,8 @@ public:
|
||||
}
|
||||
|
||||
//change level of creature or pet
|
||||
static bool HandleNpcSetLevelCommand(ChatHandler* handler, char const* args)
|
||||
static bool HandleNpcSetLevelCommand(ChatHandler* handler, uint8 lvl)
|
||||
{
|
||||
if (!*args)
|
||||
return false;
|
||||
|
||||
uint8 lvl = (uint8) atoi(args);
|
||||
if (lvl < 1 || lvl > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) + 3)
|
||||
{
|
||||
handler->SendSysMessage(LANG_BAD_VALUE);
|
||||
@@ -429,7 +308,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool HandleNpcDeleteCommand(ChatHandler* handler, Optional<Variant<Hyperlink<creature>, ObjectGuid::LowType>> spawnIdArg)
|
||||
static bool HandleNpcDeleteCommand(ChatHandler* handler, Optional<CreatureSpawnId> spawnIdArg)
|
||||
{
|
||||
ObjectGuid::LowType spawnId;
|
||||
if (spawnIdArg)
|
||||
@@ -466,11 +345,8 @@ public:
|
||||
}
|
||||
|
||||
//del item from vendor list
|
||||
static bool HandleNpcDeleteVendorItemCommand(ChatHandler* handler, char const* args)
|
||||
static bool HandleNpcDeleteVendorItemCommand(ChatHandler* handler, ItemTemplate const* item)
|
||||
{
|
||||
if (!*args)
|
||||
return false;
|
||||
|
||||
Creature* vendor = handler->getSelectedCreature();
|
||||
if (!vendor || !vendor->IsVendor())
|
||||
{
|
||||
@@ -479,18 +355,15 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
char* pitem = handler->extractKeyFromLink((char*)args, "Hitem");
|
||||
if (!pitem)
|
||||
if (!item)
|
||||
{
|
||||
handler->SendSysMessage(LANG_COMMAND_NEEDITEMSEND);
|
||||
handler->SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
uint32 itemId = atoul(pitem);
|
||||
|
||||
const uint8 type = 1; // FIXME: make type (1 item, 2 currency) an argument
|
||||
|
||||
if (!sObjectMgr->RemoveVendorItem(vendor->GetEntry(), itemId, type))
|
||||
uint32 itemId = item->GetId();
|
||||
if (!sObjectMgr->RemoveVendorItem(vendor->GetEntry(), ITEM_VENDOR_TYPE_ITEM, itemId))
|
||||
{
|
||||
handler->PSendSysMessage(LANG_ITEM_NOT_IN_LIST, itemId);
|
||||
handler->SetSentErrorMessage(true);
|
||||
@@ -504,13 +377,8 @@ public:
|
||||
}
|
||||
|
||||
//set faction of creature
|
||||
static bool HandleNpcSetFactionIdCommand(ChatHandler* handler, char const* args)
|
||||
static bool HandleNpcSetFactionIdCommand(ChatHandler* handler, uint32 factionId)
|
||||
{
|
||||
if (!*args)
|
||||
return false;
|
||||
|
||||
uint32 factionId = atoul(args);
|
||||
|
||||
if (!sFactionTemplateStore.LookupEntry(factionId))
|
||||
{
|
||||
handler->PSendSysMessage(LANG_WRONG_FACTION, factionId);
|
||||
@@ -574,23 +442,8 @@ public:
|
||||
}
|
||||
|
||||
//set data of creature for testing scripting
|
||||
static bool HandleNpcSetDataCommand(ChatHandler* handler, char const* args)
|
||||
static bool HandleNpcSetDataCommand(ChatHandler* handler, uint32 data_1, uint32 data_2)
|
||||
{
|
||||
if (!*args)
|
||||
return false;
|
||||
|
||||
char* arg1 = strtok((char*)args, " ");
|
||||
char* arg2 = strtok((char*)nullptr, "");
|
||||
|
||||
if (!arg1 || !arg2)
|
||||
return false;
|
||||
|
||||
uint32 data_1 = (uint32)atoi(arg1);
|
||||
uint32 data_2 = (uint32)atoi(arg2);
|
||||
|
||||
if (!data_1 || !data_2)
|
||||
return false;
|
||||
|
||||
Creature* creature = handler->getSelectedCreature();
|
||||
|
||||
if (!creature)
|
||||
@@ -607,7 +460,7 @@ public:
|
||||
}
|
||||
|
||||
//npc follow handling
|
||||
static bool HandleNpcFollowCommand(ChatHandler* handler, char const* /*args*/)
|
||||
static bool HandleNpcFollowCommand(ChatHandler* handler)
|
||||
{
|
||||
Player* player = handler->GetSession()->GetPlayer();
|
||||
Creature* creature = handler->getSelectedCreature();
|
||||
@@ -626,7 +479,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool HandleNpcInfoCommand(ChatHandler* handler, char const* /*args*/)
|
||||
static bool HandleNpcInfoCommand(ChatHandler* handler)
|
||||
{
|
||||
Creature* target = handler->getSelectedCreature();
|
||||
|
||||
@@ -720,9 +573,9 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool HandleNpcNearCommand(ChatHandler* handler, char const* args)
|
||||
static bool HandleNpcNearCommand(ChatHandler* handler, Optional<float> dist)
|
||||
{
|
||||
float distance = (!*args) ? 10.0f : float((atof(args)));
|
||||
float distance = dist.value_or(10.0f);
|
||||
uint32 count = 0;
|
||||
|
||||
Player* player = handler->GetSession()->GetPlayer();
|
||||
@@ -767,26 +620,17 @@ public:
|
||||
}
|
||||
|
||||
//move selected creature
|
||||
static bool HandleNpcMoveCommand(ChatHandler* handler, char const* args)
|
||||
static bool HandleNpcMoveCommand(ChatHandler* handler, Optional<CreatureSpawnId> spawnid)
|
||||
{
|
||||
ObjectGuid::LowType lowguid = UI64LIT(0);
|
||||
|
||||
Creature* creature = handler->getSelectedCreature();
|
||||
Player const* player = handler->GetSession()->GetPlayer();
|
||||
if (!player)
|
||||
return false;
|
||||
|
||||
if (creature)
|
||||
lowguid = creature->GetSpawnId();
|
||||
else
|
||||
{
|
||||
// number or [name] Shift-click form |color|Hcreature:creature_guid|h[name]|h|r
|
||||
char* cId = handler->extractKeyFromLink((char*)args, "Hcreature");
|
||||
if (!cId)
|
||||
if (!spawnid && !creature)
|
||||
return false;
|
||||
|
||||
lowguid = atoull(cId);
|
||||
}
|
||||
ObjectGuid::LowType lowguid = spawnid ? *spawnid : creature->GetSpawnId();
|
||||
// Attempting creature load from DB data
|
||||
CreatureData const* data = sObjectMgr->GetCreatureData(lowguid);
|
||||
if (!data)
|
||||
@@ -819,23 +663,15 @@ public:
|
||||
|
||||
// respawn selected creature at the new location
|
||||
if (creature)
|
||||
{
|
||||
if (creature->IsAlive())
|
||||
creature->setDeathState(JUST_DIED);
|
||||
creature->Respawn(true);
|
||||
if (!creature->GetRespawnCompatibilityMode())
|
||||
creature->AddObjectToRemoveList();
|
||||
}
|
||||
creature->DespawnOrUnsummon(0s, 1s);
|
||||
|
||||
handler->PSendSysMessage(LANG_COMMAND_CREATUREMOVED);
|
||||
return true;
|
||||
}
|
||||
|
||||
//play npc emote
|
||||
static bool HandleNpcPlayEmoteCommand(ChatHandler* handler, char const* args)
|
||||
static bool HandleNpcPlayEmoteCommand(ChatHandler* handler, uint32 emote)
|
||||
{
|
||||
uint32 emote = atoi((char*)args);
|
||||
|
||||
Creature* target = handler->getSelectedCreature();
|
||||
if (!target)
|
||||
{
|
||||
@@ -850,13 +686,8 @@ public:
|
||||
}
|
||||
|
||||
//set model of creature
|
||||
static bool HandleNpcSetModelCommand(ChatHandler* handler, char const* args)
|
||||
static bool HandleNpcSetModelCommand(ChatHandler* handler, uint32 displayId)
|
||||
{
|
||||
if (!*args)
|
||||
return false;
|
||||
|
||||
uint32 displayId = atoul(args);
|
||||
|
||||
Creature* creature = handler->getSelectedCreature();
|
||||
|
||||
if (!creature || creature->IsPet())
|
||||
@@ -868,7 +699,7 @@ public:
|
||||
|
||||
if (!sCreatureDisplayInfoStore.LookupEntry(displayId))
|
||||
{
|
||||
handler->PSendSysMessage(LANG_COMMAND_INVALID_PARAM, args);
|
||||
handler->PSendSysMessage(LANG_COMMAND_INVALID_PARAM, Trinity::ToString(displayId).c_str());
|
||||
handler->SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
@@ -893,11 +724,8 @@ public:
|
||||
* additional parameter: NODEL - so no waypoints are deleted, if you
|
||||
* change the movement type
|
||||
*/
|
||||
static bool HandleNpcSetMoveTypeCommand(ChatHandler* handler, char const* args)
|
||||
static bool HandleNpcSetMoveTypeCommand(ChatHandler* handler, Optional<CreatureSpawnId> lowGuid, Variant<ExactSequence<'s','t','a','y'>, ExactSequence<'r','a','n','d','o','m'>, ExactSequence<'w','a','y'>> type, Optional<ExactSequence<'n','o','d','e','l'>> nodel)
|
||||
{
|
||||
if (!*args)
|
||||
return false;
|
||||
|
||||
// 3 arguments:
|
||||
// GUID (optional - you can also select the creature)
|
||||
// stay|random|way (determines the kind of movement)
|
||||
@@ -905,50 +733,14 @@ public:
|
||||
// this is very handy if you want to do waypoints, that are
|
||||
// later switched on/off according to special events (like escort
|
||||
// quests, etc)
|
||||
char* guid_str = strtok((char*)args, " ");
|
||||
char* type_str = strtok((char*)nullptr, " ");
|
||||
char* dontdel_str = strtok((char*)nullptr, " ");
|
||||
|
||||
bool doNotDelete = false;
|
||||
|
||||
if (!guid_str)
|
||||
return false;
|
||||
bool doNotDelete = nodel.has_value();
|
||||
|
||||
ObjectGuid::LowType lowguid = UI64LIT(0);
|
||||
Creature* creature = nullptr;
|
||||
|
||||
if (dontdel_str)
|
||||
if (!lowGuid) // case .setmovetype $move_type (with selected creature)
|
||||
{
|
||||
//TC_LOG_ERROR("misc", "DEBUG: All 3 params are set");
|
||||
|
||||
// All 3 params are set
|
||||
// GUID
|
||||
// type
|
||||
// doNotDEL
|
||||
if (stricmp(dontdel_str, "NODEL") == 0)
|
||||
{
|
||||
//TC_LOG_ERROR("misc", "DEBUG: doNotDelete = true;");
|
||||
doNotDelete = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Only 2 params - but maybe NODEL is set
|
||||
if (type_str)
|
||||
{
|
||||
TC_LOG_ERROR("misc", "DEBUG: Only 2 params ");
|
||||
if (stricmp(type_str, "NODEL") == 0)
|
||||
{
|
||||
//TC_LOG_ERROR("misc", "DEBUG: type_str, NODEL ");
|
||||
doNotDelete = true;
|
||||
type_str = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!type_str) // case .setmovetype $move_type (with selected creature)
|
||||
{
|
||||
type_str = guid_str;
|
||||
creature = handler->getSelectedCreature();
|
||||
if (!creature || creature->IsPet())
|
||||
return false;
|
||||
@@ -956,7 +748,7 @@ public:
|
||||
}
|
||||
else // case .setmovetype #creature_guid $move_type (with selected creature)
|
||||
{
|
||||
lowguid = atoull(guid_str);
|
||||
lowguid = *lowGuid;
|
||||
|
||||
if (lowguid)
|
||||
creature = handler->GetCreatureFromPlayerMapByDbGuid(lowguid);
|
||||
@@ -982,17 +774,20 @@ public:
|
||||
// and creature point (maybe) to this creature or nullptr
|
||||
|
||||
MovementGeneratorType move_type;
|
||||
|
||||
std::string type = type_str;
|
||||
|
||||
if (type == "stay")
|
||||
switch (type.index())
|
||||
{
|
||||
case 0:
|
||||
move_type = IDLE_MOTION_TYPE;
|
||||
else if (type == "random")
|
||||
break;
|
||||
case 1:
|
||||
move_type = RANDOM_MOTION_TYPE;
|
||||
else if (type == "way")
|
||||
break;
|
||||
case 2:
|
||||
move_type = WAYPOINT_MOTION_TYPE;
|
||||
else
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
// update movement type
|
||||
//if (doNotDelete == false)
|
||||
@@ -1015,11 +810,11 @@ public:
|
||||
}
|
||||
if (doNotDelete == false)
|
||||
{
|
||||
handler->PSendSysMessage(LANG_MOVE_TYPE_SET, type_str);
|
||||
handler->PSendSysMessage(LANG_MOVE_TYPE_SET, EnumUtils::ToTitle(move_type));
|
||||
}
|
||||
else
|
||||
{
|
||||
handler->PSendSysMessage(LANG_MOVE_TYPE_SET_NODEL, type_str);
|
||||
handler->PSendSysMessage(LANG_MOVE_TYPE_SET_NODEL, EnumUtils::ToTitle(move_type));
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -1053,13 +848,9 @@ public:
|
||||
|
||||
//npc phase handling
|
||||
//change phase of creature
|
||||
static bool HandleNpcSetPhaseCommand(ChatHandler* handler, char const* args)
|
||||
static bool HandleNpcSetPhaseCommand(ChatHandler* handler, uint32 phaseID)
|
||||
{
|
||||
if (!*args)
|
||||
return false;
|
||||
|
||||
uint32 phaseID = atoul(args);
|
||||
if (!sPhaseStore.LookupEntry(phaseID))
|
||||
if (phaseID == 0)
|
||||
{
|
||||
handler->SendSysMessage(LANG_PHASE_NOTFOUND);
|
||||
handler->SetSentErrorMessage(true);
|
||||
@@ -1084,12 +875,8 @@ public:
|
||||
}
|
||||
|
||||
//set spawn dist of creature
|
||||
static bool HandleNpcSetWanderDistanceCommand(ChatHandler* handler, char const* args)
|
||||
static bool HandleNpcSetWanderDistanceCommand(ChatHandler* handler, float option)
|
||||
{
|
||||
if (!*args)
|
||||
return false;
|
||||
|
||||
float option = (float)(atof((char*)args));
|
||||
if (option < 0.0f)
|
||||
{
|
||||
handler->SendSysMessage(LANG_BAD_VALUE);
|
||||
@@ -1097,7 +884,7 @@ public:
|
||||
}
|
||||
|
||||
MovementGeneratorType mtype = IDLE_MOTION_TYPE;
|
||||
if (option >0.0f)
|
||||
if (option > 0.0f)
|
||||
mtype = RANDOM_MOTION_TYPE;
|
||||
|
||||
Creature* creature = handler->getSelectedCreature();
|
||||
@@ -1130,28 +917,15 @@ public:
|
||||
}
|
||||
|
||||
//spawn time handling
|
||||
static bool HandleNpcSetSpawnTimeCommand(ChatHandler* handler, char const* args)
|
||||
static bool HandleNpcSetSpawnTimeCommand(ChatHandler* handler, uint32 spawnTime)
|
||||
{
|
||||
if (!*args)
|
||||
return false;
|
||||
|
||||
char* stime = strtok((char*)args, " ");
|
||||
|
||||
if (!stime)
|
||||
return false;
|
||||
|
||||
uint32 spawnTime = atoul(stime);
|
||||
|
||||
Creature* creature = handler->getSelectedCreature();
|
||||
if (!creature)
|
||||
return false;
|
||||
|
||||
ObjectGuid::LowType guidLow = creature->GetSpawnId();
|
||||
|
||||
WorldDatabasePreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_CREATURE_SPAWN_TIME_SECS);
|
||||
stmt->setUInt32(0, spawnTime);
|
||||
stmt->setUInt64(1, guidLow);
|
||||
|
||||
stmt->setUInt64(1, creature->GetSpawnId());
|
||||
WorldDatabase.Execute(stmt);
|
||||
|
||||
creature->SetRespawnDelay(spawnTime);
|
||||
@@ -1160,9 +934,9 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool HandleNpcSayCommand(ChatHandler* handler, char const* args)
|
||||
static bool HandleNpcSayCommand(ChatHandler* handler, Tail text)
|
||||
{
|
||||
if (!*args)
|
||||
if (text.empty())
|
||||
return false;
|
||||
|
||||
Creature* creature = handler->getSelectedCreature();
|
||||
@@ -1173,11 +947,10 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
creature->Say(args, LANG_UNIVERSAL);
|
||||
creature->Say(text, LANG_UNIVERSAL);
|
||||
|
||||
// make some emotes
|
||||
char lastchar = args[strlen(args) - 1];
|
||||
switch (lastchar)
|
||||
switch (text.back())
|
||||
{
|
||||
case '?': creature->HandleEmoteCommand(EMOTE_ONESHOT_QUESTION); break;
|
||||
case '!': creature->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION); break;
|
||||
@@ -1188,9 +961,9 @@ public:
|
||||
}
|
||||
|
||||
//show text emote by creature in chat
|
||||
static bool HandleNpcTextEmoteCommand(ChatHandler* handler, char const* args)
|
||||
static bool HandleNpcTextEmoteCommand(ChatHandler* handler, Tail text)
|
||||
{
|
||||
if (!*args)
|
||||
if (text.empty())
|
||||
return false;
|
||||
|
||||
Creature* creature = handler->getSelectedCreature();
|
||||
@@ -1202,13 +975,13 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
creature->TextEmote(args);
|
||||
creature->TextEmote(text);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// npc unfollow handling
|
||||
static bool HandleNpcUnFollowCommand(ChatHandler* handler, char const* /*args*/)
|
||||
static bool HandleNpcUnFollowCommand(ChatHandler* handler)
|
||||
{
|
||||
Player* player = handler->GetSession()->GetPlayer();
|
||||
Creature* creature = handler->getSelectedCreature();
|
||||
@@ -1243,24 +1016,10 @@ public:
|
||||
}
|
||||
|
||||
// make npc whisper to player
|
||||
static bool HandleNpcWhisperCommand(ChatHandler* handler, char const* args)
|
||||
static bool HandleNpcWhisperCommand(ChatHandler* handler, Variant<Hyperlink<player>, std::string_view> recv, Tail text)
|
||||
{
|
||||
if (!*args)
|
||||
{
|
||||
handler->SendSysMessage(LANG_CMD_SYNTAX);
|
||||
handler->SetSentErrorMessage(true);
|
||||
if (text.empty())
|
||||
return false;
|
||||
}
|
||||
|
||||
char* receiver_str = strtok((char*)args, " ");
|
||||
char* text = strtok(nullptr, "");
|
||||
|
||||
if (!receiver_str || !text)
|
||||
{
|
||||
handler->SendSysMessage(LANG_CMD_SYNTAX);
|
||||
handler->SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
Creature* creature = handler->getSelectedCreature();
|
||||
if (!creature)
|
||||
@@ -1270,10 +1029,8 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
ObjectGuid receiver_guid = ObjectGuid::Create<HighGuid::Player>(strtoull(receiver_str, nullptr, 10));
|
||||
|
||||
// check online security
|
||||
Player* receiver = ObjectAccessor::FindPlayer(receiver_guid);
|
||||
Player* receiver = ObjectAccessor::FindPlayerByName(recv);
|
||||
if (handler->HasLowerSecurity(receiver, ObjectGuid::Empty))
|
||||
return false;
|
||||
|
||||
@@ -1281,14 +1038,10 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool HandleNpcYellCommand(ChatHandler* handler, char const* args)
|
||||
static bool HandleNpcYellCommand(ChatHandler* handler, Tail text)
|
||||
{
|
||||
if (!*args)
|
||||
{
|
||||
handler->SendSysMessage(LANG_CMD_SYNTAX);
|
||||
handler->SetSentErrorMessage(true);
|
||||
if (text.empty())
|
||||
return false;
|
||||
}
|
||||
|
||||
Creature* creature = handler->getSelectedCreature();
|
||||
if (!creature)
|
||||
@@ -1298,7 +1051,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
creature->Yell(args, LANG_UNIVERSAL);
|
||||
creature->Yell(text, LANG_UNIVERSAL);
|
||||
|
||||
// make an emote
|
||||
creature->HandleEmoteCommand(EMOTE_ONESHOT_SHOUT);
|
||||
@@ -1307,40 +1060,30 @@ public:
|
||||
}
|
||||
|
||||
// add creature, temp only
|
||||
static bool HandleNpcAddTempSpawnCommand(ChatHandler* handler, char const* args)
|
||||
static bool HandleNpcAddTempSpawnCommand(ChatHandler* handler, Optional<std::string_view> lootStr, CreatureEntry id)
|
||||
{
|
||||
if (!*args)
|
||||
return false;
|
||||
|
||||
bool loot = false;
|
||||
char const* spawntype_str = strtok((char*)args, " ");
|
||||
char const* entry_str = strtok(nullptr, "");
|
||||
if (stricmp(spawntype_str, "LOOT") == 0)
|
||||
if (lootStr)
|
||||
{
|
||||
if (StringEqualI(*lootStr, "loot"))
|
||||
loot = true;
|
||||
else if (stricmp(spawntype_str, "NOLOOT") == 0)
|
||||
else if (StringEqualI(*lootStr, "noloot"))
|
||||
loot = false;
|
||||
else
|
||||
entry_str = args;
|
||||
char* charID = handler->extractKeyFromLink((char*)entry_str, "Hcreature_entry");
|
||||
if (!charID)
|
||||
return false;
|
||||
}
|
||||
|
||||
Player* chr = handler->GetSession()->GetPlayer();
|
||||
|
||||
uint32 id = atoul(charID);
|
||||
if (!id)
|
||||
return false;
|
||||
|
||||
if (!sObjectMgr->GetCreatureTemplate(id))
|
||||
return false;
|
||||
|
||||
chr->SummonCreature(id, *chr, loot ? TEMPSUMMON_CORPSE_TIMED_DESPAWN : TEMPSUMMON_CORPSE_DESPAWN, 30s);
|
||||
chr->SummonCreature(id, chr->GetPosition(), loot ? TEMPSUMMON_CORPSE_TIMED_DESPAWN : TEMPSUMMON_CORPSE_DESPAWN, 30s);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//npc tame handling
|
||||
static bool HandleNpcTameCommand(ChatHandler* handler, char const* /*args*/)
|
||||
static bool HandleNpcTameCommand(ChatHandler* handler)
|
||||
{
|
||||
Creature* creatureTarget = handler->getSelectedCreature();
|
||||
if (!creatureTarget || creatureTarget->IsPet())
|
||||
@@ -1406,7 +1149,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool HandleNpcEvadeCommand(ChatHandler* handler, char const* args)
|
||||
static bool HandleNpcEvadeCommand(ChatHandler* handler, Optional<CreatureAI::EvadeReason> why, Optional<ExactSequence<'f','o','r','c','e'>> force)
|
||||
{
|
||||
Creature* creatureTarget = handler->getSelectedCreature();
|
||||
if (!creatureTarget || creatureTarget->IsPet())
|
||||
@@ -1423,30 +1166,9 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
char* type_str = args ? strtok((char*)args, " ") : nullptr;
|
||||
char* force_str = args ? strtok(nullptr, " ") : nullptr;
|
||||
|
||||
CreatureAI::EvadeReason why = CreatureAI::EVADE_REASON_OTHER;
|
||||
bool force = false;
|
||||
if (type_str)
|
||||
{
|
||||
if (stricmp(type_str, "NO_HOSTILES") == 0 || stricmp(type_str, "EVADE_REASON_NO_HOSTILES") == 0)
|
||||
why = CreatureAI::EVADE_REASON_NO_HOSTILES;
|
||||
else if (stricmp(type_str, "BOUNDARY") == 0 || stricmp(type_str, "EVADE_REASON_BOUNDARY") == 0)
|
||||
why = CreatureAI::EVADE_REASON_BOUNDARY;
|
||||
else if (stricmp(type_str, "SEQUENCE_BREAK") == 0 || stricmp(type_str, "EVADE_REASON_SEQUENCE_BREAK") == 0)
|
||||
why = CreatureAI::EVADE_REASON_SEQUENCE_BREAK;
|
||||
else if (stricmp(type_str, "FORCE") == 0)
|
||||
force = true;
|
||||
|
||||
if (!force && force_str)
|
||||
if (stricmp(force_str, "FORCE") == 0)
|
||||
force = true;
|
||||
}
|
||||
|
||||
if (force)
|
||||
creatureTarget->ClearUnitState(UNIT_STATE_EVADE);
|
||||
creatureTarget->AI()->EnterEvadeMode(why);
|
||||
creatureTarget->AI()->EnterEvadeMode(why.value_or(CreatureAI::EVADE_REASON_OTHER));
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1480,7 +1202,7 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
static bool HandleNpcShowLootCommand(ChatHandler* handler, char const* args)
|
||||
static bool HandleNpcShowLootCommand(ChatHandler* handler, Optional<ExactSequence<'a','l','l'>> all)
|
||||
{
|
||||
Creature* creatureTarget = handler->getSelectedCreature();
|
||||
if (!creatureTarget || creatureTarget->IsPet())
|
||||
@@ -1501,7 +1223,7 @@ public:
|
||||
handler->PSendSysMessage(LANG_COMMAND_NPC_SHOWLOOT_HEADER, creatureTarget->GetName(), creatureTarget->GetEntry());
|
||||
handler->PSendSysMessage(LANG_COMMAND_NPC_SHOWLOOT_MONEY, loot.gold / GOLD, (loot.gold%GOLD) / SILVER, loot.gold%SILVER);
|
||||
|
||||
if (strcmp(args, "all")) // nonzero from strcmp <-> not equal
|
||||
if (!all)
|
||||
{
|
||||
handler->PSendSysMessage(LANG_COMMAND_NPC_SHOWLOOT_LABEL, "Standard items", loot.items.size());
|
||||
for (LootItem const& item : loot.items)
|
||||
@@ -1542,12 +1264,8 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool HandleNpcAddFormationCommand(ChatHandler* handler, char const* args)
|
||||
static bool HandleNpcAddFormationCommand(ChatHandler* handler, ObjectGuid::LowType leaderGUID)
|
||||
{
|
||||
if (!*args)
|
||||
return false;
|
||||
|
||||
ObjectGuid::LowType leaderGUID = atoull(args);
|
||||
Creature* creature = handler->getSelectedCreature();
|
||||
|
||||
if (!creature || !creature->GetSpawnId())
|
||||
@@ -1589,13 +1307,8 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool HandleNpcSetLinkCommand(ChatHandler* handler, char const* args)
|
||||
static bool HandleNpcSetLinkCommand(ChatHandler* handler, ObjectGuid::LowType linkguid)
|
||||
{
|
||||
if (!*args)
|
||||
return false;
|
||||
|
||||
ObjectGuid::LowType linkguid = atoull(args);
|
||||
|
||||
Creature* creature = handler->getSelectedCreature();
|
||||
|
||||
if (!creature)
|
||||
@@ -1624,16 +1337,18 @@ public:
|
||||
}
|
||||
|
||||
/// @todo NpcCommands that need to be fixed :
|
||||
static bool HandleNpcAddWeaponCommand(ChatHandler* /*handler*/, char const* /*args*/)
|
||||
static bool HandleNpcAddWeaponCommand([[maybe_unused]] ChatHandler* handler, [[maybe_unused]] uint32 SlotID, [[maybe_unused]] ItemTemplate const* tmpItem)
|
||||
{
|
||||
/*if (!*args)
|
||||
return false;
|
||||
/*
|
||||
if (!tmpItem)
|
||||
return;
|
||||
|
||||
uint64 guid = handler->GetSession()->GetPlayer()->GetSelection();
|
||||
if (guid == 0)
|
||||
{
|
||||
handler->SendSysMessage(LANG_NO_SELECTION);
|
||||
return true;
|
||||
handler->SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
Creature* creature = ObjectAccessor::GetCreature(*handler->GetSession()->GetPlayer(), guid);
|
||||
@@ -1641,53 +1356,28 @@ public:
|
||||
if (!creature)
|
||||
{
|
||||
handler->SendSysMessage(LANG_SELECT_CREATURE);
|
||||
return true;
|
||||
handler->SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
char* pSlotID = strtok((char*)args, " ");
|
||||
if (!pSlotID)
|
||||
return false;
|
||||
|
||||
char* pItemID = strtok(nullptr, " ");
|
||||
if (!pItemID)
|
||||
return false;
|
||||
|
||||
uint32 ItemID = atoi(pItemID);
|
||||
uint32 SlotID = atoi(pSlotID);
|
||||
|
||||
ItemTemplate* tmpItem = sObjectMgr->GetItemTemplate(ItemID);
|
||||
|
||||
bool added = false;
|
||||
if (tmpItem)
|
||||
{
|
||||
switch (SlotID)
|
||||
{
|
||||
case 1:
|
||||
creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, ItemID);
|
||||
added = true;
|
||||
creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, tmpItem->ItemId);
|
||||
break;
|
||||
case 2:
|
||||
creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_01, ItemID);
|
||||
added = true;
|
||||
creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_01, tmpItem->ItemId);
|
||||
break;
|
||||
case 3:
|
||||
creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_02, ItemID);
|
||||
added = true;
|
||||
creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_02, tmpItem->ItemId);
|
||||
break;
|
||||
default:
|
||||
handler->PSendSysMessage(LANG_ITEM_SLOT_NOT_EXIST, SlotID);
|
||||
added = false;
|
||||
break;
|
||||
handler->SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (added)
|
||||
handler->PSendSysMessage(LANG_ITEM_ADDED_TO_SLOT, ItemID, tmpItem->Name1, SlotID);
|
||||
}
|
||||
else
|
||||
{
|
||||
handler->PSendSysMessage(LANG_ITEM_NOT_FOUND, ItemID);
|
||||
return true;
|
||||
}
|
||||
handler->PSendSysMessage(LANG_ITEM_ADDED_TO_SLOT, tmpItem->ItemID, tmpItem->Name1, SlotID);
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
@@ -1697,3 +1387,75 @@ void AddSC_npc_commandscript()
|
||||
{
|
||||
new npc_commandscript();
|
||||
}
|
||||
|
||||
bool HandleNpcSpawnGroup(ChatHandler* handler, std::vector<Variant<uint32, ExactSequence<'f','o','r','c','e'>, ExactSequence<'i','g','n','o','r','e','r','e','s','p','a','w','n'>>> const& opts)
|
||||
{
|
||||
if (opts.empty())
|
||||
return false;
|
||||
|
||||
bool ignoreRespawn = false;
|
||||
bool force = false;
|
||||
uint32 groupId = 0;
|
||||
|
||||
// Decode arguments
|
||||
for (auto const& variant : opts)
|
||||
{
|
||||
switch (variant.index())
|
||||
{
|
||||
case 0:
|
||||
groupId = variant.get<uint32>();
|
||||
break;
|
||||
case 1:
|
||||
force = true;
|
||||
break;
|
||||
case 2:
|
||||
ignoreRespawn = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Player* player = handler->GetSession()->GetPlayer();
|
||||
|
||||
std::vector <WorldObject*> creatureList;
|
||||
if (!player->GetMap()->SpawnGroupSpawn(groupId, ignoreRespawn, force, &creatureList))
|
||||
{
|
||||
handler->PSendSysMessage(LANG_SPAWNGROUP_BADGROUP, groupId);
|
||||
handler->SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
handler->PSendSysMessage(LANG_SPAWNGROUP_SPAWNCOUNT, creatureList.size());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HandleNpcDespawnGroup(ChatHandler* handler, std::vector<Variant<uint32, ExactSequence<'r','e','m','o','v','e','r','e','s','p','a','w','n','t','i','m','e'>>> const& opts)
|
||||
{
|
||||
if (opts.empty())
|
||||
return false;
|
||||
|
||||
bool deleteRespawnTimes = false;
|
||||
uint32 groupId = 0;
|
||||
|
||||
// Decode arguments
|
||||
for (auto const& variant : opts)
|
||||
{
|
||||
if (variant.holds_alternative<uint32>())
|
||||
groupId = variant.get<uint32>();
|
||||
else
|
||||
deleteRespawnTimes = true;
|
||||
}
|
||||
|
||||
Player* player = handler->GetSession()->GetPlayer();
|
||||
|
||||
size_t n = 0;
|
||||
if (!player->GetMap()->SpawnGroupDespawn(groupId, deleteRespawnTimes, &n))
|
||||
{
|
||||
handler->PSendSysMessage(LANG_SPAWNGROUP_BADGROUP, groupId);
|
||||
handler->SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
handler->PSendSysMessage("Despawned a total of %zu objects.", n);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user