public override void RezUnit() { if (_objective.Objective.NoRespawn != 1 && this.Spawn.NoRespawn != 1) { lock (_objective.ActiveCreatures) { _objective.ActiveCreatures.Remove(this); PQuestCreature newCreature = new PQuestCreature(Spawn, _objective, _publicQuest); newCreature.PQSpawnId = this.PQSpawnId; _objective.ActiveCreatures.Add(newCreature); Region.AddObject(newCreature, Spawn.ZoneId); } Destroy(); } }
/// <summary> /// When a player receives a hit from a Public Quest mob, tracks the damage dealt. /// </summary> public void AddTrackedDamage(Player target, PQuestCreature mob, uint damage) { if (!Players.ContainsKey(target.CharacterId)) { Players.Add(target.CharacterId, new ContributionInfo(target)); } if (!Players[target.CharacterId].DamageTakenFrom.ContainsKey(mob.Oid)) { Players[target.CharacterId].DamageTakenFrom.Add(mob.Oid, new ContributionInfo.HitInfo(damage)); } else { if (mob.Rank > 0 || Players[target.CharacterId].DamageTakenFrom[mob.Oid].NumHits < 10) { Players[target.CharacterId].DamageTakenFrom[mob.Oid].DamageTaken += damage; } Players[target.CharacterId].DamageTakenFrom[mob.Oid].NumHits++; } }
/// <summary> /// Dishes out contribution earned from this mob. /// </summary> /// <param name="mob"></param> public void NotifyKilled(PQuestCreature mob) { float totalDamageDealt = 1; float totalHits = 0; int damagedCount = 0; // Handle contribution to the PQ. int rankMod; switch (mob.Rank) { case 1: rankMod = 4; break; case 2: rankMod = 20; break; default: rankMod = 1; break; } #region For having taken damage foreach (ContributionInfo plrInfo in Players.Values) { if (plrInfo.DamageTakenFrom.ContainsKey(mob.Oid)) { damagedCount++; totalDamageDealt += plrInfo.DamageTakenFrom[mob.Oid].DamageTaken; totalHits += plrInfo.DamageTakenFrom[mob.Oid].NumHits; } } foreach (ContributionInfo tankerInfo in Players.Values) { if (tankerInfo.DamageTakenFrom.ContainsKey(mob.Oid)) { Player targPlayer = Player.GetPlayer(tankerInfo.PlayerCharId); float scaler = tankerInfo.DamageTakenFrom[mob.Oid].NumHits / totalHits; if (targPlayer != null && targPlayer.CrrInterface.GetArchetype() != EArchetype.ARCHETYPE_Tank && totalHits < 6) { scaler *= totalHits / 6; } if (targPlayer != null) { SplitContribution(targPlayer, (ushort)(100 * rankMod * scaler)); targPlayer.SendClientMessage("Received " + (ushort)(100 * rankMod * scaler) + " contribution from tanking damage.", ChatLogFilters.CHATLOGFILTERS_QUEST, true); } tankerInfo.ActiveTimeEnd = TCPManager.GetTimeStamp() + 5; } } #endregion #region For healers of damage float totalHealing = 0; if (_playerHealing.ContainsKey(mob.Oid)) { Dictionary <uint, uint> mobHealing = _playerHealing[mob.Oid]; foreach (uint healing in mobHealing.Values) { totalHealing += healing; } foreach (uint Plr in ActivePlayers) { Player targPlayer = Player.GetPlayer(Plr); if (targPlayer != null) { if (mobHealing.ContainsKey(targPlayer.CharacterId)) { if (!Players.ContainsKey(targPlayer.CharacterId)) { Players.Add(targPlayer.CharacterId, new ContributionInfo(targPlayer)); } if (Players.ContainsKey(targPlayer.CharacterId)) { SplitContribution(targPlayer, (ushort)(mobHealing[targPlayer.CharacterId] / totalHealing * rankMod * 100)); targPlayer.SendClientMessage("Received " + (ushort)(mobHealing[targPlayer.CharacterId] / totalHealing * rankMod * 100) + " contribution from healing other players.", ChatLogFilters.CHATLOGFILTERS_QUEST, true); Players[targPlayer.CharacterId].ActiveTimeEnd = TCPManager.GetTimeStamp() + 5; } } } } } #endregion float leftoverFactor = 1f - totalHealing / totalDamageDealt; if (leftoverFactor > 0) { foreach (ContributionInfo plrInfo in Players.Values) { if (plrInfo.DamageTakenFrom.ContainsKey(mob.Oid)) { plrInfo.HealingDamagePool += (uint)(totalDamageDealt * (leftoverFactor / damagedCount)); plrInfo.HealingContribPool += (uint)(100 * rankMod * (leftoverFactor / damagedCount)); plrInfo.DamageTakenFrom.Remove(mob.Oid); } } } _playerHealing.Remove(mob.Oid); }
public void Reset() { if (Objective == null) { Log.Error("PQuestObjective.Reset", string.Concat(Quest.Name, " has no objective!")); return; } if (Objective.Spawns == null) { Log.Error("PQuestObjective.Reset", string.Concat(Quest.Name, " - ", Objective.StageName, " has no spawn set")); return; } foreach (PQuest_Spawn spawn in Objective.Spawns) { if (spawn.Type == 1) { Creature_proto proto = CreatureService.GetCreatureProto(spawn.Entry); if (proto == null) { Log.Error("PQCreature", "No Proto"); continue; } if (Quest == null) { Log.Error("PQuestObjective", "Missing quest for: " + Objective.Objective); continue; } Creature_spawn S = new Creature_spawn { Guid = (uint)CreatureService.GenerateCreatureSpawnGUID(), WorldO = spawn.WorldO, WorldY = spawn.WorldY, WorldZ = spawn.WorldZ, WorldX = spawn.WorldX, ZoneId = spawn.ZoneId }; S.BuildFromProto(proto); //This sets the emotes for NPCs in PQ S.Emote = spawn.Emote; //This sets NPC level from puest_spawns table, we are not using creature_protos here S.Level = spawn.Level; PQuestCreature newCreature = new PQuestCreature(S, this, Quest); newCreature.PQSpawnId = spawn.pquest_spawns_ID.Replace(" ", ""); if (newCreature != null) { lock (ActiveCreatures) { ActiveCreatures.Add(newCreature); } Quest.Region.AddObject(newCreature, spawn.ZoneId); } } if (spawn.Type == 2) { GameObject_proto Proto = GameObjectService.GetGameObjectProto(spawn.Entry); if (Proto == null) { Log.Error("PQGO", "No Proto"); return; } GameObject_spawn S = new GameObject_spawn(); S.Guid = (uint)GameObjectService.GenerateGameObjectSpawnGUID(); S.BuildFromProto(Proto); S.WorldO = spawn.WorldO; S.WorldY = spawn.WorldY; S.WorldZ = spawn.WorldZ; S.WorldX = spawn.WorldX; S.ZoneId = spawn.ZoneId; S.SoundId = spawn.SoundId; S.VfxState = spawn.VfxState; S.AllowVfxUpdate = spawn.AllowVfxUpdate; S.Unks = spawn.Unks; S.Unk3 = spawn.Unk3; PQuestGameObject NewGo = new PQuestGameObject(S, this); if (NewGo != null) { lock (ActiveGameObjects) { ActiveGameObjects.Add(NewGo); } Quest.Region.AddObject(NewGo, spawn.ZoneId); } // PQ Sound player - this will play sounds on PQ Stage, need to be setup in DB if (spawn.Entry == 2000489 && Objective.SoundId != 0) { string text = ""; var prms = new List <object>() { NewGo, (ushort)Objective.SoundId, text }; for (int i = 0; i < Objective.SoundIteration; i++) { NewGo.EvtInterface.AddEvent(PlayPQSound, i * (int)Objective.SoundDelay * 1000 + 500, 1, prms); } } } if (spawn.Type == 3) { return; #warning this sucks cant get gos by spawn id ActiveInteractableGameObjects.Add(spawn.Entry); } } }