Skip to content

Commit 1313a6c

Browse files
authored
CountAsLoss + fix CheckStartSolo3v3Arena (#19)
* CountAsLoss + fix CheckStartSolo3v3Arena * restore CheckStartSolo3v3Arena * oops * Update solo3v3_sc.cpp
1 parent ee817a6 commit 1313a6c

File tree

5 files changed

+188
-53
lines changed

5 files changed

+188
-53
lines changed

conf/arena_3v3_solo_queue.conf.dist

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,12 @@ Solo.3v3.FilterTalents = 0
1717
Arena.CheckEquipAndTalents = 0
1818
Arena.3v3.BlockForbiddenTalents = 0
1919
Solo.3v3.CastDeserterOnAfk = 1
20-
Solo.3v3.CastDeserterOnLeave = 0
21-
Solo.3v3.StopGameIncomplete = 0
20+
Solo.3v3.CastDeserterOnLeave = 1
21+
Solo.3v3.StopGameIncomplete = 1
22+
Solo.3v3.RatingPenalty.LeaveDuringMatch = 24
23+
Solo.3v3.RatingPenalty.LeaveBeforeMatchStart = 50
24+
25+
2226
Solo.3v3.MinLevel = 80
2327
Solo.3v3.Cost = 45
2428
Solo.3v3.ArenaPointsMulti = 0.8

src/solo3v3.cpp

Lines changed: 73 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,64 @@ uint32 Solo3v3::GetAverageMMR(ArenaTeam* team)
4141
return matchMakerRating;
4242
}
4343

