*Update to Mangos 7183.

--HG--
branch : trunk
This commit is contained in:
megamage
2009-01-25 16:35:14 -06:00
parent 30f6b38941
commit ef88b04451
37 changed files with 914 additions and 646 deletions
+5 -1
View File
@@ -325,6 +325,10 @@ void AchievementMgr::CheckAllAchievementCriteria()
void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1, uint32 miscvalue2, Unit *unit, uint32 time)
{
sLog.outDetail("AchievementMgr::UpdateAchievementCriteria(%u, %u, %u, %u)", type, miscvalue1, miscvalue2, time);
if (!sWorld.getConfig(CONFIG_GM_ALLOW_ACHIEVEMENT_GAINS) && m_player->GetSession()->GetSecurity() > SEC_PLAYER)
return;
AchievementCriteriaEntryList const& achievementCriteriaList = achievementmgr.GetAchievementCriteriaByType(type);
for(AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList.begin(); i!=achievementCriteriaList.end(); ++i)
{
@@ -930,7 +934,7 @@ void AchievementGlobalMgr::LoadAchievementCriteriaList()
}
sLog.outString();
sLog.outErrorDb(">> Loaded %u achievement criteria.",m_AchievementCriteriasByType->size());
sLog.outString(">> Loaded %u achievement criteria.",m_AchievementCriteriasByType->size());
}
+12 -20
View File
@@ -1244,17 +1244,18 @@ void BattleGroundMgr::BuildBattleGroundStatusPacket(WorldPacket *data, BattleGro
void BattleGroundMgr::BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg)
{
uint8 type = (bg->isArena() ? 1 : 0);
// last check on 2.4.1
// last check on 3.0.3
data->Initialize(MSG_PVP_LOG_DATA, (1+1+4+40*bg->GetPlayerScoresSize()));
*data << uint8(type); // seems to be type (battleground=0/arena=1)
*data << uint8(type); // type (battleground=0/arena=1)
if(type) // arena
{
// it seems this must be according to BG_WINNER_A/H and _NOT_ BG_TEAM_A/H
for(int i = 1; i >= 0; --i)
{
*data << uint32(3000-bg->m_ArenaTeamRatingChanges[i]); // rating change: showed value - 3000
*data << uint32(bg->m_ArenaTeamRatingChanges[i]);
*data << uint32(3999); // huge thanks for TOM_RUS for this!
*data << uint32(0); // unknown - new in 3.0.3
sLog.outDebug("rating change: %d", bg->m_ArenaTeamRatingChanges[i]);
}
for(int i = 1; i >= 0; --i)
@@ -1268,9 +1269,9 @@ void BattleGroundMgr::BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg)
}
}
if(bg->GetWinner() == 2)
if(bg->GetStatus() != STATUS_WAIT_LEAVE)
{
*data << uint8(0); // bg in progress
*data << uint8(0); // bg not ended
}
else
{
@@ -1284,9 +1285,6 @@ void BattleGroundMgr::BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg)
{
*data << (uint64)itr->first;
*data << (int32)itr->second->KillingBlows;
Player *plr = objmgr.GetPlayer(itr->first);
uint32 team = bg->GetPlayerTeam(itr->first);
if(!team && plr) team = plr->GetTeam();
if(type == 0)
{
*data << (int32)itr->second->HonorableKills;
@@ -1295,18 +1293,12 @@ void BattleGroundMgr::BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg)
}
else
{
// that part probably wrong
if(plr)
{
if(team == HORDE)
*data << uint8(0);
else if(team == ALLIANCE)
{
*data << uint8(1);
}
else
*data << uint8(0);
}
Player *plr = objmgr.GetPlayer(itr->first);
uint32 team = bg->GetPlayerTeam(itr->first);
if(!team && plr)
team = plr->GetTeam();
if( ( bg->GetWinner()==0 && team == ALLIANCE ) || ( bg->GetWinner()==1 && team==HORDE ) )
*data << uint8(1);
else
*data << uint8(0);
}
+53 -18
View File
@@ -36,6 +36,22 @@
#include "AccountMgr.h"
#include "TicketMgr.h"
// Supported shift-links (client generated and server side)
// |color|Harea:area_id|h[name]|h|r
// |color|Hcreature:creature_guid|h[name]|h|r
// |color|Hcreature_entry:creature_id|h[name]|h|r
// |color|Hgameevent:id|h[name]|h|r
// |color|Hgameobject:go_guid|h[name]|h|r
// |color|Hgameobject_entry:go_id|h[name]|h|r
// |color|Hitem:item_id:perm_ench_id:0:0|h[name]|h|r
// |color|Hitemset:itemset_id|h[name]|h|r
// |color|Hquest:quest_id|h[name]|h|r
// |color|Hskill:skill_id|h[name]|h|r
// |color|Hspell:spell_id|h[name]|h|r - client, spellbook spell icon shift-click
// |color|Htalent:talent_id,rank|h[name]|h|r - client, talent icon shift-click
// |color|Htele:id|h[name]|h|r
// |color|Htrade:spell_id,cur_value,max_value,unk3int,unk3str|h[name]|h|r - client, spellbook profession icon shift-click
bool ChatHandler::load_command_table = true;
ChatCommand * ChatHandler::getCommandTable()
@@ -1317,9 +1333,18 @@ GameObject* ChatHandler::GetObjectGlobalyWithGuidOrNearWithDbGuid(uint32 lowguid
return obj;
}
static char const* const spellTalentKeys[] = {
"Hspell",
"Htalent",
enum SpellLinkType
{
SPELL_LINK_SPELL = 0,
SPELL_LINK_TALENT = 1,
SPELL_LINK_TRADE = 2
};
static char const* const spellKeys[] =
{
"Hspell", // normal spell
"Htalent", // talent spell
"Htrade", // profession/skill spell
0
};
@@ -1327,31 +1352,41 @@ uint32 ChatHandler::extractSpellIdFromLink(char* text)
{
// number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
// number or [name] Shift-click form |color|Htalent:talent_id,rank|h[name]|h|r
// number or [name] Shift-click form |color|Htrade:spell_id,skill_id,max_value,cur_value|h[name]|h|r
int type = 0;
char* rankS = NULL;
char* idS = extractKeyFromLink(text,spellTalentKeys,&type,&rankS);
char* param1_str = NULL;
char* idS = extractKeyFromLink(text,spellKeys,&type,&param1_str);
if(!idS)
return 0;
uint32 id = (uint32)atol(idS);
// spell
if(type==0)
return id;
switch(type)
{
case SPELL_LINK_SPELL:
return id;
case SPELL_LINK_TALENT:
{
// talent
TalentEntry const* talentEntry = sTalentStore.LookupEntry(id);
if(!talentEntry)
return 0;
// talent
TalentEntry const* talentEntry = sTalentStore.LookupEntry(id);
if(!talentEntry)
return 0;
int32 rank = param1_str ? (uint32)atol(param1_str) : 0;
if(rank >= 5)
return 0;
int32 rank = rankS ? (uint32)atol(rankS) : 0;
if(rank >= 5)
return 0;
if(rank < 0)
rank = 0;
if(rank < 0)
rank = 0;
return talentEntry->RankID[rank];
}
case SPELL_LINK_TRADE:
return id;
}
return talentEntry->RankID[rank];
// unknown type?
return 0;
}
GameTele const* ChatHandler::extractGameTeleFromLink(char* text)
+2
View File
@@ -499,8 +499,10 @@ class ChatHandler
Player* getSelectedPlayer();
Creature* getSelectedCreature();
Unit* getSelectedUnit();
char* extractKeyFromLink(char* text, char const* linkType, char** something1 = NULL);
char* extractKeyFromLink(char* text, char const* const* linkTypes, int* found_idx, char** something1 = NULL);
uint32 extractSpellIdFromLink(char* text);
GameTele const* extractGameTeleFromLink(char* text);
bool GetPlayerGroupAndGUIDByName(const char* cname, Player* &plr, Group* &group, uint64 &guid, bool offline = false);
+3 -3
View File
@@ -360,8 +360,8 @@ void GameObject::Update(uint32 /*p_time*/)
{
//Unit *caster = owner ? owner : ok;
//caster->CastSpell(ok, goInfo->trap.spellId, true);
CastSpell(ok, goInfo->trap.spellId);
//caster->CastSpell(ok, goInfo->trap.spellId, true, 0, 0, GetGUID());
m_cooldownTime = time(NULL) + 4; // 4 seconds
if(NeedDespawn)
@@ -411,7 +411,7 @@ void GameObject::Update(uint32 /*p_time*/)
for (; it != end; it++)
{
Unit* owner = Unit::GetUnit(*this, uint64(*it));
if (owner) owner->CastSpell(owner, spellId, false);
if (owner) owner->CastSpell(owner, spellId, false, 0, 0, GetGUID());
}
m_unique_users.clear();
@@ -826,7 +826,7 @@ void GameObject::TriggeringLinkedGameObject( uint32 trapEntry, Unit* target)
// found correct GO
// FIXME: when GO casting will be implemented trap must cast spell to target
if(trapGO)
target->CastSpell(target,trapSpell,true);
target->CastSpell(target,trapSpell,true, 0, 0, GetGUID());
}
GameObject* GameObject::LookupFishingHoleAround(float range)
+2 -2
View File
@@ -3742,7 +3742,7 @@ bool ChatHandler::HandleLearnAllCraftsCommand(const char* /*args*/)
if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
continue;
m_session->GetPlayer()->learnSpell(skillLine->spellId);
m_session->GetPlayer()->learnSpell(skillLine->spellId,false);
}
}
}
@@ -3815,7 +3815,7 @@ bool ChatHandler::HandleLearnAllRecipesCommand(const char* args)
continue;
if( !target->HasSpell(spellInfo->Id) )
m_session->GetPlayer()->learnSpell(skillLine->spellId);
m_session->GetPlayer()->learnSpell(skillLine->spellId,false);
}
uint16 maxLevel = target->GetPureMaxSkillValue(skillInfo->id);
+74 -69
View File
@@ -1292,7 +1292,7 @@ bool ChatHandler::HandleSetSkillCommand(const char* args)
{
// number or [name] Shift-click form |color|Hskill:skill_id|h[name]|h|r
char* skill_p = extractKeyFromLink((char*)args,"Hskill");
if(!skill_p)
if(!skill_p)
return false;
char *level_p = strtok (NULL, " ");
@@ -1303,7 +1303,6 @@ bool ChatHandler::HandleSetSkillCommand(const char* args)
char *max_p = strtok (NULL, " ");
int32 skill = atoi(skill_p);
if (skill <= 0)
{
PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
@@ -1353,27 +1352,12 @@ bool ChatHandler::HandleUnLearnCommand(const char* args)
return false;
// number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
uint32 min_id = extractSpellIdFromLink((char*)args);
if(!min_id)
uint32 spell_id = extractSpellIdFromLink((char*)args);
if(!spell_id)
return false;
// number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
char* tail = strtok(NULL,"");
uint32 max_id = extractSpellIdFromLink(tail);
if (!max_id)
{
// number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
max_id = min_id+1;
}
else
{
if (max_id < min_id)
std::swap(min_id,max_id);
max_id=max_id+1;
}
char const* allStr = strtok(NULL," ");
bool allRanks = allStr ? (strncmp(allStr, "all", strlen(allStr)) == 0) : false;
Player* target = getSelectedPlayer();
if(!target)
@@ -1383,13 +1367,13 @@ bool ChatHandler::HandleUnLearnCommand(const char* args)
return false;
}
for(uint32 spell=min_id;spell<max_id;spell++)
{
if (target->HasSpell(spell))
target->removeSpell(spell);
else
SendSysMessage(LANG_FORGET_SPELL);
}
if(allRanks)
spell_id = spellmgr.GetFirstSpellInChain (spell_id);
if (target->HasSpell(spell_id))
target->removeSpell(spell_id,false,!allRanks);
else
SendSysMessage(LANG_FORGET_SPELL);
return true;
}
@@ -2054,7 +2038,7 @@ bool ChatHandler::HandleLearnAllCommand(const char* /*args*/)
continue;
}
m_session->GetPlayer()->learnSpell(spell);
m_session->GetPlayer()->learnSpell(spell,false);
}
SendSysMessage(LANG_COMMAND_LEARN_MANY_SPELLS);
@@ -2094,7 +2078,7 @@ bool ChatHandler::HandleLearnAllGMCommand(const char* /*args*/)
continue;
}
m_session->GetPlayer()->learnSpell(spell);
m_session->GetPlayer()->learnSpell(spell,false);
}
SendSysMessage(LANG_LEARNING_GM_SKILLS);
@@ -2142,27 +2126,13 @@ bool ChatHandler::HandleLearnAllMySpellsCommand(const char* /*args*/)
if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
continue;
m_session->GetPlayer()->learnSpell(i);
m_session->GetPlayer()->learnSpell(i,false);
}
SendSysMessage(LANG_COMMAND_LEARN_CLASS_SPELLS);
return true;
}
static void learnAllHighRanks(Player* player, uint32 spellid)
{
SpellChainNode const* node;
do
{
node = spellmgr.GetSpellChainNode(spellid);
player->learnSpell(spellid);
if (!node)
break;
spellid=node->next;
}
while (node->next);
}
bool ChatHandler::HandleLearnAllMyTalentsCommand(const char* /*args*/)
{
Player* player = m_session->GetPlayer();
@@ -2200,11 +2170,8 @@ bool ChatHandler::HandleLearnAllMyTalentsCommand(const char* /*args*/)
if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
continue;
// learn highest rank of talent
player->learnSpell(spellid);
// and learn all non-talent spell ranks (recursive by tree)
learnAllHighRanks(player,spellid);
// learn highest rank of talent and learn all non-talent spell ranks (recursive by tree)
player->learnSpellHighRank(spellid);
}
SendSysMessage(LANG_COMMAND_LEARN_CLASS_TALENTS);
@@ -2215,7 +2182,7 @@ bool ChatHandler::HandleLearnAllLangCommand(const char* /*args*/)
{
// skipping UNIVERSAL language (0)
for(int i = 1; i < LANGUAGES_COUNT; ++i)
m_session->GetPlayer()->learnSpell(lang_description[i].spell_id);
m_session->GetPlayer()->learnSpell(lang_description[i].spell_id,false);
SendSysMessage(LANG_COMMAND_LEARN_ALL_LANG);
return true;
@@ -2271,15 +2238,8 @@ bool ChatHandler::HandleLearnCommand(const char* args)
if(!spell || !sSpellStore.LookupEntry(spell))
return false;
if (targetPlayer->HasSpell(spell))
{
if(targetPlayer == m_session->GetPlayer())
SendSysMessage(LANG_YOU_KNOWN_SPELL);
else
PSendSysMessage(LANG_TARGET_KNOWN_SPELL,targetPlayer->GetName());
SetSentErrorMessage(true);
return false;
}
char const* allStr = strtok(NULL," ");
bool allRanks = allStr ? (strncmp(allStr, "all", strlen(allStr)) == 0) : false;
SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer()))
@@ -2289,7 +2249,20 @@ bool ChatHandler::HandleLearnCommand(const char* args)
return false;
}
targetPlayer->learnSpell(spell);
if (!allRanks && targetPlayer->HasSpell(spell))
{
if(targetPlayer == m_session->GetPlayer())
SendSysMessage(LANG_YOU_KNOWN_SPELL);
else
PSendSysMessage(LANG_TARGET_KNOWN_SPELL,targetPlayer->GetName());
SetSentErrorMessage(true);
return false;
}
if(allRanks)
targetPlayer->learnSpellHighRank(spell);
else
targetPlayer->learnSpell(spell,false);
return true;
}
@@ -4703,11 +4676,28 @@ bool ChatHandler::HandleListAurasCommand (const char * /*args*/)
for (Unit::AuraMap::const_iterator itr = uAuras.begin(); itr != uAuras.end(); ++itr)
{
bool talent = GetTalentSpellCost(itr->second->GetId()) > 0;
PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(),
itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(),
itr->second->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()],
(itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID()));
char const* name = itr->second->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()];
if (m_session)
{
std::ostringstream ss_name;
ss_name << "|cffffffff|Hspell:" << itr->second->GetId() << "|h[" << name << "]|h|r";
PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(),
itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(),
ss_name.str().c_str(),
(itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID()));
}
else
{
PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(),
itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(),
name,
(itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID()));
}
}
for (int i = 0; i < TOTAL_AURAS; i++)
{
@@ -4717,9 +4707,24 @@ bool ChatHandler::HandleListAurasCommand (const char * /*args*/)
for (Unit::AuraList::const_iterator itr = uAuraList.begin(); itr != uAuraList.end(); ++itr)
{
bool talent = GetTalentSpellCost((*itr)->GetId()) > 0;
PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(),
(*itr)->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()],((*itr)->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
IS_PLAYER_GUID((*itr)->GetCasterGUID()) ? "player" : "creature",GUID_LOPART((*itr)->GetCasterGUID()));
char const* name = (*itr)->GetSpellProto()->SpellName[m_session->GetSessionDbcLocale()];
if (m_session)
{
std::ostringstream ss_name;
ss_name << "|cffffffff|Hspell:" << (*itr)->GetId() << "|h[" << name << "]|h|r";
PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(),
ss_name.str().c_str(),((*itr)->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
IS_PLAYER_GUID((*itr)->GetCasterGUID()) ? "player" : "creature",GUID_LOPART((*itr)->GetCasterGUID()));
}
else
{
PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(),
name,((*itr)->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
IS_PLAYER_GUID((*itr)->GetCasterGUID()) ? "player" : "creature",GUID_LOPART((*itr)->GetCasterGUID()));
}
}
}
return true;
+11 -13
View File
@@ -243,24 +243,22 @@ void WorldSession::HandleTrainerBuySpellOpcode( WorldPacket & recv_data )
_player->ModifyMoney( -int32(nSpellCost) );
WorldPacket data(SMSG_PLAY_SPELL_VISUAL, 12); // visual effect on trainer
data << uint64(guid) << uint32(0xB3);
SendPacket(&data);
data.Initialize(SMSG_PLAY_SPELL_IMPACT, 12); // visual effect on player
data << uint64(_player->GetGUID()) << uint32(0x016A);
SendPacket(&data);
// learn explicitly or cast explicitly
if(trainer_spell->IsCastable ())
//FIXME: prof. spell entry in trainer list not marked gray until list re-open.
unit->CastSpell(_player,trainer_spell->spell,true);
_player->CastSpell(_player,trainer_spell->spell,true);
else
{
WorldPacket data(SMSG_PLAY_SPELL_VISUAL, 12); // visual effect on trainer
data << uint64(guid) << uint32(0xB3);
SendPacket(&data);
_player->learnSpell(spellId,false);
data.Initialize(SMSG_PLAY_SPELL_IMPACT, 12); // visual effect on player
data << uint64(_player->GetGUID()) << uint32(0x016A);
SendPacket(&data);
_player->learnSpell(spellId);
}
WorldPacket data(SMSG_TRAINER_BUY_SUCCEEDED, 12);
data.Initialize(SMSG_TRAINER_BUY_SUCCEEDED, 12);
data << uint64(guid) << uint32(trainer_spell->spell);
SendPacket(&data);
}
+22 -7
View File
@@ -173,11 +173,16 @@ Corpse*
ObjectAccessor::GetCorpse(WorldObject const &u, uint64 guid)
{
Corpse * ret = GetObjectInWorld(guid, (Corpse*)NULL);
if(ret && ret->GetMapId() != u.GetMapId()) ret = NULL;
if(!ret)
return NULL;
if(ret->GetMapId() != u.GetMapId())
ret = NULL;
if(ret->GetInstanceId() != u.GetInstanceId())
return NULL;
return ret;
}
Object* ObjectAccessor::GetObjectByTypeMask(Player const &p, uint64 guid, uint32 typemask)
Object* ObjectAccessor::GetObjectByTypeMask(WorldObject const &p, uint64 guid, uint32 typemask)
{
Object *obj = NULL;
@@ -205,9 +210,9 @@ Object* ObjectAccessor::GetObjectByTypeMask(Player const &p, uint64 guid, uint32
if(obj) return obj;
}
if(typemask & TYPEMASK_ITEM)
if(typemask & TYPEMASK_ITEM && p.GetTypeId() == TYPEID_PLAYER)
{
obj = p.GetItemByGuid( guid );
obj = ((Player const &)p).GetItemByGuid( guid );
if(obj) return obj;
}
@@ -218,15 +223,25 @@ GameObject*
ObjectAccessor::GetGameObject(WorldObject const &u, uint64 guid)
{
GameObject * ret = GetObjectInWorld(guid, (GameObject*)NULL);
if(ret && ret->GetMapId() != u.GetMapId()) ret = NULL;
if(!ret)
return NULL;
if(ret->GetMapId() != u.GetMapId())
ret = NULL;
if(ret->GetInstanceId() != u.GetInstanceId())
return NULL;
return ret;
}
DynamicObject*
ObjectAccessor::GetDynamicObject(Unit const &u, uint64 guid)
ObjectAccessor::GetDynamicObject(WorldObject const &u, uint64 guid)
{
DynamicObject * ret = GetObjectInWorld(guid, (DynamicObject*)NULL);
if(ret && ret->GetMapId() != u.GetMapId()) ret = NULL;
if(!ret)
return NULL;
if(ret->GetMapId() != u.GetMapId())
ret = NULL;
if(ret->GetInstanceId() != u.GetInstanceId())
return NULL;
return ret;
}
+2 -2
View File
@@ -138,7 +138,7 @@ class TRINITY_DLL_DECL ObjectAccessor : public Trinity::Singleton<ObjectAccessor
else return NULL;
}
static Object* GetObjectByTypeMask(Player const &, uint64, uint32 typemask);
static Object* GetObjectByTypeMask(WorldObject const &, uint64, uint32 typemask);
static Creature* GetNPCIfCanInteractWith(Player const &player, uint64 guid, uint32 npcflagmask);
static Creature* GetCreature(WorldObject const &, uint64);
static Creature* GetCreatureOrPetOrVehicle(WorldObject const &, uint64);
@@ -146,7 +146,7 @@ class TRINITY_DLL_DECL ObjectAccessor : public Trinity::Singleton<ObjectAccessor
static Pet* GetPet(Unit const &, uint64 guid) { return GetPet(guid); }
static Player* GetPlayer(Unit const &, uint64 guid) { return FindPlayer(guid); }
static GameObject* GetGameObject(WorldObject const &, uint64);
static DynamicObject* GetDynamicObject(Unit const &, uint64);
static DynamicObject* GetDynamicObject(WorldObject const &, uint64);
static Corpse* GetCorpse(WorldObject const &u, uint64 guid);
static Pet* GetPet(uint64 guid);
static Vehicle* GetVehicle(uint64 guid);
+21 -3
View File
@@ -6486,11 +6486,18 @@ void ObjectMgr::LoadReservedPlayersNames()
bar.step();
fields = result->Fetch();
std::string name= fields[0].GetCppString();
if(normalizePlayerName(name))
std::wstring wstr;
if(!Utf8toWStr (name,wstr))
{
m_ReservedNames.insert(name);
++count;
sLog.outError("Table `reserved_name` have invalid name: %s", name.c_str() );
continue;
}
wstrToLower(wstr);
m_ReservedNames.insert(wstr);
++count;
} while ( result->NextRow() );
delete result;
@@ -6499,6 +6506,17 @@ void ObjectMgr::LoadReservedPlayersNames()
sLog.outString( ">> Loaded %u reserved player names", count );
}
bool ObjectMgr::IsReservedName( const std::string& name ) const
{
std::wstring wstr;
if(!Utf8toWStr (name,wstr))
return false;
wstrToLower(wstr);
return m_ReservedNames.find(wstr) != m_ReservedNames.end();
}
enum LanguageType
{
LT_BASIC_LATIN = 0x0000,
+2 -5
View File
@@ -736,10 +736,7 @@ class ObjectMgr
// reserved names
void LoadReservedPlayersNames();
bool IsReservedName(const std::string& name) const
{
return m_ReservedNames.find(name) != m_ReservedNames.end();
}
bool IsReservedName(const std::string& name) const;
// name with valid structure and symbols
static bool IsValidName( const std::string& name, bool create = false );
@@ -872,7 +869,7 @@ class ObjectMgr
PetCreateSpellMap mPetCreateSpell;
//character reserved names
typedef std::set<std::string> ReservedNamesMap;
typedef std::set<std::wstring> ReservedNamesMap;
ReservedNamesMap m_ReservedNames;
std::set<uint32> m_DisabledPlayerSpells;
+15 -32
View File
@@ -41,25 +41,14 @@ char const* petTypeSuffix[MAX_PET_TYPE] =
"'s Companion" // MINI_PET
};
Pet::Pet(PetType type) : Creature()
Pet::Pet(PetType type) :
Creature(), m_petType(type), m_removed(false), m_happinessTimer(7500), m_duration(0), m_bonusdamage(0),
m_resetTalentsCost(0), m_resetTalentsTime(0), m_usedTalentCount(0), m_auraUpdateMask(0), m_loading(false),
m_declinedname(NULL)
{
m_isPet = true;
m_name = "Pet";
m_petType = type;
m_removed = false;
m_regenTimer = 4000;
m_happinessTimer = 7500;
m_duration = 0;
m_bonusdamage = 0;
m_resetTalentsCost = 0;
m_resetTalentsTime = 0;
m_usedTalentCount = 0;
m_auraUpdateMask = 0;
m_loading = false;
// pets always have a charminfo, even if they are not actually charmed
CharmInfo* charmInfo = InitCharmInfo(this);
@@ -69,12 +58,6 @@ Pet::Pet(PetType type) : Creature()
else if(type == GUARDIAN_PET) // always aggressive
charmInfo->SetReactState(REACT_AGGRESSIVE);
m_spells.clear();
m_Auras.clear();
m_CreatureSpellCooldowns.clear();
m_CreatureCategoryCooldowns.clear();
m_autospells.clear();
m_declinedname = NULL;
m_isActive = true;
}
@@ -1117,7 +1100,7 @@ void Pet::_LoadSpells()
{
Field *fields = result->Fetch();
addSpell(fields[0].GetUInt16(), fields[1].GetUInt16(), PETSPELL_UNCHANGED);
addSpell(fields[0].GetUInt32(), fields[1].GetUInt16(), PETSPELL_UNCHANGED);
}
while( result->NextRow() );
@@ -1270,7 +1253,7 @@ void Pet::_SaveAuras()
}
}
bool Pet::addSpell(uint16 spell_id, uint16 active, PetSpellState state, PetSpellType type)
bool Pet::addSpell(uint32 spell_id, uint16 active, PetSpellState state, PetSpellType type)
{
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell_id);
if (!spellInfo)
@@ -1387,7 +1370,7 @@ bool Pet::addSpell(uint16 spell_id, uint16 active, PetSpellState state, PetSpell
return true;
}
bool Pet::learnSpell(uint16 spell_id)
bool Pet::learnSpell(uint32 spell_id)
{
// prevent duplicated entires in spell book
if (!addSpell(spell_id))
@@ -1424,7 +1407,7 @@ void Pet::learnLevelupSpells()
}
}
bool Pet::unlearnSpell(uint16 spell_id)
bool Pet::unlearnSpell(uint32 spell_id)
{
if(removeSpell(spell_id))
{
@@ -1442,7 +1425,7 @@ bool Pet::unlearnSpell(uint16 spell_id)
return false;
}
bool Pet::removeSpell(uint16 spell_id)
bool Pet::removeSpell(uint32 spell_id)
{
PetSpellMap::iterator itr = m_spells.find(spell_id);
if (itr == m_spells.end())
@@ -1476,7 +1459,7 @@ bool Pet::removeSpell(uint16 spell_id)
return true;
}
bool Pet::_removeSpell(uint16 spell_id)
bool Pet::_removeSpell(uint32 spell_id)
{
PetSpellMap::iterator itr = m_spells.find(spell_id);
if (itr != m_spells.end())
@@ -1493,7 +1476,7 @@ void Pet::InitPetCreateSpells()
m_charmInfo->InitPetActionBar();
m_spells.clear();
int32 petspellid;
uint32 petspellid;
PetCreateSpellEntry const* CreateSpells = objmgr.GetPetCreateSpellEntry(GetEntry());
if(CreateSpells)
{
@@ -1513,7 +1496,7 @@ void Pet::InitPetCreateSpells()
if(owner->GetTypeId() == TYPEID_PLAYER && !((Player*)owner)->HasSpell(learn_spellproto->Id))
{
if(IsPassiveSpell(petspellid)) //learn passive skills when tamed, not sure if thats right
((Player*)owner)->learnSpell(learn_spellproto->Id);
((Player*)owner)->learnSpell(learn_spellproto->Id,false);
else
AddTeachSpell(learn_spellproto->EffectTriggerSpell[0], learn_spellproto->Id);
}
@@ -1547,7 +1530,7 @@ void Pet::CheckLearning(uint32 spellid)
if(urand(0, 100) < 10)
{
((Player*)owner)->learnSpell(itr->second);
((Player*)owner)->learnSpell(itr->second,false);
m_teachspells.erase(itr);
}
}
@@ -1693,7 +1676,7 @@ void Pet::ToggleAutocast(uint32 spellid, bool apply)
// && tempSpell->EffectImplicitTargetA[0] != TARGET_CHAIN_DAMAGE)
// return;
PetSpellMap::const_iterator itr = m_spells.find((uint16)spellid);
PetSpellMap::const_iterator itr = m_spells.find(spellid);
int i;
@@ -1747,7 +1730,7 @@ bool Pet::Create(uint32 guidlow, Map *map, uint32 Entry, uint32 pet_number)
bool Pet::HasSpell(uint32 spell) const
{
PetSpellMap::const_iterator itr = m_spells.find((uint16)spell);
PetSpellMap::const_iterator itr = m_spells.find(spell);
return (itr != m_spells.end() && itr->second->state != PETSPELL_REMOVED );
}
+6 -6
View File
@@ -105,7 +105,7 @@ enum PetNameInvalidReason
PET_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME = 16
};
typedef UNORDERED_MAP<uint16, PetSpell*> PetSpellMap;
typedef UNORDERED_MAP<uint32, PetSpell*> PetSpellMap;
typedef std::map<uint32,uint32> TeachSpellMap;
typedef std::vector<uint32> AutoSpellList;
@@ -190,12 +190,12 @@ class Pet : public Creature
void _LoadSpells();
void _SaveSpells();
bool addSpell(uint16 spell_id,uint16 active = ACT_DECIDE, PetSpellState state = PETSPELL_NEW, PetSpellType type = PETSPELL_NORMAL);
bool learnSpell(uint16 spell_id);
bool addSpell(uint32 spell_id,uint16 active = ACT_DECIDE, PetSpellState state = PETSPELL_NEW, PetSpellType type = PETSPELL_NORMAL);
bool learnSpell(uint32 spell_id);
void learnLevelupSpells();
bool unlearnSpell(uint16 spell_id);
bool removeSpell(uint16 spell_id);
bool _removeSpell(uint16 spell_id);
bool unlearnSpell(uint32 spell_id);
bool removeSpell(uint32 spell_id);
bool _removeSpell(uint32 spell_id);
PetSpellMap m_spells;
TeachSpellMap m_teachspells;
+309 -208
View File
@@ -2649,7 +2649,7 @@ void Player::AddNewMailDeliverTime(time_t deliver_time)
}
}
bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool disabled)
bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependent, bool disabled)
{
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell_id);
if (!spellInfo)
@@ -2682,29 +2682,80 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool disabled
PlayerSpellState state = learning ? PLAYERSPELL_NEW : PLAYERSPELL_UNCHANGED;
bool dependent_set = false;
bool disabled_case = false;
bool superceded_old = false;
PlayerSpellMap::iterator itr = m_spells.find(spell_id);
if (itr != m_spells.end())
{
uint32 next_active_spell_id = 0;
// fix activate state for non-stackable low rank (and find next spell for !active case)
if(!SpellMgr::canStackSpellRanks(spellInfo) && spellmgr.GetSpellRank(spellInfo->Id) != 0)
{
if(uint32 next = spellmgr.GetNextSpellInChain(spell_id))
{
if(HasSpell(next))
{
// high rank already known so this must !active
active = false;
next_active_spell_id = next;
}
}
}
// not do anything if already known in expected state
if(itr->second->state != PLAYERSPELL_REMOVED && itr->second->active == active &&
itr->second->dependent == dependent && itr->second->disabled == disabled)
{
if(!IsInWorld() && !learning) // explicitly load from DB and then exist in it already and set correctly
itr->second->state = PLAYERSPELL_UNCHANGED;
return false;
}
// dependent spell known as not dependent, overwrite state
if (itr->second->state != PLAYERSPELL_REMOVED && !itr->second->dependent && dependent)
{
itr->second->dependent = dependent;
if (itr->second->state != PLAYERSPELL_NEW)
itr->second->state = PLAYERSPELL_CHANGED;
dependent_set = true;
}
// update active state for known spell
if(itr->second->active != active && itr->second->state != PLAYERSPELL_REMOVED && !itr->second->disabled)
{
itr->second->active = active;
// !IsInWorld() && !learning == explicitly load from DB and then exist in it already and set correctly
if(!IsInWorld() && !learning)
if(!IsInWorld() && !learning && !dependent_set) // explicitly load from DB and then exist in it already and set correctly
itr->second->state = PLAYERSPELL_UNCHANGED;
else if(itr->second->state != PLAYERSPELL_NEW)
itr->second->state = PLAYERSPELL_CHANGED;
if(!active)
if(active)
{
WorldPacket data(SMSG_REMOVED_SPELL, 4);
data << uint16(spell_id);
GetSession()->SendPacket(&data);
if (IsPassiveSpell(spell_id) && IsNeedCastPassiveSpellAtLearn(spellInfo))
CastSpell (this,spell_id,true);
}
else if(IsInWorld())
{
if(next_active_spell_id)
{
// update spell ranks in spellbook and action bar
WorldPacket data(SMSG_SUPERCEDED_SPELL, (4));
data << uint16(spell_id);
data << uint16(next_active_spell_id);
GetSession()->SendPacket( &data );
}
else
{
WorldPacket data(SMSG_REMOVED_SPELL, 4);
data << uint16(spell_id);
GetSession()->SendPacket(&data);
}
}
return active; // learn (show in spell book if active now)
}
@@ -2733,7 +2784,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool disabled
default: // known not saved yet spell (new or modified)
{
// can be in case spell loading but learned at some previous spell loading
if(!IsInWorld() && !learning)
if(!IsInWorld() && !learning && !dependent_set)
itr->second->state = PLAYERSPELL_UNCHANGED;
return false;
@@ -2755,10 +2806,6 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool disabled
if(!rankSpellId || rankSpellId==spell_id)
continue;
// skip unknown ranks
if(!HasSpell(rankSpellId))
continue;
removeSpell(rankSpellId);
}
}
@@ -2766,16 +2813,17 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool disabled
// non talent spell: learn low ranks (recursive call)
else if(uint32 prev_spell = spellmgr.GetPrevSpellInChain(spell_id))
{
if(!IsInWorld()) // at spells loading, no output, but allow save
addSpell(prev_spell,active,true,disabled);
if(!IsInWorld() || disabled) // at spells loading, no output, but allow save
addSpell(prev_spell,active,true,true,disabled);
else // at normal learning
learnSpell(prev_spell);
learnSpell(prev_spell,true);
}
PlayerSpell *newspell = new PlayerSpell;
newspell->active = active;
newspell->state = state;
newspell->disabled = disabled;
newspell->state = state;
newspell->active = active;
newspell->dependent = dependent;
newspell->disabled = disabled;
// replace spells in action bars and spellbook to bigger rank if only one spell rank must be accessible
if(newspell->active && !newspell->disabled && !SpellMgr::canStackSpellRanks(spellInfo) && spellmgr.GetSpellRank(spellInfo->Id) != 0)
@@ -2802,7 +2850,8 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool disabled
// mark old spell as disable (SMSG_SUPERCEDED_SPELL replace it in client by new)
itr->second->active = false;
itr->second->state = PLAYERSPELL_CHANGED;
if(itr->second->state != PLAYERSPELL_NEW)
itr->second->state = PLAYERSPELL_CHANGED;
superceded_old = true; // new spell replace old in action bars and spell book.
}
else if(spellmgr.IsHighRankOfSpell(itr->first,spell_id))
@@ -2844,26 +2893,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool disabled
// also cast passive spells (including all talents without SPELL_EFFECT_LEARN_SPELL) with additional checks
else if (IsPassiveSpell(spell_id))
{
bool need_cast = false;
switch(spell_id)
{
// some spells not have stance data expacted cast at form change or present
case 5420: need_cast = (m_form == FORM_TREE); break;
case 5419: need_cast = (m_form == FORM_TRAVEL); break;
case 7376: need_cast = (m_form == FORM_DEFENSIVESTANCE); break;
case 7381: need_cast = (m_form == FORM_BERSERKERSTANCE); break;
case 21156: need_cast = (m_form == FORM_BATTLESTANCE); break;
case 21178: need_cast = (m_form == FORM_BEAR || m_form == FORM_DIREBEAR); break;
case 33948: need_cast = (m_form == FORM_FLIGHT); break;
case 34764: need_cast = (m_form == FORM_FLIGHT); break;
case 40121: need_cast = (m_form == FORM_FLIGHT_EPIC); break;
case 40122: need_cast = (m_form == FORM_FLIGHT_EPIC); break;
// another spells have proper stance data
default: need_cast = !spellInfo->Stances || m_form != 0 && (spellInfo->Stances & (1<<(m_form-1))); break;
}
//Check CasterAuraStates
if (need_cast && (!spellInfo->CasterAuraState || HasAuraState(AuraState(spellInfo->CasterAuraState))))
if(IsNeedCastPassiveSpellAtLearn(spellInfo))
CastSpell(this, spell_id, true);
}
else if( IsSpellHaveEffect(spellInfo,SPELL_EFFECT_SKILL_STEP) )
@@ -2948,9 +2978,9 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool disabled
if(!itr->second.autoLearned)
{
if(!IsInWorld() || !itr->second.active) // at spells loading, no output, but allow save
addSpell(itr->second.spell,itr->second.active,true,false);
addSpell(itr->second.spell,itr->second.active,true,true,false);
else // at normal learning
learnSpell(itr->second.spell);
learnSpell(itr->second.spell,true);
}
}
@@ -2964,14 +2994,39 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool disabled
return active && !disabled && !superceded_old;
}
void Player::learnSpell(uint32 spell_id)
bool Player::IsNeedCastPassiveSpellAtLearn(SpellEntry const* spellInfo) const
{
bool need_cast = false;
switch(spellInfo->Id)
{
// some spells not have stance data expacted cast at form change or present
case 5420: need_cast = (m_form == FORM_TREE); break;
case 5419: need_cast = (m_form == FORM_TRAVEL); break;
case 7376: need_cast = (m_form == FORM_DEFENSIVESTANCE); break;
case 7381: need_cast = (m_form == FORM_BERSERKERSTANCE); break;
case 21156: need_cast = (m_form == FORM_BATTLESTANCE); break;
case 21178: need_cast = (m_form == FORM_BEAR || m_form == FORM_DIREBEAR); break;
case 33948: need_cast = (m_form == FORM_FLIGHT); break;
case 34764: need_cast = (m_form == FORM_FLIGHT); break;
case 40121: need_cast = (m_form == FORM_FLIGHT_EPIC); break;
case 40122: need_cast = (m_form == FORM_FLIGHT_EPIC); break;
// another spells have proper stance data
default: need_cast = !spellInfo->Stances || m_form != 0 && (spellInfo->Stances & (1<<(m_form-1))); break;
}
//Check CasterAuraStates
return need_cast && (!spellInfo->CasterAuraState || HasAuraState(AuraState(spellInfo->CasterAuraState)));
}
void Player::learnSpell(uint32 spell_id, bool dependent)
{
PlayerSpellMap::iterator itr = m_spells.find(spell_id);
bool disabled = (itr != m_spells.end()) ? itr->second->disabled : false;
bool active = disabled ? itr->second->active : true;
bool learning = addSpell(spell_id,active,true,false);
bool learning = addSpell(spell_id,active,true,dependent,false);
// learn all disabled higher ranks (recursive)
if(disabled)
@@ -2981,7 +3036,7 @@ void Player::learnSpell(uint32 spell_id)
{
PlayerSpellMap::iterator iter = m_spells.find(node->next);
if (iter != m_spells.end() && iter->second->disabled )
learnSpell(node->next);
learnSpell(node->next,false);
}
}
@@ -2994,7 +3049,7 @@ void Player::learnSpell(uint32 spell_id)
GetSession()->SendPacket(&data);
}
void Player::removeSpell(uint32 spell_id, bool disabled)
void Player::removeSpell(uint32 spell_id, bool disabled, bool update_action_bar_for_low_rank)
{
PlayerSpellMap::iterator itr = m_spells.find(spell_id);
if (itr == m_spells.end())
@@ -3016,10 +3071,8 @@ void Player::removeSpell(uint32 spell_id, bool disabled)
for (uint32 i=reqMap.count(spell_id);i>0;i--,itr2++)
removeSpell(itr2->second,disabled);
// removing
WorldPacket data(SMSG_REMOVED_SPELL, 4);
data << uint16(spell_id);
GetSession()->SendPacket(&data);
bool cur_active = itr->second->active;
bool cur_dependent = itr->second->dependent;
if (disabled)
{
@@ -3132,7 +3185,57 @@ void Player::removeSpell(uint32 spell_id, bool disabled)
for(SpellLearnSpellMap::const_iterator itr2 = spell_begin; itr2 != spell_end; ++itr2)
removeSpell(itr2->second.spell, disabled);
// TODO: recast if need lesser ranks spell for passive with IsPassiveSpellStackableWithRanks
// activate lesser rank in spellbook/action bar, and cast it if need
bool prev_activate = false;
if(uint32 prev_id = spellmgr.GetPrevSpellInChain (spell_id))
{
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell_id);
// if talent then lesser rank also talent and need learn
if(talentCosts)
learnSpell (prev_id,false);
// if ranked non-stackable spell: need activate lesser rank and update dendence state
else if(cur_active && !SpellMgr::canStackSpellRanks(spellInfo) && spellmgr.GetSpellRank(spellInfo->Id) != 0)
{
// need manually update dependence state (learn spell ignore like attempts)
PlayerSpellMap::iterator prev_itr = m_spells.find(prev_id);
if (prev_itr != m_spells.end())
{
if(prev_itr->second->dependent != cur_dependent)
{
prev_itr->second->dependent = cur_dependent;
if(prev_itr->second->state != PLAYERSPELL_NEW)
prev_itr->second->state = PLAYERSPELL_CHANGED;
}
// now re-learn if need re-activate
if(cur_active && !prev_itr->second->active)
{
if(addSpell(prev_id,true,false,prev_itr->second->dependent,prev_itr->second->disabled))
{
if(update_action_bar_for_low_rank)
{
// downgrade spell ranks in spellbook and action bar
WorldPacket data(SMSG_SUPERCEDED_SPELL, (4));
data << uint16(spell_id);
data << uint16(prev_id);
GetSession()->SendPacket( &data );
prev_activate = true;
}
}
}
}
}
}
// remove from spell book if not replaced by lesser rank
if(!prev_activate)
{
WorldPacket data(SMSG_REMOVED_SPELL, 4);
data << uint16(spell_id);
GetSession()->SendPacket(&data);
}
}
void Player::RemoveArenaSpellCooldowns()
@@ -3355,18 +3458,6 @@ bool Player::resetTalents(bool no_cost)
return true;
}
bool Player::_removeSpell(uint16 spell_id)
{
PlayerSpellMap::iterator itr = m_spells.find(spell_id);
if (itr != m_spells.end())
{
delete itr->second;
m_spells.erase(itr);
return true;
}
return false;
}
Mail* Player::GetMail(uint32 id)
{
for(PlayerMails::iterator itr = m_mail.begin(); itr != m_mail.end(); ++itr)
@@ -3572,8 +3663,16 @@ void Player::DestroyForPlayer( Player *target ) const
bool Player::HasSpell(uint32 spell) const
{
PlayerSpellMap::const_iterator itr = m_spells.find((uint16)spell);
return (itr != m_spells.end() && itr->second->state != PLAYERSPELL_REMOVED && !itr->second->disabled);
PlayerSpellMap::const_iterator itr = m_spells.find(spell);
return (itr != m_spells.end() && itr->second->state != PLAYERSPELL_REMOVED &&
!itr->second->disabled);
}
bool Player::HasActiveSpell(uint32 spell) const
{
PlayerSpellMap::const_iterator itr = m_spells.find(spell);
return (itr != m_spells.end() && itr->second->state != PLAYERSPELL_REMOVED &&
itr->second->active && !itr->second->disabled);
}
TrainerSpellState Player::GetTrainerSpellState(TrainerSpell const* trainer_spell) const
@@ -4828,7 +4927,7 @@ bool Player::UpdateCraftSkill(uint32 spellid)
if(spellEntry && spellEntry->Mechanic==MECHANIC_DISCOVERY)
{
if(uint32 discoveredSpell = GetSkillDiscoverySpell(_spell_idx->second->skillId, spellid, this))
learnSpell(discoveredSpell);
learnSpell(discoveredSpell,false);
}
uint32 craft_skill_gain = sWorld.getConfig(CONFIG_SKILL_GAIN_CRAFTING);
@@ -4884,6 +4983,11 @@ bool Player::UpdateFishingSkill()
return UpdateSkillPro(SKILL_FISHING,chance*10,gathering_skill_gain);
}
// levels sync. with spell requirement for skill levels to learn
// bonus abilities in sSkillLineAbilityStore
// Used only to avoid scan DBC at each skill grow
static uint32 bonusSkillLevels[] = {75,150,225,300,375,450};
bool Player::UpdateSkillPro(uint16 SkillId, int32 Chance, uint32 step)
{
sLog.outDebug("UpdateSkillPro(SkillId %d, Chance %3.1f%%)", SkillId, Chance/10.0);
@@ -4918,6 +5022,14 @@ bool Player::UpdateSkillPro(uint16 SkillId, int32 Chance, uint32 step)
new_value = MaxValue;
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(new_value,MaxValue));
for(uint32* bsl = &bonusSkillLevels[0]; *bsl; ++bsl)
{
if((SkillValue < *bsl && new_value >= *bsl))
{
learnSkillRewardedSpells( SkillId, new_value);
break;
}
}
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL);
sLog.outDebug("Player::UpdateSkillPro Chance=%3.1f%% taken", Chance/10.0);
return true;
@@ -5094,6 +5206,7 @@ void Player::SetSkill(uint32 id, uint16 currVal, uint16 maxVal)
if(currVal)
{
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(currVal,maxVal));
learnSkillRewardedSpells(id, currVal);
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL);
}
else //remove
@@ -5103,27 +5216,11 @@ void Player::SetSkill(uint32 id, uint16 currVal, uint16 maxVal)
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),0);
SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i),0);
// remove spells that depend on this skill when removing the skill
for (PlayerSpellMap::const_iterator itr = m_spells.begin(), next = m_spells.begin(); itr != m_spells.end(); itr = next)
{
++next;
if(itr->second->state == PLAYERSPELL_REMOVED)
continue;
SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(itr->first);
SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(itr->first);
for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx)
{
if (_spell_idx->second->skillId == id)
{
// this may remove more than one spell (dependents)
removeSpell(itr->first);
next = m_spells.begin();
break;
}
}
}
// remove all spells that related to this skill
for (uint32 j=0; j<sSkillLineAbilityStore.GetNumRows(); ++j)
if(SkillLineAbilityEntry const *pAbility = sSkillLineAbilityStore.LookupEntry(j))
if (pAbility->skillId==id)
removeSpell(spellmgr.GetFirstSpellInChain(pAbility->spellId));
}
}
else if(currVal) //add
@@ -5161,7 +5258,7 @@ void Player::SetSkill(uint32 id, uint16 currVal, uint16 maxVal)
(*i)->ApplyModifier(true);
// Learn all spells for skill
learnSkillRewardedSpells(id);
learnSkillRewardedSpells(id, currVal);
return;
}
}
@@ -9128,8 +9225,8 @@ uint8 Player::_CanStoreItem_InSpecificSlot( uint8 bag, uint8 slot, ItemPosCountV
if(slot >= KEYRING_SLOT_START && slot < KEYRING_SLOT_START+GetMaxKeyringSize() && !(pProto->BagFamily & BAG_FAMILY_MASK_KEYS))
return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;
// vanitypet case (disabled until proper implement)
if(slot >= VANITYPET_SLOT_START && slot < VANITYPET_SLOT_END && !(false /*pProto->BagFamily & BAG_FAMILY_MASK_VANITY_PETS*/))
// vanitypet case (not use, vanity pets stored as spells)
if(slot >= VANITYPET_SLOT_START && slot < VANITYPET_SLOT_END)
return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;
// currencytoken case (disabled until proper implement)
@@ -9472,28 +9569,9 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3
return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
}
}
/* until proper implementation
else if(pProto->BagFamily & BAG_FAMILY_MASK_VANITY_PETS)
{
res = _CanStoreItem_InInventorySlots(VANITYPET_SLOT_START,VANITYPET_SLOT_END,dest,pProto,count,false,pItem,bag,slot);
if(res!=EQUIP_ERR_OK)
{
if(no_space_count)
*no_space_count = count + no_similar_count;
return res;
}
if(count==0)
{
if(no_similar_count==0)
return EQUIP_ERR_OK;
// Vanity pet case skipped as not used
if(no_space_count)
*no_space_count = count + no_similar_count;
return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
}
}
*/
/* until proper implementation
else if(pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS)
{
@@ -9685,28 +9763,9 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3
return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
}
}
/* until proper implementation
else if(false pProto->BagFamily & BAG_FAMILY_MASK_VANITY_PETS)
{
res = _CanStoreItem_InInventorySlots(VANITYPET_SLOT_START,VANITYPET_SLOT_END,dest,pProto,count,false,pItem,bag,slot);
if(res!=EQUIP_ERR_OK)
{
if(no_space_count)
*no_space_count = count + no_similar_count;
return res;
}
if(count==0)
{
if(no_similar_count==0)
return EQUIP_ERR_OK;
// Vanity pet case skipped as not used
if(no_space_count)
*no_space_count = count + no_similar_count;
return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
}
}
*/
/* until proper implementation
else if(false pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS)
{
@@ -9821,14 +9880,12 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const
int inv_slot_items[INVENTORY_SLOT_ITEM_END-INVENTORY_SLOT_ITEM_START];
int inv_bags[INVENTORY_SLOT_BAG_END-INVENTORY_SLOT_BAG_START][MAX_BAG_SIZE];
int inv_keys[KEYRING_SLOT_END-KEYRING_SLOT_START];
int inv_pets[VANITYPET_SLOT_END-VANITYPET_SLOT_START];
int inv_tokens[CURRENCYTOKEN_SLOT_END-CURRENCYTOKEN_SLOT_START];
int inv_quests[QUESTBAG_SLOT_END-QUESTBAG_SLOT_START];
memset(inv_slot_items,0,sizeof(int)*(INVENTORY_SLOT_ITEM_END-INVENTORY_SLOT_ITEM_START));
memset(inv_bags,0,sizeof(int)*(INVENTORY_SLOT_BAG_END-INVENTORY_SLOT_BAG_START)*MAX_BAG_SIZE);
memset(inv_keys,0,sizeof(int)*(KEYRING_SLOT_END-KEYRING_SLOT_START));
memset(inv_pets,0,sizeof(int)*(VANITYPET_SLOT_END-VANITYPET_SLOT_START));
memset(inv_tokens,0,sizeof(int)*(CURRENCYTOKEN_SLOT_END-CURRENCYTOKEN_SLOT_START));
memset(inv_quests,0,sizeof(int)*(QUESTBAG_SLOT_END-QUESTBAG_SLOT_START));
@@ -9852,15 +9909,7 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const
}
}
for(int i = VANITYPET_SLOT_START; i < VANITYPET_SLOT_END; i++)
{
pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
if (pItem2 && !pItem2->IsInTrade())
{
inv_pets[i-VANITYPET_SLOT_START] = pItem2->GetCount();
}
}
// Vanity pet case skipped as not used
for(int i = CURRENCYTOKEN_SLOT_START; i < CURRENCYTOKEN_SLOT_END; i++)
{
@@ -9941,17 +9990,7 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const
}
if (b_found) continue;
for(int t = VANITYPET_SLOT_START; t < VANITYPET_SLOT_END; t++)
{
pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, t );
if( pItem2 && pItem2->GetEntry() == pItem->GetEntry() && inv_pets[t-VANITYPET_SLOT_START] + pItem->GetCount() <= pProto->GetMaxStackSize())
{
inv_pets[t-VANITYPET_SLOT_START] += pItem->GetCount();
b_found = true;
break;
}
}
if (b_found) continue;
// Vanity pet case skipped as not used
for(int t = CURRENCYTOKEN_SLOT_START; t < CURRENCYTOKEN_SLOT_END; t++)
{
@@ -10029,22 +10068,8 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const
if (b_found) continue;
/* until proper implementation
if(pProto->BagFamily & BAG_FAMILY_MASK_VANITY_PETS)
{
for(uint32 t = VANITYPET_SLOT_START; t < VANITYPET_SLOT_END; ++t)
{
if( inv_pets[t-VANITYPET_SLOT_START] == 0 )
{
inv_pets[t-VANITYPET_SLOT_START] = 1;
b_found = true;
break;
}
}
}
// Vanity pet case skipped as not used
if (b_found) continue;
*/
/* until proper implementation
if(pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS)
{
@@ -14687,24 +14712,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
SetUInt32Value(PLAYER_TRACK_CREATURES, 0 );
SetUInt32Value(PLAYER_TRACK_RESOURCES, 0 );
// reset skill modifiers and set correct unlearn flags
for (uint32 i = 0; i < PLAYER_MAX_SKILLS; i++)
{
SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i),0);
// set correct unlearn bit
uint32 id = GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF;
if(!id) continue;
SkillLineEntry const *pSkill = sSkillLineStore.LookupEntry(id);
if(!pSkill) continue;
// enable unlearn button for primary professions only
if (pSkill->categoryId == SKILL_CATEGORY_PROFESSION)
SetUInt32Value(PLAYER_SKILL_INDEX(i), MAKE_PAIR32(id,1));
else
SetUInt32Value(PLAYER_SKILL_INDEX(i), MAKE_PAIR32(id,0));
}
_LoadSkills();
// make sure the unit is considered out of combat for proper loading
ClearInCombat();
@@ -14745,7 +14753,6 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
// after spell and quest load
InitTalentForLevel();
learnSkillRewardedSpells();
learnDefaultSpells();
_LoadTutorials(holder->GetResult(PLAYER_LOGIN_QUERY_LOADTUTORIALS));
@@ -14849,6 +14856,28 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
break;
}
switch(sWorld.getConfig(CONFIG_GM_VISIBLE_STATE))
{
default:
case 0: SetGMVisible(false); break; // invisible
case 1: break; // visible
case 2: // save state
if(extraflags & PLAYER_EXTRA_GM_INVISIBLE)
SetGMVisible(false);
break;
}
/*switch(sWorld.getConfig(CONFIG_GM_ACCEPT_TICKETS))
{
default:
case 0: break; // disable
case 1: SetAcceptTicket(true); break; // enable
case 2: // save state
if(extraflags & PLAYER_EXTRA_GM_ACCEPT_TICKETS)
SetAcceptTicket(true);
break;
}*/
switch(sWorld.getConfig(CONFIG_GM_CHAT))
{
default:
@@ -15540,7 +15569,7 @@ void Player::_LoadSpells(QueryResult *result)
{
Field *fields = result->Fetch();
addSpell(fields[0].GetUInt16(), fields[1].GetBool(), false, fields[2].GetBool());
addSpell(fields[0].GetUInt16(), fields[1].GetBool(), false, false, fields[2].GetBool());
}
while( result->NextRow() );
@@ -16318,18 +16347,26 @@ void Player::_SaveReputation()
void Player::_SaveSpells()
{
for (PlayerSpellMap::const_iterator itr = m_spells.begin(), next = m_spells.begin(); itr != m_spells.end(); itr = next)
for (PlayerSpellMap::iterator itr = m_spells.begin(), next = m_spells.begin(); itr != m_spells.end();)
{
++next;
if (itr->second->state == PLAYERSPELL_REMOVED || itr->second->state == PLAYERSPELL_CHANGED)
CharacterDatabase.PExecute("DELETE FROM character_spell WHERE guid = '%u' and spell = '%u'", GetGUIDLow(), itr->first);
if (itr->second->state == PLAYERSPELL_NEW || itr->second->state == PLAYERSPELL_CHANGED)
// add only changed/new not dependent spells
if (!itr->second->dependent && (itr->second->state == PLAYERSPELL_NEW || itr->second->state == PLAYERSPELL_CHANGED))
CharacterDatabase.PExecute("INSERT INTO character_spell (guid,spell,active,disabled) VALUES ('%u', '%u', '%u', '%u')", GetGUIDLow(), itr->first, itr->second->active ? 1 : 0,itr->second->disabled ? 1 : 0);
if (itr->second->state == PLAYERSPELL_REMOVED)
_removeSpell(itr->first);
{
delete itr->second;
m_spells.erase(itr++);
}
else
{
itr->second->state = PLAYERSPELL_UNCHANGED;
++itr;
}
}
}
@@ -18678,9 +18715,9 @@ void Player::learnDefaultSpells()
uint32 tspell = *itr;
sLog.outDebug("PLAYER (Class: %u Race: %u): Adding initial spell, id = %u",uint32(getClass()),uint32(getRace()), tspell);
if(!IsInWorld()) // will send in INITIAL_SPELLS in list anyway at map add
addSpell(tspell,true,true,false);
addSpell(tspell,true,true,true,false);
else // but send in normal spell in game learn case
learnSpell(tspell);
learnSpell(tspell,true);
}
}
@@ -18772,7 +18809,7 @@ void Player::learnQuestRewardedSpells()
}
}
void Player::learnSkillRewardedSpells(uint32 skill_id )
void Player::learnSkillRewardedSpells(uint32 skill_id, uint32 skill_value )
{
uint32 raceMask = getRaceMask();
uint32 classMask = getClassMask();
@@ -18790,25 +18827,18 @@ void Player::learnSkillRewardedSpells(uint32 skill_id )
if (sSpellStore.LookupEntry(pAbility->spellId))
{
// Ok need learn spell
learnSpell(pAbility->spellId);
// need unlearn spell
if (skill_value < pAbility->req_skill_value)
removeSpell(pAbility->spellId);
// need learn
else if (!IsInWorld())
addSpell(pAbility->spellId,true,true,true,false);
else
learnSpell(pAbility->spellId,true);
}
}
}
void Player::learnSkillRewardedSpells()
{
for (uint16 i=0; i < PLAYER_MAX_SKILLS; i++)
{
if(!GetUInt32Value(PLAYER_SKILL_INDEX(i)))
continue;
uint32 pskill = GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF;
learnSkillRewardedSpells(pskill);
}
}
void Player::SendAurasForTarget(Unit *target)
{
if(target->GetVisibleAuras()->empty()) // speedup things
@@ -19486,6 +19516,13 @@ void Player::UpdateAreaDependentAuras( uint32 newArea )
if( !HasAura(51721,0) )
CastSpell(this,51721,true);
break;
// Mist of the Kvaldir
case 4028: //Riplash Strand
case 4029: //Riplash Ruins
case 4106: //Garrosh's Landing
case 4031: //Pal'ea
CastSpell(this,54119,true);
break;
}
}
@@ -20178,3 +20215,67 @@ bool Player::IsAllowUseFlyMountsHere() const
}
return true;
}
void Player::learnSpellHighRank(uint32 spellid)
{
learnSpell(spellid,false);
if(uint32 next = spellmgr.GetNextSpellInChain(spellid))
learnSpellHighRank(next);
}
void Player::_LoadSkills()
{
// Note: skill data itself loaded from `data` field. This is only cleanup part of load
// reset skill modifiers and set correct unlearn flags
for (uint32 i = 0; i < PLAYER_MAX_SKILLS; i++)
{
SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i),0);
// set correct unlearn bit
uint32 id = GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF;
if(!id) continue;
SkillLineEntry const *pSkill = sSkillLineStore.LookupEntry(id);
if(!pSkill) continue;
// enable unlearn button for primary professions only
if (pSkill->categoryId == SKILL_CATEGORY_PROFESSION)
SetUInt32Value(PLAYER_SKILL_INDEX(i), MAKE_PAIR32(id,1));
else
SetUInt32Value(PLAYER_SKILL_INDEX(i), MAKE_PAIR32(id,0));
uint32 vskill = SKILL_VALUE(GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i)));
learnSkillRewardedSpells(id, vskill);
}
// special settings
if(getClass()==CLASS_DEATH_KNIGHT)
{
uint32 base_level = std::min(getLevel(),sWorld.getConfig (CONFIG_START_HEROIC_PLAYER_LEVEL));
if(base_level < 1)
base_level = 1;
uint32 base_skill = (base_level-1)*5; // 270 at starting level 55
if(base_skill < 1)
base_skill = 1; // skill mast be known and then > 0 in any case
if(GetPureSkillValue (SKILL_FIRST_AID) < base_skill)
SetSkill(SKILL_FIRST_AID,base_skill, base_skill);
if(GetPureSkillValue (SKILL_AXES) < base_skill)
SetSkill(SKILL_AXES, base_skill,base_skill);
if(GetPureSkillValue (SKILL_DEFENSE) < base_skill)
SetSkill(SKILL_DEFENSE, base_skill,base_skill);
if(GetPureSkillValue (SKILL_POLEARMS) < base_skill)
SetSkill(SKILL_POLEARMS, base_skill,base_skill);
if(GetPureSkillValue (SKILL_SWORDS) < base_skill)
SetSkill(SKILL_SWORDS, base_skill,base_skill);
if(GetPureSkillValue (SKILL_2H_AXES) < base_skill)
SetSkill(SKILL_2H_AXES, base_skill,base_skill);
if(GetPureSkillValue (SKILL_2H_SWORDS) < base_skill)
SetSkill(SKILL_2H_SWORDS, base_skill,base_skill);
if(GetPureSkillValue (SKILL_UNARMED) < base_skill)
SetSkill(SKILL_UNARMED, base_skill,base_skill);
}
}
+15 -11
View File
@@ -88,8 +88,9 @@ enum PlayerSpellState
struct PlayerSpell
{
PlayerSpellState state : 8;
bool active : 1;
bool disabled : 1;
bool active : 1; // show in spellbook
bool dependent : 1; // learned as result another spell learn, skill grow, quest reward, etc
bool disabled : 1; // first rank has been learned in result talent learn but currently talent unlearned, save max learned ranks
};
// Spell modifier (used for modify other spells)
@@ -106,7 +107,7 @@ struct SpellModifier
Spell const* lastAffected;
};
typedef UNORDERED_MAP<uint16, PlayerSpell*> PlayerSpellMap;
typedef UNORDERED_MAP<uint32, PlayerSpell*> PlayerSpellMap;
typedef std::list<SpellModifier*> SpellModList;
struct SpellCooldown
@@ -731,8 +732,8 @@ enum KeyRingSlots
enum VanityPetSlots
{
VANITYPET_SLOT_START = 118,
VANITYPET_SLOT_END = 136
VANITYPET_SLOT_START = 118, // not use, vanity pets stored as spells
VANITYPET_SLOT_END = 136 // not alloed any content in.
};
enum CurrencyTokenSlots
@@ -1342,6 +1343,7 @@ class TRINITY_DLL_SPEC Player : public Unit
/*********************************************************/
bool LoadFromDB(uint32 guid, SqlQueryHolder *holder);
bool MinimalLoadFromDB(QueryResult *result, uint32 guid);
static bool LoadValuesArrayFromDB(Tokens& data,uint64 guid);
static uint32 GetUInt32ValueFromArray(Tokens const& data, uint16 index);
@@ -1475,18 +1477,21 @@ class TRINITY_DLL_SPEC Player : public Unit
void CharmSpellInitialize();
void PossessSpellInitialize();
bool HasSpell(uint32 spell) const;
bool HasActiveSpell(uint32 spell) const; // show in spellbook
TrainerSpellState GetTrainerSpellState(TrainerSpell const* trainer_spell) const;
bool IsSpellFitByClassAndRace( uint32 spell_id ) const;
bool IsNeedCastPassiveSpellAtLearn(SpellEntry const* spellInfo) const;
void SendProficiency(uint8 pr1, uint32 pr2);
void SendInitialSpells();
bool addSpell(uint32 spell_id, bool active, bool learning, bool disabled);
void learnSpell(uint32 spell_id);
void removeSpell(uint32 spell_id, bool disabled = false);
bool addSpell(uint32 spell_id, bool active, bool learning, bool dependent, bool disabled);
void learnSpell(uint32 spell_id, bool dependent);
void removeSpell(uint32 spell_id, bool disabled = false, bool update_action_bar_for_low_rank = false);
void resetSpells();
void learnDefaultSpells();
void learnQuestRewardedSpells();
void learnQuestRewardedSpells(Quest const* quest);
void learnSpellHighRank(uint32 spellid);
uint32 GetFreeTalentPoints() const { return GetUInt32Value(PLAYER_CHARACTER_POINTS1); }
void SetFreeTalentPoints(uint32 points) { SetUInt32Value(PLAYER_CHARACTER_POINTS1,points); }
@@ -1767,8 +1772,7 @@ class TRINITY_DLL_SPEC Player : public Unit
int16 GetSkillPermBonusValue(uint32 skill) const;
int16 GetSkillTempBonusValue(uint32 skill) const;
bool HasSkill(uint32 skill) const;
void learnSkillRewardedSpells( uint32 id );
void learnSkillRewardedSpells();
void learnSkillRewardedSpells(uint32 id, uint32 value);
void SetDontMove(bool dontMove);
bool GetDontMove() const { return m_dontMove; }
@@ -2270,6 +2274,7 @@ class TRINITY_DLL_SPEC Player : public Unit
void _LoadDailyQuestStatus(QueryResult *result);
void _LoadGroup(QueryResult *result);
void _LoadReputation(QueryResult *result);
void _LoadSkills();
void _LoadSpells(QueryResult *result);
void _LoadTutorials(QueryResult *result);
void _LoadFriendList(QueryResult *result);
@@ -2311,7 +2316,6 @@ class TRINITY_DLL_SPEC Player : public Unit
time_t m_lastHonorUpdateTime;
void outDebugValues() const;
bool _removeSpell(uint16 spell_id);
uint64 m_lootGuid;
uint32 m_race;
-1
View File
@@ -832,7 +832,6 @@ enum Targets
TARGET_UNIT_PARTY_CASTER = 20,
TARGET_SINGLE_FRIEND = 21,
TARGET_UNIT_TARGET_ALLY = 21,
TARGET_ALL_AROUND_CASTER = 22, // used only in TargetA, target selection dependent from TargetB
TARGET_DEST_CASTER = 22,
TARGET_GAMEOBJECT = 23,
//TARGET_OBJECT_OPEN
+1 -1
View File
@@ -129,7 +129,7 @@ void WorldSession::HandleLearnTalentOpcode( WorldPacket & recv_data )
return;
// learn! (other talent ranks will unlearned at learning)
GetPlayer( )->learnSpell(spellid);
GetPlayer( )->learnSpell(spellid,false);
sLog.outDetail("TalentID: %u Rank: %u Spell: %u\n", talent_id, requested_rank, spellid);
// update free talent points
+94 -98
View File
@@ -119,6 +119,14 @@ void SpellCastTargets::setDestination(Unit *target, bool send)
m_targetMask |= TARGET_FLAG_DEST_LOCATION;
}
void SpellCastTargets::setSource(float x, float y, float z)
{
m_srcX = x;
m_srcY = y;
m_srcZ = z;
m_targetMask |= TARGET_FLAG_SOURCE_LOCATION;
}
void SpellCastTargets::setGOTarget(GameObject *target)
{
m_GOTarget = target;
@@ -354,6 +362,7 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi
focusObject = NULL;
m_cast_count = 0;
m_glyphIndex = 0;
m_preCastSpell = 0;
m_triggeredByAuraSpell = NULL;
//Auto Shot & Shoot (wand)
@@ -597,7 +606,6 @@ void Spell::FillTargetMap()
}
}
if(IsChanneledSpell(m_spellInfo) && !tmpUnitMap.empty())
m_needAliveTargetMask |= (1<<i);
@@ -701,7 +709,7 @@ void Spell::prepareDataForTriggerSystem()
}
// Hunter traps spells (for Entrapment trigger)
// Gives your Immolation Trap, Frost Trap, Explosive Trap, and Snake Trap ....
if (m_spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER && m_spellInfo->SpellFamilyFlags & 0x0000200000000014LL)
if (m_spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER && m_spellInfo->SpellFamilyFlags & 0x000020000000001CLL)
m_procAttacker |= PROC_FLAG_ON_TRAP_ACTIVATION;
}
@@ -877,7 +885,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
return;
// Get original caster (if exist) and calculate damage/healing from him data
Unit *caster = m_originalCasterGUID ? m_originalCaster : m_caster;
Unit *caster = m_originalCaster ? m_originalCaster : m_caster;
// Skip if m_originalCaster not avaiable
if (!caster)
@@ -970,25 +978,6 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
int32 damagePoint = damageInfo.damage * 33 / 100;
m_caster->CastCustomSpell(m_caster, 32220, &damagePoint, NULL, NULL, true);
}
// Bloodthirst
else if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARRIOR && m_spellInfo->SpellFamilyFlags & 0x40000000000LL)
{
uint32 BTAura = 0;
switch(m_spellInfo->Id)
{
case 23881: BTAura = 23885; break;
case 23892: BTAura = 23886; break;
case 23893: BTAura = 23887; break;
case 23894: BTAura = 23888; break;
case 25251: BTAura = 25252; break;
case 30335: BTAura = 30339; break;
default:
sLog.outError("Spell::EffectSchoolDMG: Spell %u not handled in BTAura",m_spellInfo->Id);
break;
}
if (BTAura)
m_caster->CastSpell(m_caster,BTAura,true);
}
}
// Passive spell hits/misses or active spells only misses (only triggers)
else
@@ -1105,6 +1094,10 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
unit->IncrDiminishing(m_diminishGroup);
}
// Apply additional spell effects to target
if (m_preCastSpell)
m_caster->CastSpell(unit,m_preCastSpell, true, m_CastItem);
for(uint32 effectNumber=0;effectNumber<3;effectNumber++)
{
if (effectMask & (1<<effectNumber))
@@ -1604,7 +1597,6 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
m_targets.setDestination(((Player*)m_caster)->m_homebindX,((Player*)m_caster)->m_homebindY,((Player*)m_caster)->m_homebindZ, true, ((Player*)m_caster)->m_homebindMapId);
break;
case TARGET_IN_FRONT_OF_CASTER:
case TARGET_UNIT_CONE_ENEMY_UNKNOWN:
if(m_customAttr & SPELL_ATTR_CU_CONE_BACK)
@@ -2162,6 +2154,49 @@ void Spell::cast(bool skipCheck)
if(m_customAttr & SPELL_ATTR_CU_DIRECT_DAMAGE)
CalculateDamageDoneForAllTargets();
switch(m_spellInfo->SpellFamilyName)
{
case SPELLFAMILY_GENERIC:
{
if (m_spellInfo->Mechanic == MECHANIC_BANDAGE) // Bandages
m_preCastSpell = 11196; // Recently Bandaged
else if(m_spellInfo->SpellIconID == 1662 && m_spellInfo->AttributesEx & 0x20) // Blood Fury (Racial)
m_preCastSpell = 23230; // Blood Fury - Healing Reduction
break;
}
case SPELLFAMILY_MAGE:
{
if (m_spellInfo->SpellFamilyFlags&0x0000008000000000LL) // Ice Block
m_preCastSpell = 41425; // Hypothermia
break;
}
case SPELLFAMILY_PRIEST:
{
if (m_spellInfo->Mechanic == MECHANIC_SHIELD &&
m_spellInfo->SpellIconID == 566) // Power Word: Shield
m_preCastSpell = 6788; // Weakened Soul
if (m_spellInfo->Id == 47585) // Dispersion (transform)
m_preCastSpell = 60069; // Dispersion (mana regen)
break;
}
case SPELLFAMILY_PALADIN:
{
if (m_spellInfo->SpellFamilyFlags&0x0000000000400080LL) // Divine Shield, Divine Protection or Hand of Protection
m_preCastSpell = 25771; // Forbearance
break;
}
case SPELLFAMILY_SHAMAN:
{
if (m_spellInfo->Id == 2825) // Bloodlust
m_preCastSpell = 57724; // Sated
else if (m_spellInfo->Id == 32182) // Heroism
m_preCastSpell = 57723; // Exhaustion
break;
}
default:
break;
}
// traded items have trade slot instead of guid in m_itemTargetGUID
// set to real guid to be sent later to the client
m_targets.updateTradeSlotItem();
@@ -2644,68 +2679,6 @@ void Spell::finish(bool ok)
m_caster->resetAttackTimer(RANGED_ATTACK);
}
// Post effects apply on spell targets in some spells
if(!m_UniqueTargetInfo.empty())
{
uint32 spellId = 0;
switch(m_spellInfo->SpellFamilyName)
{
case SPELLFAMILY_GENERIC:
{
if (m_spellInfo->Mechanic == MECHANIC_BANDAGE) // Bandages
spellId = 11196; // Recently Bandaged
else if(m_spellInfo->SpellIconID == 1662 && m_spellInfo->AttributesEx & 0x20) // Blood Fury (Racial)
spellId = 23230; // Blood Fury - Healing Reduction
break;
}
case SPELLFAMILY_MAGE:
{
if (m_spellInfo->SpellFamilyFlags&0x0000008000000000LL) // Ice Block
spellId = 41425; // Hypothermia
break;
}
case SPELLFAMILY_PRIEST:
{
if (m_spellInfo->Mechanic == MECHANIC_SHIELD &&
m_spellInfo->SpellIconID == 566) // Power Word: Shield
spellId = 6788; // Weakened Soul
break;
}
case SPELLFAMILY_PALADIN:
{
if (m_spellInfo->SpellFamilyFlags&0x0000000000400080LL) // Divine Shield, Divine Protection or Hand of Protection
spellId = 25771; // Forbearance
break;
}
case SPELLFAMILY_SHAMAN:
{
if (m_spellInfo->Id == 2825) // Bloodlust
spellId = 57724; // Sated
else if (m_spellInfo->Id == 32182) // Heroism
spellId = 57723; // Exhaustion
break;
}
default:
break;
}
if (spellId)
{
for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit)
{
Unit* unit = m_caster->GetGUID()==ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
if (unit)
{
// TODO: fix me use cast spell (now post spell can immune by this spell)
// m_caster->CastSpell(unit, spellId, true, m_CastItem);
SpellEntry const *AdditionalSpellInfo = sSpellStore.LookupEntry(spellId);
if (!AdditionalSpellInfo)
continue;
Aura* AdditionalAura = CreateAura(AdditionalSpellInfo, 0, &m_currentBasePoints[0], unit, m_caster, m_CastItem);
unit->AddAura(AdditionalAura);
}
}
}
}
// call triggered spell only at successful cast (after clear combo points -> for add some if need)
if(!m_TriggerSpells.empty())
TriggerSpell();
@@ -2852,6 +2825,7 @@ void Spell::SendSpellGo()
}
WorldPacket data(SMSG_SPELL_GO, 50); // guess size
if(m_CastItem)
data.append(m_CastItem->GetPackGUID());
else
@@ -2949,6 +2923,8 @@ void Spell::WriteAmmoToPacket( WorldPacket * data )
void Spell::WriteSpellGoTargets( WorldPacket * data )
{
// This function also fill data for channeled spells:
// m_needAliveTargetMask req for stop channelig if one target die
uint32 hit = m_UniqueGOTargetInfo.size(); // Always hits on GO
uint32 miss = 0;
for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit)
@@ -2968,7 +2944,10 @@ void Spell::WriteSpellGoTargets( WorldPacket * data )
*data << (uint8)hit;
for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit)
if ((*ihit).missCondition == SPELL_MISS_NONE) // Add only hits
{
*data << uint64(ihit->targetGUID);
m_needAliveTargetMask |=ihit->effectMask;
}
for(std::list<GOTargetInfo>::iterator ighit= m_UniqueGOTargetInfo.begin();ighit != m_UniqueGOTargetInfo.end();++ighit)
*data << uint64(ighit->targetGUID); // Always hits
@@ -2984,6 +2963,9 @@ void Spell::WriteSpellGoTargets( WorldPacket * data )
*data << uint8(ihit->reflectResult);
}
}
// Reset m_needAliveTargetMask for non channeled spell
if(!IsChanneledSpell(m_spellInfo))
m_needAliveTargetMask = 0;
}
void Spell::SendLogExecute()
@@ -5189,18 +5171,22 @@ void Spell::Delayed() // only called in DealDamage()
//if (m_spellState == SPELL_STATE_DELAYED)
// return; // spell is active and can't be time-backed
if(isDelayableNoMore()) // Spells may only be delayed twice
return;
// spells not loosing casting time ( slam, dynamites, bombs.. )
//if(!(m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_DAMAGE))
// return;
//check resist chance
int32 resistChance = 100; //must be initialized to 100 for percent modifiers
((Player*)m_caster)->ApplySpellMod(m_spellInfo->Id,SPELLMOD_NOT_LOSE_CASTING_TIME,resistChance, this);
resistChance += m_caster->GetTotalAuraModifier(SPELL_AURA_RESIST_PUSHBACK) - 100;
if (roll_chance_i(resistChance))
//check pushback reduce
int32 delaytime = 500; // spellcasting delay is normally 500ms
int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
((Player*)m_caster)->ApplySpellMod(m_spellInfo->Id,SPELLMOD_NOT_LOSE_CASTING_TIME, delayReduce, this);
delayReduce += m_caster->GetTotalAuraModifier(SPELL_AURA_REDUCE_PUSHBACK) - 100;
if(delayReduce >= 100)
return;
int32 delaytime = GetNextDelayAtDamageMsTime();
delaytime = delaytime * (100 - delayReduce) / 100;
if(int32(m_timer) + delaytime > m_casttime)
{
@@ -5224,14 +5210,18 @@ void Spell::DelayedChannel()
if(!m_caster || m_caster->GetTypeId() != TYPEID_PLAYER || getState() != SPELL_STATE_CASTING)
return;
//check resist chance
int32 resistChance = 100; //must be initialized to 100 for percent modifiers
((Player*)m_caster)->ApplySpellMod(m_spellInfo->Id,SPELLMOD_NOT_LOSE_CASTING_TIME,resistChance, this);
resistChance += m_caster->GetTotalAuraModifier(SPELL_AURA_RESIST_PUSHBACK) - 100;
if (roll_chance_i(resistChance))
if(isDelayableNoMore()) // Spells may only be delayed twice
return;
int32 delaytime = GetNextDelayAtDamageMsTime();
//check pushback reduce
int32 delaytime = GetSpellDuration(m_spellInfo) * 25 / 100; // channeling delay is normally 25% of its time per hit
int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
((Player*)m_caster)->ApplySpellMod(m_spellInfo->Id,SPELLMOD_NOT_LOSE_CASTING_TIME,delayReduce, this);
delayReduce += m_caster->GetTotalAuraModifier(SPELL_AURA_REDUCE_PUSHBACK) - 100;
if(delayReduce >= 100)
return;
delaytime = delaytime * (100 - delayReduce) / 100;
if(int32(m_timer) < delaytime)
{
@@ -5404,7 +5394,13 @@ bool Spell::CheckTarget( Unit* target, uint32 eff, bool hitPhase )
// all ok by some way or another, skip normal check
break;
default: // normal case
if(target!=m_caster && !target->IsWithinLOSInMap(m_caster))
// Get GO cast coordinates if original caster -> GO
WorldObject *caster = NULL;
if (m_originalCasterGUID)
caster = ObjectAccessor::GetGameObject(*m_caster, m_originalCasterGUID);
if (!caster)
caster = m_caster;
if(target!=m_caster && !target->IsWithinLOSInMap(caster))
return false;
break;
}
+10 -1
View File
@@ -161,6 +161,7 @@ class SpellCastTargets
void setUnitTarget(Unit *target);
void setDestination(float x, float y, float z, bool send = true, int32 mapId = -1);
void setDestination(Unit *target, bool send = true);
void setSource(float x, float y, float z);
uint64 getGOTargetGUID() const { return m_GOTargetGUID; }
GameObject *getGOTarget() const { return m_GOTarget; }
@@ -419,6 +420,7 @@ class Spell
uint64 m_castItemGUID;
uint8 m_cast_count;
uint32 m_glyphIndex;
uint32 m_preCastSpell;
SpellCastTargets m_targets;
int32 GetCastTime() const { return m_casttime; }
@@ -485,7 +487,14 @@ class Spell
uint8 m_runesState;
uint8 m_delayAtDamageCount;
int32 GetNextDelayAtDamageMsTime() { return m_delayAtDamageCount < 5 ? 1000 - (m_delayAtDamageCount++)* 200 : 200; }
bool isDelayableNoMore()
{
if(m_delayAtDamageCount >= 2)
return true;
m_delayAtDamageCount++;
return false;
}
// Delayed spells system
uint64 m_delayStart; // time of spell delay start, filled by event handler, zero = just started
+2 -2
View File
@@ -193,7 +193,7 @@ enum AuraType
SPELL_AURA_ALLOW_TAME_PET_TYPE = 146,
SPELL_AURA_ADD_CREATURE_IMMUNITY = 147,
SPELL_AURA_RETAIN_COMBO_POINTS = 148,
SPELL_AURA_RESIST_PUSHBACK = 149, // Resist Pushback
SPELL_AURA_REDUCE_PUSHBACK = 149, // Reduce Pushback
SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT = 150,
SPELL_AURA_TRACK_STEALTHED = 151, // Track Stealthed
SPELL_AURA_MOD_DETECTED_RANGE = 152, // Mod Detected Range
@@ -304,7 +304,7 @@ enum AuraType
SPELL_AURA_MOD_TARGET_RESIST_BY_SPELL_CLASS = 257,
SPELL_AURA_258 = 258,
SPELL_AURA_259 = 259,
SPELL_AURA_260 = 260,
SPELL_AURA_SCREEN_EFFECT = 260,
SPELL_AURA_261 = 261,
SPELL_AURA_262 = 262,
SPELL_AURA_ALLOW_ONLY_ABILITY = 263,
+29 -42
View File
@@ -203,7 +203,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
&Aura::HandleNoImmediateEffect, //146 SPELL_AURA_ALLOW_TAME_PET_TYPE
&Aura::HandleNULL, //147 SPELL_AURA_ADD_CREATURE_IMMUNITY
&Aura::HandleAuraRetainComboPoints, //148 SPELL_AURA_RETAIN_COMBO_POINTS
&Aura::HandleNoImmediateEffect, //149 SPELL_AURA_RESIST_PUSHBACK
&Aura::HandleNoImmediateEffect, //149 SPELL_AURA_REDUCE_PUSHBACK
&Aura::HandleShieldBlockValue, //150 SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT
&Aura::HandleAuraTrackStealthed, //151 SPELL_AURA_TRACK_STEALTHED
&Aura::HandleNoImmediateEffect, //152 SPELL_AURA_MOD_DETECTED_RANGE implemented in Creature::GetAttackDistance
@@ -314,7 +314,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
&Aura::HandleNULL, //257 SPELL_AURA_MOD_TARGET_RESIST_BY_SPELL_CLASS Use SpellClassMask for spell select
&Aura::HandleNULL, //258 SPELL_AURA_MOD_SPELL_VISUAL
&Aura::HandleNULL, //259 corrupt healing over time spell
&Aura::HandleNULL, //260
&Aura::HandleNoImmediateEffect, //260 SPELL_AURA_SCREEN_EFFECT (miscvalue = id in ScreenEffect.dbc) not required any code
&Aura::HandleNULL, //261 out of phase?
&Aura::HandleNULL, //262
&Aura::HandleNULL, //263 SPELL_AURA_ALLOW_ONLY_ABILITY player can use only abilites set in SpellClassMask
@@ -2141,6 +2141,28 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
{
break;
}
case SPELLFAMILY_PRIEST:
{
// Pain and Suffering
if( m_spellProto->SpellIconID == 2874 && m_target->GetTypeId()==TYPEID_PLAYER )
{
if(apply)
{
// Reduce backfire damage (dot damage) from Shadow Word: Death
SpellModifier *mod = new SpellModifier;
mod->op = SPELLMOD_DOT;
mod->value = m_modifier.m_amount;
mod->type = SPELLMOD_PCT;
mod->spellId = GetId();
mod->mask = 0x0000000200000000LL;
mod->mask2= 0LL;
m_spellmod = mod;
}
((Player*)m_target)->AddSpellMod(m_spellmod, apply);
return;
}
break;
}
case SPELLFAMILY_DRUID:
{
// Lifebloom
@@ -5039,6 +5061,7 @@ void Aura::HandleShapeshiftBoosts(bool apply)
break;
case FORM_TREE:
spellId = 5420;
spellId2 = 34123;
break;
case FORM_TRAVEL:
spellId = 5419;
@@ -6073,47 +6096,11 @@ void Aura::PeriodicDummyTick()
{
if ((*i)->GetId() == GetId())
{
// Get tick number
int32 tick = (m_maxduration - m_duration) / m_modifier.periodictime;
// Default case (not on arenas)
if (tick == 0)
{
(*i)->GetModifier()->m_amount = m_modifier.m_amount;
((Player*)m_target)->UpdateManaRegen();
// Disable continue
m_isPeriodic = false;
}
return;
//**********************************************
// Code commended since arena patch not added
// This feature uses only in arenas
//**********************************************
// Here need increase mana regen per tick (6 second rule)
// on 0 tick - 0 (handled in 2 second)
// on 1 tick - 166% (handled in 4 second)
// on 2 tick - 133% (handled in 6 second)
// Not need update after 3 tick
/*
if (tick > 3)
return;
// Apply bonus for 0 - 3 tick
switch (tick)
{
case 0: // 0%
(*i)->GetModifier()->m_amount = m_modifier.m_amount = 0;
break;
case 1: // 166%
(*i)->GetModifier()->m_amount = m_modifier.m_amount * 5 / 3;
break;
case 2: // 133%
(*i)->GetModifier()->m_amount = m_modifier.m_amount * 4 / 3;
break;
default: // 100% - normal regen
(*i)->GetModifier()->m_amount = m_modifier.m_amount;
break;
}
(*i)->GetModifier()->m_amount = m_modifier.m_amount;
((Player*)m_target)->UpdateManaRegen();
return;*/
// Disable continue
m_isPeriodic = false;
return;
}
}
return;
+37 -13
View File
@@ -1377,6 +1377,12 @@ void Spell::EffectDummy(uint32 i)
m_caster->CastCustomSpell(m_caster, 12976, &healthModSpellBasePoints0, NULL, NULL, true, NULL);
return;
}
// Bloodthirst
case 23881:
{
m_caster->CastCustomSpell(unitTarget, 23885, &damage, NULL, NULL, true, NULL);
return;
}
}
break;
case SPELLFAMILY_WARLOCK:
@@ -1487,16 +1493,6 @@ void Spell::EffectDummy(uint32 i)
}
break;
case SPELLFAMILY_DRUID:
switch(m_spellInfo->Id )
{
case 5420: // Tree of Life passive
{
// Tree of Life area effect
int32 health_mod = int32(m_caster->GetStat(STAT_SPIRIT)/4);
m_caster->CastCustomSpell(m_caster,34123,&health_mod,NULL,NULL,true,NULL);
return;
}
}
break;
case SPELLFAMILY_ROGUE:
switch(m_spellInfo->Id )
@@ -2228,7 +2224,7 @@ void Spell::EffectApplyAura(uint32 i)
(unitTarget->GetTypeId()!=TYPEID_PLAYER || !((Player*)unitTarget)->GetSession()->PlayerLoading()) )
return;
Unit* caster = m_originalCasterGUID ? m_originalCaster : m_caster;
Unit* caster = m_originalCaster ? m_originalCaster : m_caster;
if(!caster)
return;
@@ -3380,7 +3376,7 @@ void Spell::EffectLearnSpell(uint32 i)
Player *player = (Player*)unitTarget;
uint32 spellToLearn = ((m_spellInfo->Id==SPELL_ID_GENERIC_LEARN) || (m_spellInfo->Id==SPELL_ID_GENERIC_LEARN_PET)) ? damage : m_spellInfo->EffectTriggerSpell[i];
player->learnSpell(spellToLearn);
player->learnSpell(spellToLearn,false);
sLog.outDebug( "Spell: Player %u have learned spell %u from NpcGUID=%u", player->GetGUIDLow(), spellToLearn, m_caster->GetGUIDLow() );
}
@@ -5045,7 +5041,7 @@ void Spell::EffectScriptEffect(uint32 effIndex)
// learn random explicit discovery recipe (if any)
if(uint32 discoveredSpell = GetExplicitDiscoverySpell(m_spellInfo->Id, player))
player->learnSpell(discoveredSpell);
player->learnSpell(discoveredSpell,false);
return;
}
}
@@ -5120,6 +5116,34 @@ void Spell::EffectScriptEffect(uint32 effIndex)
}
break;
}
case SPELLFAMILY_PRIEST:
{
switch(m_spellInfo->Id)
{
// Pain and Suffering
case 47948:
{
if (!unitTarget)
return;
// Refresh Shadow Word: Pain on target
Unit::AuraList const &mPeriodic = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
for(Unit::AuraList::const_iterator i = mPeriodic.begin(); i != mPeriodic.end(); ++i)
{
if( (*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_PRIEST &&
(*i)->GetSpellProto()->SpellFamilyFlags & 0x0000000000008000LL &&
(*i)->GetCasterGUID()==m_caster->GetGUID() )
{
(*i)->RefreshAura();
return;
}
}
return;
}
default:
break;
}
break;
}
case SPELLFAMILY_HUNTER:
{
switch(m_spellInfo->Id)
+2 -2
View File
@@ -264,8 +264,8 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
return;
}
// not have spell or spell passive and not casted by client
if ( !_player->HasSpell (spellId) || IsPassiveSpell(spellId) )
// not have spell in spellbook or spell passive and not casted by client
if ( !_player->HasActiveSpell (spellId) || IsPassiveSpell(spellId) )
{
//cheater? kick? ban?
return;
+45 -17
View File
@@ -480,8 +480,6 @@ bool IsPositiveTarget(uint32 targetA, uint32 targetB)
case TARGET_CURRENT_ENEMY_COORDINATES:
case TARGET_UNIT_CHANNEL:
return false;
case TARGET_ALL_AROUND_CASTER:
return (targetB == TARGET_ALL_PARTY || targetB == TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER);
default:
break;
}
@@ -1095,7 +1093,7 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const * spellP
return false;
// Always trigger for this
if (EventProcFlag & (PROC_FLAG_KILLED | PROC_FLAG_KILL))
if (EventProcFlag & (PROC_FLAG_KILLED | PROC_FLAG_KILL | PROC_FLAG_ON_TRAP_ACTIVATION))
return true;
if (spellProcEvent) // Exist event data
@@ -1223,28 +1221,38 @@ bool SpellMgr::IsRankSpellDueToSpell(SpellEntry const *spellInfo_1,uint32 spellI
bool SpellMgr::canStackSpellRanks(SpellEntry const *spellInfo)
{
if(IsPassiveSpell(spellInfo->Id)) // ranked passive spell
return false;
if(spellInfo->powerType != POWER_MANA && spellInfo->powerType != POWER_HEALTH)
return false;
if(IsProfessionOrRidingSpell(spellInfo->Id))
return false;
if(spellmgr.IsSkillBonusSpell(spellInfo->Id))
return false;
// All stance spells. if any better way, change it.
for (int i = 0; i < 3; i++)
{
// Paladin aura Spell
if(spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN
&& spellInfo->Effect[i]==SPELL_EFFECT_APPLY_AREA_AURA_RAID)
return false;
// Druid form Spell
if(spellInfo->SpellFamilyName == SPELLFAMILY_DRUID
&& spellInfo->Effect[i]==SPELL_EFFECT_APPLY_AURA
&& spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_SHAPESHIFT)
return false;
// Rogue Stealth
if(spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE
&& spellInfo->Effect[i]==SPELL_EFFECT_APPLY_AURA
&& spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_SHAPESHIFT)
return false;
switch(spellInfo->SpellFamilyName)
{
case SPELLFAMILY_PALADIN:
// Paladin aura Spell
if (spellInfo->Effect[i]==SPELL_EFFECT_APPLY_AREA_AURA_RAID)
return false;
break;
case SPELLFAMILY_DRUID:
// Druid form Spell
if (spellInfo->Effect[i]==SPELL_EFFECT_APPLY_AURA &&
spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_SHAPESHIFT)
return false;
break;
case SPELLFAMILY_ROGUE:
// Rogue Stealth
if (spellInfo->Effect[i]==SPELL_EFFECT_APPLY_AURA &&
spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_SHAPESHIFT)
return false;
}
}
return true;
}
@@ -1380,6 +1388,24 @@ bool SpellMgr::IsPrimaryProfessionFirstRankSpell(uint32 spellId) const
return IsPrimaryProfessionSpell(spellId) && GetSpellRank(spellId)==1;
}
bool SpellMgr::IsSkillBonusSpell(uint32 spellId) const
{
SkillLineAbilityMap::const_iterator lower = GetBeginSkillLineAbilityMap(spellId);
SkillLineAbilityMap::const_iterator upper = GetEndSkillLineAbilityMap(spellId);
for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx)
{
SkillLineAbilityEntry const *pAbility = _spell_idx->second;
if (!pAbility || pAbility->learnOnGetSkill != ABILITY_LEARNED_ON_GET_PROFESSION_SKILL)
continue;
if(pAbility->req_skill_value > 0)
return true;
}
return false;
}
SpellEntry const* SpellMgr::SelectAuraRankForPlayerLevel(SpellEntry const* spellInfo, uint32 playerLevel) const
{
// ignore passive spells
@@ -2558,6 +2584,8 @@ uint8 GetSpellAllowedInLocationError(SpellEntry const *spellInfo,uint32 map_id,u
case 51721: // Dominion Over Acherus
case 54055: // Dominion Over Acherus
return area_id == 4281 || area_id == 4342 ? 0 : SPELL_FAILED_INCORRECT_AREA;
case 54119: // Mist of the Kvaldir
return area_id == 4028 || area_id == 4029 || area_id == 4106 || area_id == 4031 ? 0 : SPELL_FAILED_INCORRECT_AREA;
}
return 0;
+12
View File
@@ -397,6 +397,7 @@ bool IsAuraAddedBySpell(uint32 auraType, uint32 spellId);
uint8 GetSpellAllowedInLocationError(SpellEntry const *spellInfo,uint32 map_id,uint32 zone_id,uint32 area_id);
static bool IsAreaEffectTarget[TOTAL_SPELL_TARGETS];
inline bool IsAreaOfEffectSpell(SpellEntry const *spellInfo)
{
if(IsAreaEffectTarget[spellInfo->EffectImplicitTargetA[0]] || IsAreaEffectTarget[spellInfo->EffectImplicitTargetB[0]])
@@ -873,6 +874,14 @@ class SpellMgr
return 0;
}
uint32 GetNextSpellInChain(uint32 spell_id) const
{
if(SpellChainNode const* node = GetSpellChainNode(spell_id))
return node->next;
return 0;
}
SpellsRequiringSpellMap const& GetSpellsRequiringSpell() const { return mSpellsReqSpell; }
// Note: not use rank for compare to spell ranks: spell chains isn't linear order
@@ -957,6 +966,9 @@ class SpellMgr
static bool IsPrimaryProfessionSpell(uint32 spellId);
bool IsPrimaryProfessionFirstRankSpell(uint32 spellId) const;
bool IsSkillBonusSpell(uint32 spellId) const;
// Spell script targets
SpellScriptTarget::const_iterator GetBeginSpellScriptTarget(uint32 spell_id) const
{
+63 -49
View File
@@ -4567,7 +4567,8 @@ bool Unit::HandleHasteAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown)
{
SpellEntry const *dummySpell = triggeredByAura->GetSpellProto ();
uint32 effIndex = triggeredByAura->GetEffIndex ();
uint32 effIndex = triggeredByAura->GetEffIndex();
int32 triggerAmount = triggeredByAura->GetModifier()->m_amount;
Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER
? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL;
@@ -4591,7 +4592,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
return false;
// return damage % to attacker but < 50% own total health
basepoints0 = triggeredByAura->GetModifier()->m_amount*int32(damage)/100;
basepoints0 = triggerAmount*int32(damage)/100;
if(basepoints0 > GetMaxHealth()/2)
basepoints0 = GetMaxHealth()/2;
@@ -4913,7 +4914,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
case 48504:
{
triggered_spell_id = 48503;
basepoints0 = triggeredByAura->GetModifier()->m_amount;
basepoints0 = triggerAmount;
target = this;
break;
}
@@ -4931,7 +4932,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
case 31872:
{
// Roll chane
if (!roll_chance_i(triggeredByAura->GetModifier()->m_amount))
if (!roll_chance_i(triggerAmount))
return false;
// Remove any stun effect on target
@@ -4962,7 +4963,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
return false;
// mana reward
basepoints0 = (triggeredByAura->GetModifier()->m_amount * GetMaxPower(POWER_MANA) / 100);
basepoints0 = (triggerAmount * GetMaxPower(POWER_MANA) / 100);
target = this;
triggered_spell_id = 29442;
break;
@@ -4975,7 +4976,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
// mana cost save
int32 cost = procSpell->manaCost + procSpell->ManaCostPercentage * GetCreateMana() / 100;
basepoints0 = cost * triggeredByAura->GetModifier()->m_amount/100;
basepoints0 = cost * triggerAmount/100;
if( basepoints0 <=0 )
return false;
@@ -4986,7 +4987,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
// Hot Streak
if (dummySpell->SpellIconID == 2999)
{
if (triggeredByAura->GetEffIndex()!=0)
if (effIndex!=0)
return true;
Aura *counter = GetAura(triggeredByAura->GetId(), 1);
if (!counter)
@@ -5000,7 +5001,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
if (mod->m_amount < 100) // not enough
return true;
// Crititcal counted -> roll chance
if (roll_chance_i(triggeredByAura->GetModifier()->m_amount))
if (roll_chance_i(triggerAmount))
CastSpell(this, 48108, true, castItem, triggeredByAura);
}
mod->m_amount = 25;
@@ -5013,7 +5014,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
return false;
int32 cost = procSpell->manaCost + procSpell->ManaCostPercentage * GetCreateMana() / 100;
basepoints0 = cost * triggeredByAura->GetModifier()->m_amount/100;
basepoints0 = cost * triggerAmount/100;
if( basepoints0 <=0 )
return false;
triggered_spell_id = 44450;
@@ -5109,7 +5110,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
if (dummySpell->SpellIconID == 3214)
{
triggered_spell_id = 59653;
basepoints0 = GetShieldBlockValue() * triggeredByAura->GetModifier()->m_amount / 100;
basepoints0 = GetShieldBlockValue() * triggerAmount / 100;
break;
}
break;
@@ -5168,7 +5169,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
if (!target)
return false;
triggered_spell_id = 54181;
basepoints0 = damage * triggeredByAura->GetModifier()->m_amount / 100;
basepoints0 = damage * triggerAmount / 100;
break;
}
switch(dummySpell->Id)
@@ -5187,7 +5188,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
case 30296:
{
// health
basepoints0 = int32(damage*triggeredByAura->GetModifier()->m_amount/100);
basepoints0 = int32(damage*triggerAmount/100);
target = this;
triggered_spell_id = 30294;
break;
@@ -5206,7 +5207,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
return false;
// heal amount
basepoints0 = damage * triggeredByAura->GetModifier()->m_amount/100;
basepoints0 = damage * triggerAmount/100;
triggered_spell_id = 37382;
break;
}
@@ -5232,14 +5233,14 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
return false;
// energize amount
basepoints0 = triggeredByAura->GetModifier()->m_amount*damage/100;
basepoints0 = triggerAmount*damage/100;
pVictim->CastCustomSpell(pVictim,34919,&basepoints0,NULL,NULL,true,castItem,triggeredByAura);
return true; // no hidden cooldown
}
// Divine Aegis
if (dummySpell->SpellIconID == 2820)
{
basepoints0 = damage * triggeredByAura->GetModifier()->m_amount/100;
basepoints0 = damage * triggerAmount/100;
triggered_spell_id = 47753;
break;
}
@@ -5256,8 +5257,9 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
return false;
// heal amount
basepoints0 = triggeredByAura->GetModifier()->m_amount*damage/100;
pVictim->CastCustomSpell(pVictim,15290,&basepoints0,NULL,NULL,true,castItem,triggeredByAura);
int32 team = triggerAmount*damage/500;
int32 self = triggerAmount*damage/100 - team;
pVictim->CastCustomSpell(pVictim,15290,&team,&self,NULL,true,castItem,triggeredByAura);
return true; // no hidden cooldown
}
// Priest Tier 6 Trinket (Ashtongue Talisman of Acumen)
@@ -5291,7 +5293,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
return false;
// heal amount
basepoints0 = damage * triggeredByAura->GetModifier()->m_amount/100;
basepoints0 = damage * triggerAmount/100;
target = this;
triggered_spell_id = 39373;
break;
@@ -5379,7 +5381,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
if (!procSpell)
return false;
// Only 0 aura can proc
if (triggeredByAura->GetEffIndex()!=0)
if (effIndex!=0)
return true;
// Wrath crit
if (procSpell->SpellFamilyFlags & 0x0000000000000001LL)
@@ -5403,7 +5405,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
else if (dummySpell->SpellIconID == 2860)
{
triggered_spell_id = 48504;
basepoints0 = triggeredByAura->GetModifier()->m_amount * damage / 100;
basepoints0 = triggerAmount * damage / 100;
break;
}
break;
@@ -5455,7 +5457,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
return false;
// energy cost save
basepoints0 = procSpell->manaCost * triggeredByAura->GetModifier()->m_amount/100;
basepoints0 = procSpell->manaCost * triggerAmount/100;
if(basepoints0 <= 0)
return false;
@@ -5474,7 +5476,8 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
return false;
// mana cost save
basepoints0 = procSpell->manaCost * 40/100;
int32 mana = procSpell->manaCost + procSpell->ManaCostPercentage * GetCreateMana() / 100;
basepoints0 = mana * 40/100;
if(basepoints0 <= 0)
return false;
@@ -5493,9 +5496,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
if ( dummySpell->SpellIconID == 3579 )
{
// Proc only from periodic (from trap activation proc another aura of this spell)
if (!(procFlag & PROC_FLAG_ON_DO_PERIODIC))
return false;
if (!roll_chance_i(triggeredByAura->GetModifier()->m_amount))
if (!(procFlag & PROC_FLAG_ON_DO_PERIODIC) || !roll_chance_i(triggerAmount))
return false;
triggered_spell_id = 56453;
target = this;
@@ -5516,7 +5517,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
case SPELLFAMILY_PALADIN:
{
// Seal of Righteousness - melee proc dummy (addition ${$MWS*(0.022*$AP+0.044*$SPH)} damage)
if (dummySpell->SpellFamilyFlags&0x000000008000000LL && triggeredByAura->GetEffIndex()==0)
if (dummySpell->SpellFamilyFlags&0x000000008000000LL && effIndex==0)
{
triggered_spell_id = 25742;
float ap = GetTotalAttackPowerValue(BASE_ATTACK);
@@ -5536,7 +5537,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
if (dummySpell->SpellIconID == 3025)
{
// 4 damage tick
basepoints0 = triggeredByAura->GetModifier()->m_amount*damage/400;
basepoints0 = triggerAmount*damage/400;
triggered_spell_id = 61840;
break;
}
@@ -5544,7 +5545,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
if (dummySpell->SpellIconID == 3030)
{
// 4 healing tick
basepoints0 = triggeredByAura->GetModifier()->m_amount*damage/400;
basepoints0 = triggerAmount*damage/400;
triggered_spell_id = 54203;
break;
}
@@ -5620,7 +5621,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
return false;
// heal amount
basepoints0 = triggeredByAura->GetModifier()->m_amount*damage/100;
basepoints0 = triggerAmount*damage/100;
target = this;
triggered_spell_id = 31786;
break;
@@ -5628,13 +5629,13 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
// Seal of Blood do damage trigger
case 31892:
{
if (triggeredByAura->GetEffIndex() == 0) // 0 effect - is proc on enemy
if (effIndex == 0) // 0 effect - is proc on enemy
triggered_spell_id = 31893;
else if (triggeredByAura->GetEffIndex() == 1) // 1 effect - is proc on self
else if (effIndex == 1) // 1 effect - is proc on self
{
// add spell damage from prev effect (27%)
damage += CalculateDamage(BASE_ATTACK, false) * 27 / 100;
basepoints0 = triggeredByAura->GetModifier()->m_amount * damage / 100;
basepoints0 = triggerAmount * damage / 100;
target = this;
triggered_spell_id = 32221;
}
@@ -5645,13 +5646,13 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
// Seal of the Martyr do damage trigger
case 53720:
{
if (triggeredByAura->GetEffIndex() == 0) // 0 effect - is proc on enemy
if (effIndex == 0) // 0 effect - is proc on enemy
triggered_spell_id = 53719;
else if (triggeredByAura->GetEffIndex() == 1) // 1 effect - is proc on self
else if (effIndex == 1) // 1 effect - is proc on self
{
// add spell damage from prev effect (27%)
damage += CalculateDamage(BASE_ATTACK, false) * 27 / 100;
basepoints0 = triggeredByAura->GetModifier()->m_amount * damage / 100;
basepoints0 = triggerAmount * damage / 100;
target = this;
triggered_spell_id = 53718;
}
@@ -5704,14 +5705,14 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
case 54936:
{
triggered_spell_id = 54957;
basepoints0 = triggeredByAura->GetModifier()->m_amount*damage/100;
basepoints0 = triggerAmount*damage/100;
break;
}
// Glyph of Holy Light
case 54937:
{
triggered_spell_id = 54968;
basepoints0 = triggeredByAura->GetModifier()->m_amount*damage/100;
basepoints0 = triggerAmount*damage/100;
break;
}
}
@@ -5864,7 +5865,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
// Not proc from self heals
if (this==pVictim)
return false;
basepoints0 = triggeredByAura->GetModifier()->m_amount * damage / 100;
basepoints0 = triggerAmount * damage / 100;
target = this;
triggered_spell_id = 55533;
break;
@@ -5876,7 +5877,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
target = GetOwner();
if(!target)
return false;
basepoints0 = triggeredByAura->GetModifier()->m_amount * damage / 100;
basepoints0 = triggerAmount * damage / 100;
triggered_spell_id = 58879;
break;
}
@@ -5886,14 +5887,14 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
{
// TODO: frite dummy fot triggered spell
triggered_spell_id = 52759;
basepoints0 = triggeredByAura->GetModifier()->m_amount * damage / 100;
basepoints0 = triggerAmount * damage / 100;
target = this;
break;
}
// Earth Shield
if(dummySpell->SpellFamilyFlags & 0x0000040000000000LL)
{
basepoints0 = triggeredByAura->GetModifier()->m_amount;
basepoints0 = triggerAmount;
target = this;
triggered_spell_id = 379;
break;
@@ -6027,14 +6028,14 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
{
if (GetTypeId() != TYPEID_PLAYER || !((Player*)this)->isHonorOrXPTarget(pVictim))
return false;
basepoints0 = triggeredByAura->GetModifier()->m_amount * damage / 100;
basepoints0 = triggerAmount * damage / 100;
triggered_spell_id = 53168;
break;
}
// Butchery
if (dummySpell->SpellIconID == 2664)
{
basepoints0 = triggeredByAura->GetModifier()->m_amount;
basepoints0 = triggerAmount;
triggered_spell_id = 50163;
target = this;
break;
@@ -6043,7 +6044,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
if (dummySpell->Id == 49028)
{
// 1 dummy aura for dismiss rune blade
if (triggeredByAura->GetEffIndex()!=2)
if (effIndex!=2)
return false;
// TODO: wite script for this "fights on its own, doing the same attacks"
// NOTE: Trigger here on every attack and spell cast
@@ -6059,7 +6060,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
// Vendetta
if (dummySpell->SpellFamilyFlags & 0x0000000000010000LL)
{
basepoints0 = triggeredByAura->GetModifier()->m_amount * GetMaxHealth() / 100;
basepoints0 = triggerAmount * GetMaxHealth() / 100;
triggered_spell_id = 50181;
target = this;
break;
@@ -6067,7 +6068,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
// Necrosis
if (dummySpell->SpellIconID == 2709)
{
basepoints0 = triggeredByAura->GetModifier()->m_amount * damage / 100;
basepoints0 = triggerAmount * damage / 100;
triggered_spell_id = 51460;
break;
}
@@ -6089,7 +6090,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
{
if (!roll_chance_f(GetUnitCriticalChance(BASE_ATTACK, pVictim)))
return false;
basepoints0 = triggeredByAura->GetModifier()->m_amount * damage / 100;
basepoints0 = triggerAmount * damage / 100;
triggered_spell_id = 50526;
break;
}
@@ -6747,11 +6748,16 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
// Need add combopoint AFTER finish movie (or they dropped in finish phase)
break;
}
// Bloodthirst (($m/100)% of max health)
case 23880:
{
basepoints0 = int32(GetMaxHealth() * triggerAmount / 10000);
break;
}
// Shamanistic Rage triggered spell
case 30824:
{
basepoints0 = int32(GetTotalAttackPowerValue(BASE_ATTACK) * triggerAmount / 100);
trigger_spell_id = 30824;
break;
}
// Enlightenment (trigger only from mana cost spells)
@@ -6806,6 +6812,14 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
return false;
break;
}
// Lock and Load
case 56453:
{
// Proc only from trap activation (from periodic proc another aura of this spell)
if (!(procFlags & PROC_FLAG_ON_TRAP_ACTIVATION) || !roll_chance_i(triggerAmount))
return false;
break;
}
}
if( cooldown && GetTypeId()==TYPEID_PLAYER && ((Player*)this)->HasSpellCooldown(trigger_spell_id))
@@ -10554,7 +10568,7 @@ bool InitTriggerAuraData()
isTriggerAura[SPELL_AURA_MOD_DAMAGE_FROM_CASTER] = true;
isNonTriggerAura[SPELL_AURA_MOD_POWER_REGEN]=true;
isNonTriggerAura[SPELL_AURA_RESIST_PUSHBACK]=true;
isNonTriggerAura[SPELL_AURA_REDUCE_PUSHBACK]=true;
return true;
}
+3 -1
View File
@@ -777,7 +777,8 @@ void World::LoadConfigSettings(bool reload)
}
m_configs[CONFIG_GM_LOGIN_STATE] = sConfig.GetIntDefault("GM.LoginState", 2);
// m_configs[CONFIG_GM_ACCEPT_TICKETS] = sConfig.GetIntDefault("GM.AcceptTickets", 2);
m_configs[CONFIG_GM_VISIBLE_STATE] = sConfig.GetIntDefault("GM.Visible", 2);
//m_configs[CONFIG_GM_ACCEPT_TICKETS] = sConfig.GetIntDefault("GM.AcceptTickets", 2);
m_configs[CONFIG_GM_CHAT] = sConfig.GetIntDefault("GM.Chat", 2);
m_configs[CONFIG_GM_WISPERING_TO] = sConfig.GetIntDefault("GM.WhisperingTo", 2);
m_configs[CONFIG_GM_IN_GM_LIST] = sConfig.GetBoolDefault("GM.InGMList", false);
@@ -796,6 +797,7 @@ void World::LoadConfigSettings(bool reload)
m_configs[CONFIG_START_GM_LEVEL] = MAX_LEVEL;
}
m_configs[CONFIG_GM_LOWER_SECURITY] = sConfig.GetBoolDefault("GM.LowerSecurity", false);
m_configs[CONFIG_GM_ALLOW_ACHIEVEMENT_GAINS] = sConfig.GetBoolDefault("GM.AllowAchievementGain", true);
m_configs[CONFIG_GROUP_VISIBILITY] = sConfig.GetIntDefault("Visibility.GroupMode",0);
+3
View File
@@ -125,6 +125,8 @@ enum WorldConfigs
CONFIG_MAX_PRIMARY_TRADE_SKILL,
CONFIG_MIN_PETITION_SIGNS,
CONFIG_GM_LOGIN_STATE,
CONFIG_GM_VISIBLE_STATE,
CONFIG_GM_ACCEPT_TICKETS,
CONFIG_GM_CHAT,
CONFIG_GM_WISPERING_TO,
CONFIG_GM_IN_GM_LIST,
@@ -132,6 +134,7 @@ enum WorldConfigs
CONFIG_GM_LOG_TRADE,
CONFIG_START_GM_LEVEL,
CONFIG_GM_LOWER_SECURITY,
CONFIG_GM_ALLOW_ACHIEVEMENT_GAINS,
CONFIG_GROUP_VISIBILITY,
CONFIG_MAIL_DELIVERY_DELAY,
CONFIG_UPTIME_UPDATE,