Fix #384 group encounter mob loot
Adding a new column to the spawn table: alter table spawn add column loot_drop_type int(10) unsigned not null default 0; - loot_drop_type of 0 means spawn will when part of an encounter transfer its loot to the next alive spawn. - loot_drop_type of 1 means the spawn will drop its own loot when it dies (like a named mob ideally). - These changes do not change body drops which remain on the spawn/npc that dies, not transferred. - loot and chest drops have been expanded beyond NPC's which means potential PVP support or even other types of spawns can drop loot/chests (probably expand loot_drop_type at a later time for more options in this area). Need lua interface support (when player dies and all that) issue #436 opened for it. - some additional mutex lock protections on spawn loot - SetLootTier(loot_tier) and GetLootTier(), SetLootDropType(drop_type) and GetLootDropType() added to lua
This commit is contained in:
parent
688104e592
commit
13b1837623
12 changed files with 200 additions and 29 deletions
1
DB/updates/loot_drop_type_june_2021.sql
Normal file
1
DB/updates/loot_drop_type_june_2021.sql
Normal file
|
@ -0,0 +1 @@
|
||||||
|
alter table spawn add column loot_drop_type int(10) unsigned not null default 0;
|
|
@ -51,6 +51,7 @@ public:
|
||||||
new_spawn->forceMapCheck = forceMapCheck;
|
new_spawn->forceMapCheck = forceMapCheck;
|
||||||
new_spawn->SetOmittedByDBFlag(IsOmittedByDBFlag());
|
new_spawn->SetOmittedByDBFlag(IsOmittedByDBFlag());
|
||||||
new_spawn->SetLootTier(GetLootTier());
|
new_spawn->SetLootTier(GetLootTier());
|
||||||
|
new_spawn->SetLootDropType(GetLootDropType());
|
||||||
return new_spawn;
|
return new_spawn;
|
||||||
}
|
}
|
||||||
bool IsGroundSpawn(){ return true; }
|
bool IsGroundSpawn(){ return true; }
|
||||||
|
|
|
@ -12808,3 +12808,63 @@ if (player && player->IsPlayer()) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int EQ2Emu_lua_GetLootTier(lua_State* state) {
|
||||||
|
int32 loot_tier = 0;
|
||||||
|
Spawn* spawn = lua_interface->GetSpawn(state);
|
||||||
|
lua_interface->ResetFunctionStack(state);
|
||||||
|
|
||||||
|
if (spawn) {
|
||||||
|
loot_tier = spawn->GetLootTier();
|
||||||
|
lua_interface->SetInt32Value(state, loot_tier);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int EQ2Emu_lua_SetLootTier(lua_State* state) {
|
||||||
|
if (!lua_interface)
|
||||||
|
return 0;
|
||||||
|
Spawn* spawn = lua_interface->GetSpawn(state);
|
||||||
|
int32 loot_tier = lua_interface->GetInt32Value(state, 2);
|
||||||
|
lua_interface->ResetFunctionStack(state);
|
||||||
|
|
||||||
|
if (spawn) {
|
||||||
|
spawn->SetLootTier(loot_tier);
|
||||||
|
lua_interface->SetBooleanValue(state, true);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_interface->SetBooleanValue(state, false);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int EQ2Emu_lua_GetLootDropType(lua_State* state) {
|
||||||
|
int32 loot_drop_type = 0;
|
||||||
|
Spawn* spawn = lua_interface->GetSpawn(state);
|
||||||
|
lua_interface->ResetFunctionStack(state);
|
||||||
|
|
||||||
|
if (spawn) {
|
||||||
|
loot_drop_type = spawn->GetLootDropType();
|
||||||
|
lua_interface->SetInt32Value(state, loot_drop_type);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int EQ2Emu_lua_SetLootDropType(lua_State* state) {
|
||||||
|
if (!lua_interface)
|
||||||
|
return 0;
|
||||||
|
Spawn* spawn = lua_interface->GetSpawn(state);
|
||||||
|
int32 loot_drop_type = lua_interface->GetInt32Value(state, 2);
|
||||||
|
lua_interface->ResetFunctionStack(state);
|
||||||
|
|
||||||
|
if (spawn) {
|
||||||
|
spawn->SetLootDropType(loot_drop_type);
|
||||||
|
lua_interface->SetBooleanValue(state, true);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_interface->SetBooleanValue(state, false);
|
||||||
|
return 1;
|
||||||
|
}
|
|
@ -609,4 +609,11 @@ int EQ2Emu_lua_GetWorldTimeMonth(lua_State* state);
|
||||||
int EQ2Emu_lua_GetWorldTimeHour(lua_State* state);
|
int EQ2Emu_lua_GetWorldTimeHour(lua_State* state);
|
||||||
int EQ2Emu_lua_GetWorldTimeMinute(lua_State* state);
|
int EQ2Emu_lua_GetWorldTimeMinute(lua_State* state);
|
||||||
int EQ2Emu_lua_SendTimeUpdate(lua_State* state);
|
int EQ2Emu_lua_SendTimeUpdate(lua_State* state);
|
||||||
|
|
||||||
|
|
||||||
|
int EQ2Emu_lua_SetLootTier(lua_State* state);
|
||||||
|
int EQ2Emu_lua_GetLootTier(lua_State* state);
|
||||||
|
|
||||||
|
int EQ2Emu_lua_SetLootDropType(lua_State* state);
|
||||||
|
int EQ2Emu_lua_GetLootDropType(lua_State* state);
|
||||||
#endif
|
#endif
|
|
@ -1467,6 +1467,11 @@ void LuaInterface::RegisterFunctions(lua_State* state) {
|
||||||
lua_register(state, "GetWorldTimeHour", EQ2Emu_lua_GetWorldTimeHour);
|
lua_register(state, "GetWorldTimeHour", EQ2Emu_lua_GetWorldTimeHour);
|
||||||
lua_register(state, "GetWorldTimeMinute", EQ2Emu_lua_GetWorldTimeMinute);
|
lua_register(state, "GetWorldTimeMinute", EQ2Emu_lua_GetWorldTimeMinute);
|
||||||
lua_register(state, "SendTimeUpdate", EQ2Emu_lua_SendTimeUpdate);
|
lua_register(state, "SendTimeUpdate", EQ2Emu_lua_SendTimeUpdate);
|
||||||
|
|
||||||
|
lua_register(state, "GetLootTier", EQ2Emu_lua_GetLootTier);
|
||||||
|
lua_register(state, "SetLootTier", EQ2Emu_lua_SetLootTier);
|
||||||
|
lua_register(state, "GetLootDropType", EQ2Emu_lua_GetLootDropType);
|
||||||
|
lua_register(state, "SetLootDropType", EQ2Emu_lua_SetLootDropType);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaInterface::LogError(const char* error, ...) {
|
void LuaInterface::LogError(const char* error, ...) {
|
||||||
|
|
|
@ -102,6 +102,7 @@ NPC::NPC(NPC* old_npc){
|
||||||
SetWaterCreature();
|
SetWaterCreature();
|
||||||
SetOmittedByDBFlag(old_npc->IsOmittedByDBFlag());
|
SetOmittedByDBFlag(old_npc->IsOmittedByDBFlag());
|
||||||
SetLootTier(old_npc->GetLootTier());
|
SetLootTier(old_npc->GetLootTier());
|
||||||
|
SetLootDropType(old_npc->GetLootDropType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -94,5 +94,6 @@ Object* Object::Copy(){
|
||||||
new_spawn->SetSoundsDisabled(IsSoundsDisabled());
|
new_spawn->SetSoundsDisabled(IsSoundsDisabled());
|
||||||
new_spawn->SetOmittedByDBFlag(IsOmittedByDBFlag());
|
new_spawn->SetOmittedByDBFlag(IsOmittedByDBFlag());
|
||||||
new_spawn->SetLootTier(GetLootTier());
|
new_spawn->SetLootTier(GetLootTier());
|
||||||
|
new_spawn->SetLootDropType(GetLootDropType());
|
||||||
return new_spawn;
|
return new_spawn;
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,6 +149,7 @@ Sign* Sign::Copy(){
|
||||||
new_spawn->SetSoundsDisabled(IsSoundsDisabled());
|
new_spawn->SetSoundsDisabled(IsSoundsDisabled());
|
||||||
new_spawn->SetOmittedByDBFlag(IsOmittedByDBFlag());
|
new_spawn->SetOmittedByDBFlag(IsOmittedByDBFlag());
|
||||||
new_spawn->SetLootTier(GetLootTier());
|
new_spawn->SetLootTier(GetLootTier());
|
||||||
|
new_spawn->SetLootDropType(GetLootDropType());
|
||||||
return new_spawn;
|
return new_spawn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -131,6 +131,7 @@ Spawn::Spawn(){
|
||||||
rail_id = 0;
|
rail_id = 0;
|
||||||
is_omitted_by_db_flag = false;
|
is_omitted_by_db_flag = false;
|
||||||
loot_tier = 0;
|
loot_tier = 0;
|
||||||
|
loot_drop_type = 0;
|
||||||
deleted_spawn = false;
|
deleted_spawn = false;
|
||||||
is_collector = false;
|
is_collector = false;
|
||||||
}
|
}
|
||||||
|
@ -3565,6 +3566,23 @@ bool Spawn::IsInSpawnGroup(Spawn* spawn) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Spawn* Spawn::IsSpawnGroupMembersAlive(Spawn* ignore_spawn, bool npc_only) {
|
||||||
|
Spawn* ret = nullptr;
|
||||||
|
if (MSpawnGroup && HasSpawnGroup()) {
|
||||||
|
|
||||||
|
MSpawnGroup->readlock(__FUNCTION__, __LINE__);
|
||||||
|
vector<Spawn*>::iterator itr;
|
||||||
|
for (itr = spawn_group_list->begin(); itr != spawn_group_list->end(); itr++) {
|
||||||
|
if ((*itr) != ignore_spawn && (*itr)->Alive() && (!npc_only || (npc_only && (*itr)->IsNPC()))) {
|
||||||
|
ret = (*itr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MSpawnGroup->releasereadlock(__FUNCTION__, __LINE__);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void Spawn::AddSpawnToGroup(Spawn* spawn){
|
void Spawn::AddSpawnToGroup(Spawn* spawn){
|
||||||
if(!spawn)
|
if(!spawn)
|
||||||
return;
|
return;
|
||||||
|
@ -3949,6 +3967,26 @@ Item* Spawn::LootItem(int32 id) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Spawn::TransferLoot(Spawn* spawn) {
|
||||||
|
if(spawn == this || spawn == nullptr)
|
||||||
|
return; // mmm no
|
||||||
|
|
||||||
|
vector<Item*>::iterator itr;
|
||||||
|
MLootItems.lock();
|
||||||
|
for (itr = loot_items.begin(); itr != loot_items.end();) {
|
||||||
|
if (!(*itr)->IsBodyDrop()) {
|
||||||
|
spawn->AddLootItem(*itr);
|
||||||
|
vector<Item*>::iterator tmpItr = itr;
|
||||||
|
|
||||||
|
itr = loot_items.erase(tmpItr);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
itr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MLootItems.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
int32 Spawn::GetLootItemID() {
|
int32 Spawn::GetLootItemID() {
|
||||||
int32 ret = 0;
|
int32 ret = 0;
|
||||||
vector<Item*>::iterator itr;
|
vector<Item*>::iterator itr;
|
||||||
|
|
|
@ -877,18 +877,28 @@ public:
|
||||||
if (master_item) {
|
if (master_item) {
|
||||||
Item* item = new Item(master_item);
|
Item* item = new Item(master_item);
|
||||||
item->details.count = charges;
|
item->details.count = charges;
|
||||||
|
LockLoot();
|
||||||
loot_items.push_back(item);
|
loot_items.push_back(item);
|
||||||
|
UnlockLoot();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void AddLootItem(Item* item) {
|
void AddLootItem(Item* item) {
|
||||||
if(item)
|
if(item) {
|
||||||
|
LockLoot();
|
||||||
loot_items.push_back(item);
|
loot_items.push_back(item);
|
||||||
|
UnlockLoot();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
bool HasLoot() {
|
bool HasLoot() {
|
||||||
if (loot_items.size() == 0 && loot_coins == 0)
|
LockLoot();
|
||||||
|
if (loot_items.size() == 0 && loot_coins == 0) {
|
||||||
|
UnlockLoot();
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
UnlockLoot();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
void TransferLoot(Spawn* spawn);
|
||||||
bool HasLootItemID(int32 id);
|
bool HasLootItemID(int32 id);
|
||||||
int32 GetLootItemID();
|
int32 GetLootItemID();
|
||||||
Item* LootItem(int32 id);
|
Item* LootItem(int32 id);
|
||||||
|
@ -934,13 +944,20 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 GetLootCoins() {
|
int32 GetLootCoins() {
|
||||||
return loot_coins;
|
LockLoot();
|
||||||
|
int32 coins = loot_coins;
|
||||||
|
UnlockLoot();
|
||||||
|
return coins;
|
||||||
}
|
}
|
||||||
void SetLootCoins(int32 val) {
|
void SetLootCoins(int32 val) {
|
||||||
|
LockLoot();
|
||||||
loot_coins = val;
|
loot_coins = val;
|
||||||
|
UnlockLoot();
|
||||||
}
|
}
|
||||||
void AddLootCoins(int32 coins) {
|
void AddLootCoins(int32 coins) {
|
||||||
|
LockLoot();
|
||||||
loot_coins += coins;
|
loot_coins += coins;
|
||||||
|
UnlockLoot();
|
||||||
}
|
}
|
||||||
Spawn* GetTarget();
|
Spawn* GetTarget();
|
||||||
void SetTarget(Spawn* spawn);
|
void SetTarget(Spawn* spawn);
|
||||||
|
@ -982,6 +999,7 @@ public:
|
||||||
vector<Spawn*>* GetSpawnGroup();
|
vector<Spawn*>* GetSpawnGroup();
|
||||||
bool HasSpawnGroup();
|
bool HasSpawnGroup();
|
||||||
bool IsInSpawnGroup(Spawn* spawn);
|
bool IsInSpawnGroup(Spawn* spawn);
|
||||||
|
Spawn* IsSpawnGroupMembersAlive(Spawn* ignore_spawn=nullptr, bool npc_only = true);
|
||||||
void SendSpawnChanges(bool val){ send_spawn_changes = val; }
|
void SendSpawnChanges(bool val){ send_spawn_changes = val; }
|
||||||
void SetSpawnGroupID(int32 id);
|
void SetSpawnGroupID(int32 id);
|
||||||
int32 GetSpawnGroupID();
|
int32 GetSpawnGroupID();
|
||||||
|
@ -1260,6 +1278,9 @@ public:
|
||||||
int32 GetLootTier() { return loot_tier; }
|
int32 GetLootTier() { return loot_tier; }
|
||||||
void SetLootTier(int32 tier) { loot_tier = tier; }
|
void SetLootTier(int32 tier) { loot_tier = tier; }
|
||||||
|
|
||||||
|
int32 GetLootDropType() { return loot_drop_type; }
|
||||||
|
void SetLootDropType(int32 type) { loot_drop_type = type; }
|
||||||
|
|
||||||
void SetDeletedSpawn(bool val) { deleted_spawn = val; }
|
void SetDeletedSpawn(bool val) { deleted_spawn = val; }
|
||||||
bool IsDeletedSpawn() { return deleted_spawn; }
|
bool IsDeletedSpawn() { return deleted_spawn; }
|
||||||
protected:
|
protected:
|
||||||
|
@ -1369,6 +1390,7 @@ private:
|
||||||
bool is_omitted_by_db_flag; // this particular spawn is omitted by an expansion or holiday flag
|
bool is_omitted_by_db_flag; // this particular spawn is omitted by an expansion or holiday flag
|
||||||
|
|
||||||
int32 loot_tier;
|
int32 loot_tier;
|
||||||
|
int32 loot_drop_type;
|
||||||
|
|
||||||
bool deleted_spawn;
|
bool deleted_spawn;
|
||||||
Mutex m_GridMutex;
|
Mutex m_GridMutex;
|
||||||
|
|
|
@ -926,7 +926,7 @@ void WorldDatabase::LoadNPCs(ZoneServer* zone){
|
||||||
NPC* npc = 0;
|
NPC* npc = 0;
|
||||||
int32 id = 0;
|
int32 id = 0;
|
||||||
int32 total = 0;
|
int32 total = 0;
|
||||||
MYSQL_RES* result = query.RunQuery2(Q_SELECT,"SELECT npc.spawn_id, s.name, npc.min_level, npc.max_level, npc.enc_level, s.race, s.model_type, npc.class_, npc.gender, s.command_primary, s.command_secondary, s.show_name, npc.min_group_size, npc.max_group_size, npc.hair_type_id, npc.facial_hair_type_id, npc.wing_type_id, npc.chest_type_id, npc.legs_type_id, npc.soga_hair_type_id, npc.soga_facial_hair_type_id, s.attackable, s.show_level, s.targetable, s.show_command_icon, s.display_hand_icon, s.hp, s.power, s.size, s.collision_radius, npc.action_state, s.visual_state, npc.mood_state, npc.initial_state, npc.activity_status, s.faction_id, s.sub_title, s.merchant_id, s.merchant_type, s.size_offset, npc.attack_type, npc.ai_strategy+0, npc.spell_list_id, npc.secondary_spell_list_id, npc.skill_list_id, npc.secondary_skill_list_id, npc.equipment_list_id, npc.str, npc.sta, npc.wis, npc.intel, npc.agi, npc.heat, npc.cold, npc.magic, npc.mental, npc.divine, npc.disease, npc.poison, npc.aggro_radius, npc.cast_percentage, npc.randomize, npc.soga_model_type, npc.heroic_flag, npc.alignment, npc.elemental, npc.arcane, npc.noxious, s.savagery, s.dissonance, npc.hide_hood, npc.emote_state, s.prefix, s.suffix, s.last_name, s.expansion_flag, s.holiday_flag, s.disable_sounds, s.merchant_min_level, s.merchant_max_level, s.aaxp_rewards, npc.water_type, npc.flying_type, s.loot_tier\n"
|
MYSQL_RES* result = query.RunQuery2(Q_SELECT,"SELECT npc.spawn_id, s.name, npc.min_level, npc.max_level, npc.enc_level, s.race, s.model_type, npc.class_, npc.gender, s.command_primary, s.command_secondary, s.show_name, npc.min_group_size, npc.max_group_size, npc.hair_type_id, npc.facial_hair_type_id, npc.wing_type_id, npc.chest_type_id, npc.legs_type_id, npc.soga_hair_type_id, npc.soga_facial_hair_type_id, s.attackable, s.show_level, s.targetable, s.show_command_icon, s.display_hand_icon, s.hp, s.power, s.size, s.collision_radius, npc.action_state, s.visual_state, npc.mood_state, npc.initial_state, npc.activity_status, s.faction_id, s.sub_title, s.merchant_id, s.merchant_type, s.size_offset, npc.attack_type, npc.ai_strategy+0, npc.spell_list_id, npc.secondary_spell_list_id, npc.skill_list_id, npc.secondary_skill_list_id, npc.equipment_list_id, npc.str, npc.sta, npc.wis, npc.intel, npc.agi, npc.heat, npc.cold, npc.magic, npc.mental, npc.divine, npc.disease, npc.poison, npc.aggro_radius, npc.cast_percentage, npc.randomize, npc.soga_model_type, npc.heroic_flag, npc.alignment, npc.elemental, npc.arcane, npc.noxious, s.savagery, s.dissonance, npc.hide_hood, npc.emote_state, s.prefix, s.suffix, s.last_name, s.expansion_flag, s.holiday_flag, s.disable_sounds, s.merchant_min_level, s.merchant_max_level, s.aaxp_rewards, npc.water_type, npc.flying_type, s.loot_tier, s.loot_drop_type\n"
|
||||||
"FROM spawn s\n"
|
"FROM spawn s\n"
|
||||||
"INNER JOIN spawn_npcs npc\n"
|
"INNER JOIN spawn_npcs npc\n"
|
||||||
"ON s.id = npc.spawn_id\n"
|
"ON s.id = npc.spawn_id\n"
|
||||||
|
@ -1090,6 +1090,8 @@ void WorldDatabase::LoadNPCs(ZoneServer* zone){
|
||||||
|
|
||||||
npc->SetLootTier(atoul(row[83]));
|
npc->SetLootTier(atoul(row[83]));
|
||||||
|
|
||||||
|
npc->SetLootDropType(atoul(row[84]));
|
||||||
|
|
||||||
zone->AddNPC(id, npc);
|
zone->AddNPC(id, npc);
|
||||||
total++;
|
total++;
|
||||||
LogWrite(NPC__DEBUG, 5, "NPC", "---Loading NPC: '%s' (%u)", npc->appearance.name, id);
|
LogWrite(NPC__DEBUG, 5, "NPC", "---Loading NPC: '%s' (%u)", npc->appearance.name, id);
|
||||||
|
@ -1213,7 +1215,7 @@ void WorldDatabase::LoadSigns(ZoneServer* zone){
|
||||||
Sign* sign = 0;
|
Sign* sign = 0;
|
||||||
int32 id = 0;
|
int32 id = 0;
|
||||||
int32 total = 0;
|
int32 total = 0;
|
||||||
MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT ss.spawn_id, s.name, s.model_type, s.size, s.show_command_icon, ss.widget_id, ss.widget_x, ss.widget_y, ss.widget_z, s.command_primary, s.command_secondary, s.collision_radius, ss.icon, ss.type, ss.title, ss.description, ss.sign_distance, ss.zone_id, ss.zone_x, ss.zone_y, ss.zone_z, ss.zone_heading, ss.include_heading, ss.include_location, s.transport_id, s.size_offset, s.display_hand_icon, s.visual_state, s.expansion_flag, s.holiday_flag, s.disable_sounds, s.merchant_min_level, s.merchant_max_level, s.aaxp_rewards, s.loot_tier\n"
|
MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT ss.spawn_id, s.name, s.model_type, s.size, s.show_command_icon, ss.widget_id, ss.widget_x, ss.widget_y, ss.widget_z, s.command_primary, s.command_secondary, s.collision_radius, ss.icon, ss.type, ss.title, ss.description, ss.sign_distance, ss.zone_id, ss.zone_x, ss.zone_y, ss.zone_z, ss.zone_heading, ss.include_heading, ss.include_location, s.transport_id, s.size_offset, s.display_hand_icon, s.visual_state, s.expansion_flag, s.holiday_flag, s.disable_sounds, s.merchant_min_level, s.merchant_max_level, s.aaxp_rewards, s.loot_tier, s.loot_drop_type\n"
|
||||||
"FROM spawn s\n"
|
"FROM spawn s\n"
|
||||||
"INNER JOIN spawn_signs ss\n"
|
"INNER JOIN spawn_signs ss\n"
|
||||||
"ON s.id = ss.spawn_id\n"
|
"ON s.id = ss.spawn_id\n"
|
||||||
|
@ -1290,6 +1292,8 @@ void WorldDatabase::LoadSigns(ZoneServer* zone){
|
||||||
|
|
||||||
sign->SetLootTier(atoul(row[34]));
|
sign->SetLootTier(atoul(row[34]));
|
||||||
|
|
||||||
|
sign->SetLootDropType(atoul(row[35]));
|
||||||
|
|
||||||
zone->AddSign(id, sign);
|
zone->AddSign(id, sign);
|
||||||
total++;
|
total++;
|
||||||
|
|
||||||
|
@ -1305,7 +1309,7 @@ void WorldDatabase::LoadWidgets(ZoneServer* zone){
|
||||||
Widget* widget = 0;
|
Widget* widget = 0;
|
||||||
int32 id = 0;
|
int32 id = 0;
|
||||||
int32 total = 0;
|
int32 total = 0;
|
||||||
MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT sw.spawn_id, s.name, s.model_type, s.size, s.show_command_icon, sw.widget_id, sw.widget_x, sw.widget_y, sw.widget_z, s.command_primary, s.command_secondary, s.collision_radius, sw.include_heading, sw.include_location, sw.icon, sw.type, sw.open_heading, sw.open_y, sw.action_spawn_id, sw.open_sound_file, sw.close_sound_file, sw.open_duration, sw.closed_heading, sw.linked_spawn_id, sw.close_y, s.transport_id, s.size_offset, sw.house_id, sw.open_x, sw.open_z, sw.close_x, sw.close_z, s.display_hand_icon, s.expansion_flag, s.holiday_flag, s.disable_sounds, s.merchant_min_level, s.merchant_max_level, s.aaxp_rewards, s.loot_tier\n"
|
MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT sw.spawn_id, s.name, s.model_type, s.size, s.show_command_icon, sw.widget_id, sw.widget_x, sw.widget_y, sw.widget_z, s.command_primary, s.command_secondary, s.collision_radius, sw.include_heading, sw.include_location, sw.icon, sw.type, sw.open_heading, sw.open_y, sw.action_spawn_id, sw.open_sound_file, sw.close_sound_file, sw.open_duration, sw.closed_heading, sw.linked_spawn_id, sw.close_y, s.transport_id, s.size_offset, sw.house_id, sw.open_x, sw.open_z, sw.close_x, sw.close_z, s.display_hand_icon, s.expansion_flag, s.holiday_flag, s.disable_sounds, s.merchant_min_level, s.merchant_max_level, s.aaxp_rewards, s.loot_tier, s.loot_drop_type\n"
|
||||||
"FROM spawn s\n"
|
"FROM spawn s\n"
|
||||||
"INNER JOIN spawn_widgets sw\n"
|
"INNER JOIN spawn_widgets sw\n"
|
||||||
"ON s.id = sw.spawn_id\n"
|
"ON s.id = sw.spawn_id\n"
|
||||||
|
@ -1396,6 +1400,8 @@ void WorldDatabase::LoadWidgets(ZoneServer* zone){
|
||||||
|
|
||||||
widget->SetLootTier(atoul(row[39]));
|
widget->SetLootTier(atoul(row[39]));
|
||||||
|
|
||||||
|
widget->SetLootDropType(atoul(row[40]));
|
||||||
|
|
||||||
zone->AddWidget(id, widget);
|
zone->AddWidget(id, widget);
|
||||||
total++;
|
total++;
|
||||||
|
|
||||||
|
@ -1411,7 +1417,7 @@ void WorldDatabase::LoadObjects(ZoneServer* zone){
|
||||||
Object* object = 0;
|
Object* object = 0;
|
||||||
int32 id = 0;
|
int32 id = 0;
|
||||||
int32 total = 0;
|
int32 total = 0;
|
||||||
MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT so.spawn_id, s.name, s.race, s.model_type, s.command_primary, s.command_secondary, s.targetable, s.size, s.show_name, s.visual_state, s.attackable, s.show_level, s.show_command_icon, s.display_hand_icon, s.faction_id, s.collision_radius, s.transport_id, s.size_offset, so.device_id, s.expansion_flag, s.holiday_flag, s.disable_sounds, s.merchant_min_level, s.merchant_max_level, s.aaxp_rewards, s.loot_tier\n"
|
MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT so.spawn_id, s.name, s.race, s.model_type, s.command_primary, s.command_secondary, s.targetable, s.size, s.show_name, s.visual_state, s.attackable, s.show_level, s.show_command_icon, s.display_hand_icon, s.faction_id, s.collision_radius, s.transport_id, s.size_offset, so.device_id, s.expansion_flag, s.holiday_flag, s.disable_sounds, s.merchant_min_level, s.merchant_max_level, s.aaxp_rewards, s.loot_tier, s.loot_drop_type\n"
|
||||||
"FROM spawn s\n"
|
"FROM spawn s\n"
|
||||||
"INNER JOIN spawn_objects so\n"
|
"INNER JOIN spawn_objects so\n"
|
||||||
"ON s.id = so.spawn_id\n"
|
"ON s.id = so.spawn_id\n"
|
||||||
|
@ -1475,6 +1481,8 @@ void WorldDatabase::LoadObjects(ZoneServer* zone){
|
||||||
|
|
||||||
object->SetLootTier(atoul(row[25]));
|
object->SetLootTier(atoul(row[25]));
|
||||||
|
|
||||||
|
object->SetLootDropType(atoul(row[26]));
|
||||||
|
|
||||||
zone->AddObject(id, object);
|
zone->AddObject(id, object);
|
||||||
total++;
|
total++;
|
||||||
|
|
||||||
|
@ -1490,7 +1498,7 @@ void WorldDatabase::LoadGroundSpawns(ZoneServer* zone){
|
||||||
GroundSpawn* spawn = 0;
|
GroundSpawn* spawn = 0;
|
||||||
int32 id = 0;
|
int32 id = 0;
|
||||||
int32 total = 0;
|
int32 total = 0;
|
||||||
MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT sg.spawn_id, s.name, s.race, s.model_type, s.command_primary, s.command_secondary, s.targetable, s.size, s.show_name, s.visual_state, s.attackable, s.show_level, s.show_command_icon, s.display_hand_icon, s.faction_id, s.collision_radius, sg.number_harvests, sg.num_attempts_per_harvest, sg.groundspawn_id, sg.collection_skill, s.size_offset, s.expansion_flag, s.holiday_flag, s.disable_sounds, s.aaxp_rewards, s.loot_tier\n"
|
MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT sg.spawn_id, s.name, s.race, s.model_type, s.command_primary, s.command_secondary, s.targetable, s.size, s.show_name, s.visual_state, s.attackable, s.show_level, s.show_command_icon, s.display_hand_icon, s.faction_id, s.collision_radius, sg.number_harvests, sg.num_attempts_per_harvest, sg.groundspawn_id, sg.collection_skill, s.size_offset, s.expansion_flag, s.holiday_flag, s.disable_sounds, s.aaxp_rewards, s.loot_tier, s.loot_drop_type\n"
|
||||||
"FROM spawn s\n"
|
"FROM spawn s\n"
|
||||||
"INNER JOIN spawn_ground sg\n"
|
"INNER JOIN spawn_ground sg\n"
|
||||||
"ON s.id = sg.spawn_id\n"
|
"ON s.id = sg.spawn_id\n"
|
||||||
|
@ -1555,6 +1563,8 @@ void WorldDatabase::LoadGroundSpawns(ZoneServer* zone){
|
||||||
|
|
||||||
spawn->SetLootTier(atoul(row[25]));
|
spawn->SetLootTier(atoul(row[25]));
|
||||||
|
|
||||||
|
spawn->SetLootDropType(atoul(row[26]));
|
||||||
|
|
||||||
zone->AddGroundSpawn(id, spawn);
|
zone->AddGroundSpawn(id, spawn);
|
||||||
total++;
|
total++;
|
||||||
LogWrite(GROUNDSPAWN__DEBUG, 5, "GSpawn", "---Loading GroundSpawn: '%s' (%u)", spawn->appearance.name, id);
|
LogWrite(GROUNDSPAWN__DEBUG, 5, "GSpawn", "---Loading GroundSpawn: '%s' (%u)", spawn->appearance.name, id);
|
||||||
|
@ -6347,7 +6357,7 @@ bool WorldDatabase::LoadSign(ZoneServer* zone, int32 spawn_id) {
|
||||||
Sign* sign = 0;
|
Sign* sign = 0;
|
||||||
int32 id = 0;
|
int32 id = 0;
|
||||||
DatabaseResult result;
|
DatabaseResult result;
|
||||||
database_new.Select(&result, "SELECT ss.spawn_id, s.name, s.model_type, s.size, s.show_command_icon, ss.widget_id, ss.widget_x, ss.widget_y, ss.widget_z, s.command_primary, s.command_secondary, s.collision_radius, ss.icon, ss.type, ss.title, ss.description, ss.sign_distance, ss.zone_id, ss.zone_x, ss.zone_y, ss.zone_z, ss.zone_heading, ss.include_heading, ss.include_location, s.transport_id, s.size_offset, s.display_hand_icon, s.visual_state, s.disable_sounds, s.merchant_min_level, s.merchant_max_level, s.aaxp_rewards, s.loot_tier\n"
|
database_new.Select(&result, "SELECT ss.spawn_id, s.name, s.model_type, s.size, s.show_command_icon, ss.widget_id, ss.widget_x, ss.widget_y, ss.widget_z, s.command_primary, s.command_secondary, s.collision_radius, ss.icon, ss.type, ss.title, ss.description, ss.sign_distance, ss.zone_id, ss.zone_x, ss.zone_y, ss.zone_z, ss.zone_heading, ss.include_heading, ss.include_location, s.transport_id, s.size_offset, s.display_hand_icon, s.visual_state, s.disable_sounds, s.merchant_min_level, s.merchant_max_level, s.aaxp_rewards, s.loot_tier, s.loot_drop_type\n"
|
||||||
"FROM spawn s\n"
|
"FROM spawn s\n"
|
||||||
"INNER JOIN spawn_signs ss\n"
|
"INNER JOIN spawn_signs ss\n"
|
||||||
"ON ss.spawn_id = s.id\n"
|
"ON ss.spawn_id = s.id\n"
|
||||||
|
@ -6407,6 +6417,7 @@ bool WorldDatabase::LoadSign(ZoneServer* zone, int32 spawn_id) {
|
||||||
|
|
||||||
sign->SetLootTier(result.GetInt32(32));
|
sign->SetLootTier(result.GetInt32(32));
|
||||||
|
|
||||||
|
sign->SetLootDropType(result.GetInt32(33));
|
||||||
zone->AddSign(id, sign);
|
zone->AddSign(id, sign);
|
||||||
|
|
||||||
|
|
||||||
|
@ -6422,7 +6433,7 @@ bool WorldDatabase::LoadWidget(ZoneServer* zone, int32 spawn_id) {
|
||||||
int32 id = 0;
|
int32 id = 0;
|
||||||
DatabaseResult result;
|
DatabaseResult result;
|
||||||
|
|
||||||
database_new.Select(&result, "SELECT sw.spawn_id, s.name, s.model_type, s.size, s.show_command_icon, sw.widget_id, sw.widget_x, sw.widget_y, sw.widget_z, s.command_primary, s.command_secondary, s.collision_radius, sw.include_heading, sw.include_location, sw.icon, sw.type, sw.open_heading, sw.open_y, sw.action_spawn_id, sw.open_sound_file, sw.close_sound_file, sw.open_duration, sw.closed_heading, sw.linked_spawn_id, sw.close_y, s.transport_id, s.size_offset, sw.house_id, sw.open_x, sw.open_z, sw.close_x, sw.close_z, s.display_hand_icon, s.disable_sounds, s.merchant_min_level, s.merchant_max_level, s.aaxp_rewards, s.loot_tier\n"
|
database_new.Select(&result, "SELECT sw.spawn_id, s.name, s.model_type, s.size, s.show_command_icon, sw.widget_id, sw.widget_x, sw.widget_y, sw.widget_z, s.command_primary, s.command_secondary, s.collision_radius, sw.include_heading, sw.include_location, sw.icon, sw.type, sw.open_heading, sw.open_y, sw.action_spawn_id, sw.open_sound_file, sw.close_sound_file, sw.open_duration, sw.closed_heading, sw.linked_spawn_id, sw.close_y, s.transport_id, s.size_offset, sw.house_id, sw.open_x, sw.open_z, sw.close_x, sw.close_z, s.display_hand_icon, s.disable_sounds, s.merchant_min_level, s.merchant_max_level, s.aaxp_rewards, s.loot_tier, s.loot_drop_type\n"
|
||||||
"FROM spawn s\n"
|
"FROM spawn s\n"
|
||||||
"INNER JOIN spawn_widgets sw\n"
|
"INNER JOIN spawn_widgets sw\n"
|
||||||
"ON sw.spawn_id = s.id\n"
|
"ON sw.spawn_id = s.id\n"
|
||||||
|
@ -6489,6 +6500,8 @@ bool WorldDatabase::LoadWidget(ZoneServer* zone, int32 spawn_id) {
|
||||||
|
|
||||||
widget->SetLootTier(result.GetInt32(37));
|
widget->SetLootTier(result.GetInt32(37));
|
||||||
|
|
||||||
|
widget->SetLootDropType(result.GetInt32(38));
|
||||||
|
|
||||||
zone->AddWidget(id, widget);
|
zone->AddWidget(id, widget);
|
||||||
|
|
||||||
LogWrite(WIDGET__DEBUG, 0, "Widget", "Loaded Widget: '%s' (%u).", widget->appearance.name, spawn_id);
|
LogWrite(WIDGET__DEBUG, 0, "Widget", "Loaded Widget: '%s' (%u).", widget->appearance.name, spawn_id);
|
||||||
|
@ -6504,7 +6517,7 @@ bool WorldDatabase::LoadObject(ZoneServer* zone, int32 spawn_id) {
|
||||||
int32 id = 0;
|
int32 id = 0;
|
||||||
DatabaseResult result;
|
DatabaseResult result;
|
||||||
|
|
||||||
database_new.Select(&result, "SELECT so.spawn_id, s.name, s.race, s.model_type, s.command_primary, s.command_secondary, s.targetable, s.size, s.show_name, s.visual_state, s.attackable, s.show_level, s.show_command_icon, s.display_hand_icon, s.faction_id, s.collision_radius, s.transport_id, s.size_offset, so.device_id, s.disable_sounds, s.merchant_min_level, s.merchant_max_level, s.aaxp_rewards, s.loot_tier\n"
|
database_new.Select(&result, "SELECT so.spawn_id, s.name, s.race, s.model_type, s.command_primary, s.command_secondary, s.targetable, s.size, s.show_name, s.visual_state, s.attackable, s.show_level, s.show_command_icon, s.display_hand_icon, s.faction_id, s.collision_radius, s.transport_id, s.size_offset, so.device_id, s.disable_sounds, s.merchant_min_level, s.merchant_max_level, s.aaxp_rewards, s.loot_tier, s.loot_drop_type\n"
|
||||||
"FROM spawn s\n"
|
"FROM spawn s\n"
|
||||||
"INNER JOIN spawn_objects so\n"
|
"INNER JOIN spawn_objects so\n"
|
||||||
"ON so.spawn_id = s.id\n"
|
"ON so.spawn_id = s.id\n"
|
||||||
|
@ -6549,6 +6562,8 @@ bool WorldDatabase::LoadObject(ZoneServer* zone, int32 spawn_id) {
|
||||||
|
|
||||||
object->SetLootTier(result.GetInt32(23));
|
object->SetLootTier(result.GetInt32(23));
|
||||||
|
|
||||||
|
object->SetLootDropType(result.GetInt32(24));
|
||||||
|
|
||||||
zone->AddObject(id, object);
|
zone->AddObject(id, object);
|
||||||
|
|
||||||
LogWrite(OBJECT__DEBUG, 0, "Object", "Loaded Object: '%s' (%u).", object->appearance.name, spawn_id);
|
LogWrite(OBJECT__DEBUG, 0, "Object", "Loaded Object: '%s' (%u).", object->appearance.name, spawn_id);
|
||||||
|
@ -6564,7 +6579,7 @@ bool WorldDatabase::LoadGroundSpawn(ZoneServer* zone, int32 spawn_id) {
|
||||||
int32 id = 0;
|
int32 id = 0;
|
||||||
DatabaseResult result;
|
DatabaseResult result;
|
||||||
|
|
||||||
database_new.Select(&result, "SELECT sg.spawn_id, s.name, s.race, s.model_type, s.command_primary, s.command_secondary, s.targetable, s.size, s.show_name, s.visual_state, s.attackable, s.show_level, s.show_command_icon, s.display_hand_icon, s.faction_id, s.collision_radius, sg.number_harvests, sg.num_attempts_per_harvest, sg.groundspawn_id, sg.collection_skill, s.size_offset, s.disable_sounds, s.aaxp_rewards, s.loot_tier\n"
|
database_new.Select(&result, "SELECT sg.spawn_id, s.name, s.race, s.model_type, s.command_primary, s.command_secondary, s.targetable, s.size, s.show_name, s.visual_state, s.attackable, s.show_level, s.show_command_icon, s.display_hand_icon, s.faction_id, s.collision_radius, sg.number_harvests, sg.num_attempts_per_harvest, sg.groundspawn_id, sg.collection_skill, s.size_offset, s.disable_sounds, s.aaxp_rewards, s.loot_tier, s.loot_drop_type\n"
|
||||||
"FROM spawn s\n"
|
"FROM spawn s\n"
|
||||||
"INNER JOIN spawn_ground sg\n"
|
"INNER JOIN spawn_ground sg\n"
|
||||||
"ON sg.spawn_id = s.id\n"
|
"ON sg.spawn_id = s.id\n"
|
||||||
|
@ -6609,6 +6624,8 @@ bool WorldDatabase::LoadGroundSpawn(ZoneServer* zone, int32 spawn_id) {
|
||||||
|
|
||||||
spawn->SetLootTier(result.GetInt32(23));
|
spawn->SetLootTier(result.GetInt32(23));
|
||||||
|
|
||||||
|
spawn->SetLootDropType(result.GetInt32(24));
|
||||||
|
|
||||||
zone->AddGroundSpawn(id, spawn);
|
zone->AddGroundSpawn(id, spawn);
|
||||||
|
|
||||||
if (!zone->GetGroundSpawnEntries(spawn->GetGroundSpawnEntryID()))
|
if (!zone->GetGroundSpawnEntries(spawn->GetGroundSpawnEntryID()))
|
||||||
|
@ -6663,7 +6680,7 @@ bool WorldDatabase::LoadNPC(ZoneServer* zone, int32 spawn_id) {
|
||||||
int32 id = 0;
|
int32 id = 0;
|
||||||
DatabaseResult result;
|
DatabaseResult result;
|
||||||
|
|
||||||
database_new.Select(&result, "SELECT npc.spawn_id, s.name, npc.min_level, npc.max_level, npc.enc_level, s.race, s.model_type, npc.class_, npc.gender, s.command_primary, s.command_secondary, s.show_name, npc.min_group_size, npc.max_group_size, npc.hair_type_id, npc.facial_hair_type_id, npc.wing_type_id, npc.chest_type_id, npc.legs_type_id, npc.soga_hair_type_id, npc.soga_facial_hair_type_id, s.attackable, s.show_level, s.targetable, s.show_command_icon, s.display_hand_icon, s.hp, s.power, s.size, s.collision_radius, npc.action_state, s.visual_state, npc.mood_state, npc.initial_state, npc.activity_status, s.faction_id, s.sub_title, s.merchant_id, s.merchant_type, s.size_offset, npc.attack_type, npc.ai_strategy+0, npc.spell_list_id, npc.secondary_spell_list_id, npc.skill_list_id, npc.secondary_skill_list_id, npc.equipment_list_id, npc.str, npc.sta, npc.wis, npc.intel, npc.agi, npc.heat, npc.cold, npc.magic, npc.mental, npc.divine, npc.disease, npc.poison, npc.aggro_radius, npc.cast_percentage, npc.randomize, npc.soga_model_type, npc.heroic_flag, npc.alignment, npc.elemental, npc.arcane, npc.noxious, s.savagery, s.dissonance, npc.hide_hood, npc.emote_state, s.prefix, s.suffix, s.last_name, s.disable_sounds, s.merchant_min_level, s.merchant_max_level, s.aaxp_rewards, s.loot_tier\n"
|
database_new.Select(&result, "SELECT npc.spawn_id, s.name, npc.min_level, npc.max_level, npc.enc_level, s.race, s.model_type, npc.class_, npc.gender, s.command_primary, s.command_secondary, s.show_name, npc.min_group_size, npc.max_group_size, npc.hair_type_id, npc.facial_hair_type_id, npc.wing_type_id, npc.chest_type_id, npc.legs_type_id, npc.soga_hair_type_id, npc.soga_facial_hair_type_id, s.attackable, s.show_level, s.targetable, s.show_command_icon, s.display_hand_icon, s.hp, s.power, s.size, s.collision_radius, npc.action_state, s.visual_state, npc.mood_state, npc.initial_state, npc.activity_status, s.faction_id, s.sub_title, s.merchant_id, s.merchant_type, s.size_offset, npc.attack_type, npc.ai_strategy+0, npc.spell_list_id, npc.secondary_spell_list_id, npc.skill_list_id, npc.secondary_skill_list_id, npc.equipment_list_id, npc.str, npc.sta, npc.wis, npc.intel, npc.agi, npc.heat, npc.cold, npc.magic, npc.mental, npc.divine, npc.disease, npc.poison, npc.aggro_radius, npc.cast_percentage, npc.randomize, npc.soga_model_type, npc.heroic_flag, npc.alignment, npc.elemental, npc.arcane, npc.noxious, s.savagery, s.dissonance, npc.hide_hood, npc.emote_state, s.prefix, s.suffix, s.last_name, s.disable_sounds, s.merchant_min_level, s.merchant_max_level, s.aaxp_rewards, s.loot_tier, s.loot_drop_type\n"
|
||||||
"FROM spawn s\n"
|
"FROM spawn s\n"
|
||||||
"INNER JOIN spawn_npcs npc\n"
|
"INNER JOIN spawn_npcs npc\n"
|
||||||
"ON npc.spawn_id = s.id\n"
|
"ON npc.spawn_id = s.id\n"
|
||||||
|
@ -6799,6 +6816,8 @@ bool WorldDatabase::LoadNPC(ZoneServer* zone, int32 spawn_id) {
|
||||||
|
|
||||||
npc->SetLootTier(result.GetInt32(79));
|
npc->SetLootTier(result.GetInt32(79));
|
||||||
|
|
||||||
|
npc->SetLootDropType(result.GetInt32(80));
|
||||||
|
|
||||||
zone->AddNPC(id, npc);
|
zone->AddNPC(id, npc);
|
||||||
|
|
||||||
//skipped spells/skills/equipment as it is all loaded, the following rely on a spawn to load
|
//skipped spells/skills/equipment as it is all loaded, the following rely on a spawn to load
|
||||||
|
|
|
@ -4521,23 +4521,38 @@ void ZoneServer::KillSpawn(bool spawnListLocked, Spawn* dead, Spawn* killer, boo
|
||||||
dead->SetActionState(0);
|
dead->SetActionState(0);
|
||||||
dead->SetTempActionState(0);
|
dead->SetTempActionState(0);
|
||||||
|
|
||||||
// If dead is an npc get the encounter and loop through it giving out the rewards, no rewards for pets
|
|
||||||
if (dead->IsNPC() && !dead->IsPet() && !dead->IsBot()) {
|
|
||||||
Spawn* spawn = 0;
|
|
||||||
int8 size = encounter->size();
|
|
||||||
// Needs npc to have access to the encounter list for who is allowed to loot
|
// Needs npc to have access to the encounter list for who is allowed to loot
|
||||||
NPC* chest = 0;
|
NPC* chest = 0;
|
||||||
|
|
||||||
if (!((NPC*)dead)->Brain()->PlayerInEncounter()) {
|
if (dead->IsNPC() && !((NPC*)dead)->Brain()->PlayerInEncounter()) {
|
||||||
dead->SetLootCoins(0);
|
dead->SetLootCoins(0);
|
||||||
dead->ClearLoot();
|
dead->ClearLoot();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Spawn* groupMemberAlive = nullptr;
|
||||||
// If dead has loot attempt to drop a chest
|
// If dead has loot attempt to drop a chest
|
||||||
if (dead->HasLoot()) {
|
if (dead->HasLoot()) {
|
||||||
chest = ((NPC*)dead)->DropChest();
|
if(!(groupMemberAlive = dead->IsSpawnGroupMembersAlive(dead))) {
|
||||||
|
LogWrite(SPAWN__ERROR, 0, "Spawn", "%s: Dead drops chest", dead->GetName());
|
||||||
|
chest = ((Entity*)dead)->DropChest();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
switch(dead->GetLootDropType()) {
|
||||||
|
case 0:
|
||||||
|
// default drop all chest type as a group
|
||||||
|
dead->TransferLoot(groupMemberAlive);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
// this is a primary mob it drops its own loot
|
||||||
|
chest = ((Entity*)dead)->DropChest();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
// If dead is an npc get the encounter and loop through it giving out the rewards, no rewards for pets
|
||||||
|
if (dead->IsNPC() && !dead->IsPet() && !dead->IsBot()) {
|
||||||
|
Spawn* spawn = 0;
|
||||||
|
int8 size = encounter->size();
|
||||||
|
|
||||||
for (int8 i = 0; i < encounter->size(); i++) {
|
for (int8 i = 0; i < encounter->size(); i++) {
|
||||||
spawn = GetSpawnByID(encounter->at(i), spawnListLocked);
|
spawn = GetSpawnByID(encounter->at(i), spawnListLocked);
|
||||||
|
@ -4589,13 +4604,13 @@ void ZoneServer::KillSpawn(bool spawnListLocked, Spawn* dead, Spawn* killer, boo
|
||||||
if (chest && spawn && spawn->IsEntity())
|
if (chest && spawn && spawn->IsEntity())
|
||||||
chest->Brain()->AddToEncounter((Entity*)spawn);
|
chest->Brain()->AddToEncounter((Entity*)spawn);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If a chest is being dropped add it to the world and set the timer to remove it.
|
// If a chest is being dropped add it to the world and set the timer to remove it.
|
||||||
if (chest) {
|
if (chest) {
|
||||||
AddSpawn(chest);
|
AddSpawn(chest);
|
||||||
AddDeadSpawn(chest, 0xFFFFFFFF);
|
AddDeadSpawn(chest, 0xFFFFFFFF);
|
||||||
LogWrite(LOOT__DEBUG, 0, "Loot", "Adding a chest to the world...");
|
LogWrite(LOOT__DEBUG, 0, "Loot", "Adding a chest to the world...");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset client pointer
|
// Reset client pointer
|
||||||
|
|
Loading…
Reference in a new issue