[Cleanup] Fix #spawn command NPCs having 0 health (#3371)

# Notes
- NPCs when spawned with this command have 0 health by default, requiring operators to manually edit their health if they're using this NPC as an NPC in their hub.
This commit is contained in:
Alex King 2023-05-21 18:48:08 -04:00 committed by GitHub
parent e305ba852b
commit ff4b117cfa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 75 additions and 28 deletions

View File

@ -2,19 +2,36 @@
void command_spawn(Client *c, const Seperator *sep)
{
if (sep->arg[1][0] != 0) {
Client *client = entity_list.GetClientByName(sep->arg[1]);
if (client) {
c->Message(Chat::White, "You cannot spawn a mob with the same name as a character!");
return;
}
}
NPC *npc = NPC::SpawnNPC(sep->argplus[1], c->GetPosition(), c);
if (!npc) {
const auto arguments = sep->argnum;
if (!arguments) {
c->Message(Chat::White, "Usage: #spawn [Name]");
c->Message(
Chat::White,
"Format: #spawn name race level material hp gender class priweapon secweapon merchantid bodytype - spawns a npc those parameters."
"Optional Usage: #spawn [Name] [Race] [Level] [Texture] [Health] [Gender] [Class] [Primary Model] [Secondary Model] [Merchant ID] [Body Type]"
);
c->Message(
Chat::White,
"Name Format: NPCFirstname_NPCLastname - All numbers in a name are stripped and \"_\" characters become a space."
);
c->Message(
Chat::White,
"Note: Using \"-\" for gender will autoselect the gender for the race. Using \"-\" for HP will use the calculated maximum HP."
);
return;
}
const auto* m = entity_list.GetClientByName(sep->arg[1]);
if (m) {
c->Message(Chat::White, "You cannot spawn a mob with the same name as a character!");
return;
}
const auto* n = NPC::SpawnNPC(sep->argplus[1], c->GetPosition(), c);
if (!n) {
c->Message(Chat::White, "Usage: #spawn [Name]");
c->Message(
Chat::White,
"Optional Usage: #spawn [Name] [Race] [Level] [Texture] [Health] [Gender] [Class] [Primary Model] [Secondary Model] [Merchant ID] [Body Type]"
);
c->Message(
Chat::White,

View File

@ -1378,7 +1378,7 @@ NPC * NPC::SpawnNodeNPC(std::string name, std::string last_name, const glm::vec4
}
NPC* NPC::SpawnNPC(const char* spawncommand, const glm::vec4& position, Client* client) {
if(spawncommand == 0 || spawncommand[0] == 0) {
if (spawncommand == 0 || spawncommand[0] == 0) {
return 0;
}
else {
@ -1387,42 +1387,54 @@ NPC* NPC::SpawnNPC(const char* spawncommand, const glm::vec4& position, Client*
if (!sep.IsNumber(1)) {
sprintf(sep.arg[1], "1");
}
if (!sep.IsNumber(2)) {
sprintf(sep.arg[2], "1");
}
if (!sep.IsNumber(3)) {
sprintf(sep.arg[3], "0");
}
if (Strings::ToInt(sep.arg[4]) > 2100000000 || Strings::ToInt(sep.arg[4]) <= 0) {
sprintf(sep.arg[4], " ");
}
if (!strcmp(sep.arg[5], "-")) {
sprintf(sep.arg[5], " ");
}
if (!sep.IsNumber(5)) {
sprintf(sep.arg[5], " ");
}
if (!sep.IsNumber(6)) {
sprintf(sep.arg[6], "1");
}
if (!sep.IsNumber(8)) {
sprintf(sep.arg[8], "0");
}
if (!sep.IsNumber(9)) {
sprintf(sep.arg[9], "0");
}
if (!sep.IsNumber(7)) {
sprintf(sep.arg[7], "0");
}
if (!strcmp(sep.arg[4], "-")) {
sprintf(sep.arg[4], " ");
}
if (!sep.IsNumber(10)) { // bodytype
sprintf(sep.arg[10], "0");
}
//Calc MaxHP if client neglected to enter it...
if (sep.arg[4] && !sep.IsNumber(4)) {
sprintf(sep.arg[4], "0");
sprintf(sep.arg[4], "1");
}
// Autoselect NPC Gender
@ -1435,6 +1447,7 @@ NPC* NPC::SpawnNPC(const char* spawncommand, const glm::vec4& position, Client*
memset(npc_type, 0, sizeof(NPCType));
strncpy(npc_type->name, sep.arg[0], 60);
npc_type->current_hp = Strings::ToInt(sep.arg[4]);
npc_type->max_hp = Strings::ToInt(sep.arg[4]);
npc_type->race = Strings::ToInt(sep.arg[1]);
@ -1445,8 +1458,8 @@ NPC* NPC::SpawnNPC(const char* spawncommand, const glm::vec4& position, Client*
npc_type->npc_id = 0;
npc_type->loottable_id = 0;
npc_type->texture = Strings::ToInt(sep.arg[3]);
npc_type->light = 0; // spawncommand needs update
npc_type->runspeed = 1.25;
npc_type->light = 0;
npc_type->runspeed = 1.25f;
npc_type->d_melee_texture1 = Strings::ToInt(sep.arg[7]);
npc_type->d_melee_texture2 = Strings::ToInt(sep.arg[8]);
npc_type->merchanttype = Strings::ToInt(sep.arg[9]);
@ -1462,8 +1475,8 @@ NPC* NPC::SpawnNPC(const char* spawncommand, const glm::vec4& position, Client*
npc_type->attack_delay = 3000;
npc_type->prim_melee_type = 28;
npc_type->sec_melee_type = 28;
npc_type->prim_melee_type = static_cast<uint8>(EQ::skills::SkillHandtoHand);
npc_type->sec_melee_type = static_cast<uint8>(EQ::skills::SkillHandtoHand);
auto npc = new NPC(npc_type, nullptr, position, GravityBehavior::Water);
npc->GiveNPCTypeData(npc_type);
@ -1472,17 +1485,34 @@ NPC* NPC::SpawnNPC(const char* spawncommand, const glm::vec4& position, Client*
if (client) {
// Notify client of spawn data
client->Message(Chat::White, "New spawn:");
client->Message(Chat::White, "Name: %s", npc->name);
client->Message(Chat::White, "Race: %u", npc->race);
client->Message(Chat::White, "Level: %u", npc->level);
client->Message(Chat::White, "Material: %u", npc->texture);
client->Message(Chat::White, "Current/Max HP: %i", npc->max_hp);
client->Message(Chat::White, "Gender: %u", npc->gender);
client->Message(Chat::White, "Class: %u", npc->class_);
client->Message(Chat::White, "Weapon Item Number: %u/%u", npc->d_melee_texture1, npc->d_melee_texture2);
client->Message(Chat::White, "MerchantID: %u", npc->MerchantType);
client->Message(Chat::White, "Bodytype: %u", npc->bodytype);
client->Message(Chat::White, fmt::format("Name | {}", npc->name).c_str());
client->Message(Chat::White, fmt::format("Level | {}", npc->level).c_str());
client->Message(Chat::White, fmt::format("Health | {}", npc->max_hp).c_str());
client->Message(Chat::White, fmt::format("Race | {} ({})", GetRaceIDName(npc->race), npc->race).c_str());
client->Message(Chat::White, fmt::format("Class | {} ({})", GetClassIDName(npc->class_), npc->class_).c_str());
client->Message(Chat::White, fmt::format("Gender | {} ({})", GetGenderName(npc->gender), npc->gender).c_str());
client->Message(Chat::White, fmt::format("Texture | {}", npc->texture).c_str());
if (npc->d_melee_texture1 || npc->d_melee_texture2) {
client->Message(
Chat::White,
fmt::format(
"Weapon Item Number | Primary: {} Secondary: {}",
npc->d_melee_texture1,
npc->d_melee_texture2
).c_str()
);
}
if (npc->MerchantType) {
client->Message(Chat::White, fmt::format("Merchant ID | {}", npc->MerchantType).c_str());
}
if (npc->bodytype) {
client->Message(Chat::White, fmt::format("Body Type | {} ({})", EQ::constants::GetBodyTypeName(npc->bodytype), npc->bodytype).c_str());
}
client->Message(Chat::White, "New NPC spawned!");
}
return npc;