started implementing battleground experience system
-players gain xp by killing enemy players (event bonuses not added for now) -player can switch xp gain on/off by talking to npc Slahtz or Behsten for a fee of 10golds NOTE: turning off xp gain will turn off ALL xp gains from quests,monsters,pvp,etc --HG-- branch : trunk
This commit is contained in:
@@ -0,0 +1 @@
|
|||||||
|
UPDATE `creature_template` SET `ScriptName` = 'npc_experience', `npcflag` = '1' WHERE `entry` IN (35364,35365);
|
||||||
@@ -1809,7 +1809,7 @@ void BattleGround::HandleKillPlayer(Player *player, Player *killer)
|
|||||||
|
|
||||||
// add +1 deaths
|
// add +1 deaths
|
||||||
UpdatePlayerScore(player, SCORE_DEATHS, 1);
|
UpdatePlayerScore(player, SCORE_DEATHS, 1);
|
||||||
|
RewardXPAtKill(killer, player);
|
||||||
// add +1 kills to group and +1 killing_blows to killer
|
// add +1 kills to group and +1 killing_blows to killer
|
||||||
if (killer)
|
if (killer)
|
||||||
{
|
{
|
||||||
@@ -1948,3 +1948,92 @@ void BattleGround::SetBracket(PvPDifficultyEntry const* bracketEntry)
|
|||||||
m_BracketId = bracketEntry->GetBracketId();
|
m_BracketId = bracketEntry->GetBracketId();
|
||||||
SetLevelRange(bracketEntry->minLevel,bracketEntry->maxLevel);
|
SetLevelRange(bracketEntry->minLevel,bracketEntry->maxLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BattleGround::RewardXPAtKill(Player* plr, Unit* victim)
|
||||||
|
{
|
||||||
|
if (!plr || !victim)
|
||||||
|
return;
|
||||||
|
|
||||||
|
uint32 xp = 0;
|
||||||
|
uint32 count = 0;
|
||||||
|
uint32 sum_level = 0;
|
||||||
|
Player* member_with_max_level = NULL;
|
||||||
|
Player* not_gray_member_with_max_level = NULL;
|
||||||
|
|
||||||
|
if (Group *pGroup = plr->GetGroup())//should be always in a raid group while in any bg
|
||||||
|
{
|
||||||
|
for (GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
|
||||||
|
{
|
||||||
|
Player* member = itr->getSource();
|
||||||
|
if (!member || !member->isAlive()) // only for alive
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!member->IsAtGroupRewardDistance(victim)) // at req. distance
|
||||||
|
continue;
|
||||||
|
|
||||||
|
++count;
|
||||||
|
sum_level += member->getLevel();
|
||||||
|
if (!member_with_max_level || member_with_max_level->getLevel() < member->getLevel())
|
||||||
|
member_with_max_level = member;
|
||||||
|
|
||||||
|
uint32 gray_level = Trinity::XP::GetGrayLevel(member->getLevel());
|
||||||
|
if (victim->getLevel() > gray_level && (!not_gray_member_with_max_level
|
||||||
|
|| not_gray_member_with_max_level->getLevel() < member->getLevel()))
|
||||||
|
not_gray_member_with_max_level = member;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (member_with_max_level)
|
||||||
|
{
|
||||||
|
xp = !not_gray_member_with_max_level ? 0 : Trinity::XP::Gain(not_gray_member_with_max_level, victim);
|
||||||
|
|
||||||
|
if (!xp)
|
||||||
|
return;
|
||||||
|
|
||||||
|
float group_rate = 1.0f;
|
||||||
|
|
||||||
|
for (GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
|
||||||
|
{
|
||||||
|
Player* pGroupGuy = itr->getSource();
|
||||||
|
if (!pGroupGuy)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!pGroupGuy->IsAtGroupRewardDistance(victim))
|
||||||
|
continue; // member (alive or dead) or his corpse at req. distance
|
||||||
|
|
||||||
|
float rate = group_rate * float(pGroupGuy->getLevel()) / sum_level;
|
||||||
|
|
||||||
|
// XP updated only for alive group member
|
||||||
|
if (pGroupGuy->isAlive() && not_gray_member_with_max_level && pGroupGuy->getLevel() <= not_gray_member_with_max_level->getLevel())
|
||||||
|
{
|
||||||
|
uint32 itr_xp = (member_with_max_level == not_gray_member_with_max_level) ? uint32(xp*rate) : uint32((xp*rate/2)+1);
|
||||||
|
|
||||||
|
// handle SPELL_AURA_MOD_XP_PCT auras
|
||||||
|
Unit::AuraEffectList const& ModXPPctAuras = plr->GetAuraEffectsByType(SPELL_AURA_MOD_XP_PCT);
|
||||||
|
for (Unit::AuraEffectList::const_iterator i = ModXPPctAuras.begin(); i != ModXPPctAuras.end(); ++i)
|
||||||
|
itr_xp = uint32(itr_xp*(1.0f + (*i)->GetAmount() / 100.0f));
|
||||||
|
|
||||||
|
pGroupGuy->GiveXP(itr_xp, victim);
|
||||||
|
if (Pet* pet = pGroupGuy->GetPet())
|
||||||
|
pet->GivePetXP(itr_xp/2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else//should be always in a raid group while in any BG, but you never know...
|
||||||
|
{
|
||||||
|
xp = Trinity::XP::Gain(plr, victim);
|
||||||
|
|
||||||
|
if (!xp)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// handle SPELL_AURA_MOD_XP_PCT auras
|
||||||
|
Unit::AuraEffectList const& ModXPPctAuras = plr->GetAuraEffectsByType(SPELL_AURA_MOD_XP_PCT);
|
||||||
|
for (Unit::AuraEffectList::const_iterator i = ModXPPctAuras.begin(); i != ModXPPctAuras.end(); ++i)
|
||||||
|
xp = uint32(xp*(1.0f + (*i)->GetAmount() / 100.0f));
|
||||||
|
|
||||||
|
plr->GiveXP(xp, victim);
|
||||||
|
|
||||||
|
if (Pet* pet = plr->GetPet())
|
||||||
|
pet->GivePetXP(xp);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -547,6 +547,8 @@ class BattleGround
|
|||||||
/* virtual score-array - get's used in bg-subclasses */
|
/* virtual score-array - get's used in bg-subclasses */
|
||||||
int32 m_TeamScores[BG_TEAMS_COUNT];
|
int32 m_TeamScores[BG_TEAMS_COUNT];
|
||||||
|
|
||||||
|
void RewardXPAtKill(Player* plr, Unit* victim);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//this method is called, when BG cannot spawn its own spirit guide, or something is wrong, It correctly ends BattleGround
|
//this method is called, when BG cannot spawn its own spirit guide, or something is wrong, It correctly ends BattleGround
|
||||||
void EndNow();
|
void EndNow();
|
||||||
|
|||||||
@@ -2063,6 +2063,10 @@ bool GossipSelect_npc_wormhole(Player* pPlayer, Creature* /*pCreature*/, uint32
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*######
|
||||||
|
## npc_pet_trainer
|
||||||
|
######*/
|
||||||
|
|
||||||
enum ePetTrainer
|
enum ePetTrainer
|
||||||
{
|
{
|
||||||
TEXT_ISHUNTER = 5838,
|
TEXT_ISHUNTER = 5838,
|
||||||
@@ -2377,7 +2381,64 @@ bool GossipSelect_npc_tabard_vendor(Player* pPlayer, Creature* pCreature, uint32
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*######
|
||||||
|
## npc_experience
|
||||||
|
######*/
|
||||||
|
|
||||||
|
#define EXP_COST 100000//10 00 00 copper (10golds)
|
||||||
|
#define GOSSIP_TEXT_EXP 14736
|
||||||
|
#define GOSSIP_XP_OFF "I no longer wish to gain experience."
|
||||||
|
#define GOSSIP_XP_ON "I wish to start gaining experience again."
|
||||||
|
|
||||||
|
|
||||||
|
bool GossipHello_npc_experience(Player* pPlayer, Creature* pCreature)
|
||||||
|
{
|
||||||
|
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_XP_OFF, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
|
||||||
|
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_XP_ON, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
|
||||||
|
pPlayer->PlayerTalkClass->SendGossipMenu(GOSSIP_TEXT_EXP, pCreature->GetGUID());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GossipSelect_npc_experience(Player* pPlayer, Creature* /*pCreature*/, uint32 /*uiSender*/, uint32 uiAction)
|
||||||
|
{
|
||||||
|
bool noXPGain = pPlayer->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_NO_XP_GAIN);
|
||||||
|
bool doSwitch = false;
|
||||||
|
|
||||||
|
switch(uiAction)
|
||||||
|
{
|
||||||
|
case GOSSIP_ACTION_INFO_DEF + 1://xp off
|
||||||
|
{
|
||||||
|
if (!noXPGain)//does gain xp
|
||||||
|
doSwitch = true;//switch to don't gain xp
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GOSSIP_ACTION_INFO_DEF + 2://xp on
|
||||||
|
{
|
||||||
|
if (noXPGain)//doesn't gain xp
|
||||||
|
doSwitch = true;//switch to gain xp
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (doSwitch)
|
||||||
|
{
|
||||||
|
if (pPlayer->GetMoney() < EXP_COST)
|
||||||
|
pPlayer->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, 0, 0, 0);
|
||||||
|
else if (noXPGain)
|
||||||
|
{
|
||||||
|
pPlayer->ModifyMoney(-EXP_COST);
|
||||||
|
pPlayer->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_NO_XP_GAIN);
|
||||||
|
}
|
||||||
|
else if (!noXPGain)
|
||||||
|
{
|
||||||
|
pPlayer->ModifyMoney(-EXP_COST);
|
||||||
|
pPlayer->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_NO_XP_GAIN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pPlayer->PlayerTalkClass->CloseGossip();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void AddSC_npcs_special()
|
void AddSC_npcs_special()
|
||||||
{
|
{
|
||||||
@@ -2528,6 +2589,12 @@ void AddSC_npcs_special()
|
|||||||
newscript->Name = "npc_tabard_vendor";
|
newscript->Name = "npc_tabard_vendor";
|
||||||
newscript->pGossipHello = &GossipHello_npc_tabard_vendor;
|
newscript->pGossipHello = &GossipHello_npc_tabard_vendor;
|
||||||
newscript->pGossipSelect = &GossipSelect_npc_tabard_vendor;
|
newscript->pGossipSelect = &GossipSelect_npc_tabard_vendor;
|
||||||
newscript->RegisterSelf();
|
newscript->RegisterSelf();
|
||||||
|
|
||||||
|
newscript = new Script;
|
||||||
|
newscript->Name = "npc_experience";
|
||||||
|
newscript->pGossipHello = &GossipHello_npc_experience;
|
||||||
|
newscript->pGossipSelect = &GossipSelect_npc_experience;
|
||||||
|
newscript->RegisterSelf();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user