summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Achievements/AchievementMgr.cpp8
-rw-r--r--src/server/game/Battlegrounds/ArenaTeam.cpp3
-rw-r--r--src/server/game/Battlegrounds/Battleground.cpp49
-rw-r--r--src/server/game/Battlegrounds/Battleground.h33
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundAB.h3
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundAV.h6
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundEY.h2
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundIC.h3
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundSA.h3
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundWS.h3
-rw-r--r--src/server/game/Entities/Item/Item.cpp35
-rw-r--r--src/server/game/Entities/Item/ItemPrototype.h35
-rw-r--r--src/server/game/Entities/Player/Player.cpp36
-rw-r--r--src/server/game/Entities/Player/Player.h2
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp6
-rw-r--r--src/server/game/Globals/ObjectMgr.h19
-rw-r--r--src/server/game/Groups/Group.cpp4
-rw-r--r--src/server/game/Handlers/BattleGroundHandler.cpp15
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp38
-rw-r--r--src/server/game/Miscellaneous/Formulas.h2
-rw-r--r--src/server/game/Scripting/ScriptMgr.cpp62
-rw-r--r--src/server/game/Scripting/ScriptMgr.h42
-rw-r--r--src/server/game/Server/WorldSession.cpp8
-rw-r--r--src/server/game/World/World.cpp9
-rw-r--r--src/server/game/World/World.h4
-rw-r--r--src/server/scripts/Commands/cs_character.cpp4
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/instance_trial_of_the_champion.cpp11
-rw-r--r--src/server/scripts/Pet/pet_dk.cpp93
-rw-r--r--src/server/shared/Database/Implementation/CharacterDatabase.cpp10
-rw-r--r--src/server/shared/Database/Implementation/CharacterDatabase.h8
-rw-r--r--src/server/worldserver/worldserver.conf.dist48
31 files changed, 475 insertions, 129 deletions
diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp
index 8430ed0273..66c0fcba99 100644
--- a/src/server/game/Achievements/AchievementMgr.cpp
+++ b/src/server/game/Achievements/AchievementMgr.cpp
@@ -554,6 +554,8 @@ void AchievementMgr::SaveToDB(SQLTransaction& trans)
trans->Append(stmt);
iter->second.changed = false;
+
+ sScriptMgr->OnAchievementSave(trans, GetPlayer(), iter->first, iter->second);
}
}
@@ -581,6 +583,8 @@ void AchievementMgr::SaveToDB(SQLTransaction& trans)
}
iter->second.changed = false;
+
+ sScriptMgr->OnCriteriaSave(trans, GetPlayer(), iter->first, iter->second);
}
}
}
@@ -2041,6 +2045,8 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry,
}
SendCriteriaUpdate(entry, progress, timeElapsed, timedCompleted);
+
+ sScriptMgr->OnCriteriaProgress(GetPlayer(), entry);
}
void AchievementMgr::RemoveCriteriaProgress(const AchievementCriteriaEntry* entry)
@@ -2138,6 +2144,8 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement)
ca.date = time(NULL);
ca.changed = true;
+ sScriptMgr->OnAchievementComplete(GetPlayer(), achievement);
+
// pussywizard: set all progress counters to 0, so progress will be deleted from db during save
{
bool allRefsCompleted = true;
diff --git a/src/server/game/Battlegrounds/ArenaTeam.cpp b/src/server/game/Battlegrounds/ArenaTeam.cpp
index 1448ef2d0b..2ae8d93f82 100644
--- a/src/server/game/Battlegrounds/ArenaTeam.cpp
+++ b/src/server/game/Battlegrounds/ArenaTeam.cpp
@@ -25,6 +25,7 @@
#include "Player.h"
#include "WorldSession.h"
#include "Opcodes.h"
+#include <Config.h>
ArenaTeam::ArenaTeam()
: TeamId(0), Type(0), TeamName(), CaptainGuid(0), BackgroundColor(0), EmblemStyle(0), EmblemColor(0),
@@ -590,6 +591,8 @@ uint32 ArenaTeam::GetPoints(uint32 memberRating)
points *= 0.76f;
else if (Type == ARENA_TEAM_3v3)
points *= 0.88f;
+
+ points *= sWorld->getRate(RATE_ARENA_POINTS);
return (uint32) points;
}
diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp
index de41ed4433..7bafc6a9a6 100644
--- a/src/server/game/Battlegrounds/Battleground.cpp
+++ b/src/server/game/Battlegrounds/Battleground.cpp
@@ -762,6 +762,27 @@ void Battleground::EndBattleground(TeamId winnerTeamId)
else
SetWinner(TEAM_NEUTRAL);
+ PreparedStatement* stmt = NULL;
+ uint64 battlegroundId = 1;
+ if (isBattleground() && sWorld->getBoolConfig(CONFIG_BATTLEGROUND_STORE_STATISTICS_ENABLE))
+ {
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PVPSTATS_MAXID);
+ PreparedQueryResult result = CharacterDatabase.Query(stmt);
+
+ if (result)
+ {
+ Field* fields = result->Fetch();
+ battlegroundId = fields[0].GetUInt64() + 1;
+ }
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PVPSTATS_BATTLEGROUND);
+ stmt->setUInt64(0, battlegroundId);
+ stmt->setUInt8(1, GetWinner());
+ stmt->setUInt8(2, GetUniqueBracketId());
+ stmt->setUInt8(3, GetBgTypeID());
+ CharacterDatabase.Execute(stmt);
+ }
+
//we must set it this way, because end time is sent in packet!
m_EndTime = TIME_TO_AUTOREMOVE;
@@ -978,6 +999,29 @@ void Battleground::EndBattleground(TeamId winnerTeamId)
player->GetSession()->SendPacket(&pvpLogData);
+ if (isBattleground() && sWorld->getBoolConfig(CONFIG_BATTLEGROUND_STORE_STATISTICS_ENABLE))
+ {
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PVPSTATS_PLAYER);
+ BattlegroundScoreMap::const_iterator score = PlayerScores.find(player->GetGUID());
+
+ stmt->setUInt32(0, battlegroundId);
+ stmt->setUInt32(1, player->GetGUIDLow());
+ stmt->setBool(2, bgTeamId == winnerTeamId);
+ stmt->setUInt32(3, score->second->GetKillingBlows());
+ stmt->setUInt32(4, score->second->GetDeaths());
+ stmt->setUInt32(5, score->second->GetHonorableKills());
+ stmt->setUInt32(6, score->second->GetBonusHonor());
+ stmt->setUInt32(7, score->second->GetDamageDone());
+ stmt->setUInt32(8, score->second->GetHealingDone());
+ stmt->setUInt32(9, score->second->GetAttr1());
+ stmt->setUInt32(10, score->second->GetAttr2());
+ stmt->setUInt32(11, score->second->GetAttr3());
+ stmt->setUInt32(12, score->second->GetAttr4());
+ stmt->setUInt32(13, score->second->GetAttr5());
+
+ CharacterDatabase.Execute(stmt);
+ }
+
WorldPacket data;
sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetCurrentBattlegroundQueueSlot(), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime(), GetArenaType(), player->GetBgTeamId());
player->GetSession()->SendPacket(&data);
@@ -1876,3 +1920,8 @@ void Battleground::RewardXPAtKill(Player* killer, Player* victim)
if (sWorld->getBoolConfig(CONFIG_BG_XP_FOR_KILL) && killer && victim)
killer->RewardPlayerAndGroupAtKill(victim, true);
}
+
+uint8 Battleground::GetUniqueBracketId() const
+{
+ return GetMinLevel() / 10;
+} \ No newline at end of file
diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h
index 9e86d69969..bfdb680949 100644
--- a/src/server/game/Battlegrounds/Battleground.h
+++ b/src/server/game/Battlegrounds/Battleground.h
@@ -45,6 +45,15 @@ class BattlegroundIC;
struct PvPDifficultyEntry;
struct WorldSafeLocsEntry;
+enum BattlegroundDesertionType
+{
+ BG_DESERTION_TYPE_LEAVE_BG = 0, // player leaves the BG
+ BG_DESERTION_TYPE_OFFLINE = 1, // player is kicked from BG because offline
+ BG_DESERTION_TYPE_LEAVE_QUEUE = 2, // player is invited to join and refuses to do it
+ BG_DESERTION_TYPE_NO_ENTER_BUTTON = 3, // player is invited to join and do nothing (time expires)
+ BG_DESERTION_TYPE_INVITE_LOGOUT = 4, // player is invited to join and logs out
+};
+
enum BattlegroundSounds
{
SOUND_HORDE_WINS = 8454,
@@ -267,6 +276,19 @@ struct BattlegroundScore
uint32 DamageDone;
uint32 HealingDone;
Player* player;
+
+ uint32 GetKillingBlows() const { return KillingBlows; }
+ uint32 GetDeaths() const { return Deaths; }
+ uint32 GetHonorableKills() const { return HonorableKills; }
+ uint32 GetBonusHonor() const { return BonusHonor; }
+ uint32 GetDamageDone() const { return DamageDone; }
+ uint32 GetHealingDone() const { return HealingDone; }
+
+ virtual uint32 GetAttr1() const { return 0; }
+ virtual uint32 GetAttr2() const { return 0; }
+ virtual uint32 GetAttr3() const { return 0; }
+ virtual uint32 GetAttr4() const { return 0; }
+ virtual uint32 GetAttr5() const { return 0; }
};
class ArenaLogEntryData
@@ -310,6 +332,14 @@ This class is used to:
3. some certain cases, same for all battlegrounds
4. It has properties same for all battlegrounds
*/
+
+enum BattlegroundQueueInvitationType
+{
+ BG_QUEUE_INVITATION_TYPE_NO_BALANCE = 0, // no balance: N+M vs N players
+ BG_QUEUE_INVITATION_TYPE_BALANCED = 1, // teams balanced: N+1 vs N players
+ BG_QUEUE_INVITATION_TYPE_EVEN = 2 // teams even: N vs N players
+};
+
class Battleground
{
public:
@@ -570,6 +600,9 @@ class Battleground
virtual TeamId GetPrematureWinner();
+ // because BattleGrounds with different types and same level range has different m_BracketId
+ uint8 GetUniqueBracketId() const;
+
BattlegroundAV* ToBattlegroundAV() { if (GetBgTypeID() == BATTLEGROUND_AV) return reinterpret_cast<BattlegroundAV*>(this); else return NULL; }
BattlegroundAV const* ToBattlegroundAV() const { if (GetBgTypeID() == BATTLEGROUND_AV) return reinterpret_cast<const BattlegroundAV*>(this); else return NULL; }
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.h b/src/server/game/Battlegrounds/Zones/BattlegroundAB.h
index c32936a765..654937a721 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.h
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.h
@@ -216,6 +216,9 @@ struct BattlegroundABScore : public BattlegroundScore
~BattlegroundABScore() { }
uint32 BasesAssaulted;
uint32 BasesDefended;
+
+ uint32 GetAttr1() const final override { return BasesAssaulted; }
+ uint32 GetAttr2() const final override { return BasesDefended; }
};
class BattlegroundAB : public Battleground
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.h b/src/server/game/Battlegrounds/Zones/BattlegroundAV.h
index a6b7d4af97..a2a43d5cec 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.h
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundAV.h
@@ -1565,6 +1565,12 @@ struct BattlegroundAVScore : public BattlegroundScore
uint32 MinesCaptured;
uint32 LeadersKilled;
uint32 SecondaryObjectives;
+
+ uint32 GetAttr1() const final override { return GraveyardsAssaulted; }
+ uint32 GetAttr2() const final override { return GraveyardsDefended; }
+ uint32 GetAttr3() const final override { return TowersAssaulted; }
+ uint32 GetAttr4() const final override { return TowersDefended; }
+ uint32 GetAttr5() const final override { return MinesCaptured; }
};
class BattlegroundAV : public Battleground
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundEY.h b/src/server/game/Battlegrounds/Zones/BattlegroundEY.h
index f502da9c7d..a42c44bab8 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundEY.h
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundEY.h
@@ -310,6 +310,8 @@ struct BattlegroundEYScore : public BattlegroundScore
BattlegroundEYScore(Player* player) : BattlegroundScore(player), FlagCaptures(0) { }
~BattlegroundEYScore() { }
uint32 FlagCaptures;
+
+ uint32 GetAttr1() const final override { return FlagCaptures; }
};
class BattlegroundEY : public Battleground
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundIC.h b/src/server/game/Battlegrounds/Zones/BattlegroundIC.h
index 027d2d85bd..87ffccff32 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundIC.h
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundIC.h
@@ -894,6 +894,9 @@ struct BattlegroundICScore : public BattlegroundScore
~BattlegroundICScore() { }
uint32 BasesAssaulted;
uint32 BasesDefended;
+
+ uint32 GetAttr1() const final override { return BasesAssaulted; }
+ uint32 GetAttr2() const final override { return BasesDefended; }
};
class BattlegroundIC : public Battleground
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundSA.h b/src/server/game/Battlegrounds/Zones/BattlegroundSA.h
index 367e8dead7..9671e5351e 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundSA.h
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundSA.h
@@ -27,6 +27,9 @@ struct BattlegroundSAScore : public BattlegroundScore
~BattlegroundSAScore() { }
uint8 demolishers_destroyed;
uint8 gates_destroyed;
+
+ uint32 GetAttr1() const final override { return demolishers_destroyed; }
+ uint32 GetAttr2() const final override { return gates_destroyed; }
};
#define BG_SA_FLAG_AMOUNT 3
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.h b/src/server/game/Battlegrounds/Zones/BattlegroundWS.h
index 71542ab2ef..a5aee6fbb6 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.h
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundWS.h
@@ -142,6 +142,9 @@ struct BattlegroundWGScore : public BattlegroundScore
~BattlegroundWGScore() { }
uint32 FlagCaptures;
uint32 FlagReturns;
+
+ uint32 GetAttr1() const final override { return FlagCaptures; }
+ uint32 GetAttr2() const final override { return FlagReturns; }
};
class BattlegroundWS : public Battleground
diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp
index 6cccb5cf44..82354bb413 100644
--- a/src/server/game/Entities/Item/Item.cpp
+++ b/src/server/game/Entities/Item/Item.cpp
@@ -510,41 +510,10 @@ Player* Item::GetOwner()const
return ObjectAccessor::FindPlayer(GetOwnerGUID());
}
+// Legacy / Shortcut
uint32 Item::GetSkill()
{
- const static uint32 item_weapon_skills[MAX_ITEM_SUBCLASS_WEAPON] =
- {
- SKILL_AXES, SKILL_2H_AXES, SKILL_BOWS, SKILL_GUNS, SKILL_MACES,
- SKILL_2H_MACES, SKILL_POLEARMS, SKILL_SWORDS, SKILL_2H_SWORDS, 0,
- SKILL_STAVES, 0, 0, SKILL_FIST_WEAPONS, 0,
- SKILL_DAGGERS, SKILL_THROWN, SKILL_ASSASSINATION, SKILL_CROSSBOWS, SKILL_WANDS,
- SKILL_FISHING
- };
-
- const static uint32 item_armor_skills[MAX_ITEM_SUBCLASS_ARMOR] =
- {
- 0, SKILL_CLOTH, SKILL_LEATHER, SKILL_MAIL, SKILL_PLATE_MAIL, 0, SKILL_SHIELD, 0, 0, 0, 0
- };
-
- ItemTemplate const* proto = GetTemplate();
-
- switch (proto->Class)
- {
- case ITEM_CLASS_WEAPON:
- if (proto->SubClass >= MAX_ITEM_SUBCLASS_WEAPON)
- return 0;
- else
- return item_weapon_skills[proto->SubClass];
-
- case ITEM_CLASS_ARMOR:
- if (proto->SubClass >= MAX_ITEM_SUBCLASS_ARMOR)
- return 0;
- else
- return item_armor_skills[proto->SubClass];
-
- default:
- return 0;
- }
+ return GetTemplate()->GetSkill();
}
uint32 Item::GetSpell()
diff --git a/src/server/game/Entities/Item/ItemPrototype.h b/src/server/game/Entities/Item/ItemPrototype.h
index 467ec80cb4..0dbdb02a8a 100644
--- a/src/server/game/Entities/Item/ItemPrototype.h
+++ b/src/server/game/Entities/Item/ItemPrototype.h
@@ -746,6 +746,41 @@ struct ItemTemplate
return std::max<float>(0.f, itemLevel);
}
+ uint32 GetSkill() const
+ {
+ const static uint32 item_weapon_skills[MAX_ITEM_SUBCLASS_WEAPON] =
+ {
+ SKILL_AXES, SKILL_2H_AXES, SKILL_BOWS, SKILL_GUNS, SKILL_MACES,
+ SKILL_2H_MACES, SKILL_POLEARMS, SKILL_SWORDS, SKILL_2H_SWORDS, 0,
+ SKILL_STAVES, 0, 0, SKILL_FIST_WEAPONS, 0,
+ SKILL_DAGGERS, SKILL_THROWN, SKILL_ASSASSINATION, SKILL_CROSSBOWS, SKILL_WANDS,
+ SKILL_FISHING
+ };
+
+ const static uint32 item_armor_skills[MAX_ITEM_SUBCLASS_ARMOR] =
+ {
+ 0, SKILL_CLOTH, SKILL_LEATHER, SKILL_MAIL, SKILL_PLATE_MAIL, 0, SKILL_SHIELD, 0, 0, 0, 0
+ };
+
+ switch (Class)
+ {
+ case ITEM_CLASS_WEAPON:
+ if (SubClass >= MAX_ITEM_SUBCLASS_WEAPON)
+ return 0;
+ else
+ return item_weapon_skills[SubClass];
+
+ case ITEM_CLASS_ARMOR:
+ if (SubClass >= MAX_ITEM_SUBCLASS_ARMOR)
+ return 0;
+ else
+ return item_armor_skills[SubClass];
+
+ default:
+ return 0;
+ }
+ }
+
bool IsPotion() const { return Class == ITEM_CLASS_CONSUMABLE && SubClass == ITEM_SUBCLASS_POTION; }
bool IsWeaponVellum() const { return Class == ITEM_CLASS_TRADE_GOODS && SubClass == ITEM_SUBCLASS_WEAPON_ENCHANTMENT; }
bool IsArmorVellum() const { return Class == ITEM_CLASS_TRADE_GOODS && SubClass == ITEM_SUBCLASS_ARMOR_ENCHANTMENT; }
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index d707cc1478..0dac632644 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -505,7 +505,7 @@ inline void KillRewarder::_InitXP(Player* player)
// * otherwise, not in PvP;
// * not if killer is on vehicle.
if (_isBattleGround || (!_isPvP && !_killer->GetVehicle()))
- _xp = Trinity::XP::Gain(player, _victim);
+ _xp = Trinity::XP::Gain(player, _victim, _isBattleGround);
if (_xp && !_isBattleGround && _victim) // pussywizard: npcs with relatively low hp give lower exp
if (_victim->GetTypeId() == TYPEID_UNIT)
@@ -6946,6 +6946,12 @@ TeamId Player::TeamIdForRace(uint8 race)
void Player::setFactionForRace(uint8 race)
{
m_team = TeamIdForRace(race);
+
+ sScriptMgr->OnPlayerUpdateFaction(this);
+
+ if (GetTeamId(true) != GetTeamId())
+ return;
+
ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(race);
setFaction(rEntry ? rEntry->FactionID : 0);
}
@@ -7385,6 +7391,20 @@ uint32 Player::GetArenaTeamIdFromStorage(uint32 guid, uint8 slot)
return 0;
}
+uint32 Player::GetArenaTeamIdFromDB(uint64 guid, uint8 type)
+{
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ARENA_TEAM_ID_BY_PLAYER_GUID);
+ stmt->setUInt32(0, GUID_LOPART(guid));
+ stmt->setUInt8(1, type);
+ PreparedQueryResult result = CharacterDatabase.Query(stmt);
+
+ if (!result)
+ return 0;
+
+ uint32 id = (*result)[0].GetUInt32();
+ return id;
+}
+
uint32 Player::GetZoneIdFromDB(uint64 guid)
{
uint32 guidLow = GUID_LOPART(guid);
@@ -12167,10 +12187,10 @@ InventoryResult Player::CanUseItem(ItemTemplate const* proto) const
if (proto)
{
- if ((proto->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY) && GetTeamId() != TEAM_HORDE)
+ if ((proto->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY) && GetTeamId(true) != TEAM_HORDE)
return EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM;
- if ((proto->Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY) && GetTeamId() != TEAM_ALLIANCE)
+ if ((proto->Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY) && GetTeamId(true) != TEAM_ALLIANCE)
return EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM;
if ((proto->AllowableClass & getClassMask()) == 0 || (proto->AllowableRace & getRaceMask()) == 0)
@@ -22172,6 +22192,16 @@ void Player::LeaveBattleground(Battleground* bg)
if (!bg)
return;
+ // Deserter tracker - leave BG
+ if (bg->isBattleground() && sWorld->getBoolConfig(CONFIG_BATTLEGROUND_TRACK_DESERTERS)
+ && (bg->GetStatus() == STATUS_IN_PROGRESS || bg->GetStatus() == STATUS_WAIT_JOIN))
+ {
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_DESERTER_TRACK);
+ stmt->setUInt32(0, GetGUIDLow());
+ stmt->setUInt8(1, BG_DESERTION_TYPE_LEAVE_BG);
+ CharacterDatabase.Execute(stmt);
+ }
+
// xinef: reset corpse reclaim time
m_deathExpireTime = time(NULL);
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index e285e374ee..97feda9fc9 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1885,6 +1885,7 @@ class Player : public Unit, public GridObject<Player>
{
SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot * ARENA_TEAM_END) + type, value);
}
+ static uint32 GetArenaTeamIdFromDB(uint64 guid, uint8 slot);
static void LeaveAllArenaTeams(uint64 guid);
uint32 GetArenaTeamId(uint8 slot) const { return GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot * ARENA_TEAM_END) + ARENA_TEAM_ID); }
uint32 GetArenaPersonalRating(uint8 slot) const { return GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot * ARENA_TEAM_END) + ARENA_TEAM_PERSONAL_RATING); }
@@ -2076,6 +2077,7 @@ class Player : public Unit, public GridObject<Player>
static TeamId TeamIdForRace(uint8 race);
TeamId GetTeamId(bool original = false) const { return original ? TeamIdForRace(getRace()) : m_team; };
void setFactionForRace(uint8 race);
+ void setTeamId(TeamId teamid) { m_team = teamid; };
void InitDisplayIds();
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 9dfaf98729..9817cd2121 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -9080,6 +9080,12 @@ GameObjectTemplate const* ObjectMgr::GetGameObjectTemplate(uint32 entry)
return NULL;
}
+Player* ObjectMgr::GetPlayerByLowGUID(uint32 lowguid) const
+{
+ uint64 guid = MAKE_NEW_GUID(lowguid, 0, HIGHGUID_PLAYER);
+ return ObjectAccessor::FindPlayer(guid);
+}
+
bool ObjectMgr::IsGameObjectStaticTransport(uint32 entry)
{
GameObjectTemplate const* goinfo = GetGameObjectTemplate(entry);
diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h
index 0805a21d76..f2b01de7bc 100644
--- a/src/server/game/Globals/ObjectMgr.h
+++ b/src/server/game/Globals/ObjectMgr.h
@@ -666,6 +666,8 @@ class ObjectMgr
typedef std::map<uint32, uint32> CharacterConversionMap;
+ Player* GetPlayerByLowGUID(uint32 lowguid) const;
+
GameObjectTemplate const* GetGameObjectTemplate(uint32 entry);
bool IsGameObjectStaticTransport(uint32 entry);
GameObjectTemplateContainer const* GetGameObjectTemplates() const { return &_gameObjectTemplateStore; }
@@ -687,6 +689,18 @@ class ObjectMgr
ItemTemplate const* GetItemTemplate(uint32 entry);
ItemTemplateContainer const* GetItemTemplateStore() const { return &_itemTemplateStore; }
+ ItemLocale const* GetItemLocale(uint32 entry) const
+ {
+ ItemLocaleContainer::const_iterator itr = _itemLocaleStore.find(entry);
+ if (itr == _itemLocaleStore.end()) return NULL;
+ return &itr->second;
+ }
+ ItemSetNameLocale const* GetItemSetNameLocale(uint32 entry) const
+ {
+ ItemSetNameLocaleContainer::const_iterator itr = _itemSetNameLocaleStore.find(entry);
+ if (itr == _itemSetNameLocaleStore.end())return NULL;
+ return &itr->second;
+ }
ItemSetNameEntry const* GetItemSetNameEntry(uint32 itemId)
{
ItemSetNameContainer::iterator itr = _itemSetNameStore.find(itemId);
@@ -1164,6 +1178,11 @@ class ObjectMgr
GraveyardContainer GraveyardStore;
static void AddLocaleString(std::string const& s, LocaleConstant locale, StringVector& data);
+ static inline void GetLocaleString(const StringVector& data, int loc_idx, std::string& value)
+ {
+ if (data.size() > size_t(loc_idx) && !data[loc_idx].empty())
+ value = data[loc_idx];
+ }
CharacterConversionMap FactionChangeAchievements;
CharacterConversionMap FactionChangeItems;
diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp
index 3a3065849f..2fa1c60fc6 100644
--- a/src/server/game/Groups/Group.cpp
+++ b/src/server/game/Groups/Group.cpp
@@ -681,8 +681,6 @@ void Group::ChangeLeader(uint64 newLeaderGuid)
if (!newLeader)
return;
- sScriptMgr->OnGroupChangeLeader(this, newLeaderGuid, m_leaderGuid);
-
if (!isBGGroup() && !isBFGroup())
{
SQLTransaction trans = CharacterDatabase.BeginTransaction();
@@ -707,6 +705,8 @@ void Group::ChangeLeader(uint64 newLeaderGuid)
WorldPacket data(SMSG_GROUP_SET_LEADER, m_leaderName.size()+1);
data << slot->name;
BroadcastPacket(&data, true);
+
+ sScriptMgr->OnGroupChangeLeader(this, newLeaderGuid, m_leaderGuid); // This hook should be executed at the end - Not used anywhere in the original core
}
void Group::Disband(bool hideDestroy /* = false */)
diff --git a/src/server/game/Handlers/BattleGroundHandler.cpp b/src/server/game/Handlers/BattleGroundHandler.cpp
index 5857635450..39528d4173 100644
--- a/src/server/game/Handlers/BattleGroundHandler.cpp
+++ b/src/server/game/Handlers/BattleGroundHandler.cpp
@@ -433,6 +433,8 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData)
_player->SpawnCorpseBones();
}
+ TeamId teamId = ginfo.teamId;
+
// remove player from all bg queues
for (uint32 qslot = 0; qslot < PLAYER_MAX_BATTLEGROUND_QUEUES; ++qslot)
if (BattlegroundQueueTypeId q = _player->GetBattlegroundQueueTypeId(qslot))
@@ -443,10 +445,10 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData)
}
// send status packet
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime(), bg->GetArenaType(), ginfo.teamId);
+ sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime(), bg->GetArenaType(), teamId);
SendPacket(&data);
- _player->SetBattlegroundId(bg->GetInstanceID(), bg->GetBgTypeID(), queueSlot, true, bgTypeId == BATTLEGROUND_RB, ginfo.teamId);
+ _player->SetBattlegroundId(bg->GetInstanceID(), bg->GetBgTypeID(), queueSlot, true, bgTypeId == BATTLEGROUND_RB, teamId);
sBattlegroundMgr->SendToBattleground(_player, ginfo.IsInvitedToBGInstanceGUID, bgTypeId);
}
@@ -455,6 +457,15 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData)
{
bgQueue.RemovePlayer(_player->GetGUID(), false, queueSlot);
_player->RemoveBattlegroundQueueId(bgQueueTypeId);
+ // track if player refuses to join the BG after being invited
+ if (bg->isBattleground() && sWorld->getBoolConfig(CONFIG_BATTLEGROUND_TRACK_DESERTERS) &&
+ (bg->GetStatus() == STATUS_IN_PROGRESS || bg->GetStatus() == STATUS_WAIT_JOIN))
+ {
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_DESERTER_TRACK);
+ stmt->setUInt32(0, _player->GetGUIDLow());
+ stmt->setUInt8(1, BG_DESERTION_TYPE_LEAVE_QUEUE);
+ CharacterDatabase.Execute(stmt);
+ }
}
break;
default:
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index 03ebb65c17..b5b65ba667 100644
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -101,6 +101,7 @@ void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket & recv_data)
Creature* unit = NULL;
GameObject* go = NULL;
+ Item* item = NULL;
if (IS_CRE_OR_VEH_GUID(guid))
{
unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_NONE);
@@ -119,6 +120,23 @@ void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket & recv_data)
return;
}
}
+ else if (IS_ITEM_GUID(guid))
+ {
+ item = _player->GetItemByGuid(guid);
+ if (!item || _player->IsBankPos(item->GetPos()))
+ {
+ //TC_LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - %s not found.", guid.ToString().c_str());
+ return;
+ }
+ }
+ else if (IS_PLAYER_GUID(guid))
+ {
+ if (guid != _player->GetGUID() || menuId != _player->PlayerTalkClass->GetGossipMenu().GetMenuId())
+ {
+ //TC_LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - %s not found.", guid.ToString().c_str());
+ return;
+ }
+ }
else
{
;//sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleGossipSelectOptionOpcode - unsupported GUID type for highguid %u. lowpart %u.", uint32(GUID_HIPART(guid)), uint32(GUID_LOPART(guid)));
@@ -147,11 +165,19 @@ void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket & recv_data)
if (!sScriptMgr->OnGossipSelectCode(_player, unit, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId), code.c_str()))
_player->OnGossipSelect(unit, gossipListId, menuId);
}
- else
+ else if (go)
{
go->AI()->GossipSelectCode(_player, menuId, gossipListId, code.c_str());
sScriptMgr->OnGossipSelectCode(_player, go, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId), code.c_str());
}
+ else if (item)
+ {
+ sScriptMgr->OnGossipSelectCode(_player, item, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId), code.c_str());
+ }
+ else
+ {
+ sScriptMgr->OnGossipSelectCode(_player, menuId, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId), code.c_str());
+ }
}
else
{
@@ -161,12 +187,20 @@ void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket & recv_data)
if (!sScriptMgr->OnGossipSelect(_player, unit, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId)))
_player->OnGossipSelect(unit, gossipListId, menuId);
}
- else
+ else if (go)
{
go->AI()->GossipSelect(_player, menuId, gossipListId);
if (!sScriptMgr->OnGossipSelect(_player, go, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId)))
_player->OnGossipSelect(go, gossipListId, menuId);
}
+ else if (item)
+ {
+ sScriptMgr->OnGossipSelect(_player, item, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId));
+ }
+ else
+ {
+ sScriptMgr->OnGossipSelect(_player, menuId, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId));
+ }
}
}
diff --git a/src/server/game/Miscellaneous/Formulas.h b/src/server/game/Miscellaneous/Formulas.h
index e44076d2e7..45d7af99f7 100644
--- a/src/server/game/Miscellaneous/Formulas.h
+++ b/src/server/game/Miscellaneous/Formulas.h
@@ -158,7 +158,7 @@ namespace Trinity
return baseGain;
}
- inline uint32 Gain(Player* player, Unit* u)
+ inline uint32 Gain(Player* player, Unit* u, bool isBattleGround = false)
{
Creature* creature = u->ToCreature();
uint32 gain = 0;
diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp
index 80bbaa9e0c..9b0d9788f0 100644
--- a/src/server/game/Scripting/ScriptMgr.cpp
+++ b/src/server/game/Scripting/ScriptMgr.cpp
@@ -1,6 +1,6 @@
/*
- * Copyright (C)
- * Copyright (C)
+ * Copyright (C)
+ * Copyright (C)
*
* 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
@@ -703,6 +703,34 @@ bool ScriptMgr::OnItemExpire(Player* player, ItemTemplate const* proto)
return tmpscript->OnExpire(player, proto);
}
+void ScriptMgr::OnGossipSelect(Player* player, Item* item, uint32 sender, uint32 action)
+{
+ ASSERT(player);
+ ASSERT(item);
+
+ GET_SCRIPT(ItemScript, item->GetScriptId(), tmpscript);
+ tmpscript->OnGossipSelect(player, item, sender, action);
+}
+
+void ScriptMgr::OnGossipSelectCode(Player* player, Item* item, uint32 sender, uint32 action, const char* code)
+{
+ ASSERT(player);
+ ASSERT(item);
+
+ GET_SCRIPT(ItemScript, item->GetScriptId(), tmpscript);
+ tmpscript->OnGossipSelectCode(player, item, sender, action, code);
+}
+
+void ScriptMgr::OnGossipSelect(Player* player, uint32 menu_id, uint32 sender, uint32 action)
+{
+ FOREACH_SCRIPT(PlayerScript)->OnGossipSelect(player, menu_id, sender, action);
+}
+
+void ScriptMgr::OnGossipSelectCode(Player* player, uint32 menu_id, uint32 sender, uint32 action, const char* code)
+{
+ FOREACH_SCRIPT(PlayerScript)->OnGossipSelectCode(player, menu_id, sender, action, code);
+}
+
bool ScriptMgr::OnGossipHello(Player* player, Creature* creature)
{
ASSERT(player);
@@ -1232,6 +1260,36 @@ void ScriptMgr::OnPlayerUpdateZone(Player* player, uint32 newZone, uint32 newAre
FOREACH_SCRIPT(PlayerScript)->OnUpdateZone(player, newZone, newArea);
}
+void ScriptMgr::OnPlayerUpdateFaction(Player* player)
+{
+ FOREACH_SCRIPT(PlayerScript)->OnUpdateFaction(player);
+}
+
+void ScriptMgr::OnPlayerRemoveFromBattleground(Player* player, Battleground* bg)
+{
+ FOREACH_SCRIPT(PlayerScript)->OnPlayerRemoveFromBattleground(player, bg);
+}
+
+void ScriptMgr::OnAchievementComplete(Player* player, AchievementEntry const* achievement)
+{
+ FOREACH_SCRIPT(PlayerScript)->OnAchiComplete(player, achievement);
+}
+
+void ScriptMgr::OnCriteriaProgress(Player* player, AchievementCriteriaEntry const* criteria)
+{
+ FOREACH_SCRIPT(PlayerScript)->OnCriteriaProgress(player, criteria);
+}
+
+void ScriptMgr::OnAchievementSave(SQLTransaction& trans, Player* player, uint16 achiId, CompletedAchievementData achiData)
+{
+ FOREACH_SCRIPT(PlayerScript)->OnAchiSave(trans, player, achiId, achiData);
+}
+
+void ScriptMgr::OnCriteriaSave(SQLTransaction& trans, Player* player, uint16 critId, CriteriaProgress criteriaData)
+{
+ FOREACH_SCRIPT(PlayerScript)->OnCriteriaSave(trans, player, critId, criteriaData);
+}
+
// Guild
void ScriptMgr::OnGuildAddMember(Guild* guild, Player* player, uint8& plRank)
{
diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h
index b7dfec043f..e470fe7625 100644
--- a/src/server/game/Scripting/ScriptMgr.h
+++ b/src/server/game/Scripting/ScriptMgr.h
@@ -29,6 +29,7 @@
#include "SharedDefines.h"
#include "World.h"
#include "Weather.h"
+#include "AchievementMgr.h"
class AuctionHouseObject;
class AuraScript;
@@ -418,6 +419,12 @@ class ItemScript : public ScriptObject
// Called when the item expires (is destroyed).
virtual bool OnExpire(Player* /*player*/, ItemTemplate const* /*proto*/) { return false; }
+
+ // Called when a player selects an option in an item gossip window
+ virtual void OnGossipSelect(Player* /*player*/, Item* /*item*/, uint32 /*sender*/, uint32 /*action*/) { }
+
+ // Called when a player selects an option in an item gossip window
+ virtual void OnGossipSelectCode(Player* /*player*/, Item* /*item*/, uint32 /*sender*/, uint32 /*action*/, const char* /*code*/) { }
};
class CreatureScript : public ScriptObject, public UpdatableScript<Creature>
@@ -748,6 +755,30 @@ class PlayerScript : public ScriptObject
// Called when a player changes to a new map (after moving to new map)
virtual void OnMapChanged(Player* /*player*/) { }
+
+ // Called when team/faction is set on player
+ virtual void OnUpdateFaction(Player* /*player*/) { }
+
+ // Called when a player is removed from battleground
+ virtual void OnPlayerRemoveFromBattleground(Player* /*player*/, Battleground* /*bg*/) { }
+
+ // Called when a player complete an achievement
+ virtual void OnAchiComplete(Player* /*player*/, AchievementEntry const* /*achievement*/) { }
+
+ // Called when a player complete an achievement criteria
+ virtual void OnCriteriaProgress(Player* /*player*/, AchievementCriteriaEntry const* /*criteria*/) { }
+
+ // Called when an Achievement is saved to DB
+ virtual void OnAchiSave(SQLTransaction& /*trans*/, Player* /*player*/, uint16 /*achId*/, CompletedAchievementData /*achiData*/) { }
+
+ // Called when an Criteria is saved to DB
+ virtual void OnCriteriaSave(SQLTransaction& /*trans*/, Player* /*player*/, uint16 /*achId*/, CriteriaProgress /*criteriaData*/) { }
+
+ // Called when a player selects an option in a player gossip window
+ virtual void OnGossipSelect(Player* /*player*/, uint32 /*menu_id*/, uint32 /*sender*/, uint32 /*action*/) { }
+
+ // Called when a player selects an option in a player gossip window
+ virtual void OnGossipSelectCode(Player* /*player*/, uint32 /*menu_id*/, uint32 /*sender*/, uint32 /*action*/, const char* /*code*/) { }
};
class GuildScript : public ScriptObject
@@ -903,6 +934,9 @@ class ScriptMgr
bool OnQuestAccept(Player* player, Item* item, Quest const* quest);
bool OnItemUse(Player* player, Item* item, SpellCastTargets const& targets);
bool OnItemExpire(Player* player, ItemTemplate const* proto);
+ void OnGossipSelect(Player* player, Item* item, uint32 sender, uint32 action);
+ void OnGossipSelectCode(Player* player, Item* item, uint32 sender, uint32 action, const char* code);
+
public: /* CreatureScript */
@@ -1017,6 +1051,14 @@ class ScriptMgr
void OnPlayerDelete(uint64 guid);
void OnPlayerBindToInstance(Player* player, Difficulty difficulty, uint32 mapid, bool permanent);
void OnPlayerUpdateZone(Player* player, uint32 newZone, uint32 newArea);
+ void OnPlayerUpdateFaction(Player* player);
+ void OnPlayerRemoveFromBattleground(Player* player, Battleground* bg);
+ void OnAchievementComplete(Player *player, AchievementEntry const* achievement);
+ void OnCriteriaProgress(Player *player, AchievementCriteriaEntry const* criteria);
+ void OnAchievementSave(SQLTransaction& trans, Player* player, uint16 achiId, CompletedAchievementData achiData);
+ void OnCriteriaSave(SQLTransaction& trans, Player* player, uint16 critId, CriteriaProgress criteriaData);
+ void OnGossipSelect(Player* player, uint32 menu_id, uint32 sender, uint32 action);
+ void OnGossipSelectCode(Player* player, uint32 menu_id, uint32 sender, uint32 action, const char* code);
public: /* GuildScript */
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index e222c9cc13..a2690005de 100644
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -463,6 +463,14 @@ void WorldSession::LogoutPlayer(bool save)
{
_player->RemoveBattlegroundQueueId(bgQueueTypeId);
sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId).RemovePlayer(_player->GetGUID(), false, i);
+ // track if player logs out after invited to join BG
+ if(_player->IsInvitedForBattlegroundInstance() && sWorld->getBoolConfig(CONFIG_BATTLEGROUND_TRACK_DESERTERS))
+ {
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_DESERTER_TRACK);
+ stmt->setUInt32(0, _player->GetGUIDLow());
+ stmt->setUInt8(1, BG_DESERTION_TYPE_INVITE_LOGOUT);
+ CharacterDatabase.Execute(stmt);
+ }
}
///- If the player is in a guild, update the guild roster and broadcast a logout message to other guild members
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index ef04fda108..f1e22d9370 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -499,6 +499,7 @@ void World::LoadConfigSettings(bool reload)
rate_values[RATE_DROP_ITEM_REFERENCED_AMOUNT] = sConfigMgr->GetFloatDefault("Rate.Drop.Item.ReferencedAmount", 1.0f);
rate_values[RATE_DROP_MONEY] = sConfigMgr->GetFloatDefault("Rate.Drop.Money", 1.0f);
rate_values[RATE_XP_KILL] = sConfigMgr->GetFloatDefault("Rate.XP.Kill", 1.0f);
+ rate_values[RATE_XP_BG_KILL] = sConfigMgr->GetFloatDefault("Rate.XP.BattlegroundKill", 1.0f);
rate_values[RATE_XP_QUEST] = sConfigMgr->GetFloatDefault("Rate.XP.Quest", 1.0f);
rate_values[RATE_XP_EXPLORE] = sConfigMgr->GetFloatDefault("Rate.XP.Explore", 1.0f);
rate_values[RATE_REPAIRCOST] = sConfigMgr->GetFloatDefault("Rate.RepairCost", 1.0f);
@@ -601,6 +602,12 @@ void World::LoadConfigSettings(bool reload)
sLog->outError("DurabilityLossChance.Block (%f) must be >=0. Using 0.0 instead.", rate_values[RATE_DURABILITY_LOSS_BLOCK]);
rate_values[RATE_DURABILITY_LOSS_BLOCK] = 0.0f;
}
+ rate_values[RATE_ARENA_POINTS] = sConfigMgr->GetFloatDefault("Arena.Points.Rate", 1.0f);
+ if (rate_values[RATE_ARENA_POINTS] < 1.0f)
+ {
+ sLog->outError("Rate.ArenaPoints (%f) must be >=1. Using 1.0 instead.", rate_values[RATE_ARENA_POINTS]);
+ rate_values[RATE_ARENA_POINTS] = 1.0f;
+ }
///- Read other configuration items from the config file
m_bool_configs[CONFIG_DURABILITY_LOSS_IN_PVP] = sConfigMgr->GetBoolDefault("DurabilityLoss.InPvP", false);
@@ -1051,6 +1058,8 @@ void World::LoadConfigSettings(bool reload)
m_bool_configs[CONFIG_BATTLEGROUND_CAST_DESERTER] = sConfigMgr->GetBoolDefault("Battleground.CastDeserter", true);
m_bool_configs[CONFIG_BATTLEGROUND_RANDOM_CROSSFACTION] = sConfigMgr->GetBoolDefault("Battleground.RandomCrossFaction.Enable", true); // [AZTH] RBG Crossfaction
m_bool_configs[CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE] = sConfigMgr->GetBoolDefault("Battleground.QueueAnnouncer.Enable", false);
+ m_bool_configs[CONFIG_BATTLEGROUND_STORE_STATISTICS_ENABLE] = sConfigMgr->GetBoolDefault("Battleground.StoreStatistics.Enable", false);
+ m_bool_configs[CONFIG_BATTLEGROUND_TRACK_DESERTERS] = sConfigMgr->GetBoolDefault("Battleground.TrackDeserters.Enable", false);
m_int_configs[CONFIG_BATTLEGROUND_PREMATURE_FINISH_TIMER] = sConfigMgr->GetIntDefault ("Battleground.PrematureFinishTimer", 5 * MINUTE * IN_MILLISECONDS);
m_int_configs[CONFIG_BATTLEGROUND_PREMADE_GROUP_WAIT_FOR_MATCH] = sConfigMgr->GetIntDefault ("Battleground.PremadeGroupWaitForMatch", 30 * MINUTE * IN_MILLISECONDS);
m_bool_configs[CONFIG_BG_XP_FOR_KILL] = sConfigMgr->GetBoolDefault("Battleground.GiveXPForKills", false);
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index cbe8d5577d..c781ef0236 100644
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -129,6 +129,8 @@ enum WorldBoolConfigs
CONFIG_BATTLEGROUND_CAST_DESERTER,
CONFIG_BATTLEGROUND_RANDOM_CROSSFACTION, // [AZTH] RBG Crossfaction
CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE,
+ CONFIG_BATTLEGROUND_STORE_STATISTICS_ENABLE,
+ CONFIG_BATTLEGROUND_TRACK_DESERTERS,
CONFIG_BG_XP_FOR_KILL,
CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS,
CONFIG_ARENA_SEASON_IN_PROGRESS,
@@ -344,6 +346,7 @@ enum Rates
RATE_DROP_ITEM_REFERENCED_AMOUNT,
RATE_DROP_MONEY,
RATE_XP_KILL,
+ RATE_XP_BG_KILL,
RATE_XP_QUEST,
RATE_XP_EXPLORE,
RATE_REPAIRCOST,
@@ -375,6 +378,7 @@ enum Rates
RATE_AUCTION_DEPOSIT,
RATE_AUCTION_CUT,
RATE_HONOR,
+ RATE_ARENA_POINTS,
RATE_TALENT,
RATE_CORPSE_DECAY_LOOTED,
RATE_INSTANCE_RESET_TIME,
diff --git a/src/server/scripts/Commands/cs_character.cpp b/src/server/scripts/Commands/cs_character.cpp
index 99738ab4c8..d78de158b9 100644
--- a/src/server/scripts/Commands/cs_character.cpp
+++ b/src/server/scripts/Commands/cs_character.cpp
@@ -212,8 +212,8 @@ public:
if (newlevel < 1)
return false; // invalid level
- if (newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level
- newlevel = STRONG_MAX_LEVEL;
+ if (newlevel > DEFAULT_MAX_LEVEL) // hardcoded maximum level
+ newlevel = DEFAULT_MAX_LEVEL;
HandleCharacterLevel(target, targetGuid, oldlevel, newlevel, handler);
if (!handler->GetSession() || handler->GetSession()->GetPlayer() != target) // including player == NULL
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/instance_trial_of_the_champion.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/instance_trial_of_the_champion.cpp
index ee82e1458e..7a882fd2a9 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/instance_trial_of_the_champion.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/instance_trial_of_the_champion.cpp
@@ -7,10 +7,13 @@ REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
#include "trial_of_the_champion.h"
#include "Vehicle.h"
#include "Player.h"
+#include "Group.h"
const Position SpawnPosition = {746.67f, 684.08f, 412.5f, 4.65f};
#define CLEANUP_CHECK_INTERVAL 5000
+class Group;
+
class instance_trial_of_the_champion : public InstanceMapScript
{
public:
@@ -91,9 +94,11 @@ public:
if (TeamIdInInstance == TEAM_NEUTRAL)
{
Map::PlayerList const &players = instance->GetPlayers();
- if( !players.isEmpty() )
- if( Player* pPlayer = players.begin()->GetSource() )
- TeamIdInInstance = pPlayer->GetTeamId();
+ if (!players.isEmpty())
+ if (Player* pPlayer = players.begin()->GetSource())
+ if (Group * group = pPlayer->GetGroup())
+ if(Player* groupLeader = ObjectAccessor::GetPlayer(*pPlayer,group->GetLeaderGUID()))
+ TeamIdInInstance = groupLeader->GetTeamId();
}
switch( creature->GetEntry() )
diff --git a/src/server/scripts/Pet/pet_dk.cpp b/src/server/scripts/Pet/pet_dk.cpp
index 5265c91f01..25daa39faf 100644
--- a/src/server/scripts/Pet/pet_dk.cpp
+++ b/src/server/scripts/Pet/pet_dk.cpp
@@ -50,11 +50,7 @@ class npc_pet_dk_ebon_gargoyle : public CreatureScript
_despawnTimer = 36000; // 30 secs + 4 fly out + 2 initial attack timer
_despawning = false;
_initialSelection = true;
- _ghoulSelection = true;
-
_targetGUID = 0;
- _markedTargetGUID = 0;
- _ghoulTargetGUID = 0;
}
void MovementInform(uint32 type, uint32 point)
@@ -89,10 +85,31 @@ class npc_pet_dk_ebon_gargoyle : public CreatureScript
_initialCastTimer = 0;
}
+ uint64 GetGhoulTargetGUID()
+ {
+ uint64 ghoulTargetGUID = 0;
+
+ std::list<Unit*> targets;
+ Trinity::AnyFriendlyUnitInObjectRangeCheck ghoul_check(me, me, 50);
+ Trinity::UnitListSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(me, targets, ghoul_check);
+ me->VisitNearbyObject(50, searcher);
+ for (std::list<Unit*>::const_iterator iter = targets.begin(); iter != targets.end(); ++iter)
+ {
+ if ((*iter)->GetEntry() == 26125) // ghoul entry
+ if ((*iter)->GetOwnerGUID() == me->GetOwnerGUID()) // same owner
+ {
+ ghoulTargetGUID = (*iter)->GetTarget();
+ break;
+ }
+ }
+
+ return ghoulTargetGUID;
+ }
+
void MySelectNextTarget()
{
Unit* owner = me->GetOwner();
- if (owner && owner->GetTypeId() == TYPEID_PLAYER && (!me->GetVictim() || me->GetVictim()->IsImmunedToSpell(sSpellMgr->GetSpellInfo(51963)) || !me->IsValidAttackTarget(me->GetVictim()) || !owner->CanSeeOrDetect(me->GetVictim())))
+ if (owner && owner->GetTypeId() == TYPEID_PLAYER)
{
Unit* ghoulTarget = ObjectAccessor::GetUnit(*me, GetGhoulTargetGUID());
Unit* dkTarget = owner->ToPlayer()->GetSelectedUnit();
@@ -107,24 +124,29 @@ class npc_pet_dk_ebon_gargoyle : public CreatureScript
if (dkTarget && dkTarget != me->GetVictim() && me->IsValidAttackTarget(dkTarget))
{
me->GetMotionMaster()->Clear(false);
- SetGazeOn(selection);
+ SwitchTargetAndAttack(dkTarget);
+ return;
}
- else if (!me->GetVictim() || !owner->CanSeeOrDetect(me->GetVictim()))
+
+ if (!me->GetVictim() || !owner->CanSeeOrDetect(me->GetVictim()))
{
me->CombatStop(true);
me->GetMotionMaster()->Clear(false);
me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, 0.0f);
RemoveTargetAura();
+ return;
}
}
}
- void AttackStart(Unit* who)
+ void SwitchTargetAndAttack(Unit* who)
{
RemoveTargetAura();
_targetGUID = who->GetGUID();
+
me->AddAura(SPELL_DK_SUMMON_GARGOYLE_1, who);
ScriptedAI::AttackStart(who);
+ me->SetReactState(REACT_PASSIVE);
}
void RemoveTargetAura()
@@ -181,66 +203,18 @@ class npc_pet_dk_ebon_gargoyle : public CreatureScript
for (std::list<Unit*>::const_iterator iter = targets.begin(); iter != targets.end(); ++iter)
if ((*iter)->GetAura(SPELL_DK_SUMMON_GARGOYLE_1, me->GetOwnerGUID()))
{
- (*iter)->RemoveAura(SPELL_DK_SUMMON_GARGOYLE_1, me->GetOwnerGUID());
- SetGazeOn(*iter);
- _targetGUID = (*iter)->GetGUID();
- _markedTargetGUID = _targetGUID;
+ SwitchTargetAndAttack((*iter));
break;
}
}
- if (_ghoulSelection) //find pet ghoul target
- {
- std::list<Unit*> targets;
- Trinity::AnyFriendlyUnitInObjectRangeCheck ghoul_check(me, me, 50);
- Trinity::UnitListSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(me, targets, ghoul_check);
- me->VisitNearbyObject(50, searcher);
- for (std::list<Unit*>::const_iterator iter = targets.begin(); iter != targets.end(); ++iter)
- {
- if ((*iter)->GetEntry() == 26125) // ghoul entry
- {
- if ((*iter)->GetOwnerGUID() == me->GetOwnerGUID()) // same owner
- {
- _ghoulTargetGUID = (*iter)->GetTarget();
- break;
- }
- }
- }
- }
-
-
-
- if (Unit* ghoulTarget = ObjectAccessor::GetUnit(*me, _ghoulTargetGUID))
- {
- if(ghoulTarget->IsAlive())
- {
- AttackStart(ghoulTarget);
- }
- }
- else
- {
- _ghoulSelection = false; // check for ghoul at next update.
-
- if (Unit* markedTarget = ObjectAccessor::GetUnit(*me, _markedTargetGUID))
- {
- if (markedTarget->IsAlive())
- {
- AttackStart(markedTarget);
- }
- }
- }
-
if (_despawnTimer > 4000)
{
_despawnTimer -= diff;
- if (!UpdateVictimWithGaze())
- {
- MySelectNextTarget();
- return;
- }
_initialCastTimer += diff;
_selectionTimer += diff;
+
if (_selectionTimer >= 1000)
{
MySelectNextTarget();
@@ -266,14 +240,11 @@ class npc_pet_dk_ebon_gargoyle : public CreatureScript
private:
uint64 _targetGUID;
- uint64 _ghoulTargetGUID;
- uint64 _markedTargetGUID;
uint32 _despawnTimer;
uint32 _selectionTimer;
uint32 _initialCastTimer;
bool _despawning;
bool _initialSelection;
- bool _ghoulSelection;
};
CreatureAI* GetAI(Creature* creature) const
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
index b117fbfb95..0ef8d1fe86 100644
--- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
@@ -400,6 +400,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_SEL_CHAR_COD_ITEM_MAIL, "SELECT id, messageType, mailTemplateId, sender, subject, body, money, has_items FROM mail WHERE receiver = ? AND has_items <> 0 AND cod <> 0", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_CHAR_SOCIAL, "SELECT DISTINCT guid FROM character_social WHERE friend = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_CHAR_OLD_CHARS, "SELECT guid, deleteInfos_Account FROM characters WHERE deleteDate IS NOT NULL AND deleteDate < ?", CONNECTION_SYNCH);
+ PrepareStatement(CHAR_SEL_ARENA_TEAM_ID_BY_PLAYER_GUID, "SELECT arena_team_member.arenateamid FROM arena_team_member JOIN arena_team ON arena_team_member.arenateamid = arena_team.arenateamid WHERE guid = ? AND type = ? LIMIT 1", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_MAIL, "SELECT id, messageType, sender, receiver, subject, body, has_items, expire_time, deliver_time, money, cod, checked, stationery, mailTemplateId FROM mail WHERE receiver = ? ORDER BY id DESC", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_MAIL_ASYNCH, "SELECT ii.creatorGuid, ii.giftCreatorGuid, ii.count, ii.duration, ii.charges, ii.flags, ii.enchantments, ii.randomPropertyId, ii.durability, ii.playedTime, ii.text, mi.item_guid, ii.itemEntry, ii.owner_guid, mail.id, mail.messageType, mail.sender, mail.receiver, mail.subject, mail.body, mail.has_items, mail.expire_time, mail.deliver_time, mail.money, mail.cod, mail.checked, mail.stationery, mail.mailTemplateId FROM mail LEFT JOIN (mail_items mi JOIN item_instance ii) ON (mi.mail_id = mail.id AND mi.item_guid = ii.guid) WHERE mail.receiver = ? ORDER BY mail.id DESC", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHAR_PLAYERBYTES2, "SELECT playerBytes2 FROM characters WHERE guid = ?", CONNECTION_SYNCH);
@@ -554,4 +555,13 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_DEL_CHAR_PET_BY_ID, "DELETE FROM character_pet WHERE id = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHAR_PET_BY_SLOT, "DELETE FROM character_pet WHERE owner = ? AND (slot = ? OR slot > ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_REP_CHAR_PET, "REPLACE INTO character_pet (id, entry, owner, modelid, CreatedBySpell, PetType, level, exp, Reactstate, name, renamed, slot, curhealth, curmana, curhappiness, savetime, abdata) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
+
+ // PvPstats
+ PrepareStatement(CHAR_SEL_PVPSTATS_MAXID, "SELECT MAX(id) FROM pvpstats_battlegrounds", CONNECTION_SYNCH);
+ PrepareStatement(CHAR_INS_PVPSTATS_BATTLEGROUND, "INSERT INTO pvpstats_battlegrounds (id, winner_faction, bracket_id, type, date) VALUES (?, ?, ?, ?, NOW())", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_INS_PVPSTATS_PLAYER, "INSERT INTO pvpstats_players (battleground_id, character_guid, winner, score_killing_blows, score_deaths, score_honorable_kills, score_bonus_honor, score_damage_done, score_healing_done, attr_1, attr_2, attr_3, attr_4, attr_5) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_SEL_PVPSTATS_FACTIONS_OVERALL, "SELECT winner_faction, COUNT(*) AS count FROM pvpstats_battlegrounds WHERE DATEDIFF(NOW(), date) < 7 GROUP BY winner_faction ORDER BY winner_faction ASC", CONNECTION_SYNCH);
+
+ // Deserter tracker
+ PrepareStatement(CHAR_INS_DESERTER_TRACK, "INSERT INTO battleground_deserters (guid, type, datetime) VALUES (?, ?, NOW())", CONNECTION_ASYNC);
}
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h
index 0a25b7751e..43ee797e5f 100644
--- a/src/server/shared/Database/Implementation/CharacterDatabase.h
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.h
@@ -348,6 +348,7 @@ enum CharacterDatabaseStatements
CHAR_SEL_CHAR_COD_ITEM_MAIL,
CHAR_SEL_CHAR_SOCIAL,
CHAR_SEL_CHAR_OLD_CHARS,
+ CHAR_SEL_ARENA_TEAM_ID_BY_PLAYER_GUID,
CHAR_SEL_MAIL,
CHAR_SEL_MAIL_ASYNCH,
CHAR_SEL_CHAR_PLAYERBYTES2,
@@ -493,6 +494,13 @@ enum CharacterDatabaseStatements
CHAR_INS_ITEMCONTAINER_SINGLE_ITEM,
CHAR_DEL_ITEMCONTAINER_CONTAINER,
+ CHAR_SEL_PVPSTATS_MAXID,
+ CHAR_INS_PVPSTATS_BATTLEGROUND,
+ CHAR_INS_PVPSTATS_PLAYER,
+ CHAR_SEL_PVPSTATS_FACTIONS_OVERALL,
+
+ CHAR_INS_DESERTER_TRACK,
+
MAX_CHARACTERDATABASE_STATEMENTS
};
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index a0e8ccb40f..d9262d4b37 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -2167,7 +2167,7 @@ Rate.Drop.Item.ReferencedAmount = 1
# Rate.XP.Kill
# Rate.XP.Quest
# Rate.XP.Explore
-# Description: Experience rates.
+# Description: Experience rates (outside battleground)
# Default: 1 - (Rate.XP.Kill)
# 1 - (Rate.XP.Quest)
# 1 - (Rate.XP.Explore)
@@ -2177,6 +2177,14 @@ Rate.XP.Quest = 1
Rate.XP.Explore = 1
#
+# Rate.XP.BattlegroundKill
+# Description: Experience rate for honorable kills in battlegrounds,
+# it works when Battleground.GiveXPForKills = 1
+# Default: 1
+
+Rate.XP.BattlegroundKill = 1
+
+#
# Rate.RepairCost
# Description: Repair cost rate.
# Default: 1
@@ -2225,6 +2233,13 @@ Rate.Auction.Cut = 1
Rate.Honor = 1
#
+# Rate.ArenaPoints
+# Description: Arena points gain rate.
+# Default: 1
+
+Rate.ArenaPoints = 1
+
+#
# Rate.Mining.Amount
# Description: Rate for minimum/maximum times a deposit can be used.
# Default: 1
@@ -2449,14 +2464,6 @@ AutoBroadcast.Timer = 60000
Battleground.CastDeserter = 1
#
-# Battleground.RandomCrossFaction.Enable
-# Description: Enable random battleground crossfaction randomizing system
-# Default: 0 - (Disabled)
-# 1 - (Enabled)
-
-Battleground.RandomCrossFaction.Enable = 1
-
-#
# Battleground.QueueAnnouncer.Enable
# Description: Announce battleground queue status to chat.
# Default: 0 - (Disabled)
@@ -2472,15 +2479,6 @@ Battleground.QueueAnnouncer.Enable = 0
Battleground.QueueAnnouncer.PlayerOnly = 0
-#
-# Battleground.InvitationType
-# Description: Set Battleground invitation type.
-# Default: 0 - (Normal, Invite as much players to battlegrounds as queued,
-# Don't bother with balance)
-# 1 - (Experimental, Don't allow to invite much more players
-# of one faction)
-
-Battleground.InvitationType = 0
#
# Battleground.PrematureFinishTimer
@@ -2516,6 +2514,20 @@ Battleground.GiveXPForKills = 0
Battleground.Random.ResetHour = 6
+# Battleground.StoreStatistics.Enable
+# Description: Store Battleground scores in the database.
+# Default: 0 - (Disabled)
+# 1 - (Enabled)
+
+Battleground.StoreStatistics.Enable = 1
+
+# Battleground.TrackDeserters.Enable
+# Description: Track deserters of Battlegrounds.
+# Default: 0 - (Disabled)
+# 1 - (Enabled)
+
+Battleground.TrackDeserters.Enable = 1
+
#
###################################################################################################