mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 16:51:29 +00:00
[Commands] #npcspawn Changes (#4311)
* Changes to npcspawn create command so it takes more stats from the target npc * Add see invis stats to npccreate command * WIP npcspawn command changes * Add npcspawn clone and help args, fix some broken things with npcspawn * Cleanup comments and add apostraphes to zone shortname query * Make it so npcspawn remove only removes spawn2 row and optionally removes spawngroup and spawnentry, make create and add spawn the npc at client loc * Make npcspawn create use the same syntax for spawngroup naming as npcspawn add * Revert npcspawn create and add to use npc location rather than client, other misc tweaks
This commit is contained in:
parent
1be86edf20
commit
c87aadbf0c
@ -6372,9 +6372,9 @@ void Client::NPCSpawn(NPC *target_npc, const char *identifier, uint32 extra)
|
||||
bool is_delete = spawn_type.find("delete") != std::string::npos;
|
||||
bool is_remove = spawn_type.find("remove") != std::string::npos;
|
||||
bool is_update = spawn_type.find("update") != std::string::npos;
|
||||
bool is_clone = spawn_type.find("clone") != std::string::npos;
|
||||
if (is_add || is_create) {
|
||||
// Add: extra tries to create the NPC ID within the range for the current Zone (Zone ID * 1000)
|
||||
// Create: extra sets the Respawn Timer for add
|
||||
// extra sets the Respawn Timer for add/create
|
||||
content_db.NPCSpawnDB(
|
||||
is_add ? NPCSpawnTypes::AddNewSpawngroup : NPCSpawnTypes::CreateNewSpawn,
|
||||
zone->GetShortName(),
|
||||
@ -6398,7 +6398,17 @@ void Client::NPCSpawn(NPC *target_npc, const char *identifier, uint32 extra)
|
||||
zone->GetShortName(),
|
||||
zone->GetInstanceVersion(),
|
||||
this,
|
||||
target_npc->CastToNPC()
|
||||
target_npc->CastToNPC(),
|
||||
extra
|
||||
);
|
||||
} else if (is_clone) {
|
||||
content_db.NPCSpawnDB(
|
||||
NPCSpawnTypes::AddSpawnFromSpawngroup,
|
||||
zone->GetShortName(),
|
||||
zone->GetInstanceVersion(),
|
||||
this,
|
||||
target_npc->CastToNPC(),
|
||||
extra
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1666,7 +1666,7 @@ void command_npcedit(Client *c, const Seperator *sep)
|
||||
} else if (!strcasecmp(sep->arg[1], "set_grid")) {
|
||||
if (sep->IsNumber(2)) {
|
||||
const uint32 grid_id = Strings::ToUnsignedInt(sep->arg[2]);
|
||||
if (grid_id) {
|
||||
if (grid_id >= 0) {
|
||||
d = fmt::format(
|
||||
"{} now has a Grid ID of {} on Spawn Group ID {}.",
|
||||
npc_id_string,
|
||||
@ -1674,14 +1674,15 @@ void command_npcedit(Client *c, const Seperator *sep)
|
||||
Strings::Commify(std::to_string(t->GetSpawnGroupId()))
|
||||
);
|
||||
auto query = fmt::format(
|
||||
"UPDATE spawn2 SET pathgrid = {} WHERE spawngroupID = {} AND version = {}",
|
||||
"UPDATE spawn2 SET pathgrid = {} WHERE spawngroupID = {} AND version = {} AND zone = '{}'",
|
||||
grid_id,
|
||||
t->GetSpawnGroupId(),
|
||||
zone->GetInstanceVersion()
|
||||
zone->GetInstanceVersion(),
|
||||
zone->GetShortName()
|
||||
);
|
||||
content_db.QueryDatabase(query);
|
||||
} else {
|
||||
c->Message(Chat::White, "Grid ID must be greater than 0.");
|
||||
c->Message(Chat::White, "Grid ID must be greater than or equal to 0.");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
|
||||
@ -9,44 +9,46 @@ void command_npcspawn(Client *c, const Seperator *sep)
|
||||
|
||||
int arguments = sep->argnum;
|
||||
if (!arguments) {
|
||||
c->Message(Chat::White, "Command Syntax: #npcspawn [Add|Create|Delete|Remove|Update]");
|
||||
c->Message(Chat::White, "Command Syntax: #npcspawn [Add|Create|Delete|Remove|Update|Clone|Help]");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcasecmp(sep->arg[1], "help")) {
|
||||
c->Message(Chat::White, "Command Syntax: #npcspawn [Add|Create|Delete|Remove|Update|Clone|Help] [optional 3rd parameter]");
|
||||
c->Message(Chat::White, "Usage: #npcspawn add [respawntime] - Using the same targeted NPC ID, creates new spawn2 and spawngroup entries");
|
||||
c->Message(Chat::White, "Usage: #npcspawn clone [respawntime] - Copies targeted NPC and spawngroup, creating only a spawn2 entry at the current client location");
|
||||
c->Message(Chat::White, "Usage: #npcspawn create [respawntime] - Creates new NPC type copying the data from the targeted NPC, with new spawn2 and spawngroup entries");
|
||||
c->Message(Chat::White, "Usage: #npcspawn delete - Deletes the spawn2, spawngroup, spawnentry and npc_types rows for targeted NPC");
|
||||
c->Message(Chat::White, "Usage: #npcspawn remove [remove_spawngroups] - Deletes the spawn2 row for targeted NPC, also delete spawngroup and spawnentry rows if remove_spawngroups is > 0");
|
||||
c->Message(Chat::White, "Usage: #npcspawn update - Updates NPC appearance in database");
|
||||
return;
|
||||
}
|
||||
|
||||
auto target = c->GetTarget()->CastToNPC();
|
||||
uint32 extra = 0;
|
||||
bool is_add = !strcasecmp(sep->arg[1], "add");
|
||||
bool is_clone = !strcasecmp(sep->arg[1], "clone");
|
||||
bool is_create = !strcasecmp(sep->arg[1], "create");
|
||||
bool is_delete = !strcasecmp(sep->arg[1], "delete");
|
||||
bool is_remove = !strcasecmp(sep->arg[1], "remove");
|
||||
bool is_update = !strcasecmp(sep->arg[1], "update");
|
||||
if (
|
||||
!is_add &&
|
||||
!is_clone &&
|
||||
!is_create &&
|
||||
!is_delete &&
|
||||
!is_remove &&
|
||||
!is_update
|
||||
) {
|
||||
c->Message(Chat::White, "Command Syntax: #npcspawn [Add|Create|Delete|Remove|Update]");
|
||||
c->Message(Chat::White, "Command Syntax: #npcspawn [Add|Create|Delete|Remove|Update|Clone|Help]");
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_add || is_create) {
|
||||
extra = (
|
||||
sep->IsNumber(2) ?
|
||||
(
|
||||
is_add ?
|
||||
Strings::ToInt(sep->arg[2]) :
|
||||
1
|
||||
) : (
|
||||
is_add ?
|
||||
1200 :
|
||||
0
|
||||
)
|
||||
); // Default to 1200 for Add, 0 for Create if not set
|
||||
if (is_add || is_create || is_clone) {
|
||||
extra = sep->IsNumber(2) ? Strings::ToInt(sep->arg[2]) : 1200; // Extra param is only used for respawn time in Add/Create/Clone, default to 1200 if not set
|
||||
|
||||
content_db.NPCSpawnDB(
|
||||
is_add ? NPCSpawnTypes::AddNewSpawngroup : NPCSpawnTypes::CreateNewSpawn,
|
||||
is_add ? NPCSpawnTypes::AddNewSpawngroup : (is_create ? NPCSpawnTypes::CreateNewSpawn : NPCSpawnTypes::AddSpawnFromSpawngroup),
|
||||
zone->GetShortName(),
|
||||
zone->GetInstanceVersion(),
|
||||
c,
|
||||
@ -58,7 +60,13 @@ void command_npcspawn(Client *c, const Seperator *sep)
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Spawn {} | Name: {}",
|
||||
is_add ? "Added" : "Created",
|
||||
is_add ?
|
||||
"Added" :
|
||||
(
|
||||
is_create ?
|
||||
"Created" :
|
||||
"Cloned"
|
||||
),
|
||||
c->GetTargetDescription(target)
|
||||
).c_str()
|
||||
);
|
||||
@ -84,12 +92,15 @@ void command_npcspawn(Client *c, const Seperator *sep)
|
||||
)
|
||||
);
|
||||
|
||||
extra = sep->IsNumber(2) ? Strings::ToInt(sep->arg[2]) : 0; // Extra param is used in Remove as a flag to optionally remove spawngroup/spawnentry if 1 (always remove spawn2 entry)
|
||||
|
||||
content_db.NPCSpawnDB(
|
||||
spawn_update_type,
|
||||
zone->GetShortName(),
|
||||
zone->GetInstanceVersion(),
|
||||
c,
|
||||
target
|
||||
target,
|
||||
extra
|
||||
);
|
||||
|
||||
c->Message(
|
||||
|
||||
83
zone/npc.cpp
83
zone/npc.cpp
@ -1209,6 +1209,7 @@ uint32 ZoneDatabase::CreateNewNPCCommand(
|
||||
e.race = n->GetRace();
|
||||
e.class_ = n->GetClass();
|
||||
e.hp = n->GetMaxHP();
|
||||
e.mana = n->GetMaxMana();
|
||||
e.gender = n->GetGender();
|
||||
e.texture = n->GetTexture();
|
||||
e.helmtexture = n->GetHelmTexture();
|
||||
@ -1216,8 +1217,50 @@ uint32 ZoneDatabase::CreateNewNPCCommand(
|
||||
e.loottable_id = n->GetLoottableID();
|
||||
e.merchant_id = n->MerchantType;
|
||||
e.runspeed = n->GetRunspeed();
|
||||
e.prim_melee_type = static_cast<uint8_t>(EQ::skills::SkillHandtoHand);
|
||||
e.sec_melee_type = static_cast<uint8_t>(EQ::skills::SkillHandtoHand);
|
||||
e.walkspeed = n->GetWalkspeed();
|
||||
e.prim_melee_type = n->GetPrimSkill();
|
||||
e.sec_melee_type = n->GetSecSkill();
|
||||
|
||||
e.bodytype = n->GetBodyType();
|
||||
e.npc_faction_id = n->GetNPCFactionID();
|
||||
e.aggroradius = n->GetAggroRange();
|
||||
e.assistradius = n->GetAssistRange();
|
||||
|
||||
e.AC = n->GetAC();
|
||||
e.ATK = n->GetATK();
|
||||
e.STR = n->GetSTR();
|
||||
e.STA = n->GetSTA();
|
||||
e.AGI = n->GetAGI();
|
||||
e.DEX = n->GetDEX();
|
||||
e.WIS = n->GetWIS();
|
||||
e._INT = n->GetINT();
|
||||
e.CHA = n->GetCHA();
|
||||
|
||||
e.PR = n->GetPR();
|
||||
e.MR = n->GetMR();
|
||||
e.DR = n->GetDR();
|
||||
e.FR = n->GetFR();
|
||||
e.CR = n->GetCR();
|
||||
e.Corrup = n->GetCorrup();
|
||||
e.PhR = n->GetPhR();
|
||||
|
||||
e.Accuracy = n->GetAccuracyRating();
|
||||
e.slow_mitigation = n->GetSlowMitigation();
|
||||
e.mindmg = n->GetMinDMG();
|
||||
e.maxdmg = n->GetMaxDMG();
|
||||
e.hp_regen_rate = n->GetHPRegen();
|
||||
e.hp_regen_per_second = n->GetHPRegenPerSecond();
|
||||
//e.attack_delay = n->GetAttackDelay(); // Attack delay isn't copying correctly, 3000 becomes 18,400 in the copied NPC?
|
||||
e.spellscale = n->GetSpellScale();
|
||||
e.healscale = n->GetHealScale();
|
||||
e.Avoidance = n->GetAvoidanceRating();
|
||||
e.heroic_strikethrough = n->GetHeroicStrikethrough();
|
||||
|
||||
e.see_hide = n->SeeHide();
|
||||
e.see_improved_hide = n->SeeImprovedHide();
|
||||
e.see_invis = n->SeeInvisible();
|
||||
e.see_invis_undead = n->SeeInvisibleUndead();
|
||||
|
||||
|
||||
e = NpcTypesRepository::InsertOne(*this, e);
|
||||
|
||||
@ -1228,9 +1271,10 @@ uint32 ZoneDatabase::CreateNewNPCCommand(
|
||||
auto sg = SpawngroupRepository::NewEntity();
|
||||
|
||||
sg.name = fmt::format(
|
||||
"{}-{}",
|
||||
"{}_{}_{}",
|
||||
zone,
|
||||
n->GetName()
|
||||
Strings::Escape(n->GetName()),
|
||||
Timer::GetCurrentTime()
|
||||
);
|
||||
|
||||
sg = SpawngroupRepository::InsertOne(*this, sg);
|
||||
@ -1249,7 +1293,7 @@ uint32 ZoneDatabase::CreateNewNPCCommand(
|
||||
s2.x = n->GetX();
|
||||
s2.y = n->GetY();
|
||||
s2.z = n->GetZ();
|
||||
s2.respawntime = 1200;
|
||||
s2.respawntime = extra > 0 ? extra : 1200;
|
||||
s2.heading = n->GetHeading();
|
||||
s2.spawngroupID = sg.id;
|
||||
|
||||
@ -1361,12 +1405,17 @@ uint32 ZoneDatabase::UpdateNPCTypeAppearance(Client* c, NPC* n)
|
||||
return updated;
|
||||
}
|
||||
|
||||
uint32 ZoneDatabase::DeleteSpawnLeaveInNPCTypeTable(const std::string& zone, Client* c, NPC* n)
|
||||
uint32 ZoneDatabase::DeleteSpawnLeaveInNPCTypeTable(const std::string& zone, Client* c, NPC* n, uint32 remove_spawngroup_id)
|
||||
{
|
||||
if (!n->respawn2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const auto& l = Spawn2Repository::GetWhere(
|
||||
*this,
|
||||
fmt::format(
|
||||
"`zone` = '{}' AND `spawngroupID` = {}",
|
||||
"`id` = {} AND `zone` = '{}' AND `spawngroupID` = {}",
|
||||
n->respawn2->GetID(),
|
||||
zone,
|
||||
n->GetSpawnGroupId()
|
||||
)
|
||||
@ -1382,12 +1431,14 @@ uint32 ZoneDatabase::DeleteSpawnLeaveInNPCTypeTable(const std::string& zone, Cli
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!SpawngroupRepository::DeleteOne(*this, e.spawngroupID)) {
|
||||
return 0;
|
||||
}
|
||||
if (remove_spawngroup_id > 0) {
|
||||
if (!SpawngroupRepository::DeleteOne(*this, e.spawngroupID)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!SpawnentryRepository::DeleteOne(*this, e.spawngroupID)) {
|
||||
return 0;
|
||||
if (!SpawnentryRepository::DeleteOne(*this, e.spawngroupID)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
@ -1440,7 +1491,7 @@ uint32 ZoneDatabase::AddSpawnFromSpawnGroup(
|
||||
uint32 instance_version,
|
||||
Client* c,
|
||||
NPC* n,
|
||||
uint32 spawngroup_id
|
||||
uint32 extra
|
||||
)
|
||||
{
|
||||
auto e = Spawn2Repository::NewEntity();
|
||||
@ -1451,8 +1502,8 @@ uint32 ZoneDatabase::AddSpawnFromSpawnGroup(
|
||||
e.y = c->GetY();
|
||||
e.z = c->GetZ();
|
||||
e.heading = c->GetHeading();
|
||||
e.respawntime = 120;
|
||||
e.spawngroupID = spawngroup_id;
|
||||
e.respawntime = extra > 0 ? extra : 1200;
|
||||
e.spawngroupID = n->GetSpawnGroupId();
|
||||
|
||||
e = Spawn2Repository::InsertOne(*this, e);
|
||||
|
||||
@ -1529,7 +1580,7 @@ uint32 ZoneDatabase::NPCSpawnDB(
|
||||
return UpdateNPCTypeAppearance(c, n);
|
||||
}
|
||||
case NPCSpawnTypes::RemoveSpawn: {
|
||||
return DeleteSpawnLeaveInNPCTypeTable(zone, c, n);
|
||||
return DeleteSpawnLeaveInNPCTypeTable(zone, c, n, extra);
|
||||
}
|
||||
case NPCSpawnTypes::DeleteSpawn: {
|
||||
return DeleteSpawnRemoveFromNPCTypeTable(zone, instance_version, c, n);
|
||||
|
||||
@ -552,7 +552,7 @@ public:
|
||||
uint32 NPCSpawnDB(uint8 command, const std::string& zone, uint32 instance_version, Client *c, NPC* n = 0, uint32 extra = 0); // 0 = Create 1 = Add; 2 = Update; 3 = Remove; 4 = Delete
|
||||
uint32 CreateNewNPCCommand(const std::string& zone, uint32 instance_version, Client* c, NPC* n, uint32 extra);
|
||||
uint32 AddNewNPCSpawnGroupCommand(const std::string& zone, uint32 instance_version, Client* c, NPC* n, uint32 in_respawn_time);
|
||||
uint32 DeleteSpawnLeaveInNPCTypeTable(const std::string& zone, Client* c, NPC* n);
|
||||
uint32 DeleteSpawnLeaveInNPCTypeTable(const std::string& zone, Client* c, NPC* n, uint32 remove_spawngroup_id);
|
||||
uint32 DeleteSpawnRemoveFromNPCTypeTable(const std::string& zone, uint32 instance_version, Client* c, NPC* n);
|
||||
uint32 AddSpawnFromSpawnGroup(const std::string& zone, uint32 instance_version, Client* c, NPC* n, uint32 spawngroup_id);
|
||||
uint32 AddNPCTypes(const std::string& zone, uint32 instance_version, Client* c, NPC* n, uint32 spawngroup_id);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user