sub commands /loot list [add/remove/clearall]

Fixes #28

/loot list add loottable_id
/loot list remove loottable_id
/loot list clearall

auto reloads loot, purges previous loot and re-assigns loot to selected spawn.

If you have multiple of the same spawn, then /repop the zone and it will repopulate after one is updated.
This commit is contained in:
Image 2020-03-10 09:12:56 -04:00
parent 4daeeb3489
commit 2ea621db1b
6 changed files with 165 additions and 22 deletions

View file

@ -1853,31 +1853,104 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
case COMMAND_LOOT_LIST:{
Spawn* spawn = cmdTarget;
if(spawn && spawn->IsEntity()){
vector<int32> loot_list = client->GetCurrentZone()->GetSpawnLootList(spawn->GetDatabaseID(), spawn->GetZone()->GetZoneID(), spawn->GetLevel(), race_types_list.GetRaceType(spawn->GetModelType()));
if(loot_list.size() > 0){
client->Message(CHANNEL_COLOR_YELLOW, "%s belongs to the following loot lists: ", spawn->GetName());
vector<int32>::iterator list_itr;
LootTable* table = 0;
for(list_itr = loot_list.begin(); list_itr != loot_list.end(); list_itr++){
table = client->GetCurrentZone()->GetLootTable(*list_itr);
if(table)
client->Message(CHANNEL_COLOR_YELLOW, "%u - %s", *list_itr, table->name.c_str());
if (sep && sep->arg[0]) {
if (!spawn->GetDatabaseID())
{
client->SimpleMessage(CHANNEL_COLOR_YELLOW, "Spawn has no database id to assign to loottables.");
break;
}
}
Entity* target = (Entity*)spawn;
client->Message(CHANNEL_COLOR_YELLOW, "Coins being carried: %u", target->GetLootCoins());
vector<Item*>* items = target->GetLootItems();
if(items){
client->SimpleMessage(CHANNEL_COLOR_YELLOW, "Spawn is carrying the following items: ");
vector<Item*>::iterator itr;
Item* item = 0;
for(itr = items->begin(); itr != items->end(); itr++){
item = *itr;
client->Message(CHANNEL_COLOR_YELLOW, "%u - %s", item->details.item_id, item->name.c_str());
else if (!spawn->IsNPC())
{
client->SimpleMessage(CHANNEL_COLOR_YELLOW, "these /loot list [add/remove/clearall] sub-commands are only designed for an NPC.");
break;
}
bool reloadLoot = false;
if (!stricmp(sep->arg[0], "remove") && sep->arg[1] && sep->IsNumber(1))
{
int32 loottable_id = atoul(sep->arg[1]);
if (loottable_id > 0 && database.RemoveSpawnLootTable(spawn, loottable_id))
{
client->Message(CHANNEL_COLOR_YELLOW, "Spawn %u loot table %u removed.", spawn->GetDatabaseID(), loottable_id);
reloadLoot = true;
}
else
client->Message(CHANNEL_COLOR_YELLOW, "/loot list remove [loottableid] - could not match any spawn_id entries against loottable_id %u.", loottable_id);
}
else if (!stricmp(sep->arg[0], "add") && sep->arg[1] && sep->IsNumber(1))
{
int32 loottable_id = atoul(sep->arg[1]);
if (loottable_id > 0)
{
database.AddLootTableToSpawn(spawn, loottable_id);
client->Message(CHANNEL_COLOR_YELLOW, "Spawn %u loot table %u added.", spawn->GetDatabaseID(), loottable_id);
reloadLoot = true;
}
else
client->SimpleMessage(CHANNEL_COLOR_YELLOW, "/loot list add [loottableid] - cannot add a loottable id of 0.");
}
else if (!stricmp(sep->arg[0], "clearall"))
{
if (database.RemoveSpawnLootTable(spawn, 0))
{
client->SimpleMessage(CHANNEL_COLOR_YELLOW, "Spawn loot tables removed.");
reloadLoot = true;
}
else
client->SimpleMessage(CHANNEL_COLOR_YELLOW, "/loot list clearall - could not match any spawn_id entries in loottable_id.");
}
else
{
client->SimpleMessage(CHANNEL_COLOR_YELLOW, "/loot list argument not supported.");
client->SimpleMessage(CHANNEL_COLOR_YELLOW, "/loot list add [loottableid] - add new loottable to spawn");
client->SimpleMessage(CHANNEL_COLOR_YELLOW, "/loot list remove [loottableid] - remove existing loottable from spawn");
client->SimpleMessage(CHANNEL_COLOR_YELLOW, "/loot list clearall - remove all loottables from spawn");
break;
}
if (reloadLoot)
{
database.LoadSpawnLoot(spawn->GetZone(), spawn);
if (spawn->IsNPC())
{
Entity* ent = (Entity*)spawn;
ent->SetLootCoins(0);
ent->ClearLootList();
spawn->GetZone()->AddLoot((NPC*)spawn);
client->Message(CHANNEL_COLOR_YELLOW, "Spawn %u active loot purged and reloaded.", spawn->GetDatabaseID());
}
}
break; // nothing further this is the end of these sub commands
}
else
client->SimpleMessage(CHANNEL_COLOR_YELLOW, "Spawn is not carrying any items.");
{
vector<int32> loot_list = client->GetCurrentZone()->GetSpawnLootList(spawn->GetDatabaseID(), spawn->GetZone()->GetZoneID(), spawn->GetLevel(), race_types_list.GetRaceType(spawn->GetModelType()));
if (loot_list.size() > 0) {
client->Message(CHANNEL_COLOR_YELLOW, "%s belongs to the following loot lists: ", spawn->GetName());
vector<int32>::iterator list_itr;
LootTable* table = 0;
for (list_itr = loot_list.begin(); list_itr != loot_list.end(); list_itr++) {
table = client->GetCurrentZone()->GetLootTable(*list_itr);
if (table)
client->Message(CHANNEL_COLOR_YELLOW, "%u - %s", *list_itr, table->name.c_str());
}
}
Entity* target = (Entity*)spawn;
client->Message(CHANNEL_COLOR_YELLOW, "Coins being carried: %u", target->GetLootCoins());
vector<Item*>* items = target->GetLootItems();
if (items) {
client->SimpleMessage(CHANNEL_COLOR_YELLOW, "Spawn is carrying the following items: ");
vector<Item*>::iterator itr;
Item* item = 0;
for (itr = items->begin(); itr != items->end(); itr++) {
item = *itr;
client->Message(CHANNEL_COLOR_YELLOW, "%u - %s", item->details.item_id, item->name.c_str());
}
}
else
client->SimpleMessage(CHANNEL_COLOR_YELLOW, "Spawn is not carrying any items.");
}
}
break;
}

View file

@ -808,6 +808,15 @@ public:
void UpdateGroupMemberInfo();
void CustomizeAppearance(PacketStruct* packet);
void ClearLootList() {
vector<Item*>::iterator itr;
for (itr = loot_items.begin(); itr != loot_items.end(); itr++)
safe_delete(*itr);
loot_items.clear();
}
Trade* trade;
// Keep track of entities that hate this spawn.

View file

@ -150,4 +150,57 @@ void WorldDatabase::LoadGlobalLoot(ZoneServer* zone) {
LogWrite(LOOT__DEBUG, 0, "Loot", "--Loaded %u Global loot list%s.", count, count == 1 ? "" : "s");
}
}
bool WorldDatabase::LoadSpawnLoot(ZoneServer* zone, Spawn* spawn)
{
if (!spawn->GetDatabaseID())
return false;
DatabaseResult result;
int32 count = 0;
zone->ClearSpawnLootList(spawn->GetDatabaseID());
// Finally, load loot tables into spawns that are set to use these loot tables
if (database_new.Select(&result, "SELECT spawn_id, loottable_id FROM spawn_loot where spawn_id=%u",spawn->GetDatabaseID())) {
count = 0;
LogWrite(LOOT__DEBUG, 0, "Loot", "--Assigning loot table(s) to spawn(s)...");
while (result.Next()) {
int32 spawn_id = result.GetInt32Str("spawn_id");
int32 table_id = result.GetInt32Str("loottable_id");
zone->AddSpawnLootList(spawn_id, table_id);
LogWrite(LOOT__DEBUG, 5, "Loot", "---Adding loot table %u to spawn %u", table_id, spawn_id);
count++;
}
LogWrite(LOOT__DEBUG, 0, "Loot", "--Loaded %u spawn loot list%s.", count, count == 1 ? "" : "s");
return true;
}
return false;
}
void WorldDatabase::AddLootTableToSpawn(Spawn* spawn, int32 loottable_id) {
Query query;
query.RunQuery2(Q_INSERT, "insert into spawn_loot set spawn_id=%u,loottable_id=%u", spawn->GetDatabaseID(), loottable_id);
}
bool WorldDatabase::RemoveSpawnLootTable(Spawn* spawn, int32 loottable_id) {
Query query;
if (loottable_id)
{
string delete_char = string("delete from spawn_loot where spawn_id=%i and loottable_id=%i");
query.RunQuery2(Q_DELETE, delete_char.c_str(), spawn->GetDatabaseID(), loottable_id);
}
else
{
string delete_char = string("delete from spawn_loot where spawn_id=%i");
query.RunQuery2(Q_DELETE, delete_char.c_str(), spawn->GetDatabaseID());
}
if (!query.GetAffectedRows())
{
//No error just in case ppl try doing stupid stuff
return false;
}
return true;
}

View file

@ -512,6 +512,9 @@ public:
/* Loot */
void LoadLoot(ZoneServer* zone);
void LoadGlobalLoot(ZoneServer* zone);
bool LoadSpawnLoot(ZoneServer* zone, Spawn* spawn);
void AddLootTableToSpawn(Spawn* spawn, int32 loottable_id);
bool RemoveSpawnLootTable(Spawn* spawn, int32 loottable_id);
void LoadCharacterHistory(int32 char_id, Player *player);
void LoadSpellErrors();

View file

@ -6663,10 +6663,14 @@ void ZoneServer::AddLootDrop(int32 id, LootDrop* drop){
loot_drops[id].push_back(drop);
}
void ZoneServer::AddSpawnLootList(int32 spawn_id, int32 id){
void ZoneServer::AddSpawnLootList(int32 spawn_id, int32 id) {
spawn_loot_list[spawn_id].push_back(id);
}
void ZoneServer::ClearSpawnLootList(int32 spawn_id) {
spawn_loot_list[spawn_id].clear();
}
void ZoneServer::AddLevelLootList(GlobalLoot* loot) {
level_loot_list.push_back(loot);
}

View file

@ -963,6 +963,7 @@ public:
void AddLootTable(int32 id, LootTable* table);
void AddLootDrop(int32 id, LootDrop* drop);
void AddSpawnLootList(int32 spawn_id, int32 id);
void ClearSpawnLootList(int32 spawn_id);
void AddLevelLootList(GlobalLoot* loot);
void AddRacialLootList(int16 racial_id, GlobalLoot* loot);
void AddZoneLootList(int32 zone, GlobalLoot* loot);