mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-13 01:08:35 +00:00
fix(Core/Player): prevent crash exploit spam duel starting (#9226)
This commit is contained in:
committed by
GitHub
parent
25ca425357
commit
ab761c9865
@@ -211,8 +211,6 @@ Player::Player(WorldSession* session): Unit(true), m_mover(this)
|
||||
m_auraRaidUpdateMask = 0;
|
||||
m_bPassOnGroupLoot = false;
|
||||
|
||||
duel = nullptr;
|
||||
|
||||
m_GuildIdInvited = 0;
|
||||
m_ArenaTeamIdInvited = 0;
|
||||
|
||||
@@ -6154,18 +6152,20 @@ uint32 Player::GetZoneIdFromDB(ObjectGuid guid)
|
||||
void Player::CheckDuelDistance(time_t currTime)
|
||||
{
|
||||
if (!duel)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ObjectGuid duelFlagGUID = GetGuidValue(PLAYER_DUEL_ARBITER);
|
||||
GameObject* obj = GetMap()->GetGameObject(duelFlagGUID);
|
||||
if (!obj)
|
||||
return;
|
||||
|
||||
if (duel->outOfBound == 0)
|
||||
if (!duel->OutOfBoundsTime)
|
||||
{
|
||||
if (!IsWithinDistInMap(obj, 50))
|
||||
{
|
||||
duel->outOfBound = currTime;
|
||||
duel->OutOfBoundsTime = currTime + 10;
|
||||
|
||||
WorldPacket data(SMSG_DUEL_OUTOFBOUNDS, 0);
|
||||
GetSession()->SendPacket(&data);
|
||||
@@ -6175,12 +6175,12 @@ void Player::CheckDuelDistance(time_t currTime)
|
||||
{
|
||||
if (IsWithinDistInMap(obj, 40))
|
||||
{
|
||||
duel->outOfBound = 0;
|
||||
duel->OutOfBoundsTime = 0;
|
||||
|
||||
WorldPacket data(SMSG_DUEL_INBOUNDS, 0);
|
||||
GetSession()->SendPacket(&data);
|
||||
}
|
||||
else if (currTime >= (duel->outOfBound + 10))
|
||||
else if (currTime >= duel->OutOfBoundsTime)
|
||||
DuelComplete(DUEL_FLED);
|
||||
}
|
||||
}
|
||||
@@ -6193,57 +6193,76 @@ bool Player::IsOutdoorPvPActive()
|
||||
void Player::DuelComplete(DuelCompleteType type)
|
||||
{
|
||||
// duel not requested
|
||||
if (!duel || !duel->opponent || !duel->initiator)
|
||||
if (!duel)
|
||||
return;
|
||||
|
||||
LOG_DEBUG("entities.unit", "Duel Complete %s %s", GetName().c_str(), duel->opponent->GetName().c_str());
|
||||
// Check if DuelComplete() has been called already up in the stack and in that case don't do anything else here
|
||||
if (duel->State == DUEL_STATE_COMPLETED)
|
||||
return;
|
||||
|
||||
Player* opponent = duel->Opponent;
|
||||
duel->State = DUEL_STATE_COMPLETED;
|
||||
opponent->duel->State = DUEL_STATE_COMPLETED;
|
||||
|
||||
LOG_DEBUG("entities.unit", "Player::DuelComplete: Player '%s' (%s), Opponent: '%s' (%s)",
|
||||
GetName().c_str(), GetGUID().ToString().c_str(), opponent->GetName().c_str(), opponent->GetGUID().ToString().c_str());
|
||||
|
||||
WorldPacket data(SMSG_DUEL_COMPLETE, (1));
|
||||
data << (uint8)((type != DUEL_INTERRUPTED) ? 1 : 0);
|
||||
GetSession()->SendPacket(&data);
|
||||
|
||||
duel->opponent->GetSession()->SendPacket(&data);
|
||||
data << uint8((type != DUEL_INTERRUPTED) ? 1 : 0);
|
||||
SendDirectMessage(&data);
|
||||
if (opponent->GetSession())
|
||||
{
|
||||
opponent->SendDirectMessage(&data);
|
||||
}
|
||||
|
||||
if (type != DUEL_INTERRUPTED)
|
||||
{
|
||||
data.Initialize(SMSG_DUEL_WINNER, (1 + 20)); // we guess size
|
||||
data.Initialize(SMSG_DUEL_WINNER, (1+20)); // we guess size
|
||||
data << uint8(type == DUEL_WON ? 0 : 1); // 0 = just won; 1 = fled
|
||||
data << duel->opponent->GetName();
|
||||
data << opponent->GetName();
|
||||
data << GetName();
|
||||
SendMessageToSet(&data, true);
|
||||
}
|
||||
|
||||
sScriptMgr->OnPlayerDuelEnd(duel->opponent, this, type);
|
||||
sScriptMgr->OnPlayerDuelEnd(opponent, this, type);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case DUEL_FLED:
|
||||
// if initiator and opponent are on the same team
|
||||
// or initiator and opponent are not PvP enabled, forcibly stop attacking
|
||||
if (duel->initiator->GetTeamId() == duel->opponent->GetTeamId())
|
||||
if (GetTeamId() == opponent->GetTeamId())
|
||||
{
|
||||
duel->initiator->AttackStop();
|
||||
duel->opponent->AttackStop();
|
||||
AttackStop();
|
||||
opponent->AttackStop();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!duel->initiator->IsPvP())
|
||||
duel->initiator->AttackStop();
|
||||
if (!duel->opponent->IsPvP())
|
||||
duel->opponent->AttackStop();
|
||||
if (!IsPvP())
|
||||
{
|
||||
AttackStop();
|
||||
}
|
||||
if (!opponent->IsPvP())
|
||||
{
|
||||
opponent->AttackStop();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DUEL_WON:
|
||||
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOSE_DUEL, 1);
|
||||
duel->opponent->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL, 1);
|
||||
opponent->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL, 1);
|
||||
|
||||
// Credit for quest Death's Challenge
|
||||
if (getClass() == CLASS_DEATH_KNIGHT && duel->opponent->GetQuestStatus(12733) == QUEST_STATUS_INCOMPLETE)
|
||||
duel->opponent->CastSpell(duel->opponent, 52994, true);
|
||||
if (getClass() == CLASS_DEATH_KNIGHT && opponent->GetQuestStatus(12733) == QUEST_STATUS_INCOMPLETE)
|
||||
{
|
||||
opponent->CastSpell(opponent, 52994, true);
|
||||
}
|
||||
|
||||
// Honor points after duel (the winner) - ImpConfig
|
||||
if (uint32 amount = sWorld->getIntConfig(CONFIG_HONOR_AFTER_DUEL))
|
||||
duel->opponent->RewardHonor(nullptr, 1, amount);
|
||||
{
|
||||
opponent->RewardHonor(nullptr, 1, amount);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
@@ -6251,56 +6270,66 @@ void Player::DuelComplete(DuelCompleteType type)
|
||||
}
|
||||
|
||||
// Victory emote spell
|
||||
if (type != DUEL_INTERRUPTED && duel->opponent)
|
||||
duel->opponent->CastSpell(duel->opponent, 52852, true);
|
||||
if (type != DUEL_INTERRUPTED)
|
||||
{
|
||||
opponent->CastSpell(opponent, 52852, true);
|
||||
}
|
||||
|
||||
//Remove Duel Flag object
|
||||
GameObject* obj = GetMap()->GetGameObject(GetGuidValue(PLAYER_DUEL_ARBITER));
|
||||
if (obj)
|
||||
duel->initiator->RemoveGameObject(obj, true);
|
||||
{
|
||||
duel->Initiator->RemoveGameObject(obj, true);
|
||||
}
|
||||
|
||||
/* remove auras */
|
||||
AuraApplicationMap& itsAuras = duel->opponent->GetAppliedAuras();
|
||||
AuraApplicationMap &itsAuras = opponent->GetAppliedAuras();
|
||||
for (AuraApplicationMap::iterator i = itsAuras.begin(); i != itsAuras.end();)
|
||||
{
|
||||
Aura const* aura = i->second->GetBase();
|
||||
if (!i->second->IsPositive() && aura->GetCasterGUID() == GetGUID() && aura->GetApplyTime() >= duel->startTime)
|
||||
duel->opponent->RemoveAura(i);
|
||||
if (!i->second->IsPositive() && aura->GetCasterGUID() == GetGUID() && aura->GetApplyTime() >= duel->StartTime)
|
||||
{
|
||||
opponent->RemoveAura(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
AuraApplicationMap& myAuras = GetAppliedAuras();
|
||||
AuraApplicationMap &myAuras = GetAppliedAuras();
|
||||
for (AuraApplicationMap::iterator i = myAuras.begin(); i != myAuras.end();)
|
||||
{
|
||||
Aura const* aura = i->second->GetBase();
|
||||
if (!i->second->IsPositive() && aura->GetCasterGUID() == duel->opponent->GetGUID() && aura->GetApplyTime() >= duel->startTime)
|
||||
if (!i->second->IsPositive() && aura->GetCasterGUID() == opponent->GetGUID() && aura->GetApplyTime() >= duel->StartTime)
|
||||
RemoveAura(i);
|
||||
else
|
||||
++i;
|
||||
}
|
||||
|
||||
// cleanup combo points
|
||||
if (GetComboTarget() == duel->opponent->GetGUID())
|
||||
if (GetComboTarget() == duel->Opponent->GetGUID())
|
||||
ClearComboPoints();
|
||||
else if (GetComboTarget() == duel->opponent->GetPetGUID())
|
||||
else if (GetComboTarget() == duel->Opponent->GetPetGUID())
|
||||
ClearComboPoints();
|
||||
|
||||
if (duel->opponent->GetComboTarget() == GetGUID())
|
||||
duel->opponent->ClearComboPoints();
|
||||
else if (duel->opponent->GetComboTarget() == GetPetGUID())
|
||||
duel->opponent->ClearComboPoints();
|
||||
if (duel->Opponent->GetComboTarget() == GetGUID())
|
||||
{
|
||||
duel->Opponent->ClearComboPoints();
|
||||
}
|
||||
else if (duel->Opponent->GetComboTarget() == GetPetGUID())
|
||||
{
|
||||
duel->Opponent->ClearComboPoints();
|
||||
}
|
||||
|
||||
//cleanups
|
||||
SetGuidValue(PLAYER_DUEL_ARBITER, ObjectGuid::Empty);
|
||||
SetUInt32Value(PLAYER_DUEL_TEAM, 0);
|
||||
duel->opponent->SetGuidValue(PLAYER_DUEL_ARBITER, ObjectGuid::Empty);
|
||||
duel->opponent->SetUInt32Value(PLAYER_DUEL_TEAM, 0);
|
||||
opponent->SetGuidValue(PLAYER_DUEL_ARBITER, ObjectGuid::Empty);
|
||||
opponent->SetUInt32Value(PLAYER_DUEL_TEAM, 0);
|
||||
|
||||
delete duel->opponent->duel;
|
||||
duel->opponent->duel = nullptr;
|
||||
delete duel;
|
||||
duel = nullptr;
|
||||
opponent->duel.reset(nullptr);
|
||||
duel.reset(nullptr);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------//
|
||||
@@ -10668,9 +10697,18 @@ bool Player::IsAlwaysDetectableFor(WorldObject const* seer) const
|
||||
if (Unit::IsAlwaysDetectableFor(seer))
|
||||
return true;
|
||||
|
||||
if (duel && duel->State != DUEL_STATE_CHALLENGED && duel->Opponent == seer)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (const Player* seerPlayer = seer->ToPlayer())
|
||||
{
|
||||
if (IsGroupVisibleFor(seerPlayer))
|
||||
return !(seerPlayer->duel && seerPlayer->duel->startTime != 0 && seerPlayer->duel->opponent == this);
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -357,16 +357,24 @@ struct PvPInfo
|
||||
time_t FFAPvPEndTimer{0}; ///> Time when player unflags himself for FFA PvP (flag removed after 30 sec)
|
||||
};
|
||||
|
||||
enum DuelState
|
||||
{
|
||||
DUEL_STATE_CHALLENGED,
|
||||
DUEL_STATE_COUNTDOWN,
|
||||
DUEL_STATE_IN_PROGRESS,
|
||||
DUEL_STATE_COMPLETED
|
||||
};
|
||||
|
||||
struct DuelInfo
|
||||
{
|
||||
DuelInfo() {}
|
||||
DuelInfo(Player* opponent, Player* initiator, bool isMounted) : Opponent(opponent), Initiator(initiator), IsMounted(isMounted) {}
|
||||
|
||||
Player* initiator{nullptr};
|
||||
Player* opponent{nullptr};
|
||||
time_t startTimer{0};
|
||||
time_t startTime{0};
|
||||
time_t outOfBound{0};
|
||||
bool isMounted{false};
|
||||
Player* const Opponent;
|
||||
Player* const Initiator;
|
||||
bool const IsMounted;
|
||||
DuelState State = DUEL_STATE_CHALLENGED;
|
||||
time_t StartTime = 0;
|
||||
time_t OutOfBoundsTime = 0;
|
||||
};
|
||||
|
||||
struct Areas
|
||||
@@ -1814,7 +1822,7 @@ public:
|
||||
}
|
||||
|
||||
/** todo: -maybe move UpdateDuelFlag+DuelComplete to independent DuelHandler.. **/
|
||||
DuelInfo* duel;
|
||||
std::unique_ptr<DuelInfo> duel;
|
||||
void UpdateDuelFlag(time_t currTime);
|
||||
void CheckDuelDistance(time_t currTime);
|
||||
void DuelComplete(DuelCompleteType type);
|
||||
|
||||
@@ -403,18 +403,16 @@ void Player::UpdateFFAPvPFlag(time_t currTime)
|
||||
|
||||
void Player::UpdateDuelFlag(time_t currTime)
|
||||
{
|
||||
if (!duel || duel->startTimer == 0 || currTime < duel->startTimer + 3)
|
||||
return;
|
||||
if (duel && duel->State == DUEL_STATE_COUNTDOWN && duel->StartTime <= currTime)
|
||||
{
|
||||
sScriptMgr->OnPlayerDuelStart(this, duel->Opponent);
|
||||
|
||||
sScriptMgr->OnPlayerDuelStart(this, duel->opponent);
|
||||
SetUInt32Value(PLAYER_DUEL_TEAM, 1);
|
||||
duel->Opponent->SetUInt32Value(PLAYER_DUEL_TEAM, 2);
|
||||
|
||||
SetUInt32Value(PLAYER_DUEL_TEAM, 1);
|
||||
duel->opponent->SetUInt32Value(PLAYER_DUEL_TEAM, 2);
|
||||
|
||||
duel->startTimer = 0;
|
||||
duel->startTime = currTime;
|
||||
duel->opponent->duel->startTimer = 0;
|
||||
duel->opponent->duel->startTime = currTime;
|
||||
duel->State = DUEL_STATE_IN_PROGRESS;
|
||||
duel->Opponent->duel->State = DUEL_STATE_IN_PROGRESS;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************/
|
||||
|
||||
@@ -921,7 +921,7 @@ uint32 Unit::DealDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage
|
||||
return 0;
|
||||
|
||||
// prevent kill only if killed in duel and killed by opponent or opponent controlled creature
|
||||
if (victim->ToPlayer()->duel->opponent == attacker || victim->ToPlayer()->duel->opponent->GetGUID() == attacker->GetOwnerGUID())
|
||||
if (victim->ToPlayer()->duel->Opponent == attacker || victim->ToPlayer()->duel->Opponent->GetGUID() == attacker->GetOwnerGUID())
|
||||
damage = health - 1;
|
||||
|
||||
duel_hasEnded = true;
|
||||
@@ -930,14 +930,14 @@ uint32 Unit::DealDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage
|
||||
{
|
||||
Player* victimRider = victim->GetCharmer()->ToPlayer();
|
||||
|
||||
if (victimRider && victimRider->duel && victimRider->duel->isMounted)
|
||||
if (victimRider && victimRider->duel && victimRider->duel->IsMounted)
|
||||
{
|
||||
// xinef: situation not possible earlier, just return silently.
|
||||
if (!attacker)
|
||||
return 0;
|
||||
|
||||
// prevent kill only if killed in duel and killed by opponent or opponent controlled creature
|
||||
if (victimRider->duel->opponent == attacker || victimRider->duel->opponent->GetGUID() == attacker->GetCharmerGUID())
|
||||
if (victimRider->duel->Opponent == attacker || victimRider->duel->Opponent->GetGUID() == attacker->GetCharmerGUID())
|
||||
damage = health - 1;
|
||||
|
||||
duel_wasMounted = true;
|
||||
@@ -1065,7 +1065,7 @@ uint32 Unit::DealDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage
|
||||
else
|
||||
he->SetHealth(1);
|
||||
|
||||
he->duel->opponent->CombatStopWithPets(true);
|
||||
he->duel->Opponent->CombatStopWithPets(true);
|
||||
he->CombatStopWithPets(true);
|
||||
|
||||
he->CastSpell(he, 7267, true); // beg
|
||||
@@ -9545,7 +9545,7 @@ ReputationRank Unit::GetReactionTo(Unit const* target) const
|
||||
return REP_FRIENDLY;
|
||||
|
||||
// duel - always hostile to opponent
|
||||
if (selfPlayerOwner->duel && selfPlayerOwner->duel->opponent == targetPlayerOwner && selfPlayerOwner->duel->startTime != 0)
|
||||
if (selfPlayerOwner->duel && selfPlayerOwner->duel->Opponent == targetPlayerOwner && selfPlayerOwner->duel->StartTime != 0)
|
||||
return REP_HOSTILE;
|
||||
|
||||
// same group - checks dependant only on our faction - skip FFA_PVP for example
|
||||
@@ -12817,7 +12817,7 @@ void Unit::SetInCombatWith(Unit* enemy, uint32 duration)
|
||||
if (eOwner->GetTypeId() == TYPEID_PLAYER && eOwner->ToPlayer()->duel)
|
||||
{
|
||||
Unit const* myOwner = GetCharmerOrOwnerOrSelf();
|
||||
if (((Player const*)eOwner)->duel->opponent == myOwner)
|
||||
if (((Player const*)eOwner)->duel->Opponent == myOwner)
|
||||
{
|
||||
SetInCombatState(true, enemy, duration);
|
||||
return;
|
||||
@@ -12890,7 +12890,7 @@ void Unit::CombatStart(Unit* victim, bool initialAggro)
|
||||
SetContestedPvP(who->ToPlayer());
|
||||
|
||||
Player* me = GetCharmerOrOwnerPlayerOrPlayerItself();
|
||||
if (me && who->IsPvP() && (who->GetTypeId() != TYPEID_PLAYER || !me->duel || me->duel->opponent != who))
|
||||
if (me && who->IsPvP() && (who->GetTypeId() != TYPEID_PLAYER || !me->duel || me->duel->Opponent != who))
|
||||
{
|
||||
me->UpdatePvP(true);
|
||||
me->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
|
||||
@@ -12917,7 +12917,7 @@ void Unit::CombatStartOnCast(Unit* target, bool initialAggro, uint32 duration)
|
||||
SetContestedPvP(who->ToPlayer());
|
||||
|
||||
Player* me = GetCharmerOrOwnerPlayerOrPlayerItself();
|
||||
if (me && who->IsPvP() && (who->GetTypeId() != TYPEID_PLAYER || !me->duel || me->duel->opponent != who))
|
||||
if (me && who->IsPvP() && (who->GetTypeId() != TYPEID_PLAYER || !me->duel || me->duel->Opponent != who))
|
||||
{
|
||||
me->UpdatePvP(true);
|
||||
me->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
|
||||
@@ -13155,7 +13155,7 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell, Wo
|
||||
|
||||
// check duel - before sanctuary checks
|
||||
if (playerAffectingAttacker && playerAffectingTarget)
|
||||
if (playerAffectingAttacker->duel && playerAffectingAttacker->duel->opponent == playerAffectingTarget && playerAffectingAttacker->duel->startTime != 0)
|
||||
if (playerAffectingAttacker->duel && playerAffectingAttacker->duel->Opponent == playerAffectingTarget && playerAffectingAttacker->duel->StartTime != 0)
|
||||
return true;
|
||||
|
||||
// PvP case - can't attack when attacker or target are in sanctuary
|
||||
@@ -16466,7 +16466,7 @@ void Unit::SetContestedPvP(Player* attackedPlayer, bool lookForNearContestedGuar
|
||||
{
|
||||
Player* player = GetCharmerOrOwnerPlayerOrPlayerItself();
|
||||
|
||||
if (!player || ((attackedPlayer && (attackedPlayer == player || (player->duel && player->duel->opponent == attackedPlayer))) || player->InBattleground()))
|
||||
if (!player || ((attackedPlayer && (attackedPlayer == player || (player->duel && player->duel->Opponent == attackedPlayer))) || player->InBattleground()))
|
||||
return;
|
||||
|
||||
// check if there any guards that should care about the contested flag on player
|
||||
@@ -17098,7 +17098,7 @@ void Unit::Kill(Unit* killer, Unit* victim, bool durabilityLoss, WeaponAttackTyp
|
||||
// last damage from non duel opponent or opponent controlled creature
|
||||
if (plrVictim->duel)
|
||||
{
|
||||
plrVictim->duel->opponent->CombatStopWithPets(true);
|
||||
plrVictim->duel->Opponent->CombatStopWithPets(true);
|
||||
plrVictim->CombatStopWithPets(true);
|
||||
plrVictim->DuelComplete(DUEL_INTERRUPTED);
|
||||
}
|
||||
@@ -18856,7 +18856,7 @@ void Unit::_ExitVehicle(Position const* exitPosition)
|
||||
Player* player = ToPlayer();
|
||||
|
||||
// If player is on mouted duel and exits the mount should immediatly lose the duel
|
||||
if (player && player->duel && player->duel->isMounted)
|
||||
if (player && player->duel && player->duel->IsMounted)
|
||||
player->DuelComplete(DUEL_FLED);
|
||||
|
||||
// This should be done before dismiss, because there may be some aura removal
|
||||
|
||||
@@ -24,48 +24,48 @@
|
||||
|
||||
void WorldSession::HandleDuelAcceptedOpcode(WorldPacket& recvPacket)
|
||||
{
|
||||
ObjectGuid guid;
|
||||
Player* player;
|
||||
Player* plTarget;
|
||||
|
||||
recvPacket >> guid;
|
||||
|
||||
if (!GetPlayer()->duel) // ignore accept from duel-sender
|
||||
Player* player = GetPlayer();
|
||||
if (!player->duel || player == player->duel->Initiator || player->duel->State != DUEL_STATE_CHALLENGED)
|
||||
return;
|
||||
|
||||
player = GetPlayer();
|
||||
plTarget = player->duel->opponent;
|
||||
ObjectGuid guid;
|
||||
recvPacket >> guid;
|
||||
|
||||
if (player == player->duel->initiator || !plTarget || player == plTarget || player->duel->startTime != 0 || plTarget->duel->startTime != 0)
|
||||
Player* target = player->duel->Opponent;
|
||||
if (target->GetGuidValue(PLAYER_DUEL_ARBITER) != guid)
|
||||
return;
|
||||
|
||||
LOG_DEBUG("network.opcode", "Player 1 is: %s (%s)", player->GetGUID().ToString().c_str(), player->GetName().c_str());
|
||||
LOG_DEBUG("network.opcode", "Player 2 is: %s (%s)", plTarget->GetGUID().ToString().c_str(), plTarget->GetName().c_str());
|
||||
LOG_DEBUG("network.opcode", "Player 2 is: %s (%s)", target->GetGUID().ToString().c_str(), target->GetName().c_str());
|
||||
|
||||
time_t now = time(nullptr);
|
||||
player->duel->startTimer = now;
|
||||
plTarget->duel->startTimer = now;
|
||||
player->duel->StartTime = now + 3;
|
||||
target->duel->StartTime = now + 3;
|
||||
|
||||
player->duel->State = DUEL_STATE_COUNTDOWN;
|
||||
target->duel->State = DUEL_STATE_COUNTDOWN;
|
||||
|
||||
player->SendDuelCountdown(3000);
|
||||
plTarget->SendDuelCountdown(3000);
|
||||
target->SendDuelCountdown(3000);
|
||||
}
|
||||
|
||||
void WorldSession::HandleDuelCancelledOpcode(WorldPacket& recvPacket)
|
||||
{
|
||||
LOG_DEBUG("network", "WORLD: Received CMSG_DUEL_CANCELLED");
|
||||
Player* player = GetPlayer();
|
||||
|
||||
ObjectGuid guid;
|
||||
recvPacket >> guid;
|
||||
|
||||
// no duel requested
|
||||
if (!GetPlayer()->duel)
|
||||
if (!player->duel || player->duel->State == DUEL_STATE_COMPLETED)
|
||||
return;
|
||||
|
||||
// player surrendered in a duel using /forfeit
|
||||
if (GetPlayer()->duel->startTime != 0)
|
||||
if (GetPlayer()->duel->State == DUEL_STATE_IN_PROGRESS)
|
||||
{
|
||||
GetPlayer()->CombatStopWithPets(true);
|
||||
if (GetPlayer()->duel->opponent)
|
||||
GetPlayer()->duel->opponent->CombatStopWithPets(true);
|
||||
GetPlayer()->duel->Opponent->CombatStopWithPets(true);
|
||||
|
||||
GetPlayer()->CastSpell(GetPlayer(), 7267, true); // beg
|
||||
GetPlayer()->DuelComplete(DUEL_WON);
|
||||
|
||||
@@ -5631,7 +5631,7 @@ SpellCastResult Spell::CheckCast(bool strict)
|
||||
{
|
||||
// Xinef: fix for duels
|
||||
Player* player = m_caster->ToPlayer();
|
||||
if (!player || !player->duel || target != player->duel->opponent)
|
||||
if (!player || !player->duel || target != player->duel->Opponent)
|
||||
return SPELL_FAILED_NOTHING_TO_DISPEL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4408,21 +4408,9 @@ void Spell::EffectDuel(SpellEffIndex effIndex)
|
||||
target->GetSession()->SendPacket(&data);
|
||||
|
||||
// create duel-info
|
||||
DuelInfo* duel = new DuelInfo;
|
||||
duel->initiator = caster;
|
||||
duel->opponent = target;
|
||||
duel->startTime = 0;
|
||||
duel->startTimer = 0;
|
||||
duel->isMounted = (GetSpellInfo()->Id == 62875); // Mounted Duel
|
||||
caster->duel = duel;
|
||||
|
||||
DuelInfo* duel2 = new DuelInfo;
|
||||
duel2->initiator = caster;
|
||||
duel2->opponent = caster;
|
||||
duel2->startTime = 0;
|
||||
duel2->startTimer = 0;
|
||||
duel2->isMounted = (GetSpellInfo()->Id == 62875); // Mounted Duel
|
||||
target->duel = duel2;
|
||||
bool isMounted = (GetSpellInfo()->Id == 62875);
|
||||
caster->duel = std::make_unique<DuelInfo>(target, caster, isMounted);
|
||||
target->duel = std::make_unique<DuelInfo>(caster, caster, isMounted);
|
||||
|
||||
caster->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
|
||||
target->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
|
||||
|
||||
@@ -221,7 +221,7 @@ public:
|
||||
areaid == AREA_RING_OF_HORDE_VALIANTS ||
|
||||
areaid == AREA_RING_OF_CHAMPIONS;
|
||||
|
||||
return checkArea && player->duel && player->duel->isMounted;
|
||||
return checkArea && player->duel && player->duel->IsMounted;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user