private void PlayerDeath(ZonePlayer zp, Mob lastAttacker, uint spellId, byte damageType, uint damage) { _log.DebugFormat("{0} bought the farm. Fatal blow dealt by {1} with {2} damage, skill {3}, spell {4}.", zp.Name, lastAttacker.Name, damage, damageType, spellId); if (zp.IsDePopped) { _log.WarnFormat("{0} is trying to die more than once or something... is already depopped!", zp.Name); return; } _zoneSvr.SendLogoutPackets(zp.Client); // Make the become corpse packet and queue to player before Death opCode packet BecomeCorpse bc = new BecomeCorpse() { SpawnId = (uint)zp.ID, X = zp.X, Y = zp.Y, Z = zp.Z }; EQApplicationPacket<BecomeCorpse> bcPack = new EQApplicationPacket<BecomeCorpse>(AppOpCode.BecomeCorpse, bc); _zoneSvr.QueuePacketToClient(zp.Client, bcPack, true, ZoneConnectionState.All); Death d = new Death() { SpawnId = (uint)zp.ID, KillerId = lastAttacker == null ? 0u : (uint)lastAttacker.ID, CorpseId = (uint)zp.ID, BindToZoneId = zp.PlayerProfile.Binds[0].ZoneId, SpellId = spellId == 0u ? 0xFFFFFFFF : spellId, AttackSkillId = spellId != 0u ? (uint)0xe7 : damageType, Damage = damage }; EQApplicationPacket<Death> dPack = new EQApplicationPacket<Death>(AppOpCode.Death, d); _zoneSvr.QueuePacketToClients(lastAttacker, dPack, false); RemoveFromAllTargets(zp); // orig emu removed self from its own hate list... don't understand why you'd do that, so skipping if (!zp.IsGM) { // GM's don't get penalized from dieing... muwhahaha // Figure out how much xp we lose, if any int xpLoss = 0; if (zp.Level >= WorldServer.ServerConfig.LevelDeathDoesXPLoss) // TODO: don't lose xp when we have become an NPC? xpLoss = (int)(zp.XP * WorldServer.ServerConfig.XPLossModifier); if (lastAttacker is ZonePlayer) // TODO: also check if the attacker is a pet owned by a player (no xp loss in that case) xpLoss = 0; // Don't lose xp when dueling _log.DebugFormat("{0} is losing {1} xp due to his ass died.", zp.Name, xpLoss); zp.XP -= xpLoss; // TODO: fade buffs (ALL - good and bad) // TODO: unmem spells (don't send packets) PlayerCorpse pc = new PlayerCorpse(zp, xpLoss, _zoneSvr.HasGraveyard()); AddCorpse(pc); _zoneSvr.QueuePacketToClients(zp, bcPack, true); // send the become corpse packet to all players in the zone } else { // TODO: fade just detrimental buffs } // Send player to bind point _zoneSvr.MovePlayer(zp, zp.PlayerProfile.Binds[0].ZoneId, 0, zp.PlayerProfile.Binds[0].X, zp.PlayerProfile.Binds[0].Y, zp.PlayerProfile.Binds[0].Z, zp.PlayerProfile.Binds[0].Heading, ZoneMode.ZoneToBindPoint); }
private void NpcDeath(NpcMob npc, Mob lastAttacker, uint spellId, byte damageType, uint damage) { RemoveFromAllTargets(npc); // Remove NPC from any entity's target & hate lists // Send Death Packet Death d = new Death() { SpawnId = (uint)npc.ID, KillerId = lastAttacker == null ? 0u : (uint)lastAttacker.ID, BindToZoneId = 0u, SpellId = spellId == 0u ? 0xFFFFFFFF : spellId, AttackSkillId = damageType, Damage = damage }; EQApplicationPacket<Death> dPack = new EQApplicationPacket<Death>(AppOpCode.Death, d); _zoneSvr.QueuePacketToClients(lastAttacker, dPack, false); // TODO: this should be cool with a null lastAttacker, right? // TODO: something about respawn? Mob killer = npc.HateMgr.GetTopHated(); Mob xpMob = npc.HateMgr.GetTopDamager(); // Give xp out if (xpMob == null) xpMob = killer; if (xpMob == null) xpMob = lastAttacker; // TODO: if xpMob is pet, get the owner ZonePlayer xpClient = xpMob as ZonePlayer; if (xpClient != null) { // TODO: handle raid split, LDON adventure crap, etc. float groupBonus = 1.0f; if (xpClient.IsGrouped) { // TODO: handle group split // TODO: add group xp bonus } else { ConLevel conLvl = Mob.GetConsiderDificulty(xpClient.Level, npc.Level); if (conLvl != ConLevel.Green) { // TODO: figure high con bonus, if any int baseXp = (int)(npc.Level * npc.Level * groupBonus * _zoneSvr.Zone.XPMultiplier); xpClient.GiveXP((int)(npc.Level * npc.Level * 75 * _zoneSvr.Zone.XPMultiplier), conLvl); } } // TODO: raise death merit event? } // TODO: faction hits // Make a corpse and add to the manager if (npc.IsLootable) { // TODO: add additional checks for stuff like a guard killing the mob, etc. Corpse c = new Corpse(npc, npc.LootItems); AddCorpse(c); // TODO: if killer is a pet, get the owner if (xpClient != null) c.AllowLooter(killer as ZonePlayer); } // TODO: raise script event _log.DebugFormat("NPC {0} has died", npc.ID); }