[Feature] Add Strings::BeginsWith() and Strings::EndsWith() (#3471)

* [Strings] Add Strings::BeginsWith() and Strings::EndsWith()

# Notes
- These are useful so that we don't have to manually calculate size or perform a substring.

* Update questmgr.cpp

* Update client.cpp
This commit is contained in:
Alex King 2023-07-03 09:40:44 -04:00 committed by GitHub
parent 2717fcc339
commit ee14aed8de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 73 additions and 68 deletions

View File

@ -695,8 +695,31 @@ std::string Strings::ConvertToDigit(int n, const std::string& suffix)
return NUM_TO_ENGLISH_X[n] + suffix; return NUM_TO_ENGLISH_X[n] + suffix;
} }
} }
bool Strings::BeginsWith(const std::string& subject, const std::string& search)
{
if (subject.length() < search.length()) {
return false;
}
return subject.starts_with(search);
}
bool Strings::EndsWith(const std::string& subject, const std::string& search)
{
if (subject.length() < search.length()) {
return false;
}
return subject.ends_with(search);
}
bool Strings::Contains(const std::string& subject, const std::string& search) bool Strings::Contains(const std::string& subject, const std::string& search)
{ {
if (subject.length() < search.length()) {
return false;
}
return subject.find(search) != std::string::npos; return subject.find(search) != std::string::npos;
} }

View File

@ -128,6 +128,8 @@ public:
static bool ToBool(const std::string& bool_string); static bool ToBool(const std::string& bool_string);
static inline bool EqualFold(const std::string &string_one, const std::string &string_two) { return strcasecmp(string_one.c_str(), string_two.c_str()) == 0; } static inline bool EqualFold(const std::string &string_one, const std::string &string_two) { return strcasecmp(string_one.c_str(), string_two.c_str()) == 0; }
static std::string Random(size_t length); static std::string Random(size_t length);
static bool BeginsWith(const std::string& subject, const std::string& search);
static bool EndsWith(const std::string& subject, const std::string& search);
template<typename T> template<typename T>
static std::string static std::string

View File

@ -5939,90 +5939,64 @@ void Client::AdventureFinish(bool win, int theme, int points)
FastQueuePacket(&outapp); FastQueuePacket(&outapp);
} }
void Client::CheckLDoNHail(Mob *target) void Client::CheckLDoNHail(NPC* n)
{
if(!zone->adv_data)
{ {
if (!zone->adv_data || !n || n->GetOwnerID()) {
return; return;
} }
if(!target || !target->IsNPC()) auto* ds = (ServerZoneAdventureDataReply_Struct*) zone->adv_data;
{ if (ds->type != Adventure_Rescue || ds->data_id != n->GetNPCTypeID()) {
return; return;
} }
if(target->GetOwnerID() != 0) if (entity_list.CheckNPCsClose(n)) {
{ n->Say(
return; "You're here to save me? I couldn't possibly risk leaving yet. There are "
}
ServerZoneAdventureDataReply_Struct* ds = (ServerZoneAdventureDataReply_Struct*)zone->adv_data;
if(ds->type != Adventure_Rescue)
{
return;
}
if(ds->data_id != target->GetNPCTypeID())
{
return;
}
if(entity_list.CheckNPCsClose(target) != 0)
{
target->Say("You're here to save me? I couldn't possibly risk leaving yet. There are "
"far too many of those horrid things out there waiting to recapture me! Please get " "far too many of those horrid things out there waiting to recapture me! Please get "
" rid of some more of those vermin and then we can try to leave."); "rid of some more of those vermin and then we can try to leave."
);
return; return;
} }
Mob *pet = GetPet(); auto pet = GetPet();
if(pet) if (pet) {
{ if (pet->GetPetType() == petCharmed) {
if(pet->GetPetType() == petCharmed)
{
pet->BuffFadeByEffect(SE_Charm); pet->BuffFadeByEffect(SE_Charm);
} } else if (pet->GetPetType() == petNPCFollow) {
else if(pet->GetPetType() == petNPCFollow)
{
pet->SetOwnerID(0); pet->SetOwnerID(0);
} } else {
else
{
pet->Depop(); pet->Depop();
} }
} }
SetPet(target); SetPet(n);
target->SetOwnerID(GetID()); n->SetOwnerID(GetID());
target->Say("Wonderful! Someone to set me free! I feared for my life for so long," n->Say(
"Wonderful! Someone to set me free! I feared for my life for so long, "
"never knowing when they might choose to end my life. Now that you're here though " "never knowing when they might choose to end my life. Now that you're here though "
"I can rest easy. Please help me find my way out of here as soon as you can " "I can rest easy. Please help me find my way out of here as soon as you can "
" I'll stay close behind you!"); "I'll stay close behind you!"
);
} }
void Client::CheckEmoteHail(Mob *target, const char* message) void Client::CheckEmoteHail(NPC* n, const char* message)
{ {
if ( if (
(message[0] != 'H' && !Strings::BeginsWith(message, "hail") &&
message[0] != 'h') || !Strings::BeginsWith(message, "Hail")
message[1] != 'a' || ) {
message[2] != 'i' ||
message[3] != 'l'){
return; return;
} }
if(!target || !target->IsNPC()) if (!n || n->GetOwnerID()) {
{
return; return;
} }
if(target->GetOwnerID() != 0) const auto emote_id = n->GetEmoteID();
{ if (emote_id) {
return; n->DoNPCEmote(EQ::constants::EmoteEventTypes::Hailed, emote_id);
} }
uint32 emoteid = target->GetEmoteID();
if(emoteid != 0)
target->CastToNPC()->DoNPCEmote(EQ::constants::EmoteEventTypes::Hailed, emoteid);
} }
void Client::MarkSingleCompassLoc(float in_x, float in_y, float in_z, uint8 count) void Client::MarkSingleCompassLoc(float in_x, float in_y, float in_z, uint8 count)

