/* * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include "Vignette.h" #include "CellImpl.h" #include "DB2Structure.h" #include "GridNotifiersImpl.h" #include "VignettePackets.h" namespace Vignettes { namespace { void UpdatePosition(VignetteData& vignette, WorldObject const* owner) { vignette.Position = owner->GetPosition(); if (WmoLocation const* wmoLocation = owner->GetCurrentWmo()) { vignette.WMOGroupID = wmoLocation->GroupId; vignette.WMODoodadPlacementID = wmoLocation->UniqueId; } } void UpdateHealth(VignetteData& vignette, Unit const* owner) { vignette.HealthPercent = float(owner->GetHealth()) / float(owner->GetMaxHealth()); // converted to percentage in lua } template void SendVignetteUpdate(VignetteData const& vignette, WorldObject const* owner) { if (!owner->IsInWorld()) return; WorldPackets::Vignette::VignetteUpdate vignetteUpdate; vignette.FillPacket(vignetteUpdate.*Field); vignetteUpdate.Write(); auto sender = [&](Player const* receiver) { if (CanSee(receiver, vignette)) receiver->SendDirectMessage(vignetteUpdate.GetRawPacket()); }; if (Player const* playerOwner = owner->ToPlayer()) sender(playerOwner); Trinity::MessageDistDeliverer notifier(owner, sender, owner->GetVisibilityRange()); Cell::VisitWorldObjects(owner, notifier, owner->GetVisibilityRange()); } } void VignetteData::FillPacket(WorldPackets::Vignette::VignetteDataSet& dataSet) const { dataSet.IDs.push_back(Guid); WorldPackets::Vignette::VignetteData& data = dataSet.Data.emplace_back(); data.ObjGUID = Object; data.Position = Position; data.VignetteID = Data->ID; data.ZoneID = ZoneID; data.WMOGroupID = WMOGroupID; data.WMODoodadPlacementID = WMODoodadPlacementID; data.HealthPercent = HealthPercent; } std::unique_ptr Create(VignetteEntry const* vignetteData, WorldObject const* owner) { std::unique_ptr vignette = std::make_unique(); vignette->Guid = ObjectGuid::Create(owner->GetMapId(), vignetteData->ID, owner->GetMap()->GenerateLowGuid()); vignette->Object = owner->GetGUID(); vignette->Position = owner->GetPosition(); vignette->Data = vignetteData; vignette->ZoneID = owner->GetZoneId(); // not updateable UpdatePosition(*vignette, owner); if (Unit const* unitOwner = owner->ToUnit()) UpdateHealth(*vignette, unitOwner); if (vignetteData->IsInfiniteAOI()) owner->GetMap()->AddInfiniteAOIVignette(vignette.get()); else SendVignetteUpdate<&WorldPackets::Vignette::VignetteUpdate::Added>(*vignette, owner); return vignette; } void Update(VignetteData& vignette, WorldObject const* owner) { UpdatePosition(vignette, owner); if (Unit const* unitOwner = owner->ToUnit()) UpdateHealth(vignette, unitOwner); if (vignette.Data->IsInfiniteAOI()) vignette.NeedUpdate = true; else SendVignetteUpdate<&WorldPackets::Vignette::VignetteUpdate::Updated>(vignette, owner); } void Remove(VignetteData& vignette, WorldObject const* owner) { if (vignette.Data->IsInfiniteAOI()) owner->GetMap()->RemoveInfiniteAOIVignette(&vignette); else { WorldPackets::Vignette::VignetteUpdate vignetteUpdate; vignetteUpdate.Removed.push_back(vignette.Guid); owner->SendMessageToSet(vignetteUpdate.Write(), true); } } bool CanSee(Player const* player, VignetteData const& vignette) { if (vignette.Data->GetFlags().HasFlag(VignetteFlags::ZoneInfiniteAOI)) if (vignette.ZoneID != player->GetZoneId()) return false; if (vignette.Data->VisibleTrackingQuestID) if (player->IsQuestRewarded(vignette.Data->VisibleTrackingQuestID)) return false; if (!ConditionMgr::IsPlayerMeetingCondition(player, vignette.Data->PlayerConditionID)) return false; return true; } }