[Rules] Add Rule to Disable NPC Last Names. (#2227)

* [Rules] Add Rule to Disable NPC Last Names.
- Add NPC:DisableLastNames to disable NPC Last Names.
- Fix #npcedit lastname to allow you to use an empty string.

* Cleanup of classes in naming.

* Duplicate.

* Update classes.cpp
This commit is contained in:
Kinglykrab 2022-06-04 14:01:00 -04:00 committed by GitHub
parent 7160aa651e
commit 8f729fe948
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 135 additions and 177 deletions

View File

@ -380,12 +380,12 @@ const char *GetClassIDName(uint8 class_id, uint8 level)
return "Merchant"; return "Merchant";
case DISCORD_MERCHANT: case DISCORD_MERCHANT:
return "Discord Merchant"; return "Discord Merchant";
case ADVENTURERECRUITER: case ADVENTURE_RECRUITER:
return "Adventure Recruiter"; return "Adventure Recruiter";
case ADVENTUREMERCHANT: case ADVENTURE_MERCHANT:
return "Adventure Merchant"; return "Adventure Merchant";
case CORPSE_CLASS: case LDON_TREASURE:
return "Corpse Class"; return "LDoN Treasure";
case TRIBUTE_MASTER: case TRIBUTE_MASTER:
return "Tribute Master"; return "Tribute Master";
case GUILD_TRIBUTE_MASTER: case GUILD_TRIBUTE_MASTER:
@ -400,7 +400,7 @@ const char *GetClassIDName(uint8 class_id, uint8 level)
return "Fellowship Master"; return "Fellowship Master";
case ALT_CURRENCY_MERCHANT: case ALT_CURRENCY_MERCHANT:
return "Alternate Currency Merchant"; return "Alternate Currency Merchant";
case MERCERNARY_MASTER: case MERCENARY_MASTER:
return "Mercenary Liaison"; return "Mercenary Liaison";
default: default:
return "Unknown"; return "Unknown";

View File

@ -55,10 +55,9 @@
#define BANKER 40 #define BANKER 40
#define MERCHANT 41 #define MERCHANT 41
#define DISCORD_MERCHANT 59 #define DISCORD_MERCHANT 59
#define ADVENTURERECRUITER 60 #define ADVENTURE_RECRUITER 60
#define ADVENTUREMERCHANT 61 #define ADVENTURE_MERCHANT 61
#define LDON_TREASURE 62 // objects you can use /open on first seen in LDONs #define LDON_TREASURE 62 // objects you can use /open on first seen in LDONs, seen on Danvi's Corpse in Akheva
#define CORPSE_CLASS 62 // only seen on Danvi's Corpse in Akheva so far..
#define TRIBUTE_MASTER 63 #define TRIBUTE_MASTER 63
#define GUILD_TRIBUTE_MASTER 64 // not sure #define GUILD_TRIBUTE_MASTER 64 // not sure
#define GUILD_BANKER 66 #define GUILD_BANKER 66
@ -66,7 +65,7 @@
#define DARK_REIGN_MERCHANT 68 #define DARK_REIGN_MERCHANT 68
#define FELLOWSHIP_MASTER 69 #define FELLOWSHIP_MASTER 69
#define ALT_CURRENCY_MERCHANT 70 #define ALT_CURRENCY_MERCHANT 70
#define MERCERNARY_MASTER 71 #define MERCENARY_MASTER 71
// player class values // player class values

View File

@ -511,6 +511,7 @@ RULE_BOOL(NPC, UseMeditateBasedManaRegen, false, "Based NPC ooc regen on Meditat
RULE_REAL(NPC, NPCHealOnGateAmount, 25, "How much the NPC will heal on gate if enabled") RULE_REAL(NPC, NPCHealOnGateAmount, 25, "How much the NPC will heal on gate if enabled")
RULE_BOOL(NPC, AnimalsOpenDoors, true, "Determines or not whether animals open doors or not when they approach them") RULE_BOOL(NPC, AnimalsOpenDoors, true, "Determines or not whether animals open doors or not when they approach them")
RULE_INT(NPC, MaxRaceID, 732, "Maximum Race ID, RoF2 by default supports up to 732") RULE_INT(NPC, MaxRaceID, 732, "Maximum Race ID, RoF2 by default supports up to 732")
RULE_BOOL(NPC, DisableLastNames, false, "Enable to disable NPC Last Names")
RULE_CATEGORY_END() RULE_CATEGORY_END()
RULE_CATEGORY(Aggro) RULE_CATEGORY(Aggro)

View File

@ -2584,7 +2584,7 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy
} }
bool allow_merchant_corpse = RuleB(Merchant, AllowCorpse); bool allow_merchant_corpse = RuleB(Merchant, AllowCorpse);
bool is_merchant = (class_ == MERCHANT || class_ == ADVENTUREMERCHANT || MerchantType != 0); bool is_merchant = (class_ == MERCHANT || class_ == ADVENTURE_MERCHANT || MerchantType != 0);
if (!HasOwner() && !IsMerc() && !GetSwarmInfo() && (!is_merchant || allow_merchant_corpse) && if (!HasOwner() && !IsMerc() && !GetSwarmInfo() && (!is_merchant || allow_merchant_corpse) &&
((killer && (killer->IsClient() || (killer->HasOwner() && killer->GetUltimateOwner()->IsClient()) || ((killer && (killer->IsClient() || (killer->HasOwner() && killer->GetUltimateOwner()->IsClient()) ||

View File

@ -1875,7 +1875,7 @@ void Client::Handle_OP_AdventureMerchantPurchase(const EQApplicationPacket *app)
Adventure_Purchase_Struct* aps = (Adventure_Purchase_Struct*)app->pBuffer; Adventure_Purchase_Struct* aps = (Adventure_Purchase_Struct*)app->pBuffer;
uint32 merchantid = 0; uint32 merchantid = 0;
Mob* tmp = entity_list.GetMob(aps->npcid); Mob* tmp = entity_list.GetMob(aps->npcid);
if (tmp == 0 || !tmp->IsNPC() || ((tmp->GetClass() != ADVENTUREMERCHANT) && if (tmp == 0 || !tmp->IsNPC() || ((tmp->GetClass() != ADVENTURE_MERCHANT) &&
(tmp->GetClass() != DISCORD_MERCHANT) && (tmp->GetClass() != NORRATHS_KEEPERS_MERCHANT) && (tmp->GetClass() != DARK_REIGN_MERCHANT))) (tmp->GetClass() != DISCORD_MERCHANT) && (tmp->GetClass() != NORRATHS_KEEPERS_MERCHANT) && (tmp->GetClass() != DARK_REIGN_MERCHANT)))
return; return;
@ -2056,7 +2056,7 @@ void Client::Handle_OP_AdventureMerchantRequest(const EQApplicationPacket *app)
uint32 merchantid = 0; uint32 merchantid = 0;
Mob* tmp = entity_list.GetMob(eid->entity_id); Mob* tmp = entity_list.GetMob(eid->entity_id);
if (tmp == 0 || !tmp->IsNPC() || ((tmp->GetClass() != ADVENTUREMERCHANT) && if (tmp == 0 || !tmp->IsNPC() || ((tmp->GetClass() != ADVENTURE_MERCHANT) &&
(tmp->GetClass() != DISCORD_MERCHANT) && (tmp->GetClass() != NORRATHS_KEEPERS_MERCHANT) && (tmp->GetClass() != DARK_REIGN_MERCHANT))) (tmp->GetClass() != DISCORD_MERCHANT) && (tmp->GetClass() != NORRATHS_KEEPERS_MERCHANT) && (tmp->GetClass() != DARK_REIGN_MERCHANT)))
return; return;
@ -2127,7 +2127,7 @@ void Client::Handle_OP_AdventureMerchantSell(const EQApplicationPacket *app)
Adventure_Sell_Struct *ams_in = (Adventure_Sell_Struct*)app->pBuffer; Adventure_Sell_Struct *ams_in = (Adventure_Sell_Struct*)app->pBuffer;
Mob* vendor = entity_list.GetMob(ams_in->npcid); Mob* vendor = entity_list.GetMob(ams_in->npcid);
if (vendor == 0 || !vendor->IsNPC() || ((vendor->GetClass() != ADVENTUREMERCHANT) && if (vendor == 0 || !vendor->IsNPC() || ((vendor->GetClass() != ADVENTURE_MERCHANT) &&
(vendor->GetClass() != NORRATHS_KEEPERS_MERCHANT) && (vendor->GetClass() != DARK_REIGN_MERCHANT))) (vendor->GetClass() != NORRATHS_KEEPERS_MERCHANT) && (vendor->GetClass() != DARK_REIGN_MERCHANT)))
{ {
Message(Chat::Red, "Vendor was not found."); Message(Chat::Red, "Vendor was not found.");
@ -2224,7 +2224,7 @@ void Client::Handle_OP_AdventureMerchantSell(const EQApplicationPacket *app)
switch (vendor->GetClass()) switch (vendor->GetClass())
{ {
case ADVENTUREMERCHANT: case ADVENTURE_MERCHANT:
{ {
UpdateLDoNPoints(6, price); UpdateLDoNPoints(6, price);
break; break;
@ -9773,7 +9773,7 @@ void Client::Handle_OP_MercenaryDataRequest(const EQApplicationPacket *app)
if (DistanceSquared(m_Position, tar->GetPosition()) > USE_NPC_RANGE2) if (DistanceSquared(m_Position, tar->GetPosition()) > USE_NPC_RANGE2)
return; return;
if (tar->GetClass() != MERCERNARY_MASTER) { if (tar->GetClass() != MERCENARY_MASTER) {
return; return;
} }

View File

@ -10,7 +10,7 @@ void command_findclass(Client *c, const Seperator *sep)
if (sep->IsNumber(1)) { if (sep->IsNumber(1)) {
int class_id = std::stoi(sep->arg[1]); int class_id = std::stoi(sep->arg[1]);
if (class_id >= WARRIOR && class_id <= MERCERNARY_MASTER) { if (class_id >= WARRIOR && class_id <= MERCENARY_MASTER) {
std::string class_name = GetClassIDName(class_id); std::string class_name = GetClassIDName(class_id);
c->Message( c->Message(
Chat::White, Chat::White,
@ -41,7 +41,7 @@ void command_findclass(Client *c, const Seperator *sep)
} else { } else {
auto search_criteria = str_tolower(sep->argplus[1]); auto search_criteria = str_tolower(sep->argplus[1]);
int found_count = 0; int found_count = 0;
for (uint16 class_id = WARRIOR; class_id <= MERCERNARY_MASTER; class_id++) { for (uint16 class_id = WARRIOR; class_id <= MERCENARY_MASTER; class_id++) {
std::string class_name = GetClassIDName(class_id); std::string class_name = GetClassIDName(class_id);
auto class_name_lower = str_tolower(class_name); auto class_name_lower = str_tolower(class_name);
if ( if (

View File

@ -204,24 +204,20 @@ void command_npcedit(Client *c, const Seperator *sep)
return; return;
} else if (!strcasecmp(sep->arg[1], "lastname")) { } else if (!strcasecmp(sep->arg[1], "lastname")) {
std::string last_name = sep->argplus[2]; std::string last_name = sep->argplus[2];
if (!last_name.empty()) { c->Message(
c->Message( Chat::Yellow,
Chat::Yellow, fmt::format(
fmt::format( "{} now has the lastname '{}'.",
"{} now has the lastname '{}'.", npc_id_string,
npc_id_string, last_name
sep->argplus[2] ).c_str()
).c_str() );
); auto query = fmt::format(
auto query = fmt::format( "UPDATE npc_types SET lastname = '{}' WHERE id = {}",
"UPDATE npc_types SET lastname = '{}' WHERE id = {}", last_name,
sep->argplus[2], npc_id
npc_id );
); content_db.QueryDatabase(query);
content_db.QueryDatabase(query);
} else {
c->Message(Chat::White, "Usage: #npcedit lastname [Last Name] - Sets an NPC's Last Name");
}
return; return;
} else if (!strcasecmp(sep->arg[1], "level")) { } else if (!strcasecmp(sep->arg[1], "level")) {
if (sep->IsNumber(2)) { if (sep->IsNumber(2)) {

View File

@ -4446,17 +4446,16 @@ luabind::scope lua_register_classes() {
luabind::value("BANKER", BANKER), luabind::value("BANKER", BANKER),
luabind::value("MERCHANT", MERCHANT), luabind::value("MERCHANT", MERCHANT),
luabind::value("DISCORD_MERCHANT", DISCORD_MERCHANT), luabind::value("DISCORD_MERCHANT", DISCORD_MERCHANT),
luabind::value("ADVENTURERECRUITER", ADVENTURERECRUITER), luabind::value("ADVENTURE_RECRUITER", ADVENTURE_RECRUITER),
luabind::value("ADVENTUREMERCHANT", ADVENTUREMERCHANT), luabind::value("ADVENTURE_MERCHANT", ADVENTURE_MERCHANT),
luabind::value("LDON_TREASURE", LDON_TREASURE), luabind::value("LDON_TREASURE", LDON_TREASURE),
luabind::value("CORPSE_CLASS", CORPSE_CLASS),
luabind::value("TRIBUTE_MASTER", TRIBUTE_MASTER), luabind::value("TRIBUTE_MASTER", TRIBUTE_MASTER),
luabind::value("GUILD_TRIBUTE_MASTER", GUILD_TRIBUTE_MASTER), luabind::value("GUILD_TRIBUTE_MASTER", GUILD_TRIBUTE_MASTER),
luabind::value("NORRATHS_KEEPERS_MERCHANT", NORRATHS_KEEPERS_MERCHANT), luabind::value("NORRATHS_KEEPERS_MERCHANT", NORRATHS_KEEPERS_MERCHANT),
luabind::value("DARK_REIGN_MERCHANT", DARK_REIGN_MERCHANT), luabind::value("DARK_REIGN_MERCHANT", DARK_REIGN_MERCHANT),
luabind::value("FELLOWSHIP_MASTER", FELLOWSHIP_MASTER), luabind::value("FELLOWSHIP_MASTER", FELLOWSHIP_MASTER),
luabind::value("ALT_CURRENCY_MERCHANT", ALT_CURRENCY_MERCHANT), luabind::value("ALT_CURRENCY_MERCHANT", ALT_CURRENCY_MERCHANT),
luabind::value("MERCERNARY_MASTER", MERCERNARY_MASTER) luabind::value("MERCENARY_MASTER", MERCENARY_MASTER)
]; ];
} }

View File

@ -1074,77 +1074,99 @@ uint8 Mob::GetArchetype() const {
} }
} }
void Mob::SetSpawnLastNameByClass(NewSpawn_Struct* ns)
{
switch (ns->spawn.class_) {
case TRIBUTE_MASTER:
strcpy(ns->spawn.lastName, "Tribute Master");
break;
case GUILD_TRIBUTE_MASTER:
strcpy(ns->spawn.lastName, "Guild Tribute Master");
break;
case GUILD_BANKER:
strcpy(ns->spawn.lastName, "Guild Banker");
break;
case ADVENTURE_RECRUITER:
strcpy(ns->spawn.lastName, "Adventure Recruiter");
break;
case ADVENTURE_MERCHANT:
strcpy(ns->spawn.lastName, "Adventure Merchant");
break;
case BANKER:
strcpy(ns->spawn.lastName, "Banker");
break;
case WARRIORGM:
strcpy(ns->spawn.lastName, "Warrior Guildmaster");
break;
case CLERICGM:
strcpy(ns->spawn.lastName, "Cleric Guildmaster");
break;
case PALADINGM:
strcpy(ns->spawn.lastName, "Paladin Guildmaster");
break;
case RANGERGM:
strcpy(ns->spawn.lastName, "Ranger Guildmaster");
break;
case SHADOWKNIGHTGM:
strcpy(ns->spawn.lastName, "Shadow Knight Guildmaster");
break;
case DRUIDGM:
strcpy(ns->spawn.lastName, "Druid Guildmaster");
break;
case MONKGM:
strcpy(ns->spawn.lastName, "Monk Guildmaster");
break;
case BARDGM:
strcpy(ns->spawn.lastName, "Bard Guildmaster");
break;
case ROGUEGM:
strcpy(ns->spawn.lastName, "Rogue Guildmaster");
break;
case SHAMANGM:
strcpy(ns->spawn.lastName, "Shaman Guildmaster");
break;
case NECROMANCERGM:
strcpy(ns->spawn.lastName, "Necromancer Guildmaster");
break;
case WIZARDGM:
strcpy(ns->spawn.lastName, "Wizard Guildmaster");
break;
case MAGICIANGM:
strcpy(ns->spawn.lastName, "Magician Guildmaster");
break;
case ENCHANTERGM:
strcpy(ns->spawn.lastName, "Enchanter Guildmaster");
break;
case BEASTLORDGM:
strcpy(ns->spawn.lastName, "Beastlord Guildmaster");
break;
case BERSERKERGM:
strcpy(ns->spawn.lastName, "Berserker Guildmaster");
break;
case MERCENARY_MASTER:
strcpy(ns->spawn.lastName, "Mercenary Liaison");
break;
default:
strcpy(ns->spawn.lastName, ns->spawn.lastName);
break;
}
}
void Mob::CreateSpawnPacket(EQApplicationPacket *app, Mob *ForWho) void Mob::CreateSpawnPacket(EQApplicationPacket *app, Mob *ForWho)
{ {
app->SetOpcode(OP_NewSpawn); app->SetOpcode(OP_NewSpawn);
app->size = sizeof(NewSpawn_Struct); app->size = sizeof(NewSpawn_Struct);
app->pBuffer = new uchar[app->size]; app->pBuffer = new uchar[app->size];
memset(app->pBuffer, 0, app->size); memset(app->pBuffer, 0, app->size);
NewSpawn_Struct *ns = (NewSpawn_Struct *) app->pBuffer; auto ns = (NewSpawn_Struct *) app->pBuffer;
FillSpawnStruct(ns, ForWho); FillSpawnStruct(ns, ForWho);
if (RuleB(NPC, UseClassAsLastName) && strlen(ns->spawn.lastName) == 0) { if (
switch (ns->spawn.class_) { !RuleB(NPC, DisableLastNames) &&
case TRIBUTE_MASTER: RuleB(NPC, UseClassAsLastName) &&
strcpy(ns->spawn.lastName, "Tribute Master"); !strlen(ns->spawn.lastName)
break; ) {
case ADVENTURERECRUITER: SetSpawnLastNameByClass(ns);
strcpy(ns->spawn.lastName, "Adventure Recruiter");
break;
case BANKER:
strcpy(ns->spawn.lastName, "Banker");
break;
case ADVENTUREMERCHANT:
strcpy(ns->spawn.lastName, "Adventure Merchant");
break;
case WARRIORGM:
strcpy(ns->spawn.lastName, "GM Warrior");
break;
case PALADINGM:
strcpy(ns->spawn.lastName, "GM Paladin");
break;
case RANGERGM:
strcpy(ns->spawn.lastName, "GM Ranger");
break;
case SHADOWKNIGHTGM:
strcpy(ns->spawn.lastName, "GM Shadowknight");
break;
case DRUIDGM:
strcpy(ns->spawn.lastName, "GM Druid");
break;
case BARDGM:
strcpy(ns->spawn.lastName, "GM Bard");
break;
case ROGUEGM:
strcpy(ns->spawn.lastName, "GM Rogue");
break;
case SHAMANGM:
strcpy(ns->spawn.lastName, "GM Shaman");
break;
case NECROMANCERGM:
strcpy(ns->spawn.lastName, "GM Necromancer");
break;
case WIZARDGM:
strcpy(ns->spawn.lastName, "GM Wizard");
break;
case MAGICIANGM:
strcpy(ns->spawn.lastName, "GM Magician");
break;
case ENCHANTERGM:
strcpy(ns->spawn.lastName, "GM Enchanter");
break;
case BEASTLORDGM:
strcpy(ns->spawn.lastName, "GM Beastlord");
break;
case BERSERKERGM:
strcpy(ns->spawn.lastName, "GM Berserker");
break;
case MERCERNARY_MASTER:
strcpy(ns->spawn.lastName, "Mercenary Recruiter");
break;
default:
break;
}
} }
} }
@ -1158,80 +1180,20 @@ void Mob::CreateSpawnPacket(EQApplicationPacket* app, NewSpawn_Struct* ns) {
memcpy(app->pBuffer, ns, sizeof(NewSpawn_Struct)); memcpy(app->pBuffer, ns, sizeof(NewSpawn_Struct));
// Custom packet data // Custom packet data
NewSpawn_Struct* ns2 = (NewSpawn_Struct*)app->pBuffer; auto ns2 = (NewSpawn_Struct*) app->pBuffer;
strcpy(ns2->spawn.name, ns->spawn.name); strcpy(ns2->spawn.name, ns->spawn.name);
// Set default Last Names for certain Classes if not defined // Set default Last Names for certain Classes if not defined
if (RuleB(NPC, UseClassAsLastName) && strlen(ns->spawn.lastName) == 0) if (
{ !RuleB(NPC, DisableLastNames) &&
switch (ns->spawn.class_) RuleB(NPC, UseClassAsLastName) &&
{ !strlen(ns->spawn.lastName)
case TRIBUTE_MASTER: ) {
strcpy(ns2->spawn.lastName, "Tribute Master"); SetSpawnLastNameByClass(ns2);
break; } else {
case ADVENTURERECRUITER:
strcpy(ns2->spawn.lastName, "Adventure Recruiter");
break;
case BANKER:
strcpy(ns2->spawn.lastName, "Banker");
break;
case ADVENTUREMERCHANT:
strcpy(ns2->spawn.lastName, "Adventure Merchant");
break;
case WARRIORGM:
strcpy(ns2->spawn.lastName, "GM Warrior");
break;
case PALADINGM:
strcpy(ns2->spawn.lastName, "GM Paladin");
break;
case RANGERGM:
strcpy(ns2->spawn.lastName, "GM Ranger");
break;
case SHADOWKNIGHTGM:
strcpy(ns2->spawn.lastName, "GM Shadowknight");
break;
case DRUIDGM:
strcpy(ns2->spawn.lastName, "GM Druid");
break;
case BARDGM:
strcpy(ns2->spawn.lastName, "GM Bard");
break;
case ROGUEGM:
strcpy(ns2->spawn.lastName, "GM Rogue");
break;
case SHAMANGM:
strcpy(ns2->spawn.lastName, "GM Shaman");
break;
case NECROMANCERGM:
strcpy(ns2->spawn.lastName, "GM Necromancer");
break;
case WIZARDGM:
strcpy(ns2->spawn.lastName, "GM Wizard");
break;
case MAGICIANGM:
strcpy(ns2->spawn.lastName, "GM Magician");
break;
case ENCHANTERGM:
strcpy(ns2->spawn.lastName, "GM Enchanter");
break;
case BEASTLORDGM:
strcpy(ns2->spawn.lastName, "GM Beastlord");
break;
case BERSERKERGM:
strcpy(ns2->spawn.lastName, "GM Berserker");
break;
case MERCERNARY_MASTER:
strcpy(ns2->spawn.lastName, "Mercenary liaison");
break;
default:
strcpy(ns2->spawn.lastName, ns->spawn.lastName);
break;
}
}
else
{
strcpy(ns2->spawn.lastName, ns->spawn.lastName); strcpy(ns2->spawn.lastName, ns->spawn.lastName);
} }
memset(&app->pBuffer[sizeof(Spawn_Struct)-7], 0xFF, 7); memset(&app->pBuffer[sizeof(Spawn_Struct)-7], 0xFF, 7);
} }

View File

@ -737,6 +737,7 @@ public:
void CreateHPPacket(EQApplicationPacket* app); void CreateHPPacket(EQApplicationPacket* app);
void SendHPUpdate(bool force_update_all = false); void SendHPUpdate(bool force_update_all = false);
virtual void ResetHPUpdateTimer() {}; // does nothing virtual void ResetHPUpdateTimer() {}; // does nothing
static void SetSpawnLastNameByClass(NewSpawn_Struct* ns);
//Util //Util
static uint32 RandomTimer(int min, int max); static uint32 RandomTimer(int min, int max);

View File

@ -265,7 +265,7 @@ NPC::NPC(const NPCType *npc_type_data, Spawn2 *in_respawn, const glm::vec4 &posi
HasAISpellEffects = false; HasAISpellEffects = false;
innate_proc_spell_id = 0; innate_proc_spell_id = 0;
if (GetClass() == MERCERNARY_MASTER && RuleB(Mercs, AllowMercs)) { if (GetClass() == MERCENARY_MASTER && RuleB(Mercs, AllowMercs)) {
LoadMercTypes(); LoadMercTypes();
LoadMercs(); LoadMercs();
} }

View File

@ -2511,8 +2511,8 @@ const NPCType *ZoneDatabase::LoadNPCTypesData(uint32 npc_type_id, bool bulk_load
t->see_invis = n.see_invis != 0; t->see_invis = n.see_invis != 0;
t->see_invis_undead = n.see_invis_undead != 0; // Set see_invis_undead flag t->see_invis_undead = n.see_invis_undead != 0; // Set see_invis_undead flag
if (!n.lastname.empty()) { if (!RuleB(NPC, DisableLastNames) && !n.lastname.empty()) {
strn0cpy(t->lastname, n.lastname.c_str(), 32); strn0cpy(t->lastname, n.lastname.c_str(), sizeof(t->lastname));
} }
t->qglobal = n.qglobal != 0; // qglobal t->qglobal = n.qglobal != 0; // qglobal

View File

@ -35,7 +35,7 @@ spawn2 mediumblob, npcs mediumblob, npc_loot mediumblob, gmspawntype mediumblob,
struct NPCType struct NPCType
{ {
char name[64]; char name[64];
char lastname[70]; char lastname[64];
int64 current_hp; int64 current_hp;
int64 max_hp; int64 max_hp;
float size; float size;