Changeset 9 for trunk/src/game/BattleGround.cpp
- Timestamp:
- 11/19/08 13:22:41 (17 years ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/game/BattleGround.cpp
r2 r9 25 25 #include "Chat.h" 26 26 #include "SpellAuras.h" 27 #include "ArenaTeam.h" 27 28 #include "World.h" 28 29 #include "Util.h" … … 48 49 m_LevelMin = 0; 49 50 m_LevelMax = 0; 51 m_InBGFreeSlotQueue = false; 52 m_SetDeleteThis = false; 50 53 51 54 m_MaxPlayersPerTeam = 0; … … 68 71 m_TeamStartLocO[BG_TEAM_HORDE] = 0; 69 72 73 m_ArenaTeamIds[BG_TEAM_ALLIANCE] = 0; 74 m_ArenaTeamIds[BG_TEAM_HORDE] = 0; 75 76 m_ArenaTeamRatingChanges[BG_TEAM_ALLIANCE] = 0; 77 m_ArenaTeamRatingChanges[BG_TEAM_HORDE] = 0; 78 70 79 m_BgRaids[BG_TEAM_ALLIANCE] = NULL; 71 80 m_BgRaids[BG_TEAM_HORDE] = NULL; … … 73 82 m_PlayersCount[BG_TEAM_ALLIANCE] = 0; 74 83 m_PlayersCount[BG_TEAM_HORDE] = 0; 84 85 m_PrematureCountDown = false; 86 m_PrematureCountDown = 0; 75 87 } 76 88 77 89 BattleGround::~BattleGround() 78 90 { 79 91 // remove objects and creatures 92 // (this is done automatically in mapmanager update, when the instance is reset after the reset time) 93 int size = m_BgCreatures.size(); 94 for(int i = 0; i < size; ++i) 95 { 96 DelCreature(i); 97 } 98 size = m_BgObjects.size(); 99 for(int i = 0; i < size; ++i) 100 { 101 DelObject(i); 102 } 103 104 // delete creature and go respawn times 105 WorldDatabase.PExecute("DELETE FROM creature_respawn WHERE instance = '%u'",GetInstanceID()); 106 WorldDatabase.PExecute("DELETE FROM gameobject_respawn WHERE instance = '%u'",GetInstanceID()); 107 // delete instance from db 108 CharacterDatabase.PExecute("DELETE FROM instance WHERE id = '%u'",GetInstanceID()); 109 // remove from battlegrounds 110 sBattleGroundMgr.RemoveBattleGround(GetInstanceID()); 111 // unload map 112 if(Map * map = MapManager::Instance().FindMap(GetMapId(), GetInstanceID())) 113 if(map->IsBattleGroundOrArena()) 114 ((BattleGroundMap*)map)->SetUnload(); 115 // remove from bg free slot queue 116 this->RemoveFromBGFreeSlotQueue(); 80 117 } 81 118 82 119 void BattleGround::Update(time_t diff) 83 120 { 84 85 121 if(!GetPlayersSize() && !GetRemovedPlayersSize() && !GetReviveQueueSize()) 86 122 //BG is empty … … 189 225 } 190 226 227 // if less then minimum players are in on one side, then start premature finish timer 228 if(GetStatus() == STATUS_IN_PROGRESS && !isArena() && sBattleGroundMgr.GetPrematureFinishTime() && (GetPlayersCountByTeam(ALLIANCE) < GetMinPlayersPerTeam() || GetPlayersCountByTeam(HORDE) < GetMinPlayersPerTeam())) 229 { 230 if(!m_PrematureCountDown) 231 { 232 m_PrematureCountDown = true; 233 m_PrematureCountDownTimer = sBattleGroundMgr.GetPrematureFinishTime(); 234 SendMessageToAll(LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING); 235 } 236 else if(m_PrematureCountDownTimer < diff) 237 { 238 // time's up! 239 EndBattleGround(0); // noone wins 240 m_PrematureCountDown = false; 241 } 242 else 243 { 244 uint32 newtime = m_PrematureCountDownTimer - diff; 245 // announce every minute 246 if(m_PrematureCountDownTimer != sBattleGroundMgr.GetPrematureFinishTime() && newtime / 60000 != m_PrematureCountDownTimer / 60000) 247 SendMessageToAll(LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING); 248 m_PrematureCountDownTimer = newtime; 249 } 250 } 251 else if (m_PrematureCountDown) 252 m_PrematureCountDown = false; 253 191 254 if(GetStatus() == STATUS_WAIT_LEAVE) 192 255 { … … 240 303 continue; 241 304 242 if(plr->GetTeam() == TeamID) 305 uint32 team = itr->second.Team;//GetPlayerTeam(plr->GetGUID()); 306 307 if(team == TeamID) 243 308 plr->GetSession()->SendPacket(packet); 244 309 } … … 266 331 } 267 332 268 if(plr->GetTeam() == TeamID) 333 uint32 team = itr->second.Team;//GetPlayerTeam(plr->GetGUID()); 334 335 if(team == TeamID) 269 336 { 270 337 sBattleGroundMgr.BuildPlaySoundPacket(&data, SoundID); … … 286 353 } 287 354 288 if(plr->GetTeam() == TeamID) 355 uint32 team = itr->second.Team;//GetPlayerTeam(plr->GetGUID()); 356 357 if(team == TeamID) 289 358 plr->CastSpell(plr, SpellID, true); 290 359 } … … 303 372 } 304 373 305 if(plr->GetTeam() == TeamID) 374 uint32 team = itr->second.Team;//GetPlayerTeam(plr->GetGUID()); 375 376 if(team == TeamID) 306 377 UpdatePlayerScore(plr, SCORE_BONUS_HONOR, Honor); 307 378 } … … 325 396 } 326 397 327 if(plr->GetTeam() == TeamID) 398 uint32 team = itr->second.Team;//GetPlayerTeam(plr->GetGUID()); 399 400 if(team == TeamID) 328 401 plr->ModifyFactionReputation(factionEntry, Reputation); 329 402 } … … 346 419 void BattleGround::EndBattleGround(uint32 winner) 347 420 { 421 // battleground finished, remove from the running bg's list 422 this->RemoveFromBGFreeSlotQueue(); 423 424 ArenaTeam * winner_arena_team = NULL; 425 ArenaTeam * loser_arena_team = NULL; 426 uint32 loser_rating = 0; 427 uint32 winner_rating = 0; 348 428 WorldPacket data; 349 429 Player *Source = NULL; … … 352 432 if(winner == ALLIANCE) 353 433 { 354 winmsg = GetMangosString(LANG_BG_A_WINS); 434 if(isBattleGround()) 435 winmsg = GetMangosString(LANG_BG_A_WINS); 436 else 437 winmsg = GetMangosString(LANG_ARENA_GOLD_WINS); 355 438 356 439 PlaySoundToAll(SOUND_ALLIANCE_WINS); // alliance wins sound … … 358 441 SetWinner(WINNER_ALLIANCE); 359 442 } 443 else if(winner == HORDE) 444 { 445 if(isBattleGround()) 446 winmsg = GetMangosString(LANG_BG_H_WINS); 447 else 448 winmsg = GetMangosString(LANG_ARENA_GREEN_WINS); 449 450 PlaySoundToAll(SOUND_HORDE_WINS); // horde wins sound 451 452 SetWinner(WINNER_HORDE); 453 } 360 454 else 361 455 { 362 winmsg = GetMangosString(LANG_BG_H_WINS); 363 364 PlaySoundToAll(SOUND_HORDE_WINS); // horde wins sound 365 366 SetWinner(WINNER_HORDE); 456 SetWinner(3); 367 457 } 368 458 … … 370 460 m_EndTime = 0; 371 461 462 // arena rating calculation 463 if(isArena() && isRated()) 464 { 465 if(winner == ALLIANCE) 466 { 467 winner_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(ALLIANCE)); 468 loser_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(HORDE)); 469 } 470 else if(winner == HORDE) 471 { 472 winner_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(HORDE)); 473 loser_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(ALLIANCE)); 474 } 475 if(winner_arena_team && loser_arena_team) 476 { 477 loser_rating = loser_arena_team->GetStats().rating; 478 winner_rating = winner_arena_team->GetStats().rating; 479 float winner_chance = winner_arena_team->GetChanceAgainst(loser_rating); 480 float loser_chance = loser_arena_team->GetChanceAgainst(winner_rating); 481 int32 winner_change = winner_arena_team->WonAgainstChance(winner_chance); 482 int32 loser_change = loser_arena_team->LostAgainstChance(loser_chance); 483 sLog.outDebug("--- %u ; %u ; %d ; %d ; %u ; %u ---",winner_rating,loser_rating,winner_chance,loser_chance,winner_change,loser_change); 484 if(winner == ALLIANCE) 485 { 486 SetArenaTeamRatingChangeForTeam(ALLIANCE, winner_change); 487 SetArenaTeamRatingChangeForTeam(HORDE, loser_change); 488 } 489 else 490 { 491 SetArenaTeamRatingChangeForTeam(HORDE, winner_change); 492 SetArenaTeamRatingChangeForTeam(ALLIANCE, loser_change); 493 } 494 } 495 else 496 { 497 SetArenaTeamRatingChangeForTeam(ALLIANCE, 0); 498 SetArenaTeamRatingChangeForTeam(HORDE, 0); 499 } 500 } 501 372 502 for(std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) 373 503 { … … 379 509 } 380 510 511 // should remove spirit of redemption 512 if(plr->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION)) 513 plr->RemoveSpellsCausingAura(SPELL_AURA_MOD_SHAPESHIFT); 514 381 515 if(!plr->isAlive()) 382 516 { … … 385 519 } 386 520 387 if(plr->GetTeam() == winner) 521 uint32 team = itr->second.Team;//GetPlayerTeam(plr->GetGUID()); 522 if(!team) team = plr->GetTeam(); 523 524 // per player calculation 525 if(isArena() && isRated() && winner_arena_team && loser_arena_team) 526 { 527 if(team == winner) 528 winner_arena_team->MemberWon(plr,loser_rating); 529 else 530 loser_arena_team->MemberLost(plr,winner_rating); 531 } 532 533 if(team == winner) 388 534 { 389 535 if(!Source) … … 405 551 plr->GetSession()->SendPacket(&data); 406 552 407 sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetTeam(), plr->GetBattleGroundQueueIndex(m_TypeID), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime()); 553 uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(GetTypeID(), GetArenaType()); 554 sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetTeam(), plr->GetBattleGroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime()); 408 555 plr->GetSession()->SendPacket(&data); 409 556 } 557 558 if(isArena() && isRated() && winner_arena_team && loser_arena_team) 559 { 560 // update arena points only after increasing the player's match count! 561 winner_arena_team->UpdateArenaPointsHelper(); 562 loser_arena_team->UpdateArenaPointsHelper(); 563 // save the stat changes 564 winner_arena_team->SaveToDB(); 565 loser_arena_team->SaveToDB(); 566 // send updated arena team stats to players 567 // this way all arena team members will get notified, not only the ones who participated in this match 568 winner_arena_team->NotifyStatsChanged(); 569 loser_arena_team->NotifyStatsChanged(); 570 } 571 572 // inform invited players about the removal 573 sBattleGroundMgr.m_BattleGroundQueues[sBattleGroundMgr.BGQueueTypeId(GetTypeID(), GetArenaType())].BGEndedRemoveInvites(this); 410 574 411 575 if(Source) … … 559 723 void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPacket) 560 724 { 725 uint32 team = GetPlayerTeam(guid); 726 bool participant = false; 561 727 // Remove from lists/maps 562 728 std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.find(guid); 563 729 if(itr != m_Players.end()) 564 730 { 565 UpdatePlayersCountByTeam( itr->second.Team, true); // -1 player731 UpdatePlayersCountByTeam(team, true); // -1 player 566 732 m_Players.erase(itr); 733 // check if the player was a participant of the match, or only entered through gm command (goname) 734 participant = true; 567 735 } 568 736 … … 578 746 Player *plr = objmgr.GetPlayer(guid); 579 747 748 // should remove spirit of redemption 749 if(plr && plr->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION)) 750 plr->RemoveSpellsCausingAura(SPELL_AURA_MOD_SHAPESHIFT); 751 580 752 if(plr && !plr->isAlive()) // resurrect on exit 581 753 { … … 590 762 plr->ClearAfkReports(); 591 763 592 if(isArena()) 593 { 594 if(!sWorld.IsFFAPvPRealm()) 595 plr->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP); 596 } 597 598 WorldPacket data; 599 if(SendPacket) 600 { 601 sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetTeam(), plr->GetBattleGroundQueueIndex(m_TypeID), STATUS_NONE, 0, 0); 602 plr->GetSession()->SendPacket(&data); 603 } 604 605 // this call is important, because player, when joins to battleground, this method is not called, so it must be called when leaving bg 606 plr->RemoveBattleGroundQueueId(m_TypeID); 607 608 DecreaseInvitedCount(plr->GetTeam()); 609 //we should update battleground queue, but only if bg isn't ending 610 if (GetQueueType() < MAX_BATTLEGROUND_QUEUES) 611 sBattleGroundMgr.m_BattleGroundQueues[GetTypeID()].Update(GetTypeID(), GetQueueType()); 612 613 if(!plr->GetBattleGroundId()) 614 return; 615 616 Group * group = plr->GetGroup(); 617 618 // remove from raid group if exist 619 if(group && group == GetBgRaid(plr->GetTeam())) 620 { 621 if(!group->RemoveMember(guid, 0)) // group was disbanded 764 if(participant) // if the player was a match participant, remove auras, calc rating, update queue 765 { 766 if(!team) team = plr->GetTeam(); 767 768 uint32 bgTypeId = GetTypeID(); 769 uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(GetTypeID(), GetArenaType()); 770 // if arena, remove the specific arena auras 771 if(isArena()) 622 772 { 623 SetBgRaid(plr->GetTeam(), NULL); 624 delete group; 773 plr->RemoveArenaAuras(true); // removes debuffs / dots etc., we don't want the player to die after porting out 774 bgTypeId=BATTLEGROUND_AA; // set the bg type to all arenas (it will be used for queue refreshing) 775 776 // summon old pet if there was one and there isn't a current pet 777 if(!plr->GetPet() && plr->GetTemporaryUnsummonedPetNumber()) 778 { 779 Pet* NewPet = new Pet; 780 if(!NewPet->LoadPetFromDB(plr, 0, (plr)->GetTemporaryUnsummonedPetNumber(), true)) 781 delete NewPet; 782 783 (plr)->SetTemporaryUnsummonedPetNumber(0); 784 } 785 786 if(isRated() && GetStatus() == STATUS_IN_PROGRESS) 787 { 788 //left a rated match while the encounter was in progress, consider as loser 789 ArenaTeam * winner_arena_team = 0; 790 ArenaTeam * loser_arena_team = 0; 791 if(team == HORDE) 792 { 793 winner_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(ALLIANCE)); 794 loser_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(HORDE)); 795 } 796 else 797 { 798 winner_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(HORDE)); 799 loser_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(ALLIANCE)); 800 } 801 if(winner_arena_team && loser_arena_team) 802 { 803 loser_arena_team->MemberLost(plr,winner_arena_team->GetRating()); 804 } 805 } 625 806 } 807 808 WorldPacket data; 809 if(SendPacket) 810 { 811 sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, team, plr->GetBattleGroundQueueIndex(bgQueueTypeId), STATUS_NONE, 0, 0); 812 plr->GetSession()->SendPacket(&data); 813 } 814 815 // this call is important, because player, when joins to battleground, this method is not called, so it must be called when leaving bg 816 plr->RemoveBattleGroundQueueId(bgQueueTypeId); 817 818 DecreaseInvitedCount(team); 819 //we should update battleground queue, but only if bg isn't ending 820 if (GetQueueType() < MAX_BATTLEGROUND_QUEUES) 821 sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, GetQueueType()); 822 823 Group * group = plr->GetGroup(); 824 // remove from raid group if exist 825 if(group && group == GetBgRaid(team)) 826 { 827 if(!group->RemoveMember(guid, 0)) // group was disbanded 828 { 829 SetBgRaid(team, NULL); 830 delete group; 831 } 832 } 833 834 // Let others know 835 sBattleGroundMgr.BuildPlayerLeftBattleGroundPacket(&data, plr); 836 SendPacketToTeam(team, &data, plr, false); 626 837 } 627 838 628 839 // Do next only if found in battleground 629 840 plr->SetBattleGroundId(0); // We're not in BG. 630 631 // Let others know 632 sBattleGroundMgr.BuildPlayerLeftBattleGroundPacket(&data, plr); 633 SendPacketToTeam(plr->GetTeam(), &data, plr, false); 841 // reset destination bg team 842 plr->SetBGTeam(0); 634 843 635 844 if(Transport) 636 845 { 637 846 plr->TeleportTo(plr->GetBattleGroundEntryPointMap(), plr->GetBattleGroundEntryPointX(), plr->GetBattleGroundEntryPointY(), plr->GetBattleGroundEntryPointZ(), plr->GetBattleGroundEntryPointO()); 638 //sLog.outDetail("BATTLEGROUND: Sending %s to %f,%f,%f,%f", pl->GetName(), x,y,z,O);639 847 } 640 848 … … 643 851 } 644 852 645 /// there will be code which will add battleground to BGFreeSlotQueue , when battleground instance will exist 646 // we always should check if BG is in that queue before adding.. 647 648 if(!GetPlayersSize()) 649 { 650 Reset(); 651 } 853 if(!GetPlayersSize() && !GetInvitedCount(HORDE) && !GetInvitedCount(ALLIANCE)) 854 { 855 // if no players left AND no invitees left, set this bg to delete in next update 856 // direct deletion could cause crashes 857 m_SetDeleteThis = true; 858 // return to prevent addition to freeslotqueue 859 return; 860 } 861 862 // a player exited the battleground, so there are free slots. add to queue 863 this->AddToBGFreeSlotQueue(); 652 864 } 653 865 … … 661 873 SetEndTime(0); 662 874 SetLastResurrectTime(0); 875 SetArenaType(0); 876 SetRated(false); 663 877 664 878 m_Events = 0; … … 669 883 m_InvitedAlliance = 0; 670 884 m_InvitedHorde = 0; 885 m_InBGFreeSlotQueue = false; 671 886 672 887 m_Players.clear(); 673 888 m_PlayerScores.clear(); 674 889 675 // reset BGSubclass 890 // reset BGSubclass (this cleans up creatures and gos as well) 676 891 this->ResetBGSubclass(); 677 892 } … … 699 914 m_Players[guid] = bp; 700 915 701 UpdatePlayersCountByTeam(team, false); 916 UpdatePlayersCountByTeam(team, false); // +1 player 702 917 703 918 WorldPacket data; … … 705 920 SendPacketToTeam(team, &data, plr, false); 706 921 922 // add arena specific auras 707 923 if(isArena()) 708 924 { 925 // remove auras first, only then reset spell cooldowns 926 // this is to prevent bugging amp. curse, combustion, etc. like spells 927 plr->RemoveArenaAuras(); 709 928 plr->RemoveArenaSpellCooldowns(); 710 //plr->RemoveArenaAuras();711 929 plr->RemoveAllEnchantments(TEMP_ENCHANTMENT_SLOT); 712 930 if(team == ALLIANCE && plr->GetTeam() == ALLIANCE) … … 720 938 plr->DestroyConjuredItems(true); 721 939 940 Pet* pet = plr->GetPet(); 941 if(pet) 942 { 943 if(pet->getPetType() == SUMMON_PET || pet->getPetType() == HUNTER_PET) 944 { 945 (plr)->SetTemporaryUnsummonedPetNumber(pet->GetCharmInfo()->GetPetNumber()); 946 (plr)->SetOldPetSpell(pet->GetUInt32Value(UNIT_CREATED_BY_SPELL)); 947 } 948 (plr)->RemovePet(NULL,PET_SAVE_NOT_IN_SLOT); 949 } 950 722 951 if(GetStatus() == STATUS_WAIT_JOIN) // not started yet 723 952 { … … 734 963 } 735 964 736 if(isArena())737 plr->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP);738 739 965 // Log 740 966 sLog.outDetail("BATTLEGROUND: Player %s joined the battle.", plr->GetName()); … … 744 970 void BattleGround::AddToBGFreeSlotQueue() 745 971 { 746 sBattleGroundMgr.BGFreeSlotQueue[m_TypeID].push_front(this); 972 // make sure to add only once 973 if(!m_InBGFreeSlotQueue) 974 { 975 sBattleGroundMgr.BGFreeSlotQueue[m_TypeID].push_front(this); 976 m_InBGFreeSlotQueue = true; 977 } 747 978 } 748 979 … … 750 981 void BattleGround::RemoveFromBGFreeSlotQueue() 751 982 { 752 /* uncomment this code when battlegrounds will work like instances 983 // set to be able to re-add if needed 984 m_InBGFreeSlotQueue = false; 985 // uncomment this code when battlegrounds will work like instances 753 986 for (std::deque<BattleGround*>::iterator itr = sBattleGroundMgr.BGFreeSlotQueue[m_TypeID].begin(); itr != sBattleGroundMgr.BGFreeSlotQueue[m_TypeID].end(); ++itr) 754 987 { … … 758 991 return; 759 992 } 760 }*/ 761 } 762 763 /* 764 this method should decide, if we can invite new player of certain team to BG, it is based on BATTLEGROUND_STATUS 765 */ 766 bool BattleGround::HasFreeSlotsForTeam(uint32 Team) const 993 } 994 } 995 996 // get the number of free slots for team 997 // works in similar way that HasFreeSlotsForTeam did, but this is needed for join as group 998 uint32 BattleGround::GetFreeSlotsForTeam(uint32 Team) const 767 999 { 768 1000 //if BG is starting ... invite anyone: 769 1001 if (GetStatus() == STATUS_WAIT_JOIN) 770 return GetInvitedCount(Team) < GetMaxPlayersPerTeam();1002 return (GetInvitedCount(Team) < GetMaxPlayersPerTeam()) ? GetMaxPlayersPerTeam() - GetInvitedCount(Team) : 0; 771 1003 //if BG is already started .. do not allow to join too much players of one faction 772 1004 uint32 otherTeam; 1005 uint32 otherIn; 773 1006 if (Team == ALLIANCE) 1007 { 774 1008 otherTeam = GetInvitedCount(HORDE); 1009 otherIn = GetPlayersCountByTeam(HORDE); 1010 } 775 1011 else 1012 { 776 1013 otherTeam = GetInvitedCount(ALLIANCE); 1014 otherIn = GetPlayersCountByTeam(ALLIANCE); 1015 } 777 1016 if (GetStatus() == STATUS_IN_PROGRESS) 778 return (GetInvitedCount(Team) <= otherTeam && GetInvitedCount(Team) < GetMaxPlayersPerTeam()); 779 780 return false; 781 } 782 783 /* this method isn't called already, it will be useful when more battlegrounds of one type will be available */ 1017 { 1018 // difference based on ppl invited (not necessarily entered battle) 1019 // default: allow 0 1020 uint32 diff = 0; 1021 // allow join one person if the sides are equal (to fill up bg to minplayersperteam) 1022 if (otherTeam == GetInvitedCount(Team)) 1023 diff = 1; 1024 // allow join more ppl if the other side has more players 1025 else if(otherTeam > GetInvitedCount(Team)) 1026 diff = otherTeam - GetInvitedCount(Team); 1027 1028 // difference based on max players per team (don't allow inviting more) 1029 uint32 diff2 = (GetInvitedCount(Team) < GetMaxPlayersPerTeam()) ? GetMaxPlayersPerTeam() - GetInvitedCount(Team) : 0; 1030 1031 // difference based on players who already entered 1032 // default: allow 0 1033 uint32 diff3 = 0; 1034 // allow join one person if the sides are equal (to fill up bg minplayersperteam) 1035 if (otherIn == GetPlayersCountByTeam(Team)) 1036 diff3 = 1; 1037 // allow join more ppl if the other side has more players 1038 else if (otherIn > GetPlayersCountByTeam(Team)) 1039 diff3 = otherIn - GetPlayersCountByTeam(Team); 1040 1041 // return the minimum of the 3 differences 1042 1043 // min of diff and diff 2 1044 diff = diff < diff2 ? diff : diff2; 1045 1046 // min of diff, diff2 and diff3 1047 return diff < diff3 ? diff : diff3 ; 1048 } 1049 1050 return 0; 1051 } 1052 784 1053 bool BattleGround::HasFreeSlots() const 785 1054 { … … 807 1076 break; 808 1077 case SCORE_BONUS_HONOR: // Honor bonus 809 // reward honor instantly 810 if(Source->RewardHonor(NULL, 1, value)) 811 itr->second->BonusHonor += value; 1078 // do not add honor in arenas 1079 if(isBattleGround()) 1080 { 1081 // reward honor instantly 1082 if(Source->RewardHonor(NULL, 1, value)) 1083 itr->second->BonusHonor += value; 1084 } 812 1085 break; 813 1086 //used only in EY, but in MSG_PVP_LOG_DATA opcode … … 865 1138 bool BattleGround::AddObject(uint32 type, uint32 entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime) 866 1139 { 867 GameObjectInfo const* goinfo = objmgr.GetGameObjectInfo(entry); 868 if(!goinfo) 1140 Map * map = MapManager::Instance().FindMap(GetMapId(),GetInstanceID()); 1141 if(!map) 1142 return false; 1143 1144 // must be created this way, adding to godatamap would add it to the base map of the instance 1145 // and when loading it (in go::LoadFromDB()), a new guid would be assigned to the object, and a new object would be created 1146 // so we must create it specific for this instance 1147 GameObject * go = new GameObject; 1148 if(!go->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT),entry, map,x,y,z,o,rotation0,rotation1,rotation2,rotation3,100,1)) 869 1149 { 870 1150 sLog.outErrorDb("Gameobject template %u not found in database! BattleGround not created!", entry); 1151 sLog.outError("Cannot create gameobject template %u! BattleGround not created!", entry); 1152 delete go; 871 1153 return false; 872 1154 } 873 874 uint32 guid = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT); 875 1155 /* 1156 uint32 guid = go->GetGUIDLow(); 1157 1158 // without this, UseButtonOrDoor caused the crash, since it tried to get go info from godata 1159 // iirc that was changed, so adding to go data map is no longer required if that was the only function using godata from GameObject without checking if it existed 876 1160 GameObjectData& data = objmgr.NewGOData(guid); 877 1161 … … 887 1171 data.rotation3 = rotation3; 888 1172 data.spawntimesecs = respawnTime; 1173 data.spawnMask = 1; 889 1174 data.animprogress = 100; 890 1175 data.go_state = 1; 891 data.spawnMask = 1; 892 objmgr.AddGameobjectToGrid(guid, &data); 893 894 m_BgObjects[type] = MAKE_NEW_GUID(guid, entry, HIGHGUID_GAMEOBJECT); 895 1176 */ 1177 // add to world, so it can be later looked up from HashMapHolder 1178 go->AddToWorld(); 1179 m_BgObjects[type] = go->GetGUID(); 896 1180 return true; 897 1181 } … … 935 1219 void BattleGround::SpawnBGObject(uint32 type, uint32 respawntime) 936 1220 { 1221 Map * map = MapManager::Instance().FindMap(GetMapId(),GetInstanceID()); 1222 if(!map) 1223 return; 937 1224 if( respawntime == 0 ) 938 1225 { … … 943 1230 if( obj->getLootState() == GO_JUST_DEACTIVATED ) 944 1231 obj->SetLootState(GO_READY); 945 obj->Respawn(); 946 } 947 else 948 objmgr.SaveGORespawnTime(GUID_LOPART(m_BgObjects[type]), 0, 0); 1232 obj->SetRespawnTime(0); 1233 map->Add(obj); 1234 } 949 1235 } 950 1236 else … … 953 1239 if(obj) 954 1240 { 1241 map->Add(obj); 955 1242 obj->SetRespawnTime(respawntime); 956 1243 obj->SetLootState(GO_JUST_DEACTIVATED); 957 1244 } 958 else 959 objmgr.SaveGORespawnTime(GUID_LOPART(m_BgObjects[type]), 0, time(NULL) + respawntime); 960 } 961 } 962 963 Creature* BattleGround::AddCreature(uint32 entry, uint32 type, uint32 teamval, float x, float y, float z, float o) 964 { 965 // note: this should normally be FindMap 966 // but it's a hack to allow the battlegrounds to initialize at server startup 967 Map * map = MapManager::Instance().GetMap(GetMapId(), 0); 968 if(!map) return NULL; 1245 } 1246 } 1247 1248 Creature* BattleGround::AddCreature(uint32 entry, uint32 type, uint32 teamval, float x, float y, float z, float o, uint32 respawntime) 1249 { 1250 Map * map = MapManager::Instance().FindMap(GetMapId(),GetInstanceID()); 1251 if(!map) 1252 return NULL; 969 1253 970 1254 Creature* pCreature = new Creature; … … 990 1274 map->Add(pCreature); 991 1275 m_BgCreatures[type] = pCreature->GetGUID(); 1276 992 1277 return pCreature; 993 1278 } … … 1073 1358 void BattleGround::EndNow() 1074 1359 { 1360 RemoveFromBGFreeSlotQueue(); 1075 1361 SetStatus(STATUS_WAIT_LEAVE); 1076 1362 SetEndTime(TIME_TO_AUTOREMOVE); 1363 // inform invited players about the removal 1364 sBattleGroundMgr.m_BattleGroundQueues[sBattleGroundMgr.BGQueueTypeId(GetTypeID(), GetArenaType())].BGEndedRemoveInvites(this); 1077 1365 } 1078 1366 … … 1152 1440 player->SetFlag( UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE ); 1153 1441 } 1442 1443 // return the player's team based on battlegroundplayer info 1444 // used in same faction arena matches mainly 1445 uint32 BattleGround::GetPlayerTeam(uint64 guid) 1446 { 1447 std::map<uint64, BattleGroundPlayer>::const_iterator itr = m_Players.find(guid); 1448 if(itr!=m_Players.end()) 1449 return itr->second.Team; 1450 return 0; 1451 } 1452 1453 uint32 BattleGround::GetAlivePlayersCountByTeam(uint32 Team) const 1454 { 1455 int count = 0; 1456 for(std::map<uint64, BattleGroundPlayer>::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) 1457 { 1458 if(itr->second.Team == Team) 1459 { 1460 Player * pl = objmgr.GetPlayer(itr->first); 1461 if(pl && pl->isAlive()) 1462 ++count; 1463 } 1464 } 1465 return count; 1466 }