View File

@ -1360,8 +1360,8 @@ public:
uint32 GetLDoNLossesTheme(uint32 t); uint32 GetLDoNLossesTheme(uint32 t);
uint32 GetLDoNPointsTheme(uint32 t); uint32 GetLDoNPointsTheme(uint32 t);
void UpdateLDoNWinLoss(uint32 theme_id, bool win = false, bool remove = false); void UpdateLDoNWinLoss(uint32 theme_id, bool win = false, bool remove = false);
void CheckLDoNHail(Mob *target); void CheckLDoNHail(NPC* n);
void CheckEmoteHail(Mob *target, const char* message); void CheckEmoteHail(NPC* n, const char* message);
void HandleLDoNOpen(NPC *target); void HandleLDoNOpen(NPC *target);
void HandleLDoNSenseTraps(NPC *target, uint16 skill, uint8 type); void HandleLDoNSenseTraps(NPC *target, uint16 skill, uint8 type);

View File

@ -9147,8 +9147,14 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app)
} }
else if (inst->IsClassCommon()) else if (inst->IsClassCommon())
{ {
if (!RuleB(Skills, RequireTomeHandin) && item->ItemType == EQ::item::ItemTypeSpell && (strstr((const char*)item->Name, "Tome of ") || strstr((const char*)item->Name, "Skill: "))) if (
{ !RuleB(Skills, RequireTomeHandin) &&
item->ItemType == EQ::item::ItemTypeSpell &&
(
Strings::BeginsWith(item->Name, "Tome of ") ||
Strings::BeginsWith(item->Name, "Skill: ")
)
) {
DeleteItemInInventory(slot_id, 1, true); DeleteItemInInventory(slot_id, 1, true);
TrainDiscipline(item->ID); TrainDiscipline(item->ID);
} }

View File

@ -622,8 +622,8 @@ bool Client::TrainDiscipline(uint32 itemid) {
const std::string item_name = item->Name; const std::string item_name = item->Name;
if ( if (
item_name.substr(0, 5) != std::string("Tome ") && !Strings::BeginsWith(item_name, "Tome of ") &&
item_name.substr(0, 7) != std::string("Skill: ") !Strings::BeginsWith(item_name, "Skill: ")
) { ) {
Message(Chat::Red, "This item is not a tome."); Message(Chat::Red, "This item is not a tome.");
//summon them the item back... //summon them the item back...
@ -709,8 +709,8 @@ bool Client::MemorizeSpellFromItem(uint32 item_id) {
const std::string item_name = item->Name; const std::string item_name = item->Name;
if ( if (
item_name.substr(0, 7) != std::string("Spell: ") && !Strings::BeginsWith(item_name, "Spell: ") &&
item_name.substr(0, 6) != std::string("Song: ") !Strings::BeginsWith(item_name, "Song: ")
) { ) {
Message(Chat::Red, "This item is not a scroll."); Message(Chat::Red, "This item is not a scroll.");
SummonItem(item_id); SummonItem(item_id);

View File

@ -1018,8 +1018,8 @@ bool QuestManager::isdisctome(uint32 item_id) {
const std::string item_name = item->Name; const std::string item_name = item->Name;
if ( if (
strcmp(item_name.substr(0, 5).c_str(), "Tome ") && !Strings::BeginsWith(item_name, "Tome of ") &&
strcmp(item_name.substr(0, 7).c_str(), "Skill: ") !Strings::BeginsWith(item_name, "Skill: ")
) { ) {
return false; return false;
} }