rendered paste bodyIndex: mangosd/mangosd.conf.in===================================================================--- mangosd/mangosd.conf.in (revision 5629)+++ mangosd/mangosd.conf.in (working copy)@@ -377,6 +377,28 @@ # Motd # Message of the Day. Displayed at worldlogin for every user ('@' for a newline). #+# Corpse.Decay.NORMAL+# Corpse.Decay.RARE+# Corpse.Decay.ELITE+# Corpse.Decay.RAREELITE+# Corpse.Decay.WORLDBOSS+# Seconds until creature corpse will decay without being looted on non-instanced map.+#+# Corpse.Decay.NORMAL.Instance+# Corpse.Decay.RARE.Instance+# Corpse.Decay.ELITE.Instance+# Corpse.Decay.RAREELITE.Instance+# Corpse.Decay.WORLDBOSS.Instance+# Seconds until creature corpse will decay without being looted in instance.+#+# Corpse.Decay.NORMAL.Looted+# Corpse.Decay.RARE.Looted+# Corpse.Decay.ELITE.Looted+# Corpse.Decay.RAREELITE.Looted+# Corpse.Decay.WORLDBOSS.Looted+# Max seconds until creature corpse will decay after being looted.+# If not-looted timer decays sooner, it will be used instead.+# ################################################################################################################### GameType = 1@@ -400,6 +422,21 @@ Event.Announce = 0 BeepAtStart = 1 Motd = "Welcome to the Massive Network Game Object Server."+Corpse.Decay.NORMAL = 60+Corpse.Decay.RARE = 300+Corpse.Decay.ELITE = 300+Corpse.Decay.RAREELITE = 300+Corpse.Decay.WORLDBOSS = 3600+Corpse.Decay.NORMAL.Instance = 300+Corpse.Decay.RARE.Instance = 600+Corpse.Decay.ELITE.Instance = 600+Corpse.Decay.RAREELITE.Instance = 600+Corpse.Decay.WORLDBOSS.Instance = 3600+Corpse.Decay.NORMAL.Looted = 5+Corpse.Decay.RARE.Looted = 20+Corpse.Decay.ELITE.Looted = 20+Corpse.Decay.RAREELITE.Looted = 20+Corpse.Decay.WORLDBOSS.Looted = 60 ################################################################################################################### # PLAYER INTERACTIONIndex: game/World.h===================================================================--- game/World.h (revision 5629)+++ game/World.h (working copy)@@ -121,6 +121,21 @@ CONFIG_TALENTS_INSPECTING, CONFIG_CHAT_FAKE_MESSAGE_PREVENTING, CONFIG_TCP_NO_DELAY,+ CONFIG_CORPSE_DECAY_NORMAL,+ CONFIG_CORPSE_DECAY_RARE,+ CONFIG_CORPSE_DECAY_ELITE,+ CONFIG_CORPSE_DECAY_RAREELITE,+ CONFIG_CORPSE_DECAY_WORLDBOSS,+ CONFIG_CORPSE_DECAY_NORMAL_INSTANCE,+ CONFIG_CORPSE_DECAY_RARE_INSTANCE,+ CONFIG_CORPSE_DECAY_ELITE_INSTANCE,+ CONFIG_CORPSE_DECAY_RAREELITE_INSTANCE,+ CONFIG_CORPSE_DECAY_WORLDBOSS_INSTANCE,+ CONFIG_CORPSE_DECAY_NORMAL_LOOTED,+ CONFIG_CORPSE_DECAY_RARE_LOOTED,+ CONFIG_CORPSE_DECAY_ELITE_LOOTED,+ CONFIG_CORPSE_DECAY_RAREELITE_LOOTED,+ CONFIG_CORPSE_DECAY_WORLDBOSS_LOOTED, CONFIG_VALUE_COUNT }; Index: game/World.cpp===================================================================--- game/World.cpp (revision 5629)+++ game/World.cpp (working copy)@@ -510,6 +510,22 @@ m_configs[CONFIG_TALENTS_INSPECTING] = sConfig.GetBoolDefault("TalentsInspecting", true); m_configs[CONFIG_CHAT_FAKE_MESSAGE_PREVENTING] = sConfig.GetBoolDefault("ChatFakeMessagePreventing", false); + m_configs[CONFIG_CORPSE_DECAY_NORMAL] = sConfig.GetIntDefault("Corpse.Decay.NORMAL", 1);+ m_configs[CONFIG_CORPSE_DECAY_RARE] = sConfig.GetIntDefault("Corpse.Decay.RARE", 1);+ m_configs[CONFIG_CORPSE_DECAY_ELITE] = sConfig.GetIntDefault("Corpse.Decay.ELITE", 1);+ m_configs[CONFIG_CORPSE_DECAY_RAREELITE] = sConfig.GetIntDefault("Corpse.Decay.RAREELITE", 1);+ m_configs[CONFIG_CORPSE_DECAY_WORLDBOSS] = sConfig.GetIntDefault("Corpse.Decay.WORLDBOSS", 1);+ m_configs[CONFIG_CORPSE_DECAY_NORMAL_INSTANCE] = sConfig.GetIntDefault("Corpse.Decay.NORMAL.Instance", 1);+ m_configs[CONFIG_CORPSE_DECAY_RARE_INSTANCE] = sConfig.GetIntDefault("Corpse.Decay.RARE.Instance", 1);+ m_configs[CONFIG_CORPSE_DECAY_ELITE_INSTANCE] = sConfig.GetIntDefault("Corpse.Decay.ELITE.Instance", 1);+ m_configs[CONFIG_CORPSE_DECAY_RAREELITE_INSTANCE] = sConfig.GetIntDefault("Corpse.Decay.RAREELITE.Instance", 1);+ m_configs[CONFIG_CORPSE_DECAY_WORLDBOSS_INSTANCE] = sConfig.GetIntDefault("Corpse.Decay.WORLDBOSS.Instance", 1);+ m_configs[CONFIG_CORPSE_DECAY_NORMAL_LOOTED] = sConfig.GetIntDefault("Corpse.Decay.NORMAL.Looted", 1);+ m_configs[CONFIG_CORPSE_DECAY_RARE_LOOTED] = sConfig.GetIntDefault("Corpse.Decay.RARE.Looted", 1);+ m_configs[CONFIG_CORPSE_DECAY_ELITE_LOOTED] = sConfig.GetIntDefault("Corpse.Decay.ELITE.Looted", 1);+ m_configs[CONFIG_CORPSE_DECAY_RAREELITE_LOOTED] = sConfig.GetIntDefault("Corpse.Decay.RAREELITE.Looted", 1);+ m_configs[CONFIG_CORPSE_DECAY_WORLDBOSS_LOOTED] = sConfig.GetIntDefault("Corpse.Decay.WORLDBOSS.Looted", 1);+ m_VisibleUnitGreyDistance = sConfig.GetFloatDefault("Visibility.Distance.Grey.Unit", 1); if(m_VisibleUnitGreyDistance > MAX_VISIBILITY_DISTANCE) {Index: game/Creature.h===================================================================--- game/Creature.h (revision 5629)+++ game/Creature.h (working copy)@@ -546,6 +546,8 @@ uint32 m_corpseDelay; // (secs) delay between death and corpse disappearance float m_respawnradius; + bool m_corpseLooted; // creature corpse was looted and skinned (if skinnable)+ bool m_gossipOptionLoaded; GossipOptionList m_goptions; uint32 m_NPCTextId; // cached valueIndex: game/Creature.cpp===================================================================--- game/Creature.cpp (revision 5629)+++ game/Creature.cpp (working copy)@@ -46,7 +46,7 @@ Unit( instantiator ), i_AI(NULL), lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), lootingGroupLeaderGUID(0), m_itemsLoaded(false), m_trainerSpellsLoaded(false), m_trainer_type(0), m_lootMoney(0), m_lootRecipient(0),-m_deathTimer(0), m_respawnTime(0), m_respawnDelay(25), m_corpseDelay(60), m_respawnradius(0.0f),+m_deathTimer(0), m_respawnTime(0), m_respawnDelay(25), m_corpseDelay(0), m_respawnradius(0.0f), m_corpseLooted(false), m_gossipOptionLoaded(false),m_NPCTextId(0), m_emoteState(0), m_isPet(false), m_isTotem(false), m_regenTimer(2000), m_defaultMovementType(IDLE_MOTION_TYPE), m_equipmentId(0), m_AlreadyCallAssistence(false), m_regenHealth(true), m_AI_locked(false), m_isDeadByDefault(false)@@ -157,6 +157,7 @@ return; m_deathTimer = 0;+ m_corpseLooted = false; setDeathState(DEAD); ObjectAccessor::UpdateObjectVisibility(this); loot.clear();@@ -192,6 +193,7 @@ m_respawnTime = 0; lootForPickPocketed = false; lootForBody = false;+ m_corpseLooted = false; CreatureInfo const *cinfo = objmgr.GetCreatureTemplate(this->GetEntry()); @@ -249,6 +251,36 @@ lootingGroupLeaderGUID = 0; } }++ if (m_corpseDelay == 0 && !m_corpseLooted && lootForBody && loot.empty() && !HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE))+ {+ // corpse delay had been not set by script and this code had been not yet executed during this death+ // and loot had been generated but is already empty and creature was skinned (or isn't skinnable)+ m_corpseLooted = true; // mark that creature had been looted - to not repeat this code again++ uint32 nDeathTimer = 1000;+ switch (GetCreatureInfo()->rank)+ {+ case CREATURE_ELITE_RARE:+ nDeathTimer *= sWorld.getConfig(CONFIG_CORPSE_DECAY_RARE_LOOTED);+ break;+ case CREATURE_ELITE_ELITE:+ nDeathTimer *= sWorld.getConfig(CONFIG_CORPSE_DECAY_ELITE_LOOTED);+ break;+ case CREATURE_ELITE_RAREELITE:+ nDeathTimer *= sWorld.getConfig(CONFIG_CORPSE_DECAY_RAREELITE_LOOTED);+ break;+ case CREATURE_ELITE_WORLDBOSS:+ nDeathTimer *= sWorld.getConfig(CONFIG_CORPSE_DECAY_WORLDBOSS_LOOTED);+ break;+ default:+ nDeathTimer *= sWorld.getConfig(CONFIG_CORPSE_DECAY_NORMAL_LOOTED);+ break;+ }++ if (m_deathTimer > nDeathTimer) // update death timer only if looted timer is shorter+ m_deathTimer = nDeathTimer;+ } } break;@@ -1261,8 +1293,6 @@ m_DBTableGuid = stored_guid; LoadCreaturesAddon();- if(GetCreatureInfo()->rank > 0)- this->m_corpseDelay *= 3; //if creature is elite, then remove corpse later m_respawnradius = data->spawndist; respawn_cord[0] = data->spawn_posX;@@ -1272,6 +1302,7 @@ m_respawnDelay = data->spawntimesecs; m_isDeadByDefault = data->is_dead; m_deathState = m_isDeadByDefault ? DEAD : ALIVE;+ m_corpseLooted = false; m_respawnTime = objmgr.GetCreatureRespawnTime(m_DBTableGuid,GetInstanceId()); if(m_respawnTime > time(NULL)) // not ready to respawn@@ -1452,8 +1483,41 @@ { if((s == JUST_DIED && !m_isDeadByDefault)||(s == JUST_ALIVED && m_isDeadByDefault)) {- m_deathTimer = m_corpseDelay*1000;+ if (m_corpseDelay == 0)+ {+ // corpse delay had been not set by script+ uint32 nDeathTimer = 60; // set base delay to 60s + if (!m_isDeadByDefault && !isPet())+ {+ // ignore pets and mobs that are dead by default+ const bool bInstance = MapManager::Instance().GetBaseMap(GetMapId())->Instanceable();++ switch (GetCreatureInfo()->rank)+ {+ case CREATURE_ELITE_RARE:+ nDeathTimer = sWorld.getConfig(bInstance ? CONFIG_CORPSE_DECAY_RARE_INSTANCE : CONFIG_CORPSE_DECAY_RARE);+ break;+ case CREATURE_ELITE_ELITE:+ nDeathTimer = sWorld.getConfig(bInstance ? CONFIG_CORPSE_DECAY_ELITE_INSTANCE : CONFIG_CORPSE_DECAY_ELITE);+ break;+ case CREATURE_ELITE_RAREELITE:+ nDeathTimer = sWorld.getConfig(bInstance ? CONFIG_CORPSE_DECAY_RAREELITE_INSTANCE : CONFIG_CORPSE_DECAY_RAREELITE);+ break;+ case CREATURE_ELITE_WORLDBOSS:+ nDeathTimer = sWorld.getConfig(bInstance ? CONFIG_CORPSE_DECAY_WORLDBOSS_INSTANCE : CONFIG_CORPSE_DECAY_WORLDBOSS);+ break;+ default:+ nDeathTimer = sWorld.getConfig(bInstance ? CONFIG_CORPSE_DECAY_NORMAL_INSTANCE : CONFIG_CORPSE_DECAY_NORMAL);+ break;+ }+ }++ m_deathTimer = nDeathTimer * 1000; // set death timer according to configuration+ }+ else+ m_deathTimer = m_corpseDelay * 1000; // corpse delay had been set by script -> use it+ // always save boss respawn time at death to prevent crash cheating if(sWorld.getConfig(CONFIG_SAVE_RESPAWN_TIME_IMMEDIATLY) || isWorldBoss()) SaveRespawnTime();@@ -1474,6 +1538,7 @@ if ( tab != skinStore.end() ) SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); }+ m_corpseLooted = false; Unit::setDeathState(CORPSE); } if(s == JUST_ALIVED)@@ -1495,6 +1560,7 @@ if(getDeathState()==CORPSE && !m_isDeadByDefault ||getDeathState()==ALIVE && m_isDeadByDefault) { m_deathTimer = 0;+ m_corpseLooted = false; Update(0); // despawn corpse } if(getDeathState()==DEAD)