44+
void Solo3v3::CountAsLoss(Player* player, bool isInProgress)
45+
{
46+
ArenaTeam* plrArenaTeam = sArenaTeamMgr->GetArenaTeamById(player->GetArenaTeamId(ARENA_SLOT_SOLO_3v3));
47+
48+
if (!plrArenaTeam)
49+
return;
50+
51+
int32 ratingLoss = 0;
52+
53+
// leave while arena is in progress
54+
if (isInProgress)
55+
{
56+
ratingLoss = sConfigMgr->GetOption<int32>("Solo.3v3.RatingPenalty.LeaveDuringMatch", 24);
57+
}
58+
// leave while arena is in preparation || don't accept queue || logout while invited
59+
else
60+
{
61+
ratingLoss = sConfigMgr->GetOption<int32>("Solo.3v3.RatingPenalty.LeaveBeforeMatchStart", 50);
62+
}
63+
64+
ArenaTeamStats atStats = plrArenaTeam->GetStats();
65+
66+
if (int32(atStats.Rating) - ratingLoss < 0)
67+
atStats.Rating = 0;
68+
else
69+
atStats.Rating -= ratingLoss;
70+
71+
atStats.SeasonGames += 1;
72+
atStats.WeekGames += 1;
73+
atStats.Rank = 1;
74+
75+
// Update team's rank, start with rank 1 and increase until no team with more rating was found
76+
ArenaTeamMgr::ArenaTeamContainer::const_iterator i = sArenaTeamMgr->GetArenaTeamMapBegin();
77+
for (; i != sArenaTeamMgr->GetArenaTeamMapEnd(); ++i) {
78+
if (i->second->GetType() == ARENA_TEAM_SOLO_3v3 && i->second->GetStats().Rating > atStats.Rating)
79+
++atStats.Rank;
80+
}
81+
82+
for (ArenaTeam::MemberList::iterator itr = plrArenaTeam->GetMembers().begin(); itr != plrArenaTeam->GetMembers().end(); ++itr) {
83+
if (itr->Guid == player->GetGUID()) {
84+
itr->WeekGames = atStats.WeekGames;
85+
itr->SeasonGames = atStats.SeasonGames;
86+
itr->PersonalRating = atStats.Rating;
87+
88+
if (int32(itr->MatchMakerRating) - ratingLoss < 0)
89+
itr->MatchMakerRating = 0;
90+
else
91+
itr->MatchMakerRating -= ratingLoss;
92+
93+
break;
94+
}
95+
}
96+
97+
plrArenaTeam->SetArenaTeamStats(atStats);
98+
plrArenaTeam->NotifyStatsChanged();
99+
plrArenaTeam->SaveToDB(true);
100+
}
101+
44102
void Solo3v3::CleanUp3v3SoloQ(Battleground* bg)
45103
{
46104
// Cleanup temp arena teams for solo 3v3
@@ -65,50 +123,31 @@ void Solo3v3::CleanUp3v3SoloQ(Battleground* bg)
65123

66124
void Solo3v3::CheckStartSolo3v3Arena(Battleground* bg)
67125
{
68-
// Fix crash with Arena Replay module
126+
bool someoneNotInArena = false;
127+
uint32 PlayersInArena = 0;
128+
69129
for (const auto& playerPair : bg->GetPlayers())
70130
{
71131
Player* player = playerPair.second;
72-
if (player->IsSpectator())
73-
return;
74-
}
75132

76-
if (bg->GetArenaType() != ARENA_TYPE_3v3_SOLO)
77-
return;
78-
79-
if (bg->GetStatus() != STATUS_IN_PROGRESS)
80-
return; // if CheckArenaWinConditions ends the game
81-
82-
bool someoneNotInArena = false;
133+
if (!player)
134+
continue;
83135

84-
ArenaTeam* team[2];
85-
team[0] = sArenaTeamMgr->GetArenaTeamById(bg->GetArenaTeamIdForTeam(TEAM_ALLIANCE));
86-
team[1] = sArenaTeamMgr->GetArenaTeamById(bg->GetArenaTeamIdForTeam(TEAM_HORDE));
136+
// Fix crash with Arena Replay module
137+
if (player->IsSpectator())
138+
return;
87139

88-
ASSERT(team[0] && team[1]);
140+
PlayersInArena++;
141+
}
89142

90-
for (int i = 0; i < 2; i++)
143+
uint32 AmountPlayersSolo3v3 = 6;
144+
if (PlayersInArena < AmountPlayersSolo3v3)
91145
{
92-
for (auto const& itr : team[i]->GetMembers())
93-
{
94-
Player* plr = ObjectAccessor::FindPlayer(itr.Guid);
95-
if (!plr)
96-
{
97-
someoneNotInArena = true;
98-
continue;
99-
}
100-
101-
if (plr->GetInstanceId() != bg->GetInstanceID())
102-
{
103-
if (sConfigMgr->GetOption<bool>("Solo.3v3.CastDeserterOnAfk", true))
104-
plr->CastSpell(plr, 26013, true); // Deserter
105-
106-
someoneNotInArena = true;
107-
}
108-
}
146+
someoneNotInArena = true;
109147
}
110148

111-
if (someoneNotInArena && sConfigMgr->GetOption<bool>("Solo.3v3.StopGameIncomplete", false))
149+
// if one player didn't enter arena and StopGameIncomplete is true, then end arena
150+
if (someoneNotInArena && sConfigMgr->GetOption<bool>("Solo.3v3.StopGameIncomplete", true))
112151
{
113152
bg->SetRated(false);
114153
bg->EndBattleground(TEAM_NEUTRAL);

src/solo3v3.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ class Solo3v3
127127
void CleanUp3v3SoloQ(Battleground* bg);
128128
bool CheckSolo3v3Arena(BattlegroundQueue* queue, BattlegroundBracketId bracket_id, bool isRated);
129129
void CreateTempArenaTeamForQueue(BattlegroundQueue* queue, ArenaTeam* arenaTeams[]);
130+
void CountAsLoss(Player* player, bool isInProgress);
130131

131132
// Return false, if player have invested more than 35 talentpoints in a forbidden talenttree.
132133
bool Arena3v3CheckTalents(Player* player);

src/solo3v3_sc.cpp

Lines changed: 105 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ bool NpcSolo3v3::OnGossipSelect(Player* player, Creature* creature, uint32 /*sen
106106
}
107107
else
108108
{
109-
ChatHandler(player->GetSession()).PSendSysMessage("You need level %u+ to create an arena team.", sConfigMgr->GetOption<uint32>("Solo.3v3.MinLevel", 80));
109+
ChatHandler(player->GetSession()).PSendSysMessage("You need level {}+ to create an arena team.", sConfigMgr->GetOption<uint32>("Solo.3v3.MinLevel", 80));
110110
}
111111

112112
CloseGossipMenuFor(player);
@@ -180,6 +180,19 @@ bool NpcSolo3v3::OnGossipSelect(Player* player, Creature* creature, uint32 /*sen
180180

181181
ChatHandler(player->GetSession()).PSendSysMessage("{}", s.str().c_str());
182182
CloseGossipMenuFor(player);
183+
184+
ArenaTeam::MemberList::iterator itr;
185+
for (itr = at->GetMembers().begin(); itr != at->GetMembers().end(); ++itr)
186+
{
187+
if (itr->Guid == player->GetGUID())
188+
{
189+
std::stringstream s;
190+
s << "\nSolo MMR: " << itr->MatchMakerRating;
191+
192+
ChatHandler(player->GetSession()).PSendSysMessage("{}", s.str().c_str());
193+
break;
194+
}
195+
}
183196
}
184197

185198
return true;
@@ -519,14 +532,6 @@ bool Solo3v3BG::OnQueueUpdateValidity(BattlegroundQueue* /* queue */, uint32 /*d
519532
return true;
520533
}
521534

522-
void Solo3v3BG::OnBattlegroundUpdate(Battleground* bg, uint32 /*diff*/)
523-
{
524-
if (bg->GetStatus() != STATUS_IN_PROGRESS || !bg->isArena())
525-
return;
526-
527-
sSolo->CheckStartSolo3v3Arena(bg);
528-
}
529-
530535
void Solo3v3BG::OnBattlegroundDestroy(Battleground* bg)
531536
{
532537
sSolo->CleanUp3v3SoloQ(bg);
@@ -536,7 +541,8 @@ void Solo3v3BG::OnBattlegroundEndReward(Battleground* bg, Player* player, TeamId
536541
{
537542
if (bg->isRated() && bg->GetArenaType() == ARENA_TYPE_3v3_SOLO)
538543
{
539-
ArenaTeam* plrArenaTeam = sArenaTeamMgr->GetArenaTeamByCaptain(player->GetGUID(), ARENA_TYPE_3v3_SOLO);
544+
// this way we always get the correct solo team (sometimes when using GetArenaTeamByCaptain inside solo arena it can return a teamID >= 4293918720)
545+
ArenaTeam* plrArenaTeam = sArenaTeamMgr->GetArenaTeamById(player->GetArenaTeamId(ARENA_SLOT_SOLO_3v3));
540546

541547
if (!plrArenaTeam)
542548
return;
@@ -572,13 +578,10 @@ void Solo3v3BG::OnBattlegroundEndReward(Battleground* bg, Player* player, TeamId
572578
atStats.Rank = 1;
573579
ArenaTeamMgr::ArenaTeamContainer::const_iterator i = sArenaTeamMgr->GetArenaTeamMapBegin();
574580
for (; i != sArenaTeamMgr->GetArenaTeamMapEnd(); ++i) {
575-
if (i->second->GetType() == ARENA_TYPE_3v3_SOLO && i->second->GetStats().Rating > atStats.Rating)
581+
if (i->second->GetType() == ARENA_TEAM_SOLO_3v3 && i->second->GetStats().Rating > atStats.Rating)
576582
++atStats.Rank;
577583
}
578584

579-
plrArenaTeam->SetArenaTeamStats(atStats);
580-
plrArenaTeam->NotifyStatsChanged();
581-
582585
for (ArenaTeam::MemberList::iterator itr = plrArenaTeam->GetMembers().begin(); itr != plrArenaTeam->GetMembers().end(); ++itr)
583586
{
584587
if (itr->Guid == player->GetGUID())
@@ -607,6 +610,8 @@ void Solo3v3BG::OnBattlegroundEndReward(Battleground* bg, Player* player, TeamId
607610

608611
}
609612

613+
plrArenaTeam->SetArenaTeamStats(atStats);
614+
plrArenaTeam->NotifyStatsChanged();
610615
plrArenaTeam->SaveToDB(true);
611616
}
612617
}
@@ -653,9 +658,94 @@ void Team3v3arena::OnQueueIdToArenaType(const BattlegroundQueueTypeId _bgQueueTy
653658
}
654659
}
655660

661+
void Arena_SC::OnArenaStart(Battleground* bg)
662+
{
663+
if (bg->GetArenaType() != ARENA_TYPE_3v3_SOLO)
664+
return;
665+
666+
sSolo->CheckStartSolo3v3Arena(bg);
667+
}
668+
669+
void PlayerScript3v3Arena::OnBattlegroundDesertion(Player* player, const BattlegroundDesertionType type)
670+
{
671+
Battleground* bg = ((BattlegroundMap*)player->FindMap())->GetBG();
672+
673+
switch (type)
674+
{
675+
case ARENA_DESERTION_TYPE_LEAVE_BG:
676+
677+
if (bg->GetArenaType() == ARENA_TYPE_3v3_SOLO)
678+
{
679+
if (bg->GetStatus() == STATUS_WAIT_JOIN)
680+
{
681+
if (sConfigMgr->GetOption<bool>("Solo.3v3.CastDeserterOnAfk", true) || sConfigMgr->GetOption<bool>("Solo.3v3.CastDeserterOnLeave", true))
682+
player->CastSpell(player, 26013, true);
683+
684+
// end arena if a player leaves while in preparation
685+
if (sConfigMgr->GetOption<bool>("Solo.3v3.StopGameIncomplete", true))
686+
{
687+
bg->SetRated(false);
688+
bg->EndBattleground(TEAM_NEUTRAL);
689+
}
690+
691+
sSolo->CountAsLoss(player, false);
692+
}
693+
694+
if (bg->GetStatus() == STATUS_IN_PROGRESS)
695+
sSolo->CountAsLoss(player, true);
696+
}
697+
break;
698+
699+
case ARENA_DESERTION_TYPE_NO_ENTER_BUTTON: // called if player doesn't click 'enter arena' for solo 3v3
700+
701+
if (player->IsInvitedForBattlegroundQueueType((BattlegroundQueueTypeId)BATTLEGROUND_QUEUE_3v3_SOLO))
702+
{
703+
if (sConfigMgr->GetOption<bool>("Solo.3v3.CastDeserterOnAfk", true))
704+
player->CastSpell(player, 26013, true);
705+
706+
sSolo->CountAsLoss(player, false);
707+
}
708+
break;
709+
710+
case ARENA_DESERTION_TYPE_INVITE_LOGOUT: // called if player logout when solo 3v3 queue pops (it removes the queue)
711+
712+
if (player->IsInvitedForBattlegroundQueueType((BattlegroundQueueTypeId)BATTLEGROUND_QUEUE_3v3_SOLO))
713+
{
714+
if (sConfigMgr->GetOption<bool>("Solo.3v3.CastDeserterOnAfk", true) || sConfigMgr->GetOption<bool>("Solo.3v3.CastDeserterOnLeave", true))
715+
player->CastSpell(player, 26013, true);
716+
717+
sSolo->CountAsLoss(player, false);
718+
}
719+
break;
720+
721+
/*
722+
case ARENA_DESERTION_TYPE_LEAVE_QUEUE: // called if player uses macro to leave queue when it pops. /run AcceptBattlefieldPort(1, 0);
723+
724+
// I believe these are being called AFTER the player removes the queue, so we can't know his queue
725+
if (player->IsInvitedForBattlegroundQueueType((BattlegroundQueueTypeId)BATTLEGROUND_QUEUE_3v3_SOLO))
726+
{
727+
LOG_ERROR("solo3v3", "IsInvitedForBattlegroundQueueType BATTLEGROUND_QUEUE_3v3_SOLO");
728+
sSolo->CountAsLoss(player, false);
729+
730+
}
731+
else if (player->InBattlegroundQueueForBattlegroundQueueType((BattlegroundQueueTypeId)BATTLEGROUND_QUEUE_3v3_SOLO))
732+
{
733+
LOG_ERROR("solo3v3", "InBattlegroundQueueForBattlegroundQueueType BATTLEGROUND_QUEUE_3v3_SOLO");
734+
}
735+
else
736+
{
737+
LOG_ERROR("solo3v3", "ARENA_DESERTION_TYPE_LEAVE_QUEUE - else");
738+
}
739+
*/
740+
741+
default:
742+
break;
743+
}
744+
}
745+
656746
void PlayerScript3v3Arena::OnLogin(Player* pPlayer)
657747
{
658-
if (sConfigMgr->GetOption<bool>("Solo.3v3.Enable", false)) {
748+
if (sConfigMgr->GetOption<bool>("Solo.3v3.ShowMessageOnLogin", false)) {
659749
ChatHandler(pPlayer->GetSession()).SendSysMessage("This server is running the |cff4CFF00Arena solo Q 3v3 |rmodule.");
660750
}
661751
}
@@ -709,7 +799,6 @@ bool PlayerScript3v3Arena::NotSetArenaTeamInfoField(Player* player, uint8 slot,
709799
return true;
710800
}
711801

712-
713802
bool PlayerScript3v3Arena::CanBattleFieldPort(Player* player, uint8 arenaType, BattlegroundTypeId BGTypeID, uint8 /*action*/)
714803
{
715804
if (!player)

src/solo3v3_sc.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ class Solo3v3BG : public AllBattlegroundScript
7070
uint32 oldTeamRatingHorde;
7171

7272
void OnQueueUpdate(BattlegroundQueue* queue, uint32 /*diff*/, BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id, uint8 arenaType, bool isRated, uint32 /*arenaRatedTeamId*/) override;
73-
void OnBattlegroundUpdate(Battleground* bg, uint32 /*diff*/) override;
7473
bool OnQueueUpdateValidity(BattlegroundQueue* /* queue */, uint32 /*diff*/, BattlegroundTypeId /* bgTypeId */, BattlegroundBracketId /* bracket_id */, uint8 arenaType, bool /* isRated */, uint32 /*arenaRatedTeamId*/) override;
7574
void OnBattlegroundDestroy(Battleground* bg) override;
7675
void OnBattlegroundEndReward(Battleground* bg, Player* player, TeamId /* winnerTeamId */) override;
@@ -106,6 +105,7 @@ class PlayerScript3v3Arena : public PlayerScript
106105
void OnGetArenaTeamId(Player* player, uint8 slot, uint32& result) override;
107106
bool NotSetArenaTeamInfoField(Player* player, uint8 slot, ArenaTeamInfoType type, uint32 value) override;
108107
bool CanBattleFieldPort(Player* player, uint8 arenaType, BattlegroundTypeId BGTypeID, uint8 action) override;
108+
void OnBattlegroundDesertion(Player* player, const BattlegroundDesertionType type) override;
109109
};
110110

111111
class Arena_SC : public ArenaScript
@@ -143,6 +143,8 @@ class Arena_SC : public ArenaScript
143143

144144
return true;
145145
}
146+
147+
void OnArenaStart(Battleground* bg) override;
146148
};
147149

148150
class Solo3v3Spell : public SpellSC

0 commit comments

Comments
 (0)