diff options
author | Shauren <shauren.trinity@gmail.com> | 2013-02-26 17:14:13 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2013-02-26 17:14:13 +0100 |
commit | af4ac778d7f47e4ab20c042009cb8bbd9c41d94b (patch) | |
tree | 509522e290a47563cfafde66ce2f3b5929e5098e | |
parent | e3e5d14d52da6ab6005f28acca6492ff805fe6a0 (diff) |
Core/Quests: Implemented quest flag forcing the player to be flagged for PvP as long as the quest is in his log.
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 71 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 13 | ||||
-rw-r--r-- | src/server/game/Handlers/MiscHandler.cpp | 6 | ||||
-rw-r--r-- | src/server/game/Handlers/MovementHandler.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Handlers/QuestHandler.cpp | 6 | ||||
-rw-r--r-- | src/server/game/Handlers/TaxiHandler.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Spells/SpellEffects.cpp | 6 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_quest.cpp | 6 |
8 files changed, 85 insertions, 29 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 467604960ed..8647d9d6f5e 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -7417,17 +7417,17 @@ void Player::UpdateArea(uint32 newArea) m_areaUpdateId = newArea; AreaTableEntry const* area = GetAreaEntryByAreaID(newArea); - pvpInfo.inFFAPvPArea = area && (area->flags & AREA_FLAG_ARENA); + pvpInfo.IsInFFAPvPArea = area && (area->flags & AREA_FLAG_ARENA); UpdatePvPState(true); UpdateAreaDependentAuras(newArea); // previously this was in UpdateZone (but after UpdateArea) so nothing will break - pvpInfo.inNoPvPArea = false; + pvpInfo.IsInNoPvPArea = false; if (area && area->IsSanctuary()) // in sanctuary { SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY); - pvpInfo.inNoPvPArea = true; + pvpInfo.IsInNoPvPArea = true; CombatStopWithPets(); } else @@ -7482,29 +7482,32 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea) switch (zone->team) { case AREATEAM_ALLY: - pvpInfo.inHostileArea = GetTeam() != ALLIANCE && (sWorld->IsPvPRealm() || zone->flags & AREA_FLAG_CAPITAL); + pvpInfo.IsInHostileArea = GetTeam() != ALLIANCE && (sWorld->IsPvPRealm() || zone->flags & AREA_FLAG_CAPITAL); break; case AREATEAM_HORDE: - pvpInfo.inHostileArea = GetTeam() != HORDE && (sWorld->IsPvPRealm() || zone->flags & AREA_FLAG_CAPITAL); + pvpInfo.IsInHostileArea = GetTeam() != HORDE && (sWorld->IsPvPRealm() || zone->flags & AREA_FLAG_CAPITAL); break; case AREATEAM_NONE: // overwrite for battlegrounds, maybe batter some zone flags but current known not 100% fit to this - pvpInfo.inHostileArea = sWorld->IsPvPRealm() || InBattleground() || zone->flags & AREA_FLAG_WINTERGRASP; + pvpInfo.IsInHostileArea = sWorld->IsPvPRealm() || InBattleground() || zone->flags & AREA_FLAG_WINTERGRASP; break; default: // 6 in fact - pvpInfo.inHostileArea = false; + pvpInfo.IsInHostileArea = false; break; } + // Treat players having a quest flagging for PvP as always in hostile area + pvpInfo.IsHostile = pvpInfo.IsInHostileArea || HasPvPForcingQuest(); + if (zone->flags & AREA_FLAG_CAPITAL) // Is in a capital city { - if (!pvpInfo.inHostileArea || zone->IsSanctuary()) + if (!pvpInfo.IsHostile || zone->IsSanctuary()) { SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING); SetRestType(REST_TYPE_IN_CITY); InnEnter(time(0), GetMapId(), 0, 0, 0); } - pvpInfo.inNoPvPArea = true; + pvpInfo.IsInNoPvPArea = true; } else { @@ -15046,6 +15049,12 @@ void Player::AddQuest(Quest const* quest, Object* questGiver) else questStatusData.Timer = 0; + if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP)) + { + pvpInfo.IsHostile = true; + UpdatePvPState(); + } + SetQuestSlot(log_slot, quest_id, qtime); m_QuestStatusSave[quest_id] = true; @@ -15242,6 +15251,12 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver, UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT); UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST, quest->GetQuestId()); + if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP)) + { + pvpInfo.IsHostile = pvpInfo.IsInHostileArea || HasPvPForcingQuest(); + UpdatePvPState(); + } + //lets remove flag for delayed teleports SetCanDelayTeleport(false); } @@ -16555,6 +16570,25 @@ void Player::SendQuestUpdateAddPlayer(Quest const* quest, uint16 old_count, uint SetQuestSlotCounter(log_slot, QUEST_PVP_KILL_SLOT, GetQuestSlotCounter(log_slot, QUEST_PVP_KILL_SLOT) + add_count); } +bool Player::HasPvPForcingQuest() const +{ + for (uint8 i = 0; i < MAX_QUEST_LOG_SIZE; ++i) + { + uint32 questId = GetQuestSlotQuestId(i); + if (questId == 0) + continue; + + Quest const* quest = sObjectMgr->GetQuestTemplate(questId); + if (!quest) + continue; + + if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP)) + return true; + } + + return false; +} + /*********************************************************/ /*** LOAD SYSTEM ***/ /*********************************************************/ @@ -19887,7 +19921,8 @@ void Player::UpdatePvPFlag(time_t currTime) { if (!IsPvP()) return; - if (pvpInfo.endTimer == 0 || currTime < (pvpInfo.endTimer + 300) || pvpInfo.inHostileArea) + + if (!pvpInfo.EndTimer || currTime < (pvpInfo.EndTimer + 300) || pvpInfo.IsHostile) return; UpdatePvP(false); @@ -21333,8 +21368,8 @@ void Player::UpdatePvPState(bool onlyFFA) { // TODO: should we always synchronize UNIT_FIELD_BYTES_2, 1 of controller and controlled? // no, we shouldn't, those are checked for affecting player by client - if (!pvpInfo.inNoPvPArea && !isGameMaster() - && (pvpInfo.inFFAPvPArea || sWorld->IsFFAPvPRealm())) + if (!pvpInfo.IsInNoPvPArea && !isGameMaster() + && (pvpInfo.IsInFFAPvPArea || sWorld->IsFFAPvPRealm())) { if (!HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP)) { @@ -21353,15 +21388,15 @@ void Player::UpdatePvPState(bool onlyFFA) if (onlyFFA) return; - if (pvpInfo.inHostileArea) // in hostile area + if (pvpInfo.IsHostile) // in hostile area { - if (!IsPvP() || pvpInfo.endTimer != 0) + if (!IsPvP() || pvpInfo.EndTimer) UpdatePvP(true, true); } else // in friendly area { - if (IsPvP() && !HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP) && pvpInfo.endTimer == 0) - pvpInfo.endTimer = time(NULL); // start toggle-off + if (IsPvP() && !HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP) && !pvpInfo.EndTimer) + pvpInfo.EndTimer = time(NULL); // start toggle-off } } @@ -21370,11 +21405,11 @@ void Player::UpdatePvP(bool state, bool override) if (!state || override) { SetPvP(state); - pvpInfo.endTimer = 0; + pvpInfo.EndTimer = 0; } else { - pvpInfo.endTimer = time(NULL); + pvpInfo.EndTimer = time(NULL); SetPvP(state); } } diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 362b6aca631..a2086f0b68a 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -270,12 +270,13 @@ struct PlayerInfo struct PvPInfo { - PvPInfo() : inHostileArea(false), inNoPvPArea(false), inFFAPvPArea(false), endTimer(0) {} + PvPInfo() : IsHostile(false), IsInHostileArea(false), IsInNoPvPArea(false), IsInFFAPvPArea(false), EndTimer(0) {} - bool inHostileArea; - bool inNoPvPArea; - bool inFFAPvPArea; - time_t endTimer; + bool IsHostile; + bool IsInHostileArea; ///> Marks if player is in an area which forces PvP flag + bool IsInNoPvPArea; ///> Marks if player is in a sanctuary or friendly capital city + bool IsInFFAPvPArea; ///> Marks if player is in an FFAPvP area (such as Gurubashi Arena) + time_t EndTimer; ///> Time when player unflags himself for PvP (flag removed after 5 minutes) }; struct DuelInfo @@ -1500,6 +1501,8 @@ class Player : public Unit, public GridObject<Player> void AddTimedQuest(uint32 quest_id) { m_timedquests.insert(quest_id); } void RemoveTimedQuest(uint32 quest_id) { m_timedquests.erase(quest_id); } + bool HasPvPForcingQuest() const; + /*********************************************************/ /*** LOAD SYSTEM ***/ /*********************************************************/ diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 3864acb8f88..2a4f4a15037 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -475,13 +475,13 @@ void WorldSession::HandleTogglePvP(WorldPacket& recvData) if (GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP)) { - if (!GetPlayer()->IsPvP() || GetPlayer()->pvpInfo.endTimer != 0) + if (!GetPlayer()->IsPvP() || GetPlayer()->pvpInfo.EndTimer) GetPlayer()->UpdatePvP(true, true); } else { - if (!GetPlayer()->pvpInfo.inHostileArea && GetPlayer()->IsPvP()) - GetPlayer()->pvpInfo.endTimer = time(NULL); // start toggle-off + if (!GetPlayer()->pvpInfo.IsHostile && GetPlayer()->IsPvP()) + GetPlayer()->pvpInfo.EndTimer = time(NULL); // start toggle-off } //if (OutdoorPvP* pvp = _player->GetOutdoorPvP()) diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index 3308c7bee24..5b023fa160c 100644 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -174,7 +174,7 @@ void WorldSession::HandleMoveWorldportAckOpcode() GetPlayer()->UpdateZone(newzone, newarea); // honorless target - if (GetPlayer()->pvpInfo.inHostileArea) + if (GetPlayer()->pvpInfo.IsHostile) GetPlayer()->CastSpell(GetPlayer(), 2479, true); // in friendly area @@ -224,7 +224,7 @@ void WorldSession::HandleMoveTeleportAck(WorldPacket& recvData) if (old_zone != newzone) { // honorless target - if (plMover->pvpInfo.inHostileArea) + if (plMover->pvpInfo.IsHostile) plMover->CastSpell(plMover, 2479, true); // in friendly area diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index b9301347afb..2724a523667 100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -429,6 +429,12 @@ void WorldSession::HandleQuestLogRemoveQuest(WorldPacket& recvData) { if (quest->HasFlag(QUEST_TRINITY_FLAGS_TIMED)) _player->RemoveTimedQuest(questId); + + if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP)) + { + _player->pvpInfo.IsHostile = _player->pvpInfo.IsInHostileArea || _player->HasPvPForcingQuest(); + _player->UpdatePvPState(); + } } _player->TakeQuestSourceItem(questId, true); // remove quest src item from player diff --git a/src/server/game/Handlers/TaxiHandler.cpp b/src/server/game/Handlers/TaxiHandler.cpp index b7155e552c7..53334cffd18 100644 --- a/src/server/game/Handlers/TaxiHandler.cpp +++ b/src/server/game/Handlers/TaxiHandler.cpp @@ -269,7 +269,7 @@ void WorldSession::HandleMoveSplineDoneOpcode(WorldPacket& recvData) GetPlayer()->CleanupAfterTaxiFlight(); GetPlayer()->SetFallInformation(0, GetPlayer()->GetPositionZ()); - if (GetPlayer()->pvpInfo.inHostileArea) + if (GetPlayer()->pvpInfo.IsHostile) GetPlayer()->CastSpell(GetPlayer(), 2479, true); } diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 9d3ec6630e5..2aa8b6daed8 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -5041,6 +5041,12 @@ void Spell::EffectQuestClear(SpellEffIndex effIndex) // we ignore unequippable quest items in this case, it's still be equipped player->TakeQuestSourceItem(logQuest, false); + + if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP)) + { + player->pvpInfo.IsHostile = player->pvpInfo.IsInHostileArea || player->HasPvPForcingQuest(); + player->UpdatePvPState(); + } } } diff --git a/src/server/scripts/Commands/cs_quest.cpp b/src/server/scripts/Commands/cs_quest.cpp index e10cf883518..e0d67b55989 100644 --- a/src/server/scripts/Commands/cs_quest.cpp +++ b/src/server/scripts/Commands/cs_quest.cpp @@ -138,6 +138,12 @@ public: // we ignore unequippable quest items in this case, its' still be equipped player->TakeQuestSourceItem(logQuest, false); + + if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP)) + { + player->pvpInfo.IsHostile = player->pvpInfo.IsInHostileArea || player->HasPvPForcingQuest(); + player->UpdatePvPState(); + } } } |