[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(
"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 "
"rid of some more of those vermin and then we can try to leave."
);
return; return;
} }
ServerZoneAdventureDataReply_Struct* ds = (ServerZoneAdventureDataReply_Struct*)zone->adv_data; auto pet = GetPet();
if(ds->type != Adventure_Rescue) if (pet) {
{ if (pet->GetPetType() == petCharmed) {
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"
" rid of some more of those vermin and then we can try to leave.");
return;
}
Mob *pet = GetPet();
if(pet)
{
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(
" never knowing when they might choose to end my life. Now that you're here though" "Wonderful! Someone to set me free! I feared for my life for so long, "
" I can rest easy. Please help me find my way out of here as soon as you can" "never knowing when they might choose to end my life. Now that you're here though "
" I'll stay close behind you!"); "I can rest easy. Please help me find my way out of here as soon as you can "
"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;
} }