*Update to Mangos 6938. (Only build for VC9)
--HG-- branch : trunk
This commit is contained in:
@@ -0,0 +1,910 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "AchievementMgr.h"
|
||||
#include "Common.h"
|
||||
#include "Player.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "Database/DBCEnums.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Guild.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "GameEvent.h"
|
||||
#include "World.h"
|
||||
#include "SpellMgr.h"
|
||||
|
||||
const CriteriaCastSpellRequirement AchievementMgr::criteriaCastSpellRequirements[CRITERIA_CAST_SPELL_REQ_COUNT] =
|
||||
{
|
||||
{5272, 3057, 0, 0},
|
||||
{5273, 2784, 0, 0},
|
||||
{5752, 9099, 0, 0},
|
||||
{5753, 8403, 0, 0},
|
||||
{5772, 0, 0, RACE_GNOME},
|
||||
{5774, 0, 0, RACE_BLOODELF},
|
||||
{5775, 0, 0, RACE_DRAENEI},
|
||||
{5776, 0, 0, RACE_DWARF},
|
||||
{5777, 0, 0, RACE_HUMAN},
|
||||
{5778, 0, 0, RACE_NIGHTELF},
|
||||
{5779, 0, 0, RACE_ORC},
|
||||
{5780, 0, 0, RACE_TAUREN},
|
||||
{5781, 0, 0, RACE_TROLL},
|
||||
{5782, 0, 0, RACE_UNDEAD_PLAYER},
|
||||
{6225, 5661, 0, 0},
|
||||
{6226, 26044, 0, 0},
|
||||
{6228, 739, 0, 0},
|
||||
{6229, 927, 0, 0},
|
||||
{6230, 1444, 0, 0},
|
||||
{6231, 8140, 0, 0},
|
||||
{6232, 5489, 0, 0},
|
||||
{6233,12336, 0, 0},
|
||||
{6234, 1351, 0, 0},
|
||||
{6235, 5484, 0, 0},
|
||||
{6236, 1182, 0, 0},
|
||||
{6237, 0, CLASS_DEATH_KNIGHT, RACE_ORC},
|
||||
{6238, 0, CLASS_WARRIOR, RACE_HUMAN},
|
||||
{6239, 0, CLASS_SHAMAN, RACE_TAUREN},
|
||||
{6240, 0, CLASS_DRUID, RACE_NIGHTELF},
|
||||
{6241, 0, CLASS_ROGUE, RACE_UNDEAD_PLAYER},
|
||||
{6242, 0, CLASS_HUNTER, RACE_TROLL},
|
||||
{6243, 0, CLASS_MAGE, RACE_GNOME},
|
||||
{6244, 0, CLASS_PALADIN, RACE_DWARF},
|
||||
{6245, 0, CLASS_WARLOCK, RACE_BLOODELF},
|
||||
{6246, 0, CLASS_PRIEST, RACE_DRAENEI},
|
||||
{6312, 0, CLASS_WARLOCK, RACE_GNOME},
|
||||
{6313, 0, CLASS_DEATH_KNIGHT, RACE_HUMAN},
|
||||
{6314, 0, CLASS_PRIEST, RACE_NIGHTELF},
|
||||
{6315, 0, CLASS_SHAMAN, RACE_ORC},
|
||||
{6316, 0, CLASS_DRUID, RACE_TAUREN},
|
||||
{6317, 0, CLASS_ROGUE, RACE_TROLL},
|
||||
{6318, 0, CLASS_WARRIOR, RACE_UNDEAD_PLAYER},
|
||||
{6319, 0, CLASS_MAGE, RACE_BLOODELF},
|
||||
{6320, 0, CLASS_PALADIN, RACE_DRAENEI},
|
||||
{6321, 0, CLASS_HUNTER, RACE_DWARF},
|
||||
{6662, 31261, 0, 0}
|
||||
};
|
||||
|
||||
const AchievementReward AchievementMgr::achievementRewards[ACHIEVEMENT_REWARD_COUNT] =
|
||||
{
|
||||
// achievementId, horde titleid, alliance titleid, itemid
|
||||
{45, 0, 0, 43348},
|
||||
{46, 78, 78, 0},
|
||||
{230, 72, 72, 0},
|
||||
{456, 139, 139, 0},
|
||||
{614, 0, 0, 44223},
|
||||
{619, 0, 0, 44224},
|
||||
{714, 47, 47, 0},
|
||||
{762, 130, 130, 0},
|
||||
{870, 127, 126, 0},
|
||||
{871, 144, 144, 0},
|
||||
{876, 0, 0, 43349},
|
||||
{907, 48, 48, 0},
|
||||
{913, 74, 74, 0},
|
||||
{942, 79, 79, 0},
|
||||
{943, 79, 79, 0},
|
||||
{945, 131, 131, 0},
|
||||
{948, 130, 130, 0},
|
||||
{953, 132, 132, 0},
|
||||
{978, 81, 81, 0},
|
||||
{1015, 77, 77, 0},
|
||||
{1021, 0, 0, 40643},
|
||||
{1038, 75, 75, 0},
|
||||
{1039, 76, 76, 0},
|
||||
{1163, 128, 128, 0},
|
||||
{1174, 82, 82, 0},
|
||||
{1175, 72, 72, 0},
|
||||
{1250, 0, 0, 40653},
|
||||
{1400, 120, 120, 0},
|
||||
{1402, 122, 122, 0},
|
||||
{1516, 83, 83, 0},
|
||||
{1563, 84, 84, 0},
|
||||
{1656, 124, 124, 0},
|
||||
{1657, 124, 124, 0},
|
||||
{1658, 129, 129, 0},
|
||||
{1681, 125, 125, 43300},
|
||||
{1682, 125, 125, 43300},
|
||||
{1683, 133, 133, 0},
|
||||
{1684, 133, 133, 0},
|
||||
{1691, 134, 134, 0},
|
||||
{1692, 134, 134, 0},
|
||||
{1693, 135, 135, 0},
|
||||
{1707, 135, 135, 0},
|
||||
{1784, 84, 84, 0},
|
||||
{1793, 137, 137, 0},
|
||||
{1956, 0, 0, 43824},
|
||||
{2051, 140, 140, 0},
|
||||
{2054, 121, 121, 0},
|
||||
{2096, 0, 0, 44430},
|
||||
{2136, 0, 0, 0},// <- TODO: find item for spell 59961
|
||||
{2137, 0, 0, 0},// <- TODO: find item for spell 60021
|
||||
{2138, 0, 0, 0},// <- TODO: find item for spell 59976
|
||||
{2143, 0, 0, 44178},
|
||||
{2144, 0, 0, 0},// <- TODO: find item for spell 60024
|
||||
{2145, 0, 0, 0},// <- TODO: find item for spell 60024
|
||||
{2186, 141, 141, 0},
|
||||
{2187, 142, 142, 0},
|
||||
{2188, 143, 143, 0}
|
||||
};
|
||||
|
||||
AchievementMgr::AchievementMgr(Player *player)
|
||||
{
|
||||
m_player = player;
|
||||
}
|
||||
|
||||
AchievementMgr::~AchievementMgr()
|
||||
{
|
||||
}
|
||||
|
||||
void AchievementMgr::SaveToDB()
|
||||
{
|
||||
if(!m_completedAchievements.empty())
|
||||
{
|
||||
bool need_execute = false;
|
||||
std::ostringstream ssdel;
|
||||
std::ostringstream ssins;
|
||||
for(CompletedAchievementMap::iterator iter = m_completedAchievements.begin(); iter!=m_completedAchievements.end(); iter++)
|
||||
{
|
||||
if(!iter->second.changed)
|
||||
continue;
|
||||
|
||||
/// first new/changed record prefix
|
||||
if(!need_execute)
|
||||
{
|
||||
ssdel << "DELETE FROM character_achievement WHERE guid = " << GetPlayer()->GetGUIDLow() << " AND achievement IN (";
|
||||
ssins << "INSERT INTO character_achievement (guid, achievement, date) VALUES ";
|
||||
need_execute = true;
|
||||
}
|
||||
/// next new/changed record prefix
|
||||
else
|
||||
{
|
||||
ssdel << ", ";
|
||||
ssins << ", ";
|
||||
}
|
||||
|
||||
// new/changed record data
|
||||
ssdel << iter->first;
|
||||
ssins << "("<<GetPlayer()->GetGUIDLow() << ", " << iter->first << ", " << uint64(iter->second.date) << ")";
|
||||
|
||||
/// mark as saved in db
|
||||
iter->second.changed = false;
|
||||
}
|
||||
|
||||
if(need_execute)
|
||||
ssdel << ")";
|
||||
|
||||
if(need_execute)
|
||||
{
|
||||
CharacterDatabase.BeginTransaction ();
|
||||
CharacterDatabase.Execute( ssdel.str().c_str() );
|
||||
CharacterDatabase.Execute( ssins.str().c_str() );
|
||||
CharacterDatabase.CommitTransaction ();
|
||||
}
|
||||
}
|
||||
|
||||
if(!m_criteriaProgress.empty())
|
||||
{
|
||||
/// prepare deleting and insert
|
||||
bool need_execute = false;
|
||||
std::ostringstream ssdel;
|
||||
std::ostringstream ssins;
|
||||
for(CriteriaProgressMap::iterator iter = m_criteriaProgress.begin(); iter!=m_criteriaProgress.end(); ++iter)
|
||||
{
|
||||
if(!iter->second.changed)
|
||||
continue;
|
||||
|
||||
/// first new/changed record prefix
|
||||
if(!need_execute)
|
||||
{
|
||||
ssdel << "DELETE FROM character_achievement_progress WHERE guid = " << GetPlayer()->GetGUIDLow() << " AND criteria IN (";
|
||||
ssins << "INSERT INTO character_achievement_progress (guid, criteria, counter, date) VALUES ";
|
||||
need_execute = true;
|
||||
}
|
||||
/// next new/changed record prefix
|
||||
else
|
||||
{
|
||||
ssdel << ", ";
|
||||
ssins << ", ";
|
||||
}
|
||||
|
||||
// new/changed record data
|
||||
ssdel << iter->first;
|
||||
ssins << "(" << GetPlayer()->GetGUIDLow() << ", " << iter->first << ", " << iter->second.counter << ", " << iter->second.date << ")";
|
||||
|
||||
/// mark as saved in db
|
||||
iter->second.changed = false;
|
||||
}
|
||||
|
||||
if(need_execute)
|
||||
ssdel << ")";
|
||||
|
||||
if(need_execute)
|
||||
{
|
||||
CharacterDatabase.BeginTransaction ();
|
||||
CharacterDatabase.Execute( ssdel.str().c_str() );
|
||||
CharacterDatabase.Execute( ssins.str().c_str() );
|
||||
CharacterDatabase.CommitTransaction ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AchievementMgr::LoadFromDB(QueryResult *achievementResult, QueryResult *criteriaResult)
|
||||
{
|
||||
if(achievementResult)
|
||||
{
|
||||
do
|
||||
{
|
||||
Field *fields = achievementResult->Fetch();
|
||||
CompletedAchievementData& ca = m_completedAchievements[fields[0].GetUInt32()];
|
||||
ca.date = time_t(fields[1].GetUInt64());
|
||||
ca.changed = false;
|
||||
} while(achievementResult->NextRow());
|
||||
delete achievementResult;
|
||||
}
|
||||
|
||||
if(criteriaResult)
|
||||
{
|
||||
do
|
||||
{
|
||||
Field *fields = criteriaResult->Fetch();
|
||||
|
||||
uint32 id = fields[0].GetUInt32();
|
||||
uint32 counter = fields[1].GetUInt32();
|
||||
time_t date = time_t(fields[2].GetUInt64());
|
||||
|
||||
AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(id);
|
||||
if(!criteria || criteria->timeLimit && date + criteria->timeLimit < time(NULL))
|
||||
continue;
|
||||
|
||||
CriteriaProgress& progress = m_criteriaProgress[id];
|
||||
progress.counter = counter;
|
||||
progress.date = date;
|
||||
progress.changed = false;
|
||||
} while(criteriaResult->NextRow());
|
||||
delete criteriaResult;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void AchievementMgr::SendAchievementEarned(AchievementEntry const* achievement)
|
||||
{
|
||||
sLog.outString("AchievementMgr::SendAchievementEarned(%u)", achievement->ID);
|
||||
|
||||
const char *msg = "|Hplayer:$N|h[$N]|h has earned the achievement $a!";
|
||||
if(Guild* guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()))
|
||||
{
|
||||
WorldPacket data(SMSG_MESSAGECHAT, 200);
|
||||
data << uint8(CHAT_MSG_ACHIEVEMENT);
|
||||
data << uint8(CHAT_MSG_GUILD_ACHIEVEMENT);
|
||||
data << uint32(LANG_UNIVERSAL);
|
||||
data << uint64(GetPlayer()->GetGUID());
|
||||
data << uint32(5);
|
||||
data << uint64(GetPlayer()->GetGUID());
|
||||
data << uint32(strlen(msg)+1);
|
||||
data << msg;
|
||||
data << uint8(0);
|
||||
data << uint32(achievement->ID);
|
||||
guild->BroadcastPacket(&data);
|
||||
}
|
||||
if(achievement->flags & (ACHIEVEMENT_FLAG_REALM_FIRST_KILL|ACHIEVEMENT_FLAG_REALM_FIRST_REACH))
|
||||
{
|
||||
// broadcast realm first reached
|
||||
WorldPacket data(SMSG_SERVER_FIRST_ACHIEVEMENT, strlen(GetPlayer()->GetName())+1+8+4+4);
|
||||
data << GetPlayer()->GetName();
|
||||
data << uint64(GetPlayer()->GetGUID());
|
||||
data << uint32(achievement->ID);
|
||||
data << uint32(0); // 1=link supplied string as player name, 0=display plain string
|
||||
sWorld.SendGlobalMessage(&data);
|
||||
}
|
||||
else
|
||||
{
|
||||
WorldPacket data(SMSG_MESSAGECHAT, 200);
|
||||
data << uint8(CHAT_MSG_ACHIEVEMENT);
|
||||
data << uint32(LANG_UNIVERSAL);
|
||||
data << uint64(GetPlayer()->GetGUID());
|
||||
data << uint32(5);
|
||||
data << uint64(GetPlayer()->GetGUID());
|
||||
data << uint32(strlen(msg)+1);
|
||||
data << msg;
|
||||
data << uint8(0);
|
||||
data << uint32(achievement->ID);
|
||||
GetPlayer()->SendMessageToSet(&data, true);
|
||||
|
||||
}
|
||||
WorldPacket data(SMSG_ACHIEVEMENT_EARNED, 8+4+8);
|
||||
data.append(GetPlayer()->GetPackGUID());
|
||||
data << uint32(achievement->ID);
|
||||
data << uint32(secsToTimeBitFields(time(NULL)));
|
||||
data << uint32(0);
|
||||
GetPlayer()->SendMessageToSet(&data, true);
|
||||
}
|
||||
|
||||
void AchievementMgr::SendCriteriaUpdate(uint32 id, CriteriaProgress const* progress)
|
||||
{
|
||||
WorldPacket data(SMSG_CRITERIA_UPDATE, 8+4+8);
|
||||
data << uint32(id);
|
||||
|
||||
// the counter is packed like a packed Guid
|
||||
data.appendPackGUID(progress->counter);
|
||||
|
||||
data.append(GetPlayer()->GetPackGUID());
|
||||
data << uint32(0);
|
||||
data << uint32(secsToTimeBitFields(progress->date));
|
||||
data << uint32(0); // timer 1
|
||||
data << uint32(0); // timer 2
|
||||
GetPlayer()->SendMessageToSet(&data, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* called at player login. The player might have fulfilled some achievements when the achievement system wasn't working yet
|
||||
*/
|
||||
void AchievementMgr::CheckAllAchievementCriteria()
|
||||
{
|
||||
// suppress sending packets
|
||||
for(uint32 i=0; i<ACHIEVEMENT_CRITERIA_TYPE_TOTAL; i++)
|
||||
UpdateAchievementCriteria(AchievementCriteriaTypes(i));
|
||||
}
|
||||
|
||||
/**
|
||||
* this function will be called whenever the user might have done a criteria relevant action
|
||||
*/
|
||||
void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1, uint32 miscvalue2, Unit *unit, uint32 time)
|
||||
{
|
||||
sLog.outString("AchievementMgr::UpdateAchievementCriteria(%u, %u, %u, %u)", type, miscvalue1, miscvalue2, time);
|
||||
AchievementCriteriaEntryList const& achievementCriteriaList = objmgr.GetAchievementCriteriaByType(type);
|
||||
for(AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList.begin(); i!=achievementCriteriaList.end(); ++i)
|
||||
{
|
||||
AchievementCriteriaEntry const *achievementCriteria = (*i);
|
||||
|
||||
// don't update already completed criteria
|
||||
if(IsCompletedCriteria(achievementCriteria))
|
||||
continue;
|
||||
|
||||
if(achievementCriteria->groupFlag & ACHIEVEMENT_CRITERIA_GROUP_NOT_IN_GROUP && GetPlayer()->GetGroup())
|
||||
continue;
|
||||
|
||||
AchievementEntry const *achievement = sAchievementStore.LookupEntry(achievementCriteria->referredAchievement);
|
||||
if(!achievement)
|
||||
continue;
|
||||
|
||||
if(achievement->factionFlag == ACHIEVEMENT_FACTION_FLAG_HORDE && GetPlayer()->GetTeam() != HORDE ||
|
||||
achievement->factionFlag == ACHIEVEMENT_FACTION_FLAG_ALLIANCE && GetPlayer()->GetTeam() != ALLIANCE)
|
||||
continue;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL:
|
||||
SetCriteriaProgress(achievementCriteria, GetPlayer()->getLevel());
|
||||
break;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT:
|
||||
SetCriteriaProgress(achievementCriteria, GetPlayer()->GetByteValue(PLAYER_BYTES_2, 2)+1);
|
||||
break;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE:
|
||||
// AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
|
||||
if(!miscvalue1)
|
||||
continue;
|
||||
if(achievementCriteria->kill_creature.creatureID != miscvalue1)
|
||||
continue;
|
||||
SetCriteriaProgress(achievementCriteria, miscvalue2, true);
|
||||
break;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL:
|
||||
if(uint32 skillvalue = GetPlayer()->GetBaseSkillValue(achievementCriteria->reach_skill_level.skillID))
|
||||
SetCriteriaProgress(achievementCriteria, skillvalue);
|
||||
break;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT:
|
||||
{
|
||||
uint32 counter =0;
|
||||
for(QuestStatusMap::iterator itr = GetPlayer()->getQuestStatusMap().begin(); itr!=GetPlayer()->getQuestStatusMap().end(); itr++)
|
||||
if(itr->second.m_rewarded)
|
||||
counter++;
|
||||
SetCriteriaProgress(achievementCriteria, counter);
|
||||
break;
|
||||
}
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE:
|
||||
{
|
||||
uint32 counter =0;
|
||||
for(QuestStatusMap::iterator itr = GetPlayer()->getQuestStatusMap().begin(); itr!=GetPlayer()->getQuestStatusMap().end(); itr++)
|
||||
{
|
||||
Quest const* quest = objmgr.GetQuestTemplate(itr->first);
|
||||
if(itr->second.m_rewarded && quest->GetZoneOrSort() == achievementCriteria->complete_quests_in_zone.zoneID)
|
||||
counter++;
|
||||
}
|
||||
SetCriteriaProgress(achievementCriteria, counter);
|
||||
break;
|
||||
}
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST:
|
||||
// AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
|
||||
if(!miscvalue1)
|
||||
continue;
|
||||
SetCriteriaProgress(achievementCriteria, miscvalue1, true);
|
||||
break;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND:
|
||||
// AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
|
||||
if(!miscvalue1)
|
||||
continue;
|
||||
if(GetPlayer()->GetMapId() != achievementCriteria->complete_battleground.mapID)
|
||||
continue;
|
||||
SetCriteriaProgress(achievementCriteria, miscvalue1, true);
|
||||
break;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL:
|
||||
if(GetPlayer()->HasSpell(achievementCriteria->learn_spell.spellID))
|
||||
SetCriteriaProgress(achievementCriteria, 1);
|
||||
break;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP:
|
||||
// AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
|
||||
if(!miscvalue1)
|
||||
continue;
|
||||
if(GetPlayer()->GetMapId() != achievementCriteria->death_at_map.mapID)
|
||||
continue;
|
||||
SetCriteriaProgress(achievementCriteria, 1, true);
|
||||
break;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE:
|
||||
// AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
|
||||
if(!miscvalue1)
|
||||
continue;
|
||||
if(miscvalue1 != achievementCriteria->killed_by_creature.creatureEntry)
|
||||
continue;
|
||||
SetCriteriaProgress(achievementCriteria, 1, true);
|
||||
break;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER:
|
||||
// AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
|
||||
if(!miscvalue1)
|
||||
continue;
|
||||
SetCriteriaProgress(achievementCriteria, 1, true);
|
||||
break;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING:
|
||||
{
|
||||
// AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
|
||||
if(!miscvalue1)
|
||||
continue;
|
||||
if(achievement->ID == 1260)
|
||||
{
|
||||
if(Player::GetDrunkenstateByValue(GetPlayer()->GetDrunkValue()) != DRUNKEN_SMASHED)
|
||||
continue;
|
||||
// TODO: hardcoding eventid is bad, it can differ from DB to DB - maye implement something using HolidayNames.dbc?
|
||||
if(!gameeventmgr.IsActiveEvent(26))
|
||||
continue;
|
||||
}
|
||||
// miscvalue1 is the ingame fallheight*100 as stored in dbc
|
||||
SetCriteriaProgress(achievementCriteria, miscvalue1);
|
||||
break;
|
||||
}
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST:
|
||||
if(GetPlayer()->GetQuestRewardStatus(achievementCriteria->complete_quest.questID))
|
||||
SetCriteriaProgress(achievementCriteria, 1);
|
||||
break;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM:
|
||||
// AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
|
||||
if(!miscvalue1)
|
||||
continue;
|
||||
if(achievementCriteria->use_item.itemID != miscvalue1)
|
||||
continue;
|
||||
SetCriteriaProgress(achievementCriteria, 1, true);
|
||||
break;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM:
|
||||
// speedup for non-login case
|
||||
if(miscvalue1 && achievementCriteria->own_item.itemID!=miscvalue1)
|
||||
continue;
|
||||
SetCriteriaProgress(achievementCriteria, GetPlayer()->GetItemCount(achievementCriteria->own_item.itemID, true));
|
||||
break;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM:
|
||||
// You _have_ to loot that item, just owning it when logging in does _not_ count!
|
||||
if(!miscvalue1)
|
||||
continue;
|
||||
if(miscvalue1 != achievementCriteria->own_item.itemID)
|
||||
continue;
|
||||
SetCriteriaProgress(achievementCriteria, miscvalue2, true);
|
||||
break;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2:
|
||||
if (!miscvalue1 || miscvalue1 != achievementCriteria->be_spell_target.spellID)
|
||||
continue;
|
||||
SetCriteriaProgress(achievementCriteria, 1, true);
|
||||
break;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL:
|
||||
if (!miscvalue1 || miscvalue1 != achievementCriteria->cast_spell.spellID)
|
||||
continue;
|
||||
SetCriteriaProgress(achievementCriteria, 1, true);
|
||||
break;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2:
|
||||
{
|
||||
if (!miscvalue1 || miscvalue1 != achievementCriteria->cast_spell.spellID)
|
||||
continue;
|
||||
// those requirements couldn't be found in the dbc
|
||||
|
||||
const CriteriaCastSpellRequirement *requirement = NULL;
|
||||
for (uint32 i=0; i<CRITERIA_CAST_SPELL_REQ_COUNT; i++)
|
||||
{
|
||||
if (criteriaCastSpellRequirements[i].achievementCriteriaId == achievementCriteria->ID)
|
||||
{
|
||||
requirement = &criteriaCastSpellRequirements[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (requirement)
|
||||
{
|
||||
if (!unit)
|
||||
continue;
|
||||
|
||||
if (requirement->creatureEntry && unit->GetEntry() != requirement->creatureEntry)
|
||||
continue;
|
||||
|
||||
if (requirement->playerRace && (unit->GetTypeId() != TYPEID_PLAYER || unit->getRace()!=requirement->playerRace))
|
||||
continue;
|
||||
|
||||
if (requirement->playerClass && (unit->GetTypeId() != TYPEID_PLAYER || unit->getClass()!=requirement->playerClass))
|
||||
continue;
|
||||
}
|
||||
SetCriteriaProgress(achievementCriteria, 1, true);
|
||||
break;
|
||||
}
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS:
|
||||
{
|
||||
uint32 spellCount = 0;
|
||||
for (PlayerSpellMap::const_iterator spellIter = GetPlayer()->GetSpellMap().begin();
|
||||
spellIter != GetPlayer()->GetSpellMap().end();
|
||||
spellIter++)
|
||||
{
|
||||
for(SkillLineAbilityMap::const_iterator skillIter = spellmgr.GetBeginSkillLineAbilityMap(spellIter->first);
|
||||
skillIter != spellmgr.GetEndSkillLineAbilityMap(spellIter->first);
|
||||
skillIter++)
|
||||
{
|
||||
if(skillIter->second->skillId == achievementCriteria->learn_skilline_spell.skillLine)
|
||||
spellCount++;
|
||||
}
|
||||
}
|
||||
SetCriteriaProgress(achievementCriteria, spellCount);
|
||||
break;
|
||||
}
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP:
|
||||
{
|
||||
// skip for login case
|
||||
if(!miscvalue1)
|
||||
continue;
|
||||
SetCriteriaProgress(achievementCriteria, 1);
|
||||
break;
|
||||
}
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION:
|
||||
{
|
||||
int32 reputation = GetPlayer()->GetReputation(achievementCriteria->gain_reputation.factionID);
|
||||
if (reputation > 0)
|
||||
SetCriteriaProgress(achievementCriteria, reputation);
|
||||
break;
|
||||
}
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION:
|
||||
{
|
||||
uint32 counter = 0;
|
||||
const FactionStateList factionStateList = GetPlayer()->GetFactionStateList();
|
||||
for (FactionStateList::const_iterator iter = factionStateList.begin(); iter!= factionStateList.end(); iter++)
|
||||
{
|
||||
if(GetPlayer()->ReputationToRank(iter->second.Standing) >= REP_EXALTED)
|
||||
++counter;
|
||||
}
|
||||
SetCriteriaProgress(achievementCriteria, counter);
|
||||
break;
|
||||
}
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA:
|
||||
{
|
||||
WorldMapOverlayEntry const* worldOverlayEntry = sWorldMapOverlayStore.LookupEntry(achievementCriteria->explore_area.areaReference);
|
||||
if(!worldOverlayEntry)
|
||||
break;
|
||||
|
||||
int32 exploreFlag = GetAreaFlagByAreaID(worldOverlayEntry->areatableID);
|
||||
if(exploreFlag < 0)
|
||||
break;
|
||||
|
||||
uint32 playerIndexOffset = uint32(exploreFlag) / 32;
|
||||
uint32 mask = 1<< (uint32(exploreFlag) % 32);
|
||||
|
||||
if(GetPlayer()->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + playerIndexOffset) & mask)
|
||||
SetCriteriaProgress(achievementCriteria, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
if(IsCompletedCriteria(achievementCriteria))
|
||||
CompletedCriteria(achievementCriteria);
|
||||
}
|
||||
}
|
||||
|
||||
bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achievementCriteria)
|
||||
{
|
||||
AchievementEntry const* achievement = sAchievementStore.LookupEntry(achievementCriteria->referredAchievement);
|
||||
if(!achievement)
|
||||
return false;
|
||||
|
||||
// counter can never complete
|
||||
if(achievement->flags & ACHIEVEMENT_FLAG_COUNTER)
|
||||
return false;
|
||||
|
||||
if(achievement->flags & (ACHIEVEMENT_FLAG_REALM_FIRST_REACH | ACHIEVEMENT_FLAG_REALM_FIRST_KILL))
|
||||
{
|
||||
// someone on this realm has already completed that achievement
|
||||
if(objmgr.allCompletedAchievements.find(achievement->ID)!=objmgr.allCompletedAchievements.end())
|
||||
return false;
|
||||
}
|
||||
|
||||
CriteriaProgressMap::const_iterator itr = m_criteriaProgress.find(achievementCriteria->ID);
|
||||
if(itr == m_criteriaProgress.end())
|
||||
return false;
|
||||
|
||||
CriteriaProgress const* progress = &itr->second;
|
||||
|
||||
switch(achievementCriteria->requiredType)
|
||||
{
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL:
|
||||
if(achievement->ID == 467 && GetPlayer()->getClass() != CLASS_SHAMAN ||
|
||||
achievement->ID == 466 && GetPlayer()->getClass() != CLASS_DRUID ||
|
||||
achievement->ID == 465 && GetPlayer()->getClass() != CLASS_PALADIN ||
|
||||
achievement->ID == 464 && GetPlayer()->getClass() != CLASS_PRIEST ||
|
||||
achievement->ID == 463 && GetPlayer()->getClass() != CLASS_WARLOCK ||
|
||||
achievement->ID == 462 && GetPlayer()->getClass() != CLASS_HUNTER ||
|
||||
achievement->ID == 461 && GetPlayer()->getClass() != CLASS_DEATH_KNIGHT ||
|
||||
achievement->ID == 460 && GetPlayer()->getClass() != CLASS_MAGE ||
|
||||
achievement->ID == 459 && GetPlayer()->getClass() != CLASS_WARRIOR ||
|
||||
achievement->ID == 458 && GetPlayer()->getClass() != CLASS_ROGUE ||
|
||||
|
||||
achievement->ID == 1404 && GetPlayer()->getRace() != RACE_GNOME ||
|
||||
achievement->ID == 1405 && GetPlayer()->getRace() != RACE_BLOODELF ||
|
||||
achievement->ID == 1406 && GetPlayer()->getRace() != RACE_DRAENEI ||
|
||||
achievement->ID == 1407 && GetPlayer()->getRace() != RACE_DWARF ||
|
||||
achievement->ID == 1408 && GetPlayer()->getRace() != RACE_HUMAN ||
|
||||
achievement->ID == 1409 && GetPlayer()->getRace() != RACE_NIGHTELF ||
|
||||
achievement->ID == 1410 && GetPlayer()->getRace() != RACE_ORC ||
|
||||
achievement->ID == 1411 && GetPlayer()->getRace() != RACE_TAUREN ||
|
||||
achievement->ID == 1412 && GetPlayer()->getRace() != RACE_TROLL ||
|
||||
achievement->ID == 1413 && GetPlayer()->getRace() != RACE_UNDEAD_PLAYER )
|
||||
return false;
|
||||
return progress->counter >= achievementCriteria->reach_level.level;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT:
|
||||
return progress->counter >= achievementCriteria->buy_bank_slot.numberOfSlots;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE:
|
||||
return progress->counter >= achievementCriteria->kill_creature.creatureCount;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT:
|
||||
return m_completedAchievements.find(achievementCriteria->complete_achievement.linkedAchievement) != m_completedAchievements.end();
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL:
|
||||
return progress->counter >= achievementCriteria->reach_skill_level.skillLevel;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE:
|
||||
return progress->counter >= achievementCriteria->complete_quests_in_zone.questCount;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST:
|
||||
return progress->counter >= achievementCriteria->complete_daily_quest.questCount;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL:
|
||||
return progress->counter >= 1;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING:
|
||||
return progress->counter >= achievementCriteria->fall_without_dying.fallHeight;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST:
|
||||
return progress->counter >= 1;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM:
|
||||
return progress->counter >= achievementCriteria->use_item.itemCount;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM:
|
||||
return progress->counter >= achievementCriteria->own_item.itemCount;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM:
|
||||
return progress->counter >= achievementCriteria->loot_item.itemCount;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2:
|
||||
return progress->counter >= achievementCriteria->be_spell_target.spellCount;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2:
|
||||
return progress->counter >= achievementCriteria->cast_spell.castCount;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS:
|
||||
return progress->counter >= achievementCriteria->learn_skilline_spell.spellCount;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP:
|
||||
return progress->counter >= achievementCriteria->visit_barber.numberOfVisits;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION:
|
||||
return progress->counter >= achievementCriteria->gain_reputation.reputationAmount;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION:
|
||||
return progress->counter >= achievementCriteria->gain_exalted_reputation.numberOfExaltedFactions;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA:
|
||||
return progress->counter >= 1;
|
||||
|
||||
// handle all statistic-only criteria here
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void AchievementMgr::CompletedCriteria(AchievementCriteriaEntry const* criteria)
|
||||
{
|
||||
AchievementEntry const* achievement = sAchievementStore.LookupEntry(criteria->referredAchievement);
|
||||
if(!achievement)
|
||||
return;
|
||||
// counter can never complete
|
||||
if(achievement->flags & ACHIEVEMENT_FLAG_COUNTER)
|
||||
return;
|
||||
|
||||
if(criteria->completionFlag & ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL || GetAchievementCompletionState(achievement)==ACHIEVEMENT_COMPLETED_COMPLETED_NOT_STORED)
|
||||
{
|
||||
CompletedAchievement(achievement);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: achievement 705 requires 4 criteria to be fulfilled
|
||||
AchievementCompletionState AchievementMgr::GetAchievementCompletionState(AchievementEntry const* entry)
|
||||
{
|
||||
if(m_completedAchievements.find(entry->ID)!=m_completedAchievements.end())
|
||||
return ACHIEVEMENT_COMPLETED_COMPLETED_STORED;
|
||||
|
||||
bool foundOutstanding = false;
|
||||
for (uint32 entryId = 0; entryId<sAchievementCriteriaStore.GetNumRows(); entryId++)
|
||||
{
|
||||
AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(entryId);
|
||||
if(!criteria || criteria->referredAchievement!= entry->ID)
|
||||
continue;
|
||||
|
||||
if(IsCompletedCriteria(criteria) && criteria->completionFlag & ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL)
|
||||
return ACHIEVEMENT_COMPLETED_COMPLETED_NOT_STORED;
|
||||
|
||||
// found an umcompleted criteria, but DONT return false yet - there might be a completed criteria with ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL
|
||||
if(!IsCompletedCriteria(criteria))
|
||||
foundOutstanding = true;
|
||||
}
|
||||
if(foundOutstanding)
|
||||
return ACHIEVEMENT_COMPLETED_NONE;
|
||||
else
|
||||
return ACHIEVEMENT_COMPLETED_COMPLETED_NOT_STORED;
|
||||
}
|
||||
|
||||
void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 newValue, bool relative)
|
||||
{
|
||||
sLog.outString("AchievementMgr::SetCriteriaProgress(%u, %u)", entry->ID, newValue);
|
||||
CriteriaProgress *progress = NULL;
|
||||
|
||||
CriteriaProgressMap::iterator iter = m_criteriaProgress.find(entry->ID);
|
||||
|
||||
if(iter == m_criteriaProgress.end())
|
||||
{
|
||||
progress = &m_criteriaProgress[entry->ID];
|
||||
progress->counter = 0;
|
||||
progress->date = time(NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
progress = &iter->second;
|
||||
if(relative)
|
||||
newValue += progress->counter;
|
||||
if(progress->counter == newValue)
|
||||
return;
|
||||
progress->counter = newValue;
|
||||
}
|
||||
|
||||
progress->changed = true;
|
||||
|
||||
if(entry->timeLimit)
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
if(progress->date + entry->timeLimit < now)
|
||||
{
|
||||
progress->counter = 1;
|
||||
}
|
||||
// also it seems illogical, the timeframe will be extended at every criteria update
|
||||
progress->date = now;
|
||||
}
|
||||
SendCriteriaUpdate(entry->ID,progress);
|
||||
}
|
||||
|
||||
void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement)
|
||||
{
|
||||
sLog.outString("AchievementMgr::CompletedAchievement(%u)", achievement->ID);
|
||||
if(achievement->flags & ACHIEVEMENT_FLAG_COUNTER || m_completedAchievements.find(achievement->ID)!=m_completedAchievements.end())
|
||||
return;
|
||||
|
||||
SendAchievementEarned(achievement);
|
||||
CompletedAchievementData& ca = m_completedAchievements[achievement->ID];
|
||||
ca.date = time(NULL);
|
||||
ca.changed = true;
|
||||
|
||||
// don't insert for ACHIEVEMENT_FLAG_REALM_FIRST_KILL since otherwise only the first group member would reach that achievement
|
||||
// TODO: where do set this instead?
|
||||
if(!(achievement->flags & ACHIEVEMENT_FLAG_REALM_FIRST_KILL))
|
||||
objmgr.allCompletedAchievements.insert(achievement->ID);
|
||||
|
||||
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT);
|
||||
|
||||
// reward items and titles
|
||||
AchievementReward const* reward = NULL;
|
||||
for (uint32 i=0; i<ACHIEVEMENT_REWARD_COUNT; i++)
|
||||
{
|
||||
if (achievementRewards[i].achievementId == achievement->ID)
|
||||
{
|
||||
reward = &achievementRewards[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (reward)
|
||||
{
|
||||
sLog.outString("achiev %u, title= %u, %u", reward->achievementId, reward->titleId[0], reward->titleId[1]);
|
||||
uint32 titleId = reward->titleId[GetPlayer()->GetTeam() == HORDE?0:1];
|
||||
if(CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(titleId))
|
||||
GetPlayer()->SetTitle(titleEntry);
|
||||
|
||||
if (reward->itemId)
|
||||
{
|
||||
ItemPrototype const *pProto = objmgr.GetItemPrototype( reward->itemId );
|
||||
|
||||
if(!pProto)
|
||||
{
|
||||
GetPlayer()->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL );
|
||||
return;
|
||||
}
|
||||
|
||||
ItemPosCountVec dest;
|
||||
uint32 no_space = 0;
|
||||
uint8 msg = GetPlayer()->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, reward->itemId, 1, &no_space );
|
||||
|
||||
if( msg != EQUIP_ERR_OK )
|
||||
{
|
||||
GetPlayer()->SendEquipError( msg, NULL, NULL );
|
||||
return;
|
||||
}
|
||||
Item* pItem = GetPlayer()->StoreNewItem( dest, reward->itemId, true);
|
||||
|
||||
if(!pItem)
|
||||
{
|
||||
GetPlayer()->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AchievementMgr::SendAllAchievementData()
|
||||
{
|
||||
// since we don't know the exact size of the packed GUIDs this is just an approximation
|
||||
WorldPacket data(SMSG_ALL_ACHIEVEMENT_DATA, 4*2+m_completedAchievements.size()*4*2+m_completedAchievements.size()*7*4);
|
||||
BuildAllDataPacket(&data);
|
||||
GetPlayer()->GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
||||
void AchievementMgr::SendRespondInspectAchievements(Player* player)
|
||||
{
|
||||
// since we don't know the exact size of the packed GUIDs this is just an approximation
|
||||
WorldPacket data(SMSG_RESPOND_INSPECT_ACHIEVEMENTS, 4+4*2+m_completedAchievements.size()*4*2+m_completedAchievements.size()*7*4);
|
||||
data.append(GetPlayer()->GetPackGUID());
|
||||
BuildAllDataPacket(&data);
|
||||
player->GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
||||
/**
|
||||
* used by both SMSG_ALL_ACHIEVEMENT_DATA and SMSG_RESPOND_INSPECT_ACHIEVEMENT
|
||||
*/
|
||||
void AchievementMgr::BuildAllDataPacket(WorldPacket *data)
|
||||
{
|
||||
for(CompletedAchievementMap::const_iterator iter = m_completedAchievements.begin(); iter!=m_completedAchievements.end(); ++iter)
|
||||
{
|
||||
*data << uint32(iter->first);
|
||||
*data << uint32(secsToTimeBitFields(iter->second.date));
|
||||
}
|
||||
*data << int32(-1);
|
||||
|
||||
for(CriteriaProgressMap::const_iterator iter = m_criteriaProgress.begin(); iter!=m_criteriaProgress.end(); ++iter)
|
||||
{
|
||||
*data << uint32(iter->first);
|
||||
data->appendPackGUID(iter->second.counter);
|
||||
data->append(GetPlayer()->GetPackGUID());
|
||||
*data << uint32(0);
|
||||
*data << uint32(secsToTimeBitFields(iter->second.date));
|
||||
*data << uint32(0);
|
||||
*data << uint32(0);
|
||||
}
|
||||
|
||||
*data << int32(-1);
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __MANGOS_ACHIEVEMENTMGR_H
|
||||
#define __MANGOS_ACHIEVEMENTMGR_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "Database/DBCEnums.h"
|
||||
#include "Database/DBCStores.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
|
||||
#define CRITERIA_CAST_SPELL_REQ_COUNT 46
|
||||
#define ACHIEVEMENT_REWARD_COUNT 57
|
||||
|
||||
struct CriteriaProgress
|
||||
{
|
||||
uint32 counter;
|
||||
time_t date;
|
||||
bool changed;
|
||||
};
|
||||
|
||||
struct CriteriaCastSpellRequirement
|
||||
{
|
||||
uint32 achievementCriteriaId;
|
||||
uint32 creatureEntry;
|
||||
uint8 playerClass;
|
||||
uint8 playerRace;
|
||||
};
|
||||
|
||||
struct AchievementReward
|
||||
{
|
||||
uint32 achievementId;
|
||||
uint32 titleId[2];
|
||||
uint32 itemId;
|
||||
};
|
||||
|
||||
struct CompletedAchievementData
|
||||
{
|
||||
time_t date;
|
||||
bool changed;
|
||||
};
|
||||
|
||||
typedef UNORDERED_MAP<uint32, CriteriaProgress> CriteriaProgressMap;
|
||||
typedef UNORDERED_MAP<uint32, CompletedAchievementData> CompletedAchievementMap;
|
||||
|
||||
class Unit;
|
||||
class Player;
|
||||
class WorldPacket;
|
||||
|
||||
enum AchievementCompletionState
|
||||
{
|
||||
ACHIEVEMENT_COMPLETED_NONE,
|
||||
ACHIEVEMENT_COMPLETED_COMPLETED_NOT_STORED,
|
||||
ACHIEVEMENT_COMPLETED_COMPLETED_STORED,
|
||||
};
|
||||
|
||||
class AchievementMgr
|
||||
{
|
||||
public:
|
||||
AchievementMgr(Player* pl);
|
||||
~AchievementMgr();
|
||||
|
||||
void LoadFromDB(QueryResult *achievementResult, QueryResult *criteriaResult);
|
||||
void SaveToDB();
|
||||
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1=0, uint32 miscvalue2=0, Unit *unit=NULL, uint32 time=0);
|
||||
void CheckAllAchievementCriteria();
|
||||
void SendAllAchievementData();
|
||||
void SendRespondInspectAchievements(Player* player);
|
||||
Player* GetPlayer() { return m_player;}
|
||||
|
||||
private:
|
||||
void SendAchievementEarned(AchievementEntry const* achievement);
|
||||
void SendCriteriaUpdate(uint32 id, CriteriaProgress const* progress);
|
||||
void SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 newValue, bool relative=false);
|
||||
void CompletedCriteria(AchievementCriteriaEntry const* entry);
|
||||
void CompletedAchievement(AchievementEntry const* entry);
|
||||
bool IsCompletedCriteria(AchievementCriteriaEntry const* entry);
|
||||
AchievementCompletionState GetAchievementCompletionState(AchievementEntry const* entry);
|
||||
void BuildAllDataPacket(WorldPacket *data);
|
||||
|
||||
Player* m_player;
|
||||
CriteriaProgressMap m_criteriaProgress;
|
||||
CompletedAchievementMap m_completedAchievements;
|
||||
static const CriteriaCastSpellRequirement criteriaCastSpellRequirements[];
|
||||
static const AchievementReward achievementRewards[];
|
||||
};
|
||||
#endif
|
||||
@@ -752,3 +752,23 @@ void WorldSession::HandleAuctionListItems( WorldPacket & recv_data )
|
||||
data << (uint32) 300; // unk 2.3.0 const?
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::HandleAuctionListPendingSales( WorldPacket & recv_data )
|
||||
{
|
||||
sLog.outDebug("CMSG_AUCTION_LIST_PENDING_SALES");
|
||||
recv_data.hexlike();
|
||||
|
||||
uint32 count = 0;
|
||||
|
||||
WorldPacket data(SMSG_AUCTION_LIST_PENDING_SALES, 4);
|
||||
data << uint32(count); // count
|
||||
/*for(uint32 i = 0; i < count; ++i)
|
||||
{
|
||||
data << ""; // string
|
||||
data << ""; // string
|
||||
data << uint32(0);
|
||||
data << uint32(0);
|
||||
data << float(0);
|
||||
}*/
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ Bag::Bag( ): Item()
|
||||
|
||||
m_valuesCount = CONTAINER_END;
|
||||
|
||||
memset(m_bagslot, 0, sizeof(Item *) * MAX_BAG_SIZE); // Maximum 20 Slots
|
||||
memset(m_bagslot, 0, sizeof(Item *) * MAX_BAG_SIZE);
|
||||
}
|
||||
|
||||
Bag::~Bag()
|
||||
|
||||
@@ -576,6 +576,7 @@ void BattleGround::EndBattleGround(uint32 winner)
|
||||
uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(GetTypeID(), GetArenaType());
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetTeam(), plr->GetBattleGroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime());
|
||||
plr->GetSession()->SendPacket(&data);
|
||||
plr->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND, 1);
|
||||
}
|
||||
|
||||
if(isArena() && isRated() && winner_arena_team && loser_arena_team)
|
||||
@@ -1405,10 +1406,10 @@ bool BattleGround::AddSpiritGuide(uint32 type, float x, float y, float z, float
|
||||
|
||||
pCreature->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT, pCreature->GetGUID());
|
||||
// aura
|
||||
pCreature->SetUInt32Value(UNIT_FIELD_AURA, SPELL_SPIRIT_HEAL_CHANNEL);
|
||||
pCreature->SetUInt32Value(UNIT_FIELD_AURAFLAGS, 0x00000009);
|
||||
pCreature->SetUInt32Value(UNIT_FIELD_AURALEVELS, 0x0000003C);
|
||||
pCreature->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS, 0x000000FF);
|
||||
pCreature->SetVisibleAura(0, SPELL_SPIRIT_HEAL_CHANNEL);
|
||||
//pCreature->SetUInt32Value(UNIT_FIELD_AURAFLAGS, 0x00000009);
|
||||
//pCreature->SetUInt32Value(UNIT_FIELD_AURALEVELS, 0x0000003C);
|
||||
//pCreature->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS, 0x000000FF);
|
||||
// casting visual effect
|
||||
pCreature->SetUInt32Value(UNIT_CHANNEL_SPELL, SPELL_SPIRIT_HEAL_CHANNEL);
|
||||
// correct cast speed
|
||||
|
||||
@@ -132,8 +132,6 @@ struct BattleGroundObjectInfo
|
||||
uint32 spellid;
|
||||
};
|
||||
|
||||
#define MAX_QUEUED_PLAYERS_MAP 7
|
||||
|
||||
enum BattleGroundTypeId
|
||||
{
|
||||
BATTLEGROUND_AV = 1,
|
||||
@@ -143,7 +141,10 @@ enum BattleGroundTypeId
|
||||
BATTLEGROUND_BE = 5,
|
||||
BATTLEGROUND_AA = 6,
|
||||
BATTLEGROUND_EY = 7,
|
||||
BATTLEGROUND_RL = 8
|
||||
BATTLEGROUND_RL = 8,
|
||||
BATTLEGROUND_SA = 9,
|
||||
BATTLEGROUND_DS = 10,
|
||||
BATTLEGROUND_RV = 11
|
||||
};
|
||||
|
||||
// handle the queue types and bg types separately to enable joining queue for different sized arenas at the same time
|
||||
|
||||
@@ -1267,13 +1267,16 @@ void BattleGroundMgr::BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg)
|
||||
*data << (uint32)((BattleGroundABScore*)itr->second)->BasesDefended; // bases defended
|
||||
break;
|
||||
case BATTLEGROUND_EY:
|
||||
*data << (uint32)0x00000001; // count of next fields
|
||||
*data << (uint32)0x00000001; // count of next fields
|
||||
*data << (uint32)((BattleGroundEYScore*)itr->second)->FlagCaptures; // flag captures
|
||||
break;
|
||||
case BATTLEGROUND_NA:
|
||||
case BATTLEGROUND_BE:
|
||||
case BATTLEGROUND_AA:
|
||||
case BATTLEGROUND_RL:
|
||||
case BATTLEGROUND_SA: // wotlk
|
||||
case BATTLEGROUND_DS: // wotlk
|
||||
case BATTLEGROUND_RV: // wotlk
|
||||
*data << (int32)0; // 0
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -32,9 +32,9 @@ typedef std::map<uint32, BattleGround*> BattleGroundSet;
|
||||
//typedef std::map<uint32, BattleGroundQueue*> BattleGroundQueueSet;
|
||||
typedef std::deque<BattleGround*> BGFreeSlotQueueType;
|
||||
|
||||
#define MAX_BATTLEGROUND_QUEUES 7 // for level ranges 10-19, 20-29, 30-39, 40-49, 50-59, 60-69, 70+
|
||||
#define MAX_BATTLEGROUND_QUEUES 8 // for level ranges 10-19, 20-29, 30-39, 40-49, 50-59, 60-69, 70-79, 80+
|
||||
|
||||
#define MAX_BATTLEGROUND_TYPES 9 // each BG type will be in array
|
||||
#define MAX_BATTLEGROUND_TYPES 12 // each BG type will be in array
|
||||
|
||||
#define MAX_BATTLEGROUND_QUEUE_TYPES 8
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef MANGOS_CALENDAR_H
|
||||
#define MANGOS_CALENDAR_H
|
||||
|
||||
class Calendar
|
||||
{
|
||||
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Common.h"
|
||||
#include "Log.h"
|
||||
#include "Player.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
#include "Opcodes.h"
|
||||
|
||||
void WorldSession::HandleCalendarGetCalendar(WorldPacket &recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: CMSG_CALENDAR_GET_CALENDAR");
|
||||
recv_data.hexlike();
|
||||
}
|
||||
|
||||
void WorldSession::HandleCalendarGetEvent(WorldPacket &recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: CMSG_CALENDAR_GET_EVENT");
|
||||
recv_data.hexlike();
|
||||
}
|
||||
|
||||
void WorldSession::HandleCalendarGuildFilter(WorldPacket &recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: CMSG_CALENDAR_GUILD_FILTER");
|
||||
recv_data.hexlike();
|
||||
}
|
||||
|
||||
void WorldSession::HandleCalendarArenaTeam(WorldPacket &recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: CMSG_CALENDAR_ARENA_TEAM");
|
||||
recv_data.hexlike();
|
||||
}
|
||||
|
||||
void WorldSession::HandleCalendarAddEvent(WorldPacket &recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: CMSG_CALENDAR_ADD_EVENT");
|
||||
recv_data.hexlike();
|
||||
}
|
||||
|
||||
void WorldSession::HandleCalendarUpdateEvent(WorldPacket &recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: CMSG_CALENDAR_UPDATE_EVENT");
|
||||
recv_data.hexlike();
|
||||
}
|
||||
|
||||
void WorldSession::HandleCalendarRemoveEvent(WorldPacket &recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: CMSG_CALENDAR_REMOVE_EVENT");
|
||||
recv_data.hexlike();
|
||||
}
|
||||
|
||||
void WorldSession::HandleCalendarCopyEvent(WorldPacket &recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: CMSG_CALENDAR_COPY_EVENT");
|
||||
recv_data.hexlike();
|
||||
}
|
||||
|
||||
void WorldSession::HandleCalendarEventInvite(WorldPacket &recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_INVITE");
|
||||
recv_data.hexlike();
|
||||
}
|
||||
|
||||
void WorldSession::HandleCalendarEventRsvp(WorldPacket &recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_RSVP");
|
||||
recv_data.hexlike();
|
||||
}
|
||||
|
||||
void WorldSession::HandleCalendarEventRemoveInvite(WorldPacket &recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_REMOVE_INVITE");
|
||||
recv_data.hexlike();
|
||||
}
|
||||
|
||||
void WorldSession::HandleCalendarEventStatus(WorldPacket &recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_STATUS");
|
||||
recv_data.hexlike();
|
||||
}
|
||||
|
||||
void WorldSession::HandleCalendarEventModeratorStatus(WorldPacket &recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_MODERATOR_STATUS");
|
||||
recv_data.hexlike();
|
||||
}
|
||||
|
||||
void WorldSession::HandleCalendarComplain(WorldPacket &recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: CMSG_CALENDAR_COMPLAIN");
|
||||
recv_data.hexlike();
|
||||
}
|
||||
|
||||
void WorldSession::HandleCalendarGetNumPending(WorldPacket &recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: CMSG_CALENDAR_GET_NUM_PENDING");
|
||||
recv_data.hexlike();
|
||||
|
||||
WorldPacket data(SMSG_CALENDAR_SEND_NUM_PENDING, 4);
|
||||
data << uint32(0); // 0 - no pending invites, 1 - some pending invites
|
||||
SendPacket(&data);
|
||||
}
|
||||
+295
-54
@@ -82,7 +82,9 @@ bool LoginQueryHolder::Initialize()
|
||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADDECLINEDNAMES, "SELECT genitive, dative, accusative, instrumental, prepositional FROM character_declinedname WHERE guid = '%u'",GUID_LOPART(m_guid));
|
||||
// in other case still be dummy query
|
||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADGUILD, "SELECT guildid,rank FROM guild_member WHERE guid = '%u'", GUID_LOPART(m_guid));
|
||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADARENAINFO, "SELECT arenateamid, played_week, played_season, personal_rating FROM arena_team_member WHERE guid='%u'", GUID_LOPART(m_guid));
|
||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADARENAINFO, "SELECT arenateamid, played_week, played_season, personal_rating FROM arena_team_member WHERE guid='%u'", GUID_LOPART(m_guid));
|
||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADACHIEVEMENTS, "SELECT achievement, date FROM character_achievement WHERE guid = '%u'", GUID_LOPART(m_guid));
|
||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADCRITERIAPROGRESS,"SELECT criteria, counter, date FROM character_achievement_progress WHERE guid = '%u'", GUID_LOPART(m_guid));
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -232,17 +234,16 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data )
|
||||
if (raceEntry->addon > Expansion())
|
||||
{
|
||||
data << (uint8)CHAR_CREATE_EXPANSION;
|
||||
sLog.outError("Not Expansion 1 account:[%d] but tried to Create character with expansion 1 race (%u)",GetAccountId(),race_);
|
||||
sLog.outError("Expansion %u account:[%d] tried to Create character with expansion %u race (%u)",Expansion(),GetAccountId(),raceEntry->addon,race_);
|
||||
SendPacket( &data );
|
||||
return;
|
||||
}
|
||||
|
||||
// prevent character creating Expansion class without Expansion account
|
||||
// TODO: use possible addon field in ChrClassesEntry in next dbc version
|
||||
if (Expansion() < 2 && class_ == CLASS_DEATH_KNIGHT)
|
||||
if (classEntry->addon > Expansion())
|
||||
{
|
||||
data << (uint8)CHAR_CREATE_EXPANSION;
|
||||
sLog.outError("Not Expansion 2 account:[%d] but tried to Create character with expansion 2 class (%u)",GetAccountId(),class_);
|
||||
data << (uint8)CHAR_CREATE_EXPANSION_CLASS;
|
||||
sLog.outError("Expansion %u account:[%d] tried to Create character with expansion %u class (%u)",Expansion(),GetAccountId(),classEntry->addon,class_);
|
||||
SendPacket( &data );
|
||||
return;
|
||||
}
|
||||
@@ -309,29 +310,77 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data )
|
||||
}
|
||||
}
|
||||
|
||||
// speedup check for heroic class disabled case
|
||||
uint32 heroic_free_slots = sWorld.getConfig(CONFIG_HEROIC_CHARACTERS_PER_REALM);
|
||||
if(heroic_free_slots==0 && GetSecurity()==SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT)
|
||||
{
|
||||
data << (uint8)CHAR_CREATE_UNIQUE_CLASS_LIMIT;
|
||||
SendPacket( &data );
|
||||
return;
|
||||
}
|
||||
|
||||
// speedup check for heroic class disabled case
|
||||
uint32 req_level_for_heroic = sWorld.getConfig(CONFIG_MIN_LEVEL_FOR_HEROIC_CHARACTER_CREATING);
|
||||
if(GetSecurity()==SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT && req_level_for_heroic > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
|
||||
{
|
||||
data << (uint8)CHAR_CREATE_LEVEL_REQUIREMENT;
|
||||
SendPacket( &data );
|
||||
return;
|
||||
}
|
||||
|
||||
bool AllowTwoSideAccounts = !sWorld.IsPvPRealm() || sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || GetSecurity() > SEC_PLAYER;
|
||||
uint32 skipCinematics = sWorld.getConfig(CONFIG_SKIP_CINEMATICS);
|
||||
|
||||
bool have_same_race = false;
|
||||
if(!AllowTwoSideAccounts || skipCinematics == 1)
|
||||
|
||||
// if 0 then allowed creating without any characters
|
||||
bool have_req_level_for_heroic = (req_level_for_heroic==0);
|
||||
|
||||
if(!AllowTwoSideAccounts || skipCinematics == 1 || class_ == CLASS_DEATH_KNIGHT)
|
||||
{
|
||||
QueryResult *result2 = CharacterDatabase.PQuery("SELECT DISTINCT race FROM characters WHERE account = '%u' %s", GetAccountId(),skipCinematics == 1 ? "" : "LIMIT 1");
|
||||
QueryResult *result2 = CharacterDatabase.PQuery("SELECT guid,race,class FROM characters WHERE account = '%u' %s",
|
||||
GetAccountId(), (skipCinematics == 1 || class_ == CLASS_DEATH_KNIGHT) ? "" : "LIMIT 1");
|
||||
if(result2)
|
||||
{
|
||||
uint32 team_= Player::TeamForRace(race_);
|
||||
|
||||
Field* field = result2->Fetch();
|
||||
uint8 race = field[0].GetUInt32();
|
||||
uint8 acc_race = field[1].GetUInt32();
|
||||
|
||||
if(GetSecurity()==SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT)
|
||||
{
|
||||
uint8 acc_class = field[2].GetUInt32();
|
||||
if(acc_class == CLASS_DEATH_KNIGHT)
|
||||
{
|
||||
if(heroic_free_slots > 0)
|
||||
--heroic_free_slots;
|
||||
|
||||
if(heroic_free_slots==0)
|
||||
{
|
||||
data << (uint8)CHAR_CREATE_UNIQUE_CLASS_LIMIT;
|
||||
SendPacket( &data );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(!have_req_level_for_heroic)
|
||||
{
|
||||
uint32 acc_guid = field[0].GetUInt32();
|
||||
uint32 acc_level = Player::GetUInt32ValueFromDB(UNIT_FIELD_LEVEL,acc_guid);
|
||||
if(acc_level >= req_level_for_heroic)
|
||||
have_req_level_for_heroic = true;
|
||||
}
|
||||
}
|
||||
|
||||
// need to check team only for first character
|
||||
// TODO: what to if account already has characters of both races?
|
||||
if (!AllowTwoSideAccounts)
|
||||
{
|
||||
uint32 team=0;
|
||||
if(race > 0)
|
||||
team = Player::TeamForRace(race);
|
||||
uint32 acc_team=0;
|
||||
if(acc_race > 0)
|
||||
acc_team = Player::TeamForRace(acc_race);
|
||||
|
||||
if(team != team_)
|
||||
if(acc_team != team_)
|
||||
{
|
||||
data << (uint8)CHAR_CREATE_PVP_TEAMS_VIOLATION;
|
||||
SendPacket( &data );
|
||||
@@ -340,20 +389,55 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data )
|
||||
}
|
||||
}
|
||||
|
||||
if (skipCinematics == 1)
|
||||
// search same race for cinematic or same class if need
|
||||
// TODO: check if cinematic already shown? (already logged in?; cinematic field)
|
||||
while ((skipCinematics == 1 && !have_same_race) || class_ == CLASS_DEATH_KNIGHT)
|
||||
{
|
||||
// TODO: check if cinematic already shown? (already logged in?; cinematic field)
|
||||
while (race_ != race && result2->NextRow())
|
||||
if(!result2->NextRow())
|
||||
break;
|
||||
|
||||
field = result2->Fetch();
|
||||
acc_race = field[1].GetUInt32();
|
||||
|
||||
if(!have_same_race)
|
||||
have_same_race = race_ == acc_race;
|
||||
|
||||
if(GetSecurity()==SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT)
|
||||
{
|
||||
field = result2->Fetch();
|
||||
race = field[0].GetUInt32();
|
||||
uint8 acc_class = field[2].GetUInt32();
|
||||
if(acc_class == CLASS_DEATH_KNIGHT)
|
||||
{
|
||||
if(heroic_free_slots > 0)
|
||||
--heroic_free_slots;
|
||||
|
||||
if(heroic_free_slots==0)
|
||||
{
|
||||
data << (uint8)CHAR_CREATE_UNIQUE_CLASS_LIMIT;
|
||||
SendPacket( &data );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(!have_req_level_for_heroic)
|
||||
{
|
||||
uint32 acc_guid = field[0].GetUInt32();
|
||||
uint32 acc_level = Player::GetUInt32ValueFromDB(UNIT_FIELD_LEVEL,acc_guid);
|
||||
if(acc_level >= req_level_for_heroic)
|
||||
have_req_level_for_heroic = true;
|
||||
}
|
||||
}
|
||||
have_same_race = race_ == race;
|
||||
}
|
||||
delete result2;
|
||||
}
|
||||
}
|
||||
|
||||
if(GetSecurity()==SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT && !have_req_level_for_heroic)
|
||||
{
|
||||
data << (uint8)CHAR_CREATE_LEVEL_REQUIREMENT;
|
||||
SendPacket( &data );
|
||||
return;
|
||||
}
|
||||
|
||||
// extract other data required for player creating
|
||||
uint8 gender, skin, face, hairStyle, hairColor, facialHair, outfitId;
|
||||
recv_data >> gender >> skin >> face;
|
||||
@@ -510,9 +594,11 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
|
||||
data << pCurrChar->GetOrientation();
|
||||
SendPacket(&data);
|
||||
|
||||
data.Initialize( SMSG_ACCOUNT_DATA_TIMES, 128 );
|
||||
for(int i = 0; i < 32; i++)
|
||||
data << uint32(0);
|
||||
data.Initialize( SMSG_ACCOUNT_DATA_TIMES, 4+1+8*4 ); // changed in WotLK
|
||||
data << uint32(time(NULL)); // unix time of something
|
||||
data << uint8(1);
|
||||
for(int i = 0; i < NUM_ACCOUNT_DATA_TYPES; i++)
|
||||
data << uint32(GetAccountData(i)->Time); // also unix time
|
||||
SendPacket(&data);
|
||||
|
||||
data.Initialize(SMSG_FEATURE_SYSTEM_STATUS, 2); // added in 2.2.0
|
||||
@@ -609,12 +695,20 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
|
||||
{
|
||||
pCurrChar->setCinematic(1);
|
||||
|
||||
ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(pCurrChar->getRace());
|
||||
if(rEntry)
|
||||
if(ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(pCurrChar->getClass()))
|
||||
{
|
||||
data.Initialize( SMSG_TRIGGER_CINEMATIC,4 );
|
||||
data << uint32(rEntry->startmovie);
|
||||
SendPacket( &data );
|
||||
if(cEntry->CinematicSequence)
|
||||
{
|
||||
data.Initialize(SMSG_TRIGGER_CINEMATIC, 4);
|
||||
data << uint32(cEntry->CinematicSequence);
|
||||
SendPacket( &data );
|
||||
}
|
||||
else if(ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(pCurrChar->getRace()))
|
||||
{
|
||||
data.Initialize(SMSG_TRIGGER_CINEMATIC, 4);
|
||||
data << uint32(rEntry->CinematicSequence);
|
||||
SendPacket( &data );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -658,22 +752,6 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
|
||||
pCurrChar->CastSpell(pCurrChar, 20584, true, 0);// auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form)
|
||||
pCurrChar->CastSpell(pCurrChar, 8326, true, 0); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?)
|
||||
|
||||
//pCurrChar->SetUInt32Value(UNIT_FIELD_AURA+41, 8326);
|
||||
//pCurrChar->SetUInt32Value(UNIT_FIELD_AURA+42, 20584);
|
||||
//pCurrChar->SetUInt32Value(UNIT_FIELD_AURAFLAGS+6, 238);
|
||||
//pCurrChar->SetUInt32Value(UNIT_FIELD_AURALEVELS+11, 514);
|
||||
//pCurrChar->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS+11, 65535);
|
||||
//pCurrChar->SetUInt32Value(UNIT_FIELD_DISPLAYID, 1825);
|
||||
//if (pCurrChar->getRace() == RACE_NIGHTELF)
|
||||
//{
|
||||
// pCurrChar->SetSpeed(MOVE_RUN, 1.5f*1.2f, true);
|
||||
// pCurrChar->SetSpeed(MOVE_SWIM, 1.5f*1.2f, true);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// pCurrChar->SetSpeed(MOVE_RUN, 1.5f, true);
|
||||
// pCurrChar->SetSpeed(MOVE_SWIM, 1.5f, true);
|
||||
//}
|
||||
pCurrChar->SetMovement(MOVE_WATER_WALK);
|
||||
}
|
||||
|
||||
@@ -903,11 +981,11 @@ void WorldSession::HandleToggleCloakOpcode( WorldPacket & /*recv_data*/ )
|
||||
|
||||
void WorldSession::HandleChangePlayerNameOpcode(WorldPacket& recv_data)
|
||||
{
|
||||
CHECK_PACKET_SIZE(recv_data, 8+1);
|
||||
|
||||
uint64 guid;
|
||||
std::string newname;
|
||||
|
||||
CHECK_PACKET_SIZE(recv_data, 8+1);
|
||||
|
||||
recv_data >> guid;
|
||||
recv_data >> newname;
|
||||
|
||||
@@ -915,15 +993,15 @@ void WorldSession::HandleChangePlayerNameOpcode(WorldPacket& recv_data)
|
||||
if(!normalizePlayerName(newname))
|
||||
{
|
||||
WorldPacket data(SMSG_CHAR_RENAME, 1);
|
||||
data << (uint8)CHAR_NAME_NO_NAME;
|
||||
data << uint8(CHAR_NAME_NO_NAME);
|
||||
SendPacket( &data );
|
||||
return;
|
||||
}
|
||||
|
||||
if(!ObjectMgr::IsValidName(newname,true))
|
||||
if(!ObjectMgr::IsValidName(newname, true))
|
||||
{
|
||||
WorldPacket data(SMSG_CHAR_RENAME, 1);
|
||||
data << (uint8)CHAR_NAME_INVALID_CHARACTER;
|
||||
data << uint8(CHAR_NAME_INVALID_CHARACTER);
|
||||
SendPacket( &data );
|
||||
return;
|
||||
}
|
||||
@@ -932,7 +1010,7 @@ void WorldSession::HandleChangePlayerNameOpcode(WorldPacket& recv_data)
|
||||
if(GetSecurity() == SEC_PLAYER && objmgr.IsReservedName(newname))
|
||||
{
|
||||
WorldPacket data(SMSG_CHAR_RENAME, 1);
|
||||
data << (uint8)CHAR_NAME_RESERVED;
|
||||
data << uint8(CHAR_NAME_RESERVED);
|
||||
SendPacket( &data );
|
||||
return;
|
||||
}
|
||||
@@ -961,7 +1039,7 @@ void WorldSession::HandleChangePlayerNameOpcodeCallBack(QueryResult *result, uin
|
||||
if (!result)
|
||||
{
|
||||
WorldPacket data(SMSG_CHAR_RENAME, 1);
|
||||
data << (uint8)CHAR_CREATE_ERROR;
|
||||
data << uint8(CHAR_CREATE_ERROR);
|
||||
session->SendPacket( &data );
|
||||
return;
|
||||
}
|
||||
@@ -975,11 +1053,11 @@ void WorldSession::HandleChangePlayerNameOpcodeCallBack(QueryResult *result, uin
|
||||
CharacterDatabase.PExecute("UPDATE characters set name = '%s', at_login = at_login & ~ %u WHERE guid ='%u'", newname.c_str(), uint32(AT_LOGIN_RENAME), guidLow);
|
||||
CharacterDatabase.PExecute("DELETE FROM character_declinedname WHERE guid ='%u'", guidLow);
|
||||
|
||||
sLog.outChar("Account: %d (IP: %s) Character:[%s] (guid:%u) Changed name to: %s",session->GetAccountId(), session->GetRemoteAddress().c_str(), oldname.c_str(), guidLow, newname.c_str());
|
||||
sLog.outChar("Account: %d (IP: %s) Character:[%s] (guid:%u) Changed name to: %s", session->GetAccountId(), session->GetRemoteAddress().c_str(), oldname.c_str(), guidLow, newname.c_str());
|
||||
|
||||
WorldPacket data(SMSG_CHAR_RENAME,1+8+(newname.size()+1));
|
||||
data << (uint8)RESPONSE_SUCCESS;
|
||||
data << guid;
|
||||
WorldPacket data(SMSG_CHAR_RENAME, 1+8+(newname.size()+1));
|
||||
data << uint8(RESPONSE_SUCCESS);
|
||||
data << uint64(guid);
|
||||
data << newname;
|
||||
session->SendPacket(&data);
|
||||
}
|
||||
@@ -1073,3 +1151,166 @@ void WorldSession::HandleDeclinedPlayerNameOpcode(WorldPacket& recv_data)
|
||||
data << uint64(guid);
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::HandleAlterAppearance( WorldPacket & recv_data )
|
||||
{
|
||||
sLog.outDebug("CMSG_ALTER_APPEARANCE");
|
||||
|
||||
CHECK_PACKET_SIZE(recv_data, 4+4+4);
|
||||
|
||||
uint32 Hair, Color, FacialHair;
|
||||
recv_data >> Hair >> Color >> FacialHair;
|
||||
|
||||
BarberShopStyleEntry const* bs_hair = sBarberShopStyleStore.LookupEntry(Hair);
|
||||
|
||||
if(!bs_hair || bs_hair->type != 0 || bs_hair->race != _player->getRace() || bs_hair->gender != _player->getGender())
|
||||
return;
|
||||
|
||||
BarberShopStyleEntry const* bs_facialHair = sBarberShopStyleStore.LookupEntry(FacialHair);
|
||||
|
||||
if(!bs_facialHair || bs_facialHair->type != 2 || bs_facialHair->race != _player->getRace() || bs_facialHair->gender != _player->getGender())
|
||||
return;
|
||||
|
||||
uint32 Cost = _player->GetBarberShopCost(bs_hair->hair_id, Color, bs_facialHair->hair_id);
|
||||
|
||||
// 0 - ok
|
||||
// 1,3 - not enough money
|
||||
// 2 - you have to seat on barber chair
|
||||
if(_player->GetMoney() < Cost)
|
||||
{
|
||||
WorldPacket data(SMSG_BARBER_SHOP_RESULT, 4);
|
||||
data << uint32(1); // no money
|
||||
SendPacket(&data);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
WorldPacket data(SMSG_BARBER_SHOP_RESULT, 4);
|
||||
data << uint32(0); // ok
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
_player->SetMoney(_player->GetMoney() - Cost); // it isn't free
|
||||
|
||||
_player->SetByteValue(PLAYER_BYTES, 2, uint8(bs_hair->hair_id));
|
||||
_player->SetByteValue(PLAYER_BYTES, 3, uint8(Color));
|
||||
_player->SetByteValue(PLAYER_BYTES_2, 0, uint8(bs_facialHair->hair_id));
|
||||
|
||||
_player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP, 1);
|
||||
|
||||
_player->SetStandState(0); // stand up
|
||||
}
|
||||
|
||||
void WorldSession::HandleRemoveGlyph( WorldPacket & recv_data )
|
||||
{
|
||||
CHECK_PACKET_SIZE(recv_data, 4);
|
||||
|
||||
uint32 slot;
|
||||
recv_data >> slot;
|
||||
|
||||
if(slot > 5)
|
||||
{
|
||||
sLog.outDebug("Client sent wrong glyph slot number in opcode CMSG_REMOVE_GLYPH %u", slot);
|
||||
return;
|
||||
}
|
||||
|
||||
if(uint32 glyph = _player->GetGlyph(slot))
|
||||
{
|
||||
if(GlyphPropertiesEntry const *gp = sGlyphPropertiesStore.LookupEntry(glyph))
|
||||
{
|
||||
_player->RemoveAurasDueToSpell(gp->SpellId);
|
||||
_player->SetGlyph(slot, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::HandleCharCustomize(WorldPacket& recv_data)
|
||||
{
|
||||
CHECK_PACKET_SIZE(recv_data, 8+1);
|
||||
|
||||
uint64 guid;
|
||||
std::string newname;
|
||||
|
||||
recv_data >> guid;
|
||||
recv_data >> newname;
|
||||
|
||||
CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+1+1+1+1+1+1);
|
||||
|
||||
uint8 gender, skin, face, hairStyle, hairColor, facialHair;
|
||||
recv_data >> gender >> skin >> face >> hairStyle >> hairColor >> facialHair;
|
||||
|
||||
QueryResult *result = CharacterDatabase.PQuery("SELECT at_login FROM characters WHERE guid ='%u'", GUID_LOPART(guid));
|
||||
if (!result)
|
||||
{
|
||||
WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1);
|
||||
data << uint8(CHAR_CREATE_ERROR);
|
||||
SendPacket( &data );
|
||||
return;
|
||||
}
|
||||
|
||||
Field *fields = result->Fetch();
|
||||
uint32 at_loginFlags = fields[0].GetUInt32();
|
||||
delete result;
|
||||
|
||||
if (!(at_loginFlags & AT_LOGIN_CUSTOMIZE))
|
||||
{
|
||||
WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1);
|
||||
data << uint8(CHAR_CREATE_ERROR);
|
||||
SendPacket( &data );
|
||||
return;
|
||||
}
|
||||
|
||||
// prevent character rename to invalid name
|
||||
if(!normalizePlayerName(newname))
|
||||
{
|
||||
WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1);
|
||||
data << uint8(CHAR_NAME_NO_NAME);
|
||||
SendPacket( &data );
|
||||
return;
|
||||
}
|
||||
|
||||
if(!ObjectMgr::IsValidName(newname,true))
|
||||
{
|
||||
WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1);
|
||||
data << uint8(CHAR_NAME_INVALID_CHARACTER);
|
||||
SendPacket( &data );
|
||||
return;
|
||||
}
|
||||
|
||||
// check name limitations
|
||||
if(GetSecurity() == SEC_PLAYER && objmgr.IsReservedName(newname))
|
||||
{
|
||||
WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1);
|
||||
data << uint8(CHAR_NAME_RESERVED);
|
||||
SendPacket( &data );
|
||||
return;
|
||||
}
|
||||
|
||||
if(objmgr.GetPlayerGUIDByName(newname)) // character with this name already exist
|
||||
{
|
||||
WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1);
|
||||
data << uint8(CHAR_CREATE_NAME_IN_USE);
|
||||
SendPacket( &data );
|
||||
return;
|
||||
}
|
||||
|
||||
CharacterDatabase.escape_string(newname);
|
||||
Player::Customize(guid, gender, skin, face, hairStyle, hairColor, facialHair);
|
||||
CharacterDatabase.PExecute("UPDATE characters set name = '%s', at_login = at_login & ~ %u WHERE guid ='%u'", newname.c_str(), uint32(AT_LOGIN_CUSTOMIZE), GUID_LOPART(guid));
|
||||
CharacterDatabase.PExecute("DELETE FROM character_declinedname WHERE guid ='%u'", GUID_LOPART(guid));
|
||||
|
||||
std::string IP_str = GetRemoteAddress();
|
||||
sLog.outChar("Account: %d (IP: %s), Character guid: %u Customized to: %s", GetAccountId(), IP_str.c_str(), GUID_LOPART(guid), newname.c_str());
|
||||
|
||||
WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1+8+(newname.size()+1)+6);
|
||||
data << uint8(RESPONSE_SUCCESS);
|
||||
data << uint64(guid);
|
||||
data << newname;
|
||||
data << uint8(gender);
|
||||
data << uint8(skin);
|
||||
data << uint8(face);
|
||||
data << uint8(hairStyle);
|
||||
data << uint8(hairColor);
|
||||
data << uint8(facialHair);
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
@@ -190,6 +190,7 @@ ChatCommand * ChatHandler::getCommandTable()
|
||||
{ "sellerr", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSellErrorCommand, "", NULL },
|
||||
{ "buyerr", SEC_ADMINISTRATOR, false, &ChatHandler::HandleBuyErrorCommand, "", NULL },
|
||||
{ "sendopcode", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSendOpcodeCommand, "", NULL },
|
||||
{ "spawnvehicle", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSpawnVehicle, "", NULL },
|
||||
{ "uws", SEC_ADMINISTRATOR, false, &ChatHandler::HandleUpdateWorldStateCommand, "", NULL },
|
||||
{ "ps", SEC_ADMINISTRATOR, false, &ChatHandler::HandlePlaySound2Command, "", NULL },
|
||||
{ "scn", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSendChannelNotifyCommand, "", NULL },
|
||||
@@ -263,6 +264,7 @@ ChatCommand * ChatHandler::getCommandTable()
|
||||
{ "item_enchantment_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadItemEnchantementsCommand, "", NULL },
|
||||
{ "item_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesItemCommand, "", NULL },
|
||||
{ "trinity_string", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadTrinityStringCommand, "", NULL },
|
||||
{ "milling_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesMillingCommand, "", NULL },
|
||||
{ "npc_gossip", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcGossipCommand, "", NULL },
|
||||
{ "npc_option", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcOptionCommand, "", NULL },
|
||||
{ "npc_trainer", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcTrainerCommand, "", NULL },
|
||||
@@ -589,6 +591,7 @@ ChatCommand * ChatHandler::getCommandTable()
|
||||
{ "sendmail", SEC_MODERATOR, true, &ChatHandler::HandleSendMailCommand, "", NULL },
|
||||
{ "sendmoney", SEC_ADMINISTRATOR, true, &ChatHandler::HandleSendMoneyCommand, "", NULL },
|
||||
{ "rename", SEC_GAMEMASTER, true, &ChatHandler::HandleRenameCommand, "", NULL },
|
||||
{ "customize", SEC_GAMEMASTER, true, &ChatHandler::HandleCustomizeCommand, "", NULL },
|
||||
{ "loadscripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLoadScriptsCommand, "", NULL },
|
||||
{ "mute", SEC_GAMEMASTER, true, &ChatHandler::HandleMuteCommand, "", NULL },
|
||||
{ "unmute", SEC_GAMEMASTER, true, &ChatHandler::HandleUnmuteCommand, "", NULL },
|
||||
|
||||
@@ -233,6 +233,7 @@ class ChatHandler
|
||||
bool HandleReloadLootTemplatesFishingCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesGameobjectCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesItemCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesMillingCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesPickpocketingCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesProspectingCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesReferenceCommand(const char* args);
|
||||
@@ -434,6 +435,7 @@ class ChatHandler
|
||||
bool HandleSendChannelNotifyCommand(const char* args);
|
||||
bool HandleSendChatMsgCommand(const char* args);
|
||||
bool HandleRenameCommand(const char * args);
|
||||
bool HandleCustomizeCommand(const char * args);
|
||||
bool HandleLoadPDumpCommand(const char *args);
|
||||
bool HandleWritePDumpCommand(const char *args);
|
||||
bool HandleCastCommand(const char *args);
|
||||
@@ -467,6 +469,7 @@ class ChatHandler
|
||||
bool HandleUnPossessCommand(const char* args);
|
||||
bool HandleBindSightCommand(const char* args);
|
||||
bool HandleUnbindSightCommand(const char* args);
|
||||
bool HandleSpawnVehicle(const char * args);
|
||||
|
||||
Player* getSelectedPlayer();
|
||||
Creature* getSelectedCreature();
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ Corpse::Corpse(CorpseType type) : WorldObject()
|
||||
m_objectType |= TYPEMASK_CORPSE;
|
||||
m_objectTypeId = TYPEID_CORPSE;
|
||||
// 2.3.2 - 0x58
|
||||
m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HASPOSITION);
|
||||
m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION);
|
||||
|
||||
m_valuesCount = CORPSE_END;
|
||||
|
||||
|
||||
+10
-15
@@ -145,11 +145,12 @@ Unit(), i_AI(NULL), i_AI_possessed(NULL),
|
||||
lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), lootingGroupLeaderGUID(0),
|
||||
m_lootMoney(0), m_lootRecipient(0),
|
||||
m_deathTimer(0), m_respawnTime(0), m_respawnDelay(25), m_corpseDelay(60), m_respawnradius(0.0f),
|
||||
m_gossipOptionLoaded(false), m_emoteState(0), m_isPet(false), m_isTotem(false), m_reactState(REACT_AGGRESSIVE),
|
||||
m_regenTimer(2000), m_defaultMovementType(IDLE_MOTION_TYPE), m_equipmentId(0),
|
||||
m_gossipOptionLoaded(false), m_emoteState(0), m_isPet(false), m_isTotem(false), m_isVehicle(false), m_reactState(REACT_AGGRESSIVE),
|
||||
m_defaultMovementType(IDLE_MOTION_TYPE), m_equipmentId(0),
|
||||
m_AlreadyCallAssistance(false), m_regenHealth(true), m_AI_locked(false), m_isDeadByDefault(false),
|
||||
m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL),m_creatureInfo(NULL), m_DBTableGuid(0), m_formationID(0)
|
||||
{
|
||||
m_regenTimer = 200;
|
||||
m_valuesCount = UNIT_END;
|
||||
|
||||
for(int i =0; i<4; ++i)
|
||||
@@ -315,7 +316,6 @@ bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData *data )
|
||||
|
||||
// creatures always have melee weapon ready if any
|
||||
SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE );
|
||||
SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_AURAS );
|
||||
|
||||
SelectLevel(GetCreatureInfo());
|
||||
if (team == HORDE)
|
||||
@@ -765,8 +765,11 @@ bool Creature::isCanInteractWithBattleMaster(Player* pPlayer, bool msg) const
|
||||
case BATTLEGROUND_NA:
|
||||
case BATTLEGROUND_BE:
|
||||
case BATTLEGROUND_AA:
|
||||
case BATTLEGROUND_RL: pPlayer->PlayerTalkClass->SendGossipMenu(10024,GetGUID()); break;
|
||||
break;
|
||||
case BATTLEGROUND_RL:
|
||||
case BATTLEGROUND_SA:
|
||||
case BATTLEGROUND_DS:
|
||||
case BATTLEGROUND_RV: pPlayer->PlayerTalkClass->SendGossipMenu(10024,GetGUID()); break;
|
||||
default: break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -1459,11 +1462,7 @@ void Creature::LoadEquipment(uint32 equip_entry, bool force)
|
||||
if (force)
|
||||
{
|
||||
for (uint8 i = 0; i < 3; i++)
|
||||
{
|
||||
SetUInt32Value( UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + i, 0);
|
||||
SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + (i * 2), 0);
|
||||
SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + (i * 2) + 1, 0);
|
||||
}
|
||||
SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + i, 0);
|
||||
m_equipmentId = 0;
|
||||
}
|
||||
return;
|
||||
@@ -1475,11 +1474,7 @@ void Creature::LoadEquipment(uint32 equip_entry, bool force)
|
||||
|
||||
m_equipmentId = equip_entry;
|
||||
for (uint8 i = 0; i < 3; i++)
|
||||
{
|
||||
SetUInt32Value( UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + i, einfo->equipmodel[i]);
|
||||
SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + (i * 2), einfo->equipinfo[i]);
|
||||
SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + (i * 2) + 1, einfo->equipslot[i]);
|
||||
}
|
||||
SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + i, einfo->equipentry[i]);
|
||||
}
|
||||
|
||||
bool Creature::hasQuest(uint32 quest_id) const
|
||||
|
||||
+3
-4
@@ -244,9 +244,7 @@ struct NpcOptionLocale
|
||||
struct EquipmentInfo
|
||||
{
|
||||
uint32 entry;
|
||||
uint32 equipmodel[3];
|
||||
uint32 equipinfo[3];
|
||||
uint32 equipslot[3];
|
||||
uint32 equipentry[3];
|
||||
};
|
||||
|
||||
// from `creature` table
|
||||
@@ -423,6 +421,7 @@ class TRINITY_DLL_SPEC Creature : public Unit
|
||||
uint32 GetEquipmentId() const { return m_equipmentId; }
|
||||
|
||||
bool isPet() const { return m_isPet; }
|
||||
bool isVehicle() const { return m_isVehicle; }
|
||||
void SetCorpseDelay(uint32 delay) { m_corpseDelay = delay; }
|
||||
bool isTotem() const { return m_isTotem; }
|
||||
bool isRacialLeader() const { return GetCreatureInfo()->RacialLeader; }
|
||||
@@ -657,11 +656,11 @@ class TRINITY_DLL_SPEC Creature : public Unit
|
||||
|
||||
uint8 m_emoteState;
|
||||
bool m_isPet; // set only in Pet::Pet
|
||||
bool m_isVehicle; // set only in Vehicle::Vehicle
|
||||
bool m_isTotem; // set only in Totem::Totem
|
||||
ReactStates m_reactState; // for AI, not charmInfo
|
||||
void RegenerateMana();
|
||||
void RegenerateHealth();
|
||||
uint32 m_regenTimer;
|
||||
MovementGeneratorType m_defaultMovementType;
|
||||
Cell m_currentCell; // store current cell where creature listed
|
||||
uint32 m_DBTableGuid; ///< For new or temporary creatures is 0 for saved it is lowguid
|
||||
|
||||
@@ -38,7 +38,7 @@ DynamicObject::DynamicObject() : WorldObject()
|
||||
m_objectType |= TYPEMASK_DYNAMICOBJECT;
|
||||
m_objectTypeId = TYPEID_DYNAMICOBJECT;
|
||||
// 2.3.2 - 0x58
|
||||
m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HASPOSITION);
|
||||
m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION);
|
||||
|
||||
m_valuesCount = DYNAMICOBJECT_END;
|
||||
}
|
||||
|
||||
+60
-36
@@ -46,7 +46,7 @@ GameObject::GameObject() : WorldObject()
|
||||
m_objectType |= TYPEMASK_GAMEOBJECT;
|
||||
m_objectTypeId = TYPEID_GAMEOBJECT;
|
||||
// 2.3.2 - 0x58
|
||||
m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HASPOSITION);
|
||||
m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION);
|
||||
|
||||
m_valuesCount = GAMEOBJECT_END;
|
||||
m_respawnTime = 0;
|
||||
@@ -127,17 +127,33 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, float x, float
|
||||
SetFloatValue(GAMEOBJECT_POS_Z, z);
|
||||
SetFloatValue(GAMEOBJECT_FACING, ang); //this is not facing angle
|
||||
|
||||
SetFloatValue (GAMEOBJECT_ROTATION, rotation0);
|
||||
SetFloatValue (GAMEOBJECT_ROTATION+1, rotation1);
|
||||
SetFloatValue (GAMEOBJECT_ROTATION+2, rotation2);
|
||||
SetFloatValue (GAMEOBJECT_ROTATION+3, rotation3);
|
||||
int64 rotation = 0;
|
||||
|
||||
float f_rot1 = sin(ang / 2.0f);
|
||||
int64 i_rot1 = f_rot1 / atan(pow(2.0f, -20.0f));
|
||||
rotation |= (i_rot1 << 43 >> 43) & 0x00000000001FFFFF;
|
||||
|
||||
//float f_rot2 = sin(0.0f / 2.0f);
|
||||
//int64 i_rot2 = f_rot2 / atan(pow(2.0f, -20.0f));
|
||||
//rotation |= (((i_rot2 << 22) >> 32) >> 11) & 0x000003FFFFE00000;
|
||||
|
||||
//float f_rot3 = sin(0.0f / 2.0f);
|
||||
//int64 i_rot3 = f_rot3 / atan(pow(2.0f, -21.0f));
|
||||
//rotation |= (i_rot3 >> 42) & 0x7FFFFC0000000000;
|
||||
|
||||
SetUInt64Value(GAMEOBJECT_ROTATION, rotation);
|
||||
|
||||
SetFloatValue(GAMEOBJECT_PARENTROTATION+0, rotation0);
|
||||
SetFloatValue(GAMEOBJECT_PARENTROTATION+1, rotation1);
|
||||
SetFloatValue(GAMEOBJECT_PARENTROTATION+2, rotation2);
|
||||
SetFloatValue(GAMEOBJECT_PARENTROTATION+3, rotation3);
|
||||
|
||||
SetFloatValue(OBJECT_FIELD_SCALE_X, goinfo->size);
|
||||
|
||||
SetUInt32Value(GAMEOBJECT_FACTION, goinfo->faction);
|
||||
SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags);
|
||||
|
||||
SetUInt32Value(OBJECT_FIELD_ENTRY, goinfo->id);
|
||||
SetEntry(goinfo->id);
|
||||
|
||||
SetUInt32Value(GAMEOBJECT_DISPLAYID, goinfo->displayId);
|
||||
|
||||
@@ -146,8 +162,6 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, float x, float
|
||||
|
||||
SetGoAnimProgress(animprogress);
|
||||
|
||||
SetUInt32Value (GAMEOBJECT_ARTKIT, ArtKit);
|
||||
|
||||
// Spell charges for GAMEOBJECT_TYPE_SPELLCASTER (22)
|
||||
if (goinfo->type == GAMEOBJECT_TYPE_SPELLCASTER)
|
||||
m_charges = goinfo->spellcaster.charges;
|
||||
@@ -264,7 +278,7 @@ void GameObject::Update(uint32 /*p_time*/)
|
||||
return;
|
||||
}
|
||||
// respawn timer
|
||||
MapManager::Instance().GetMap(GetMapId(), this)->Add(this);
|
||||
GetMap()->Add(this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -414,7 +428,7 @@ void GameObject::Update(uint32 /*p_time*/)
|
||||
//burning flags in some battlegrounds, if you find better condition, just add it
|
||||
if (GetGoAnimProgress() > 0)
|
||||
{
|
||||
SendObjectDeSpawnAnim(this->GetGUID());
|
||||
SendObjectDeSpawnAnim(GetGUID());
|
||||
//reset flags
|
||||
SetUInt32Value(GAMEOBJECT_FLAGS, GetGOInfo()->flags);
|
||||
}
|
||||
@@ -451,7 +465,7 @@ void GameObject::Refresh()
|
||||
return;
|
||||
|
||||
if(isSpawned())
|
||||
MapManager::Instance().GetMap(GetMapId(), this)->Add(this);
|
||||
GetMap()->Add(this);
|
||||
}
|
||||
|
||||
void GameObject::AddUniqueUse(Player* player)
|
||||
@@ -504,7 +518,7 @@ void GameObject::SaveToDB(uint32 mapid, uint8 spawnMask)
|
||||
|
||||
if (!goI)
|
||||
return;
|
||||
|
||||
|
||||
if (!m_DBTableGuid)
|
||||
m_DBTableGuid = GetGUIDLow();
|
||||
// update in loaded data (changing data only in this place)
|
||||
@@ -517,34 +531,33 @@ void GameObject::SaveToDB(uint32 mapid, uint8 spawnMask)
|
||||
data.posY = GetFloatValue(GAMEOBJECT_POS_Y);
|
||||
data.posZ = GetFloatValue(GAMEOBJECT_POS_Z);
|
||||
data.orientation = GetFloatValue(GAMEOBJECT_FACING);
|
||||
data.rotation0 = GetFloatValue(GAMEOBJECT_ROTATION+0);
|
||||
data.rotation1 = GetFloatValue(GAMEOBJECT_ROTATION+1);
|
||||
data.rotation2 = GetFloatValue(GAMEOBJECT_ROTATION+2);
|
||||
data.rotation3 = GetFloatValue(GAMEOBJECT_ROTATION+3);
|
||||
data.rotation0 = GetFloatValue(GAMEOBJECT_PARENTROTATION+0);
|
||||
data.rotation1 = GetFloatValue(GAMEOBJECT_PARENTROTATION+1);
|
||||
data.rotation2 = GetFloatValue(GAMEOBJECT_PARENTROTATION+2);
|
||||
data.rotation3 = GetFloatValue(GAMEOBJECT_PARENTROTATION+3);
|
||||
data.spawntimesecs = m_spawnedByDefault ? m_respawnDelayTime : -(int32)m_respawnDelayTime;
|
||||
data.animprogress = GetGoAnimProgress();
|
||||
data.go_state = GetGoState();
|
||||
data.spawnMask = spawnMask;
|
||||
data.ArtKit = GetUInt32Value (GAMEOBJECT_ARTKIT);
|
||||
|
||||
// updated in DB
|
||||
std::ostringstream ss;
|
||||
ss << "INSERT INTO gameobject VALUES ( "
|
||||
<< m_DBTableGuid << ", "
|
||||
<< GetUInt32Value (OBJECT_FIELD_ENTRY) << ", "
|
||||
<< GetEntry() << ", "
|
||||
<< mapid << ", "
|
||||
<< (uint32)spawnMask << ", "
|
||||
<< GetFloatValue(GAMEOBJECT_POS_X) << ", "
|
||||
<< GetFloatValue(GAMEOBJECT_POS_Y) << ", "
|
||||
<< GetFloatValue(GAMEOBJECT_POS_Z) << ", "
|
||||
<< GetFloatValue(GAMEOBJECT_FACING) << ", "
|
||||
<< GetFloatValue(GAMEOBJECT_ROTATION) << ", "
|
||||
<< GetFloatValue(GAMEOBJECT_ROTATION+1) << ", "
|
||||
<< GetFloatValue(GAMEOBJECT_ROTATION+2) << ", "
|
||||
<< GetFloatValue(GAMEOBJECT_ROTATION+3) << ", "
|
||||
<< GetFloatValue(GAMEOBJECT_PARENTROTATION) << ", "
|
||||
<< GetFloatValue(GAMEOBJECT_PARENTROTATION+1) << ", "
|
||||
<< GetFloatValue(GAMEOBJECT_PARENTROTATION+2) << ", "
|
||||
<< GetFloatValue(GAMEOBJECT_PARENTROTATION+3) << ", "
|
||||
<< m_respawnDelayTime << ", "
|
||||
<< GetGoAnimProgress() << ", "
|
||||
<< GetGoState() << ")";
|
||||
<< (uint32)GetGoAnimProgress() << ", "
|
||||
<< (uint32)GetGoState() << ")";
|
||||
|
||||
WorldDatabase.BeginTransaction();
|
||||
WorldDatabase.PExecuteLog("DELETE FROM gameobject WHERE guid = '%u'", m_DBTableGuid);
|
||||
@@ -563,7 +576,7 @@ bool GameObject::LoadFromDB(uint32 guid, Map *map)
|
||||
}
|
||||
|
||||
uint32 entry = data->id;
|
||||
uint32 map_id = data->mapid;
|
||||
//uint32 map_id = data->mapid; // already used before call
|
||||
float x = data->posX;
|
||||
float y = data->posY;
|
||||
float z = data->posZ;
|
||||
@@ -576,12 +589,11 @@ bool GameObject::LoadFromDB(uint32 guid, Map *map)
|
||||
|
||||
uint32 animprogress = data->animprogress;
|
||||
uint32 go_state = data->go_state;
|
||||
uint32 ArtKit = data->ArtKit;
|
||||
|
||||
m_DBTableGuid = guid;
|
||||
if (map->GetInstanceId() != 0) guid = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT);
|
||||
|
||||
if (!Create(guid,entry, map, x, y, z, ang, rotation0, rotation1, rotation2, rotation3, animprogress, go_state, ArtKit) )
|
||||
if (!Create(guid,entry, map, x, y, z, ang, rotation0, rotation1, rotation2, rotation3, animprogress, go_state) )
|
||||
return false;
|
||||
|
||||
switch(GetGOInfo()->type)
|
||||
@@ -846,14 +858,6 @@ void GameObject::UseDoorOrButton(uint32 time_to_restore)
|
||||
|
||||
}
|
||||
|
||||
void GameObject::SetGoArtKit(uint32 kit)
|
||||
{
|
||||
SetUInt32Value(GAMEOBJECT_ARTKIT, kit);
|
||||
GameObjectData *data = const_cast<GameObjectData*>(objmgr.GetGOData(m_DBTableGuid));
|
||||
if(data)
|
||||
data->ArtKit = kit;
|
||||
}
|
||||
|
||||
void GameObject::SwitchDoorOrButton(bool activate)
|
||||
{
|
||||
if(activate)
|
||||
@@ -1209,7 +1213,7 @@ void GameObject::Use(Unit* user)
|
||||
|
||||
Player* player = (Player*)user;
|
||||
|
||||
if( player->isAllowUseBattleGroundObject() )
|
||||
if( player->isAllowUseBattleGroundObject() )
|
||||
{
|
||||
// in battleground check
|
||||
BattleGround *bg = player->GetBattleGround();
|
||||
@@ -1247,6 +1251,26 @@ void GameObject::Use(Unit* user)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GAMEOBJECT_TYPE_BARBER_CHAIR: //32
|
||||
{
|
||||
GameObjectInfo const* info = GetGOInfo();
|
||||
if(!info)
|
||||
return;
|
||||
|
||||
if(user->GetTypeId()!=TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
Player* player = (Player*)user;
|
||||
|
||||
// fallback, will always work
|
||||
player->TeleportTo(GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation(),TELE_TO_NOT_LEAVE_TRANSPORT | TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET);
|
||||
|
||||
WorldPacket data(SMSG_ENABLE_BARBER_SHOP, 0);
|
||||
player->GetSession()->SendPacket(&data);
|
||||
|
||||
player->SetStandState(PLAYER_STATE_SIT_LOW_CHAIR+info->barberChair.chairheight);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
sLog.outDebug("Unknown Object Type %u", GetGoType());
|
||||
break;
|
||||
|
||||
+19
-12
@@ -336,12 +336,12 @@ struct GameObjectInfo
|
||||
uint32 mapID; //0
|
||||
uint32 difficulty; //1
|
||||
} dungeonDifficulty;
|
||||
//32 GAMEOBJECT_TYPE_DO_NOT_USE_YET
|
||||
//32 GAMEOBJECT_TYPE_BARBER_CHAIR
|
||||
struct
|
||||
{
|
||||
uint32 mapID; //0
|
||||
uint32 difficulty; //1
|
||||
} doNotUseYet;
|
||||
uint32 chairheight; //0
|
||||
uint32 heightOffset; //1
|
||||
} barberChair;
|
||||
//33 GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING
|
||||
struct
|
||||
{
|
||||
@@ -350,6 +350,13 @@ struct GameObjectInfo
|
||||
uint32 state1Name; //2
|
||||
uint32 state2Name; //3
|
||||
} destructibleBuilding;
|
||||
//34 GAMEOBJECT_TYPE_TRAPDOOR
|
||||
struct
|
||||
{
|
||||
uint32 whenToPause; // 0
|
||||
uint32 startOpen; // 1
|
||||
uint32 autoClose; // 2
|
||||
} trapDoor;
|
||||
|
||||
// not use for specific field access (only for output with loop by all filed), also this determinate max union size
|
||||
struct // GAMEOBJECT_TYPE_SPELLCASTER
|
||||
@@ -504,14 +511,14 @@ class TRINITY_DLL_SPEC GameObject : public WorldObject
|
||||
void SetSpellId(uint32 id) { m_spellId = id;}
|
||||
uint32 GetSpellId() const { return m_spellId;}
|
||||
void getFishLoot(Loot *loot);
|
||||
GameobjectTypes GetGoType() const { return GameobjectTypes(GetUInt32Value(GAMEOBJECT_TYPE_ID)); }
|
||||
void SetGoType(GameobjectTypes type) { SetUInt32Value(GAMEOBJECT_TYPE_ID, type); }
|
||||
uint32 GetGoState() const { return GetUInt32Value(GAMEOBJECT_STATE); }
|
||||
void SetGoState(uint32 state) { SetUInt32Value(GAMEOBJECT_STATE, state); }
|
||||
uint32 GetGoArtKit() const { return GetUInt32Value(GAMEOBJECT_ARTKIT); }
|
||||
void SetGoArtKit(uint32 artkit);
|
||||
uint32 GetGoAnimProgress() const { return GetUInt32Value(GAMEOBJECT_ANIMPROGRESS); }
|
||||
void SetGoAnimProgress(uint32 animprogress) { SetUInt32Value(GAMEOBJECT_ANIMPROGRESS, animprogress); }
|
||||
GameobjectTypes GetGoType() const { return GameobjectTypes(GetByteValue(GAMEOBJECT_BYTES_1, 1)); }
|
||||
void SetGoType(GameobjectTypes type) { SetByteValue(GAMEOBJECT_BYTES_1, 1, type); }
|
||||
uint8 GetGoState() const { return GetByteValue(GAMEOBJECT_BYTES_1, 0); }
|
||||
void SetGoState(uint8 state) { SetByteValue(GAMEOBJECT_BYTES_1, 0, state); }
|
||||
uint8 GetGoArtKit() const { return GetByteValue(GAMEOBJECT_BYTES_1, 2); }
|
||||
void SetGoArtKit(uint8 artkit) { SetByteValue(GAMEOBJECT_BYTES_1, 2, artkit); }
|
||||
uint8 GetGoAnimProgress() const { return GetByteValue(GAMEOBJECT_BYTES_1, 3); }
|
||||
void SetGoAnimProgress(uint8 animprogress) { SetByteValue(GAMEOBJECT_BYTES_1, 3, animprogress); }
|
||||
|
||||
void Use(Unit* user);
|
||||
|
||||
|
||||
+13
-4
@@ -417,10 +417,14 @@ void PlayerMenu::SendQuestGiverQuestDetails( Quest const *pQuest, uint64 npcGUID
|
||||
}
|
||||
|
||||
data << uint64(npcGUID);
|
||||
data << uint64(0); // wotlk, something todo with quest sharing?
|
||||
data << uint32(pQuest->GetQuestId());
|
||||
data << Title << Details << Objectives;
|
||||
data << Title;
|
||||
data << Details;
|
||||
data << Objectives;
|
||||
data << uint32(ActivateAccept);
|
||||
data << uint32(pQuest->GetSuggestedPlayers());
|
||||
data << uint8(0); // new wotlk
|
||||
|
||||
if (pQuest->HasFlag(QUEST_FLAGS_HIDDEN_REWARDS))
|
||||
{
|
||||
@@ -466,6 +470,7 @@ void PlayerMenu::SendQuestGiverQuestDetails( Quest const *pQuest, uint64 npcGUID
|
||||
data << uint32(pQuest->GetRewSpell()); // reward spell, this spell will display (icon) (casted if RewSpellCast==0)
|
||||
data << uint32(pQuest->GetRewSpellCast()); // casted spell
|
||||
data << uint32(pQuest->GetCharTitleId()); // CharTitleId, new 2.4.0, player gets this title (id from CharTitles)
|
||||
data << uint32(pQuest->GetBonusTalents()); // bonus talents
|
||||
|
||||
data << uint32(QUEST_EMOTE_COUNT);
|
||||
for (uint32 i=0; i < QUEST_EMOTE_COUNT; i++)
|
||||
@@ -542,6 +547,8 @@ void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest )
|
||||
data << uint32(pQuest->GetSrcItemId());
|
||||
data << uint32(pQuest->GetFlags() & 0xFFFF);
|
||||
data << uint32(pQuest->GetCharTitleId()); // CharTitleId, new 2.4.0, player gets this title (id from CharTitles)
|
||||
data << uint32(pQuest->GetPlayersSlain()); // players slain
|
||||
data << uint32(pQuest->GetBonusTalents()); // bonus talents
|
||||
|
||||
int iI;
|
||||
|
||||
@@ -590,13 +597,14 @@ void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest )
|
||||
data << uint32(pQuest->ReqCreatureOrGOCount[iI]);
|
||||
data << uint32(pQuest->ReqItemId[iI]);
|
||||
data << uint32(pQuest->ReqItemCount[iI]);
|
||||
data << uint32(0); // added in WotLK, dunno if offset if correct
|
||||
}
|
||||
|
||||
for (iI = 0; iI < QUEST_OBJECTIVES_COUNT; iI++)
|
||||
data << ObjectiveText[iI];
|
||||
|
||||
pSession->SendPacket( &data );
|
||||
sLog.outDebug( "WORLD: Sent SMSG_QUEST_QUERY_RESPONSE questid=%u",pQuest->GetQuestId() );
|
||||
sLog.outDebug( "WORLD: Sent SMSG_QUEST_QUERY_RESPONSE questid=%u", pQuest->GetQuestId() );
|
||||
}
|
||||
|
||||
void PlayerMenu::SendQuestGiverOfferReward( Quest const* pQuest, uint64 npcGUID, bool EnbleNext )
|
||||
@@ -678,9 +686,10 @@ void PlayerMenu::SendQuestGiverOfferReward( Quest const* pQuest, uint64 npcGUID,
|
||||
data << uint32(0x08); // unused by client?
|
||||
data << uint32(pQuest->GetRewSpell()); // reward spell, this spell will display (icon) (casted if RewSpellCast==0)
|
||||
data << uint32(pQuest->GetRewSpellCast()); // casted spell
|
||||
data << uint32(0x00); // unk, NOT honor
|
||||
data << uint32(0); // unknown
|
||||
data << uint32(pQuest->GetBonusTalents()); // bonus talents
|
||||
pSession->SendPacket( &data );
|
||||
sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_OFFER_REWARD NPCGuid=%u, questid=%u",GUID_LOPART(npcGUID),pQuest->GetQuestId() );
|
||||
sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_OFFER_REWARD NPCGuid=%u, questid=%u", GUID_LOPART(npcGUID), pQuest->GetQuestId() );
|
||||
}
|
||||
|
||||
void PlayerMenu::SendQuestGiverRequestItems( Quest const *pQuest, uint64 npcGUID, bool Completable, bool CloseOnCancel )
|
||||
|
||||
@@ -140,7 +140,7 @@ VisibleNotifier::Notify()
|
||||
// send data at target visibility change (adding to client)
|
||||
for(std::set<WorldObject*>::const_iterator vItr = i_visibleNow.begin(); vItr != i_visibleNow.end(); ++vItr)
|
||||
if((*vItr)!=&i_player && (*vItr)->isType(TYPEMASK_UNIT))
|
||||
i_player.SendAuraDurationsForTarget((Unit*)(*vItr));
|
||||
i_player.SendAurasForTarget((Unit*)(*vItr));
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
+7
-6
@@ -66,24 +66,25 @@ enum GroupUpdateFlags
|
||||
{
|
||||
GROUP_UPDATE_FLAG_NONE = 0x00000000, // nothing
|
||||
GROUP_UPDATE_FLAG_STATUS = 0x00000001, // uint16, flags
|
||||
GROUP_UPDATE_FLAG_CUR_HP = 0x00000002, // uint16
|
||||
GROUP_UPDATE_FLAG_MAX_HP = 0x00000004, // uint16
|
||||
GROUP_UPDATE_FLAG_CUR_HP = 0x00000002, // uint32
|
||||
GROUP_UPDATE_FLAG_MAX_HP = 0x00000004, // uint32
|
||||
GROUP_UPDATE_FLAG_POWER_TYPE = 0x00000008, // uint8
|
||||
GROUP_UPDATE_FLAG_CUR_POWER = 0x00000010, // uint16
|
||||
GROUP_UPDATE_FLAG_MAX_POWER = 0x00000020, // uint16
|
||||
GROUP_UPDATE_FLAG_LEVEL = 0x00000040, // uint16
|
||||
GROUP_UPDATE_FLAG_ZONE = 0x00000080, // uint16
|
||||
GROUP_UPDATE_FLAG_POSITION = 0x00000100, // uint16, uint16
|
||||
GROUP_UPDATE_FLAG_AURAS = 0x00000200, // uint64 mask, for each bit set uint16 spellid + uint8 unk
|
||||
GROUP_UPDATE_FLAG_AURAS = 0x00000200, // uint64 mask, for each bit set uint32 spellid + uint8 unk
|
||||
GROUP_UPDATE_FLAG_PET_GUID = 0x00000400, // uint64 pet guid
|
||||
GROUP_UPDATE_FLAG_PET_NAME = 0x00000800, // pet name, NULL terminated string
|
||||
GROUP_UPDATE_FLAG_PET_MODEL_ID = 0x00001000, // uint16, model id
|
||||
GROUP_UPDATE_FLAG_PET_CUR_HP = 0x00002000, // uint16 pet cur health
|
||||
GROUP_UPDATE_FLAG_PET_MAX_HP = 0x00004000, // uint16 pet max health
|
||||
GROUP_UPDATE_FLAG_PET_CUR_HP = 0x00002000, // uint32 pet cur health
|
||||
GROUP_UPDATE_FLAG_PET_MAX_HP = 0x00004000, // uint32 pet max health
|
||||
GROUP_UPDATE_FLAG_PET_POWER_TYPE = 0x00008000, // uint8 pet power type
|
||||
GROUP_UPDATE_FLAG_PET_CUR_POWER = 0x00010000, // uint16 pet cur power
|
||||
GROUP_UPDATE_FLAG_PET_MAX_POWER = 0x00020000, // uint16 pet max power
|
||||
GROUP_UPDATE_FLAG_PET_AURAS = 0x00040000, // uint64 mask, for each bit set uint16 spellid + uint8 unk, pet auras...
|
||||
GROUP_UPDATE_FLAG_PET_AURAS = 0x00040000, // uint64 mask, for each bit set uint32 spellid + uint8 unk, pet auras...
|
||||
GROUP_UPDATE_FLAG_VEHICLE_SEAT = 0x00080000, // uint32 vehicle_seat_id (index from VehicleSeat.dbc)
|
||||
GROUP_UPDATE_PET = 0x0007FC00, // all pet flags
|
||||
GROUP_UPDATE_FULL = 0x0007FFFF, // all known flags
|
||||
};
|
||||
|
||||
+19
-17
@@ -688,10 +688,10 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke
|
||||
}
|
||||
|
||||
if (mask & GROUP_UPDATE_FLAG_CUR_HP)
|
||||
*data << (uint16) player->GetHealth();
|
||||
*data << (uint32) player->GetHealth();
|
||||
|
||||
if (mask & GROUP_UPDATE_FLAG_MAX_HP)
|
||||
*data << (uint16) player->GetMaxHealth();
|
||||
*data << (uint32) player->GetMaxHealth();
|
||||
|
||||
Powers powerType = player->getPowerType();
|
||||
if (mask & GROUP_UPDATE_FLAG_POWER_TYPE)
|
||||
@@ -720,7 +720,7 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke
|
||||
{
|
||||
if(auramask & (uint64(1) << i))
|
||||
{
|
||||
*data << uint16(player->GetUInt32Value(UNIT_FIELD_AURA + i));
|
||||
*data << uint32(player->GetVisibleAura(i));
|
||||
*data << uint8(1);
|
||||
}
|
||||
}
|
||||
@@ -754,17 +754,17 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke
|
||||
if (mask & GROUP_UPDATE_FLAG_PET_CUR_HP)
|
||||
{
|
||||
if(pet)
|
||||
*data << (uint16) pet->GetHealth();
|
||||
*data << (uint32) pet->GetHealth();
|
||||
else
|
||||
*data << (uint16) 0;
|
||||
*data << (uint32) 0;
|
||||
}
|
||||
|
||||
if (mask & GROUP_UPDATE_FLAG_PET_MAX_HP)
|
||||
{
|
||||
if(pet)
|
||||
*data << (uint16) pet->GetMaxHealth();
|
||||
*data << (uint32) pet->GetMaxHealth();
|
||||
else
|
||||
*data << (uint16) 0;
|
||||
*data << (uint32) 0;
|
||||
}
|
||||
|
||||
if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE)
|
||||
@@ -801,7 +801,7 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke
|
||||
{
|
||||
if(auramask & (uint64(1) << i))
|
||||
{
|
||||
*data << uint16(pet->GetUInt32Value(UNIT_FIELD_AURA + i));
|
||||
*data << uint32(pet->GetVisibleAura(i));
|
||||
*data << uint8(1);
|
||||
}
|
||||
}
|
||||
@@ -824,6 +824,7 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
|
||||
if(!player)
|
||||
{
|
||||
WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2);
|
||||
data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
|
||||
data.appendPackGUID(Guid);
|
||||
data << (uint32) GROUP_UPDATE_FLAG_STATUS;
|
||||
data << (uint16) MEMBER_STATUS_OFFLINE;
|
||||
@@ -834,6 +835,7 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
|
||||
Pet *pet = player->GetPet();
|
||||
|
||||
WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8);
|
||||
data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
|
||||
data.append(player->GetPackGUID());
|
||||
|
||||
uint32 mask1 = 0x00040BFF; // common mask, real flags used 0x000040BFF
|
||||
@@ -843,8 +845,8 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
|
||||
Powers powerType = player->getPowerType();
|
||||
data << (uint32) mask1; // group update mask
|
||||
data << (uint16) MEMBER_STATUS_ONLINE; // member's online status
|
||||
data << (uint16) player->GetHealth(); // GROUP_UPDATE_FLAG_CUR_HP
|
||||
data << (uint16) player->GetMaxHealth(); // GROUP_UPDATE_FLAG_MAX_HP
|
||||
data << (uint32) player->GetHealth(); // GROUP_UPDATE_FLAG_CUR_HP
|
||||
data << (uint32) player->GetMaxHealth(); // GROUP_UPDATE_FLAG_MAX_HP
|
||||
data << (uint8) powerType; // GROUP_UPDATE_FLAG_POWER_TYPE
|
||||
data << (uint16) player->GetPower(powerType); // GROUP_UPDATE_FLAG_CUR_POWER
|
||||
data << (uint16) player->GetMaxPower(powerType); // GROUP_UPDATE_FLAG_MAX_POWER
|
||||
@@ -858,11 +860,11 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
|
||||
data << (uint64) auramask; // placeholder
|
||||
for(uint8 i = 0; i < MAX_AURAS; ++i)
|
||||
{
|
||||
if(uint32 aura = player->GetUInt32Value(UNIT_FIELD_AURA + i))
|
||||
if(uint32 aura = player->GetVisibleAura(i))
|
||||
{
|
||||
auramask |= (uint64(1) << i);
|
||||
data << uint16(aura);
|
||||
data << uint8(1);
|
||||
data << (uint32) aura;
|
||||
data << (uint8) 1;
|
||||
}
|
||||
}
|
||||
data.put<uint64>(maskPos,auramask); // GROUP_UPDATE_FLAG_AURAS
|
||||
@@ -873,8 +875,8 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
|
||||
data << (uint64) pet->GetGUID(); // GROUP_UPDATE_FLAG_PET_GUID
|
||||
data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME
|
||||
data << (uint16) pet->GetDisplayId(); // GROUP_UPDATE_FLAG_PET_MODEL_ID
|
||||
data << (uint16) pet->GetHealth(); // GROUP_UPDATE_FLAG_PET_CUR_HP
|
||||
data << (uint16) pet->GetMaxHealth(); // GROUP_UPDATE_FLAG_PET_MAX_HP
|
||||
data << (uint32) pet->GetHealth(); // GROUP_UPDATE_FLAG_PET_CUR_HP
|
||||
data << (uint32) pet->GetMaxHealth(); // GROUP_UPDATE_FLAG_PET_MAX_HP
|
||||
data << (uint8) petpowertype; // GROUP_UPDATE_FLAG_PET_POWER_TYPE
|
||||
data << (uint16) pet->GetPower(petpowertype); // GROUP_UPDATE_FLAG_PET_CUR_POWER
|
||||
data << (uint16) pet->GetMaxPower(petpowertype); // GROUP_UPDATE_FLAG_PET_MAX_POWER
|
||||
@@ -884,10 +886,10 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
|
||||
data << (uint64) petauramask; // placeholder
|
||||
for(uint8 i = 0; i < MAX_AURAS; ++i)
|
||||
{
|
||||
if(uint32 petaura = pet->GetUInt32Value(UNIT_FIELD_AURA + i))
|
||||
if(uint32 petaura = pet->GetVisibleAura(i))
|
||||
{
|
||||
petauramask |= (uint64(1) << i);
|
||||
data << (uint16) petaura;
|
||||
data << (uint32) petaura;
|
||||
data << (uint8) 1;
|
||||
}
|
||||
}
|
||||
|
||||
+32
-6
@@ -785,6 +785,7 @@ void Guild::Query(WorldSession *session)
|
||||
data << uint32(BorderStyle);
|
||||
data << uint32(BorderColor);
|
||||
data << uint32(BackgroundColor);
|
||||
data << uint32(0); // something new in WotLK
|
||||
|
||||
session->SendPacket( &data );
|
||||
sLog.outDebug( "WORLD: Sent (SMSG_GUILD_QUERY_RESPONSE)" );
|
||||
@@ -1602,7 +1603,21 @@ void Guild::DisplayGuildBankLogs(WorldSession *session, uint8 TabId)
|
||||
{
|
||||
data << uint8((*itr)->LogEntry);
|
||||
data << uint64(MAKE_NEW_GUID((*itr)->PlayerGuid,0,HIGHGUID_PLAYER));
|
||||
data << uint32((*itr)->ItemOrMoney);
|
||||
if ((*itr)->LogEntry == GUILD_BANK_LOG_DEPOSIT_MONEY ||
|
||||
(*itr)->LogEntry == GUILD_BANK_LOG_WITHDRAW_MONEY ||
|
||||
(*itr)->LogEntry == GUILD_BANK_LOG_REPAIR_MONEY ||
|
||||
(*itr)->LogEntry == GUILD_BANK_LOG_UNK1 ||
|
||||
(*itr)->LogEntry == GUILD_BANK_LOG_UNK2)
|
||||
{
|
||||
data << uint32((*itr)->ItemOrMoney);
|
||||
}
|
||||
else
|
||||
{
|
||||
data << uint32((*itr)->ItemOrMoney);
|
||||
data << uint32((*itr)->ItemStackCount);
|
||||
if ((*itr)->LogEntry == GUILD_BANK_LOG_MOVE_ITEM || (*itr)->LogEntry == GUILD_BANK_LOG_MOVE_ITEM2)
|
||||
data << uint8((*itr)->DestTabId); // moved tab
|
||||
}
|
||||
data << uint32(time(NULL)-(*itr)->TimeStamp);
|
||||
}
|
||||
session->SendPacket(&data);
|
||||
@@ -1618,10 +1633,21 @@ void Guild::DisplayGuildBankLogs(WorldSession *session, uint8 TabId)
|
||||
{
|
||||
data << uint8((*itr)->LogEntry);
|
||||
data << uint64(MAKE_NEW_GUID((*itr)->PlayerGuid,0,HIGHGUID_PLAYER));
|
||||
data << uint32((*itr)->ItemOrMoney);
|
||||
data << uint8((*itr)->ItemStackCount);
|
||||
if ((*itr)->LogEntry == GUILD_BANK_LOG_MOVE_ITEM || (*itr)->LogEntry == GUILD_BANK_LOG_MOVE_ITEM2)
|
||||
data << uint8((*itr)->DestTabId); // moved tab
|
||||
if ((*itr)->LogEntry == GUILD_BANK_LOG_DEPOSIT_MONEY ||
|
||||
(*itr)->LogEntry == GUILD_BANK_LOG_WITHDRAW_MONEY ||
|
||||
(*itr)->LogEntry == GUILD_BANK_LOG_REPAIR_MONEY ||
|
||||
(*itr)->LogEntry == GUILD_BANK_LOG_UNK1 ||
|
||||
(*itr)->LogEntry == GUILD_BANK_LOG_UNK2)
|
||||
{
|
||||
data << uint32((*itr)->ItemOrMoney);
|
||||
}
|
||||
else
|
||||
{
|
||||
data << uint32((*itr)->ItemOrMoney);
|
||||
data << uint32((*itr)->ItemStackCount);
|
||||
if ((*itr)->LogEntry == GUILD_BANK_LOG_MOVE_ITEM || (*itr)->LogEntry == GUILD_BANK_LOG_MOVE_ITEM2)
|
||||
data << uint8((*itr)->DestTabId); // moved tab
|
||||
}
|
||||
data << uint32(time(NULL)-(*itr)->TimeStamp);
|
||||
}
|
||||
session->SendPacket(&data);
|
||||
@@ -1703,7 +1729,7 @@ void Guild::AppendDisplayGuildBankSlot( WorldPacket& data, GuildBankTab const *t
|
||||
// SuffixFactor +4
|
||||
data << (uint32) pItem->GetItemSuffixFactor();
|
||||
// +12 // ITEM_FIELD_STACK_COUNT
|
||||
data << uint8(pItem->GetCount());
|
||||
data << uint32(pItem->GetCount());
|
||||
data << uint32(0); // +16 // Unknown value
|
||||
data << uint8(0); // unknown 2.4.2
|
||||
if (uint32 Enchant0 = pItem->GetEnchantmentId(PERM_ENCHANTMENT_SLOT))
|
||||
|
||||
+4
-1
@@ -56,7 +56,8 @@ enum GuildRankRights
|
||||
GR_RIGHT_REPAIR_FROM_GUILD = 0x00020000, // unused in 2.4.x?, Remove money withdraw capacity
|
||||
GR_RIGHT_WITHDRAW_REPAIR = 0x00040000, // withdraw for repair
|
||||
GR_RIGHT_WITHDRAW_GOLD = 0x00080000, // withdraw gold
|
||||
GR_RIGHT_ALL = 0x000FF1FF
|
||||
GR_RIGHT_CREATE_GUILD_EVENT = 0x00100000, // wotlk
|
||||
GR_RIGHT_ALL = 0x001FF1FF
|
||||
};
|
||||
|
||||
enum Typecommand
|
||||
@@ -156,6 +157,8 @@ enum GuildBankLogEntries
|
||||
GUILD_BANK_LOG_WITHDRAW_MONEY = 5,
|
||||
GUILD_BANK_LOG_REPAIR_MONEY = 6,
|
||||
GUILD_BANK_LOG_MOVE_ITEM2 = 7,
|
||||
GUILD_BANK_LOG_UNK1 = 8,
|
||||
GUILD_BANK_LOG_UNK2 = 9,
|
||||
};
|
||||
|
||||
enum GuildEventLogEntryTypes
|
||||
|
||||
+11
-7
@@ -206,6 +206,10 @@ bool ItemCanGoIntoBag(ItemPrototype const *pProto, ItemPrototype const *pBagProt
|
||||
if(!(pProto->BagFamily & BAG_FAMILY_MASK_LEATHERWORKING_SUPP))
|
||||
return false;
|
||||
return true;
|
||||
case ITEM_SUBCLASS_INSCRIPTION_CONTAINER:
|
||||
if(!(pProto->BagFamily & BAG_FAMILY_MASK_INSCRIPTION_SUPP))
|
||||
return false;
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -450,7 +454,7 @@ uint32 Item::GetSkill()
|
||||
|
||||
const static uint32 item_armor_skills[MAX_ITEM_SUBCLASS_ARMOR] =
|
||||
{
|
||||
0,SKILL_CLOTH,SKILL_LEATHER,SKILL_MAIL,SKILL_PLATE_MAIL,0,SKILL_SHIELD,0,0,0
|
||||
0,SKILL_CLOTH,SKILL_LEATHER,SKILL_MAIL,SKILL_PLATE_MAIL,0,SKILL_SHIELD,0,0,0,0
|
||||
};
|
||||
|
||||
ItemPrototype const* proto = GetProto();
|
||||
@@ -765,9 +769,9 @@ void Item::SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint
|
||||
if((GetEnchantmentId(slot) == id) && (GetEnchantmentDuration(slot) == duration) && (GetEnchantmentCharges(slot) == charges))
|
||||
return;
|
||||
|
||||
SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_ID_OFFSET,id);
|
||||
SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET,duration);
|
||||
SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET,charges);
|
||||
SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_ID_OFFSET,id);
|
||||
SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET,duration);
|
||||
SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET,charges);
|
||||
SetState(ITEM_CHANGED);
|
||||
}
|
||||
|
||||
@@ -776,7 +780,7 @@ void Item::SetEnchantmentDuration(EnchantmentSlot slot, uint32 duration)
|
||||
if(GetEnchantmentDuration(slot) == duration)
|
||||
return;
|
||||
|
||||
SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET,duration);
|
||||
SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET,duration);
|
||||
SetState(ITEM_CHANGED);
|
||||
}
|
||||
|
||||
@@ -785,7 +789,7 @@ void Item::SetEnchantmentCharges(EnchantmentSlot slot, uint32 charges)
|
||||
if(GetEnchantmentCharges(slot) == charges)
|
||||
return;
|
||||
|
||||
SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET,charges);
|
||||
SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET,charges);
|
||||
SetState(ITEM_CHANGED);
|
||||
}
|
||||
|
||||
@@ -795,7 +799,7 @@ void Item::ClearEnchantment(EnchantmentSlot slot)
|
||||
return;
|
||||
|
||||
for(uint8 x = 0; x < 3; ++x)
|
||||
SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + x, 0);
|
||||
SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + x, 0);
|
||||
SetState(ITEM_CHANGED);
|
||||
}
|
||||
|
||||
|
||||
+20
-18
@@ -148,29 +148,30 @@ enum SellFailure
|
||||
// -1 from client enchantment slot number
|
||||
enum EnchantmentSlot
|
||||
{
|
||||
PERM_ENCHANTMENT_SLOT = 0,
|
||||
TEMP_ENCHANTMENT_SLOT = 1,
|
||||
SOCK_ENCHANTMENT_SLOT = 2,
|
||||
SOCK_ENCHANTMENT_SLOT_2 = 3,
|
||||
SOCK_ENCHANTMENT_SLOT_3 = 4,
|
||||
BONUS_ENCHANTMENT_SLOT = 5,
|
||||
MAX_INSPECTED_ENCHANTMENT_SLOT = 6,
|
||||
PERM_ENCHANTMENT_SLOT = 0,
|
||||
TEMP_ENCHANTMENT_SLOT = 1,
|
||||
SOCK_ENCHANTMENT_SLOT = 2,
|
||||
SOCK_ENCHANTMENT_SLOT_2 = 3,
|
||||
SOCK_ENCHANTMENT_SLOT_3 = 4,
|
||||
BONUS_ENCHANTMENT_SLOT = 5,
|
||||
WOTLK_ENCHANTMENT_SLOT = 6,
|
||||
MAX_INSPECTED_ENCHANTMENT_SLOT = 7,
|
||||
|
||||
PROP_ENCHANTMENT_SLOT_0 = 6, // used with RandomSuffix
|
||||
PROP_ENCHANTMENT_SLOT_1 = 7, // used with RandomSuffix
|
||||
PROP_ENCHANTMENT_SLOT_2 = 8, // used with RandomSuffix and RandomProperty
|
||||
PROP_ENCHANTMENT_SLOT_3 = 9, // used with RandomProperty
|
||||
PROP_ENCHANTMENT_SLOT_4 = 10, // used with RandomProperty
|
||||
MAX_ENCHANTMENT_SLOT = 11
|
||||
PROP_ENCHANTMENT_SLOT_0 = 7, // used with RandomSuffix
|
||||
PROP_ENCHANTMENT_SLOT_1 = 8, // used with RandomSuffix
|
||||
PROP_ENCHANTMENT_SLOT_2 = 9, // used with RandomSuffix and RandomProperty
|
||||
PROP_ENCHANTMENT_SLOT_3 = 10, // used with RandomProperty
|
||||
PROP_ENCHANTMENT_SLOT_4 = 11, // used with RandomProperty
|
||||
MAX_ENCHANTMENT_SLOT = 12
|
||||
};
|
||||
|
||||
#define MAX_VISIBLE_ITEM_OFFSET 16 // 16 fields per visible item (creator(2) + enchantments(12) + properties(1) + pad(1))
|
||||
#define MAX_VISIBLE_ITEM_OFFSET 18 // 18 fields per visible item (creator(2) + enchantments(13) + properties(1) + seed(1) + pad(1))
|
||||
|
||||
enum EnchantmentOffset
|
||||
{
|
||||
ENCHANTMENT_ID_OFFSET = 0,
|
||||
ENCHANTMENT_DURATION_OFFSET = 1,
|
||||
ENCHANTMENT_CHARGES_OFFSET = 2
|
||||
ENCHANTMENT_CHARGES_OFFSET = 2 // now here not only charges, but something new in wotlk
|
||||
};
|
||||
|
||||
#define MAX_ENCHANTMENT_OFFSET 3
|
||||
@@ -211,6 +212,7 @@ class TRINITY_DLL_SPEC Item : public Object
|
||||
|
||||
void SetBinding(bool val) { ApplyModFlag(ITEM_FIELD_FLAGS,ITEM_FLAGS_BINDED,val); }
|
||||
bool IsSoulBound() const { return HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_BINDED); }
|
||||
bool IsAccountBound() const { return HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_BOA); }
|
||||
bool IsBindedNotWith(uint64 guid) const { return IsSoulBound() && GetOwnerGUID()!= guid; }
|
||||
bool IsBoundByEnchant() const;
|
||||
virtual void SaveToDB();
|
||||
@@ -256,9 +258,9 @@ class TRINITY_DLL_SPEC Item : public Object
|
||||
void SetEnchantmentDuration(EnchantmentSlot slot, uint32 duration);
|
||||
void SetEnchantmentCharges(EnchantmentSlot slot, uint32 charges);
|
||||
void ClearEnchantment(EnchantmentSlot slot);
|
||||
uint32 GetEnchantmentId(EnchantmentSlot slot) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_ID_OFFSET);}
|
||||
uint32 GetEnchantmentDuration(EnchantmentSlot slot) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET);}
|
||||
uint32 GetEnchantmentCharges(EnchantmentSlot slot) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET);}
|
||||
uint32 GetEnchantmentId(EnchantmentSlot slot) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_ID_OFFSET);}
|
||||
uint32 GetEnchantmentDuration(EnchantmentSlot slot) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET);}
|
||||
uint32 GetEnchantmentCharges(EnchantmentSlot slot) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET);}
|
||||
|
||||
void SendTimeUpdate(Player* owner);
|
||||
void UpdateDuration(Player* owner, uint32 diff);
|
||||
|
||||
@@ -324,7 +324,7 @@ void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data )
|
||||
data << pProto->ItemId;
|
||||
data << pProto->Class;
|
||||
data << pProto->SubClass;
|
||||
data << uint32(-1); // new 2.0.3, not exist in wdb cache?
|
||||
data << pProto->Unk0; // new 2.0.3, not exist in wdb cache?
|
||||
data << Name;
|
||||
data << uint8(0x00); //pProto->Name2; // blizz not send name there, just uint8(0x00); <-- \0 = empty string = empty name...
|
||||
data << uint8(0x00); //pProto->Name3; // blizz not send name there, just uint8(0x00);
|
||||
@@ -349,11 +349,14 @@ void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data )
|
||||
data << pProto->MaxCount;
|
||||
data << pProto->Stackable;
|
||||
data << pProto->ContainerSlots;
|
||||
for(int i = 0; i < 10; i++)
|
||||
data << pProto->StatsCount; // item stats count
|
||||
for(int i = 0; i < pProto->StatsCount; i++)
|
||||
{
|
||||
data << pProto->ItemStat[i].ItemStatType;
|
||||
data << pProto->ItemStat[i].ItemStatValue;
|
||||
}
|
||||
data << pProto->ScalingStatDistribution; // scaling stats distribution
|
||||
data << pProto->ScalingStatValue; // some kind of flags used to determine stat values column
|
||||
for(int i = 0; i < 5; i++)
|
||||
{
|
||||
data << pProto->Damage[i].DamageMin;
|
||||
@@ -437,7 +440,8 @@ void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data )
|
||||
data << pProto->GemProperties;
|
||||
data << pProto->RequiredDisenchantSkill;
|
||||
data << pProto->ArmorDamageModifier;
|
||||
data << uint32(0); // added in 2.4.2.8209, duration (seconds)
|
||||
data << pProto->Duration; // added in 2.4.2.8209, duration (seconds)
|
||||
data << pProto->ItemLimitCategory; // WotLK, ItemLimitCategory
|
||||
SendPacket( &data );
|
||||
}
|
||||
else
|
||||
@@ -845,6 +849,7 @@ void WorldSession::HandleBuyBankSlotOpcode(WorldPacket& /*recvPacket*/)
|
||||
if (_player->GetMoney() < price)
|
||||
return;
|
||||
|
||||
_player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT, slot);
|
||||
_player->SetByteValue(PLAYER_BYTES_2, 2, slot);
|
||||
_player->ModifyMoney(-int32(price));
|
||||
}
|
||||
|
||||
+70
-12
@@ -57,10 +57,18 @@ enum ItemModType
|
||||
ITEM_MOD_CRIT_TAKEN_RATING = 34,
|
||||
ITEM_MOD_RESILIENCE_RATING = 35,
|
||||
ITEM_MOD_HASTE_RATING = 36,
|
||||
ITEM_MOD_EXPERTISE_RATING = 37
|
||||
ITEM_MOD_EXPERTISE_RATING = 37,
|
||||
ITEM_MOD_ATTACK_POWER = 38,
|
||||
ITEM_MOD_RANGED_ATTACK_POWER = 39,
|
||||
ITEM_MOD_FERAL_ATTACK_POWER = 40,
|
||||
ITEM_MOD_SPELL_HEALING_DONE = 41,
|
||||
ITEM_MOD_SPELL_DAMAGE_DONE = 42,
|
||||
ITEM_MOD_MANA_REGENERATION = 43,
|
||||
ITEM_MOD_ARMOR_PENETRATION_RATING = 44,
|
||||
ITEM_MOD_SPELL_POWER = 45
|
||||
};
|
||||
|
||||
#define MAX_ITEM_MOD 38
|
||||
#define MAX_ITEM_MOD 46
|
||||
|
||||
enum ItemSpelltriggerType
|
||||
{
|
||||
@@ -185,10 +193,11 @@ enum ItemClass
|
||||
ITEM_CLASS_QUEST = 12,
|
||||
ITEM_CLASS_KEY = 13,
|
||||
ITEM_CLASS_PERMANENT = 14,
|
||||
ITEM_CLASS_JUNK = 15
|
||||
ITEM_CLASS_MISC = 15,
|
||||
ITEM_CLASS_GLYPH = 16
|
||||
};
|
||||
|
||||
#define MAX_ITEM_CLASS 16
|
||||
#define MAX_ITEM_CLASS 17
|
||||
|
||||
enum ItemSubclassConsumable
|
||||
{
|
||||
@@ -214,10 +223,11 @@ enum ItemSubclassContainer
|
||||
ITEM_SUBCLASS_ENGINEERING_CONTAINER = 4,
|
||||
ITEM_SUBCLASS_GEM_CONTAINER = 5,
|
||||
ITEM_SUBCLASS_MINING_CONTAINER = 6,
|
||||
ITEM_SUBCLASS_LEATHERWORKING_CONTAINER = 7
|
||||
ITEM_SUBCLASS_LEATHERWORKING_CONTAINER = 7,
|
||||
ITEM_SUBCLASS_INSCRIPTION_CONTAINER = 8
|
||||
};
|
||||
|
||||
#define MAX_ITEM_SUBCLASS_CONTAINER 8
|
||||
#define MAX_ITEM_SUBCLASS_CONTAINER 9
|
||||
|
||||
enum ItemSubclassWeapon
|
||||
{
|
||||
@@ -272,10 +282,11 @@ enum ItemSubclassArmor
|
||||
ITEM_SUBCLASS_ARMOR_SHIELD = 6,
|
||||
ITEM_SUBCLASS_ARMOR_LIBRAM = 7,
|
||||
ITEM_SUBCLASS_ARMOR_IDOL = 8,
|
||||
ITEM_SUBCLASS_ARMOR_TOTEM = 9
|
||||
ITEM_SUBCLASS_ARMOR_TOTEM = 9,
|
||||
ITEM_SUBCLASS_ARMOR_SIGIL = 10
|
||||
};
|
||||
|
||||
#define MAX_ITEM_SUBCLASS_ARMOR 10
|
||||
#define MAX_ITEM_SUBCLASS_ARMOR 11
|
||||
|
||||
enum ItemSubclassReagent
|
||||
{
|
||||
@@ -310,10 +321,12 @@ enum ItemSubclassTradeGoods
|
||||
ITEM_SUBCLASS_ELEMENTAL = 10,
|
||||
ITEM_SUBCLASS_TRADE_GOODS_OTHER = 11,
|
||||
ITEM_SUBCLASS_ENCHANTING = 12,
|
||||
ITEM_SUBCLASS_MATERIAL = 13 // Added in 2.4.2
|
||||
ITEM_SUBCLASS_MATERIAL = 13,
|
||||
ITEM_SUBCLASS_ARMOR_ENCHANTMENT = 14,
|
||||
ITEM_SUBCLASS_WEAPON_ENCHANTMENT = 15
|
||||
};
|
||||
|
||||
#define MAX_ITEM_SUBCLASS_TRADE_GOODS 14
|
||||
#define MAX_ITEM_SUBCLASS_TRADE_GOODS 16
|
||||
|
||||
enum ItemSubclassGeneric
|
||||
{
|
||||
@@ -423,7 +436,8 @@ const uint32 MaxItemSubclassValues[MAX_ITEM_CLASS] =
|
||||
MAX_ITEM_SUBCLASS_QUEST,
|
||||
MAX_ITEM_SUBCLASS_KEY,
|
||||
MAX_ITEM_SUBCLASS_PERMANENT,
|
||||
MAX_ITEM_SUBCLASS_JUNK
|
||||
MAX_ITEM_SUBCLASS_JUNK,
|
||||
MAX_ITEM_SUBCLASS_GLYPH
|
||||
};
|
||||
|
||||
inline uint8 ItemSubClassToDurabilityMultiplierId(uint32 ItemClass, uint32 ItemSubClass)
|
||||
@@ -500,7 +514,10 @@ struct ItemPrototype
|
||||
uint32 MaxCount;
|
||||
uint32 Stackable;
|
||||
uint32 ContainerSlots;
|
||||
uint32 StatsCount;
|
||||
_ItemStat ItemStat[10];
|
||||
uint32 ScalingStatDistribution; // id from ScalingStatDistribution.dbc
|
||||
uint32 ScalingStatValue; // mask for selecting column in ScalingStatValues.dbc
|
||||
_Damage Damage[5];
|
||||
uint32 Armor;
|
||||
uint32 HolyRes;
|
||||
@@ -536,12 +553,13 @@ struct ItemPrototype
|
||||
uint32 GemProperties; // id from GemProperties.dbc
|
||||
uint32 RequiredDisenchantSkill;
|
||||
float ArmorDamageModifier;
|
||||
int32 Duration; // negative = realtime, positive = ingame time
|
||||
uint32 ItemLimitCategory; // id from ItemLimitCategory.dbc
|
||||
uint32 ScriptId;
|
||||
uint32 DisenchantID;
|
||||
uint32 FoodType;
|
||||
uint32 MinMoneyLoot;
|
||||
uint32 MaxMoneyLoot;
|
||||
int32 Duration; // negative = realtime, positive = ingame time
|
||||
|
||||
// helpers
|
||||
bool CanChangeEquipStateInCombat() const
|
||||
@@ -563,6 +581,46 @@ struct ItemPrototype
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 GetScalingStatValuesColumn() const
|
||||
{
|
||||
if(ScalingStatValue & 0x00000001) // stat mod
|
||||
return 0;
|
||||
if(ScalingStatValue & 0x00000002) // stat mod
|
||||
return 1;
|
||||
if(ScalingStatValue & 0x00000004) // stat mod
|
||||
return 2;
|
||||
if(ScalingStatValue & 0x00000008) // stat mod
|
||||
return 3;
|
||||
if(ScalingStatValue & 0x00000010) // stat mod
|
||||
return 4;
|
||||
if(ScalingStatValue & 0x00000020) // armor mod
|
||||
return 5;
|
||||
if(ScalingStatValue & 0x00000040) // armor mod
|
||||
return 6;
|
||||
if(ScalingStatValue & 0x00000080) // armor mod
|
||||
return 7;
|
||||
if(ScalingStatValue & 0x00000100) // armor mod
|
||||
return 8;
|
||||
if(ScalingStatValue & 0x00000200) // damage mod
|
||||
return 9;
|
||||
if(ScalingStatValue & 0x00000400) // damage mod
|
||||
return 10;
|
||||
if(ScalingStatValue & 0x00000800) // damage mod
|
||||
return 11;
|
||||
if(ScalingStatValue & 0x00001000) // damage mod
|
||||
return 12;
|
||||
if(ScalingStatValue & 0x00002000) // damage mod
|
||||
return 13;
|
||||
if(ScalingStatValue & 0x00004000) // damage mod
|
||||
return 14;
|
||||
if(ScalingStatValue & 0x00008000) // spell power
|
||||
return 15;
|
||||
if(ScalingStatValue & 0x00020000) // feral AP
|
||||
return 16;
|
||||
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct ItemLocale
|
||||
|
||||
@@ -328,6 +328,8 @@ enum TrinityStrings
|
||||
LANG_CREATURE_NOT_FOLLOW_YOU_NOW = 342,
|
||||
LANG_CREATURE_NON_TAMEABLE = 343,
|
||||
LANG_YOU_ALREADY_HAVE_PET = 344,
|
||||
LANG_CUSTOMIZE_PLAYER = 345,
|
||||
LANG_CUSTOMIZE_PLAYER_GUID = 346,
|
||||
// Room for more level 2 345-399 not used
|
||||
|
||||
// level 3 chat
|
||||
|
||||
+154
-5
@@ -950,7 +950,7 @@ bool ChatHandler::HandleNpcDeleteCommand(const char* args)
|
||||
else
|
||||
unit = getSelectedCreature();
|
||||
|
||||
if(!unit || unit->isPet() || unit->isTotem())
|
||||
if(!unit || unit->isPet() || unit->isTotem() || unit->isVehicle())
|
||||
{
|
||||
SendSysMessage(LANG_SELECT_CREATURE);
|
||||
SetSentErrorMessage(true);
|
||||
@@ -1063,8 +1063,8 @@ bool ChatHandler::HandleTurnObjectCommand(const char* args)
|
||||
obj->Relocate(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), o);
|
||||
|
||||
obj->SetFloatValue(GAMEOBJECT_FACING, o);
|
||||
obj->SetFloatValue(GAMEOBJECT_ROTATION+2, rot2);
|
||||
obj->SetFloatValue(GAMEOBJECT_ROTATION+3, rot3);
|
||||
obj->SetFloatValue(GAMEOBJECT_PARENTROTATION+2, rot2);
|
||||
obj->SetFloatValue(GAMEOBJECT_PARENTROTATION+3, rot3);
|
||||
|
||||
map->Add(obj);
|
||||
|
||||
@@ -3213,6 +3213,59 @@ bool ChatHandler::HandleRenameCommand(const char* args)
|
||||
return true;
|
||||
}
|
||||
|
||||
// customize characters
|
||||
bool ChatHandler::HandleCustomizeCommand(const char* args)
|
||||
{
|
||||
Player* target = NULL;
|
||||
uint64 targetGUID = 0;
|
||||
std::string oldname;
|
||||
|
||||
char* px = strtok((char*)args, " ");
|
||||
|
||||
if(px)
|
||||
{
|
||||
oldname = px;
|
||||
|
||||
if(!normalizePlayerName(oldname))
|
||||
{
|
||||
SendSysMessage(LANG_PLAYER_NOT_FOUND);
|
||||
SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
target = objmgr.GetPlayer(oldname.c_str());
|
||||
|
||||
if (!target)
|
||||
targetGUID = objmgr.GetPlayerGUIDByName(oldname);
|
||||
}
|
||||
|
||||
if(!target && !targetGUID)
|
||||
{
|
||||
target = getSelectedPlayer();
|
||||
}
|
||||
|
||||
if(!target && !targetGUID)
|
||||
{
|
||||
SendSysMessage(LANG_PLAYER_NOT_FOUND);
|
||||
SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(target)
|
||||
{
|
||||
PSendSysMessage(LANG_CUSTOMIZE_PLAYER, target->GetName());
|
||||
target->SetAtLoginFlag(AT_LOGIN_CUSTOMIZE);
|
||||
CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", target->GetGUIDLow());
|
||||
}
|
||||
else
|
||||
{
|
||||
PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldname.c_str(), GUID_LOPART(targetGUID));
|
||||
CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", GUID_LOPART(targetGUID));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//spawn go
|
||||
bool ChatHandler::HandleGameObjectCommand(const char* args)
|
||||
{
|
||||
@@ -3840,6 +3893,36 @@ bool ChatHandler::HandleRepairitemsCommand(const char* /*args*/)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChatHandler::HandleWaterwalkCommand(const char* args)
|
||||
{
|
||||
if(!*args)
|
||||
return false;
|
||||
|
||||
Player *player = getSelectedPlayer();
|
||||
|
||||
if(!player)
|
||||
{
|
||||
PSendSysMessage(LANG_NO_CHAR_SELECTED);
|
||||
SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strncmp(args, "on", 3) == 0)
|
||||
player->SetMovement(MOVE_WATER_WALK); // ON
|
||||
else if (strncmp(args, "off", 4) == 0)
|
||||
player->SetMovement(MOVE_LAND_WALK); // OFF
|
||||
else
|
||||
{
|
||||
SendSysMessage(LANG_USE_BOL);
|
||||
return false;
|
||||
}
|
||||
|
||||
PSendSysMessage(LANG_YOU_SET_WATERWALK, args, player->GetName());
|
||||
if(needReportToTarget(player))
|
||||
ChatHandler(player).PSendSysMessage(LANG_YOUR_WATERWALK_SET, args, GetName());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChatHandler::HandleNpcFollowCommand(const char* /*args*/)
|
||||
{
|
||||
Player *player = m_session->GetPlayer();
|
||||
@@ -3896,6 +3979,72 @@ bool ChatHandler::HandleNpcUnFollowCommand(const char* /*args*/)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChatHandler::HandleNpcTameCommand(const char* /*args*/)
|
||||
{
|
||||
Creature *creatureTarget = getSelectedCreature ();
|
||||
if (!creatureTarget || creatureTarget->isPet ())
|
||||
{
|
||||
PSendSysMessage (LANG_SELECT_CREATURE);
|
||||
SetSentErrorMessage (true);
|
||||
return false;
|
||||
}
|
||||
|
||||
Player *player = m_session->GetPlayer ();
|
||||
|
||||
if(player->GetPetGUID ())
|
||||
{
|
||||
SendSysMessage (LANG_YOU_ALREADY_HAVE_PET);
|
||||
SetSentErrorMessage (true);
|
||||
return false;
|
||||
}
|
||||
|
||||
CreatureInfo const* cInfo = creatureTarget->GetCreatureInfo();
|
||||
|
||||
if (!cInfo->isTameable ())
|
||||
{
|
||||
PSendSysMessage (LANG_CREATURE_NON_TAMEABLE,cInfo->Entry);
|
||||
SetSentErrorMessage (true);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Everything looks OK, create new pet
|
||||
Pet* pet = player->CreateTamedPetFrom (creatureTarget);
|
||||
if (!pet)
|
||||
{
|
||||
PSendSysMessage (LANG_CREATURE_NON_TAMEABLE,cInfo->Entry);
|
||||
SetSentErrorMessage (true);
|
||||
return false;
|
||||
}
|
||||
|
||||
// place pet before player
|
||||
float x,y,z;
|
||||
player->GetClosePoint (x,y,z,creatureTarget->GetObjectSize (),CONTACT_DISTANCE);
|
||||
pet->Relocate (x,y,z,M_PI-player->GetOrientation ());
|
||||
|
||||
// set pet to defensive mode by default (some classes can't control controlled pets in fact).
|
||||
pet->GetCharmInfo()->SetReactState(REACT_DEFENSIVE);
|
||||
|
||||
// calculate proper level
|
||||
uint32 level = (creatureTarget->getLevel() < (player->getLevel() - 5)) ? (player->getLevel() - 5) : creatureTarget->getLevel();
|
||||
|
||||
// prepare visual effect for levelup
|
||||
pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1);
|
||||
|
||||
// add to world
|
||||
pet->GetMap()->Add((Creature*)pet);
|
||||
|
||||
// visual effect for levelup
|
||||
pet->SetUInt32Value(UNIT_FIELD_LEVEL, level);
|
||||
|
||||
// caster have pet now
|
||||
player->SetPet(pet);
|
||||
|
||||
pet->SavePetToDB(PET_SAVE_AS_CURRENT);
|
||||
player->PetSpellInitialize();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChatHandler::HandleCreatePetCommand(const char* args)
|
||||
{
|
||||
Player *player = m_session->GetPlayer();
|
||||
@@ -4055,7 +4204,7 @@ bool ChatHandler::HandlePetTpCommand(const char *args)
|
||||
|
||||
uint32 tp = atol(args);
|
||||
|
||||
pet->SetTP(tp);
|
||||
//pet->SetTP(tp);
|
||||
|
||||
PSendSysMessage("Pet's tp changed to %u", tp);
|
||||
return true;
|
||||
@@ -4094,4 +4243,4 @@ bool ChatHandler::HandleActivateObjectCommand(const char *args)
|
||||
PSendSysMessage("Object activated!");
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+31
-46
@@ -299,6 +299,15 @@ bool ChatHandler::HandleReloadLootTemplatesItemCommand(const char*)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChatHandler::HandleReloadLootTemplatesMillingCommand(const char*)
|
||||
{
|
||||
sLog.outString( "Re-Loading Loot Tables... (`milling_loot_template`)" );
|
||||
LoadLootTemplates_Milling();
|
||||
LootTemplates_Milling.CheckLootRefs();
|
||||
SendGlobalSysMessage("DB table `milling_loot_template` reloaded.");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChatHandler::HandleReloadLootTemplatesPickpocketingCommand(const char*)
|
||||
{
|
||||
sLog.outString( "Re-Loading Loot Tables... (`pickpocketing_loot_template`)" );
|
||||
@@ -1741,6 +1750,10 @@ bool ChatHandler::HandleLearnAllMySpellsCommand(const char* /*args*/)
|
||||
if(!spellInfo)
|
||||
continue;
|
||||
|
||||
// skip server-side/triggered spells
|
||||
if(spellInfo->spellLevel==0)
|
||||
continue;
|
||||
|
||||
// skip wrong class/race skills
|
||||
if(!m_session->GetPlayer()->IsSpellFitByClassAndRace(spellInfo->Id))
|
||||
continue;
|
||||
@@ -1749,8 +1762,6 @@ bool ChatHandler::HandleLearnAllMySpellsCommand(const char* /*args*/)
|
||||
if( spellInfo->SpellFamilyName != family)
|
||||
continue;
|
||||
|
||||
//TODO: skip triggered spells
|
||||
|
||||
// skip spells with first rank learned as talent (and all talents then also)
|
||||
uint32 first_rank = spellmgr.GetFirstSpellInChain(spellInfo->Id);
|
||||
if(GetTalentSpellCost(first_rank) > 0 )
|
||||
@@ -3813,36 +3824,6 @@ bool ChatHandler::HandleHoverCommand(const char* args)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChatHandler::HandleWaterwalkCommand(const char* args)
|
||||
{
|
||||
if(!args)
|
||||
return false;
|
||||
|
||||
Player *player = getSelectedPlayer();
|
||||
if(!player)
|
||||
{
|
||||
PSendSysMessage(LANG_NO_CHAR_SELECTED);
|
||||
SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strncmp(args, "on", 3) == 0)
|
||||
player->SetMovement(MOVE_WATER_WALK); // ON
|
||||
else if (strncmp(args, "off", 4) == 0)
|
||||
player->SetMovement(MOVE_LAND_WALK); // OFF
|
||||
else
|
||||
{
|
||||
SendSysMessage(LANG_USE_BOL);
|
||||
return false;
|
||||
}
|
||||
|
||||
PSendSysMessage(LANG_YOU_SET_WATERWALK, args, player->GetName());
|
||||
if(needReportToTarget(player))
|
||||
ChatHandler(player).PSendSysMessage(LANG_YOUR_WATERWALK_SET, args, GetName());
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool ChatHandler::HandleLevelUpCommand(const char* args)
|
||||
{
|
||||
char* px = strtok((char*)args, " ");
|
||||
@@ -4458,7 +4439,7 @@ static bool HandleResetStatsOrLevelHelper(Player* player)
|
||||
|
||||
// set UNIT_FIELD_BYTES_1 to init state but preserve m_form value
|
||||
player->SetUInt32Value(UNIT_FIELD_BYTES_1, unitfield);
|
||||
player->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_UNK3 | UNIT_BYTE2_FLAG_UNK5 );
|
||||
player->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP );
|
||||
player->SetByteValue(UNIT_FIELD_BYTES_2, 3, player->m_form);
|
||||
|
||||
player->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
|
||||
@@ -4503,6 +4484,7 @@ bool ChatHandler::HandleResetLevelCommand(const char * args)
|
||||
player->SetLevel(1);
|
||||
player->InitStatsForLevel(true);
|
||||
player->InitTaxiNodesForLevel();
|
||||
player->InitGlyphsForLevel();
|
||||
player->InitTalentForLevel();
|
||||
player->SetUInt32Value(PLAYER_XP,0);
|
||||
|
||||
@@ -4546,6 +4528,7 @@ bool ChatHandler::HandleResetStatsCommand(const char * args)
|
||||
|
||||
player->InitStatsForLevel(true);
|
||||
player->InitTaxiNodesForLevel();
|
||||
player->InitGlyphsForLevel();
|
||||
player->InitTalentForLevel();
|
||||
|
||||
return true;
|
||||
@@ -6608,30 +6591,27 @@ bool ChatHandler::HandleModifyGenderCommand(const char *args)
|
||||
return false;
|
||||
}
|
||||
|
||||
PlayerInfo const* info = objmgr.GetPlayerInfo(player->getRace(), player->getClass());
|
||||
if(!info)
|
||||
return false;
|
||||
|
||||
char const* gender_str = (char*)args;
|
||||
int gender_len = strlen(gender_str);
|
||||
|
||||
uint32 displayId = player->GetNativeDisplayId();
|
||||
char const* gender_full = NULL;
|
||||
uint32 new_displayId = displayId;
|
||||
Gender gender;
|
||||
|
||||
if(!strncmp(gender_str,"male",gender_len)) // MALE
|
||||
if(!strncmp(gender_str, "male", gender_len)) // MALE
|
||||
{
|
||||
if(player->getGender() == GENDER_MALE)
|
||||
return true;
|
||||
|
||||
gender_full = "male";
|
||||
new_displayId = player->getRace() == RACE_BLOODELF ? displayId+1 : displayId-1;
|
||||
gender = GENDER_MALE;
|
||||
}
|
||||
else if (!strncmp(gender_str,"female",gender_len)) // FEMALE
|
||||
else if (!strncmp(gender_str, "female", gender_len)) // FEMALE
|
||||
{
|
||||
if(player->getGender() == GENDER_FEMALE)
|
||||
return true;
|
||||
|
||||
gender_full = "female";
|
||||
new_displayId = player->getRace() == RACE_BLOODELF ? displayId-1 : displayId+1;
|
||||
gender = GENDER_FEMALE;
|
||||
}
|
||||
else
|
||||
@@ -6643,14 +6623,19 @@ bool ChatHandler::HandleModifyGenderCommand(const char *args)
|
||||
|
||||
// Set gender
|
||||
player->SetByteValue(UNIT_FIELD_BYTES_0, 2, gender);
|
||||
player->SetByteValue(PLAYER_BYTES_3, 0, gender);
|
||||
|
||||
// Change display ID
|
||||
player->SetDisplayId(new_displayId);
|
||||
player->SetNativeDisplayId(new_displayId);
|
||||
player->SetDisplayId(gender ? info->displayId_f : info->displayId_m);
|
||||
player->SetNativeDisplayId(gender ? info->displayId_f : info->displayId_m);
|
||||
|
||||
char const* gender_full = gender ? "female" : "male";
|
||||
|
||||
PSendSysMessage(LANG_YOU_CHANGE_GENDER, player->GetName(), gender_full);
|
||||
|
||||
PSendSysMessage(LANG_YOU_CHANGE_GENDER, player->GetName(),gender_full);
|
||||
if (needReportToTarget(player))
|
||||
ChatHandler(player).PSendSysMessage(LANG_YOUR_GENDER_CHANGED, gender_full,GetName());
|
||||
ChatHandler(player).PSendSysMessage(LANG_YOUR_GENDER_CHANGED, gender_full, GetName());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -154,6 +154,7 @@ void WorldSession::HandleAutostoreLootItemOpcode( WorldPacket & recv_data )
|
||||
--loot->unlootedCount;
|
||||
|
||||
player->SendNewItem(newitem, uint32(item->count), false, false, true);
|
||||
player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item->itemid, item->count);
|
||||
}
|
||||
else
|
||||
player->SendEquipError( msg, NULL, NULL );
|
||||
@@ -326,7 +327,7 @@ void WorldSession::DoLootRelease( uint64 lguid )
|
||||
int32 ReqValue = 175;
|
||||
LockEntry const *lockInfo = sLockStore.LookupEntry(go->GetGOInfo()->chest.lockId);
|
||||
if(lockInfo)
|
||||
ReqValue = lockInfo->requiredminingskill;
|
||||
ReqValue = lockInfo->Skill[0];
|
||||
float skill = float(player->GetSkillValue(SKILL_MINING))/(ReqValue+25);
|
||||
double chance = pow(0.8*chance_rate,4*(1/double(max_amount))*double(uses));
|
||||
if(roll_chance_f(100*chance+skill))
|
||||
@@ -495,6 +496,7 @@ void WorldSession::HandleLootMasterGiveOpcode( WorldPacket & recv_data )
|
||||
// not move item from loot to target inventory
|
||||
Item * newitem = target->StoreNewItem( dest, item.itemid, true, item.randomPropertyId );
|
||||
target->SendNewItem(newitem, uint32(item.count), false, false, true );
|
||||
target->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item.itemid, item.count);
|
||||
|
||||
// mark as looted
|
||||
item.count=0;
|
||||
|
||||
@@ -41,6 +41,7 @@ LootStore LootTemplates_Disenchant( "disenchant_loot_template", "item disenc
|
||||
LootStore LootTemplates_Fishing( "fishing_loot_template", "area id");
|
||||
LootStore LootTemplates_Gameobject( "gameobject_loot_template", "gameobject entry");
|
||||
LootStore LootTemplates_Item( "item_loot_template", "item entry");
|
||||
LootStore LootTemplates_Milling( "milling_loot_template", "item entry");
|
||||
LootStore LootTemplates_Pickpocketing("pickpocketing_loot_template","creature pickpocket lootid");
|
||||
LootStore LootTemplates_Prospecting( "prospecting_loot_template", "item entry");
|
||||
LootStore LootTemplates_QuestMail( "quest_mail_loot_template", "quest id");
|
||||
@@ -1138,6 +1139,21 @@ void LoadLootTemplates_Item()
|
||||
LootTemplates_Item.ReportUnusedIds(ids_set);
|
||||
}
|
||||
|
||||
void LoadLootTemplates_Milling()
|
||||
{
|
||||
LootIdSet ids_set;
|
||||
LootTemplates_Milling.LoadAndCollectLootIds(ids_set);
|
||||
|
||||
// remove real entries and check existence loot
|
||||
for(uint32 i = 1; i < sItemStorage.MaxEntry; ++i )
|
||||
if(ItemPrototype const* proto = sItemStorage.LookupEntry<ItemPrototype>(i))
|
||||
if(ids_set.count(proto->ItemId))
|
||||
ids_set.erase(proto->ItemId);
|
||||
|
||||
// output error for any still listed (not referenced from appropriate table) ids
|
||||
LootTemplates_Milling.ReportUnusedIds(ids_set);
|
||||
}
|
||||
|
||||
void LoadLootTemplates_Pickpocketing()
|
||||
{
|
||||
LootIdSet ids_set, ids_setUsed;
|
||||
@@ -1230,6 +1246,7 @@ void LoadLootTemplates_Reference()
|
||||
LootTemplates_Fishing.CheckLootRefs(&ids_set);
|
||||
LootTemplates_Gameobject.CheckLootRefs(&ids_set);
|
||||
LootTemplates_Item.CheckLootRefs(&ids_set);
|
||||
LootTemplates_Milling.CheckLootRefs(&ids_set);
|
||||
LootTemplates_Pickpocketing.CheckLootRefs(&ids_set);
|
||||
LootTemplates_Skinning.CheckLootRefs(&ids_set);
|
||||
LootTemplates_Disenchant.CheckLootRefs(&ids_set);
|
||||
|
||||
@@ -297,6 +297,7 @@ extern LootStore LootTemplates_Creature;
|
||||
extern LootStore LootTemplates_Fishing;
|
||||
extern LootStore LootTemplates_Gameobject;
|
||||
extern LootStore LootTemplates_Item;
|
||||
extern LootStore LootTemplates_Milling;
|
||||
extern LootStore LootTemplates_Pickpocketing;
|
||||
extern LootStore LootTemplates_Skinning;
|
||||
extern LootStore LootTemplates_Disenchant;
|
||||
@@ -307,6 +308,7 @@ void LoadLootTemplates_Creature();
|
||||
void LoadLootTemplates_Fishing();
|
||||
void LoadLootTemplates_Gameobject();
|
||||
void LoadLootTemplates_Item();
|
||||
void LoadLootTemplates_Milling();
|
||||
void LoadLootTemplates_Pickpocketing();
|
||||
void LoadLootTemplates_Skinning();
|
||||
void LoadLootTemplates_Disenchant();
|
||||
@@ -320,6 +322,7 @@ inline void LoadLootTables()
|
||||
LoadLootTemplates_Fishing();
|
||||
LoadLootTemplates_Gameobject();
|
||||
LoadLootTemplates_Item();
|
||||
LoadLootTemplates_Milling();
|
||||
LoadLootTemplates_Pickpocketing();
|
||||
LoadLootTemplates_Skinning();
|
||||
LoadLootTemplates_Disenchant();
|
||||
|
||||
+5
-3
@@ -593,7 +593,7 @@ void WorldSession::HandleGetMail(WorldPacket & recv_data )
|
||||
data << (uint32) (*itr)->mailTemplateId; // mail template (MailTemplate.dbc)
|
||||
data << (*itr)->subject; // Subject string - once 00, when mail type = 3
|
||||
|
||||
data << (uint8) item_count;
|
||||
data << (uint8) item_count; // client limit is 0x10
|
||||
|
||||
for(uint8 i = 0; i < item_count; ++i)
|
||||
{
|
||||
@@ -604,7 +604,7 @@ void WorldSession::HandleGetMail(WorldPacket & recv_data )
|
||||
data << (uint32) (item ? item->GetGUIDLow() : 0);
|
||||
// entry
|
||||
data << (uint32) (item ? item->GetEntry() : 0);
|
||||
for(uint8 j = 0; j < 6; ++j)
|
||||
for(uint8 j = 0; j < 7; ++j)
|
||||
{
|
||||
// unsure
|
||||
data << (uint32) (item ? item->GetEnchantmentCharges((EnchantmentSlot)j) : 0);
|
||||
@@ -618,13 +618,15 @@ void WorldSession::HandleGetMail(WorldPacket & recv_data )
|
||||
// unk
|
||||
data << (uint32) (item ? item->GetItemSuffixFactor() : 0);
|
||||
// stack count
|
||||
data << (uint8) (item ? item->GetCount() : 0);
|
||||
data << (uint32) (item ? item->GetCount() : 0);
|
||||
// charges
|
||||
data << (uint32) (item ? item->GetSpellCharges() : 0);
|
||||
// durability
|
||||
data << (uint32) (item ? item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY) : 0);
|
||||
// durability
|
||||
data << (uint32) (item ? item->GetUInt32Value(ITEM_FIELD_DURABILITY) : 0);
|
||||
// unknown wotlk
|
||||
data << (uint8) 0;
|
||||
}
|
||||
|
||||
mails_count += 1;
|
||||
|
||||
@@ -28,6 +28,7 @@ AM_CPPFLAGS =
|
||||
# later.
|
||||
noinst_LIBRARIES = libgame.a
|
||||
|
||||
<<<<<<< HEAD:src/game/Makefile.am
|
||||
libgame_a_CPPFLAGS = \
|
||||
$(MYSQL_INCLUDES) \
|
||||
$(POSTGRE_INCLUDES) \
|
||||
@@ -36,6 +37,258 @@ $(TRINI_INCLUDES) \
|
||||
-I$(top_srcdir)/src/framework \
|
||||
-I$(top_srcdir)/src/shared \
|
||||
-I$(top_srcdir)/src/shared/vmap
|
||||
=======
|
||||
# libmangossgame library will later be reused by ...
|
||||
libmangosgame_a_SOURCES = \
|
||||
AccountMgr.cpp \
|
||||
AccountMgr.h \
|
||||
AchievementMgr.h \
|
||||
AchievementMgr.cpp \
|
||||
AddonHandler.cpp \
|
||||
AddonHandler.h \
|
||||
AggressorAI.cpp \
|
||||
AggressorAI.h \
|
||||
AnimalRandomMovementGenerator.h \
|
||||
ArenaTeam.cpp \
|
||||
ArenaTeam.h \
|
||||
ArenaTeamHandler.cpp \
|
||||
AuctionHouse.cpp \
|
||||
AuctionHouseObject.h \
|
||||
Bag.cpp \
|
||||
Bag.h \
|
||||
BattleGround.cpp \
|
||||
BattleGroundAA.cpp \
|
||||
BattleGroundAB.cpp \
|
||||
BattleGroundAV.cpp \
|
||||
BattleGroundBE.cpp \
|
||||
BattleGroundEY.cpp \
|
||||
BattleGroundNA.cpp \
|
||||
BattleGroundRL.cpp \
|
||||
BattleGroundWS.cpp \
|
||||
BattleGround.h \
|
||||
BattleGroundAA.h \
|
||||
BattleGroundAB.h \
|
||||
BattleGroundAV.h \
|
||||
BattleGroundBE.h \
|
||||
BattleGroundEY.h \
|
||||
BattleGroundNA.h \
|
||||
BattleGroundRL.h \
|
||||
BattleGroundWS.h \
|
||||
BattleGroundHandler.cpp \
|
||||
BattleGroundMgr.cpp \
|
||||
BattleGroundMgr.h \
|
||||
Calendar.cpp \
|
||||
Calendar.h \
|
||||
CalendarHandler.cpp \
|
||||
Cell.h \
|
||||
CellImpl.h \
|
||||
Channel.cpp \
|
||||
Channel.h \
|
||||
ChannelHandler.cpp \
|
||||
ChannelMgr.h \
|
||||
CharacterHandler.cpp \
|
||||
Chat.cpp \
|
||||
Chat.h \
|
||||
ChatHandler.cpp \
|
||||
CombatHandler.cpp \
|
||||
ConfusedMovementGenerator.cpp \
|
||||
ConfusedMovementGenerator.h \
|
||||
Corpse.cpp \
|
||||
Corpse.h \
|
||||
CreatureAI.cpp \
|
||||
CreatureAI.h \
|
||||
CreatureAIImpl.h \
|
||||
CreatureAIRegistry.cpp \
|
||||
CreatureAIRegistry.h \
|
||||
CreatureAISelector.cpp \
|
||||
CreatureAISelector.h \
|
||||
Creature.cpp \
|
||||
Creature.h \
|
||||
debugcmds.cpp \
|
||||
DestinationHolder.cpp \
|
||||
DestinationHolder.h \
|
||||
DestinationHolderImp.h \
|
||||
DuelHandler.cpp \
|
||||
DynamicObject.cpp \
|
||||
DynamicObject.h \
|
||||
FleeingMovementGenerator.cpp \
|
||||
FleeingMovementGenerator.h \
|
||||
Formulas.h \
|
||||
GameEvent.cpp \
|
||||
GameEvent.h \
|
||||
GameObject.cpp \
|
||||
GameObject.h \
|
||||
GlobalEvents.cpp \
|
||||
GlobalEvents.h \
|
||||
GMTicketHandler.cpp \
|
||||
GMTicketMgr.cpp \
|
||||
GMTicketMgr.h \
|
||||
GossipDef.cpp \
|
||||
GossipDef.h \
|
||||
GridDefines.h \
|
||||
GridNotifiers.cpp \
|
||||
GridNotifiers.h \
|
||||
GridNotifiersImpl.h \
|
||||
GridStates.cpp \
|
||||
GridStates.h \
|
||||
Group.cpp \
|
||||
Group.h \
|
||||
GroupHandler.cpp \
|
||||
GuardAI.cpp \
|
||||
GuardAI.h \
|
||||
Guild.cpp \
|
||||
Guild.h \
|
||||
GuildHandler.cpp \
|
||||
HomeMovementGenerator.cpp \
|
||||
HomeMovementGenerator.h \
|
||||
HostilRefManager.cpp \
|
||||
HostilRefManager.h \
|
||||
IdleMovementGenerator.cpp \
|
||||
IdleMovementGenerator.h \
|
||||
InstanceData.cpp \
|
||||
InstanceData.h \
|
||||
InstanceSaveMgr.cpp \
|
||||
InstanceSaveMgr.h \
|
||||
Item.cpp \
|
||||
Item.h \
|
||||
ItemEnchantmentMgr.cpp \
|
||||
ItemEnchantmentMgr.h \
|
||||
ItemHandler.cpp \
|
||||
ItemPrototype.h \
|
||||
Language.h \
|
||||
Level0.cpp \
|
||||
Level1.cpp \
|
||||
Level2.cpp \
|
||||
Level3.cpp \
|
||||
LFGHandler.cpp \
|
||||
LootHandler.cpp \
|
||||
LootMgr.cpp \
|
||||
LootMgr.h \
|
||||
Mail.cpp \
|
||||
Mail.h \
|
||||
Map.cpp \
|
||||
Map.h \
|
||||
MapInstanced.cpp \
|
||||
MapInstanced.h \
|
||||
MapManager.cpp \
|
||||
MapManager.h \
|
||||
MapReference.h \
|
||||
MapRefManager.h \
|
||||
MiscHandler.cpp \
|
||||
MotionMaster.cpp \
|
||||
MotionMaster.h \
|
||||
MovementGenerator.cpp \
|
||||
MovementGenerator.h \
|
||||
MovementGeneratorImpl.h \
|
||||
MovementHandler.cpp \
|
||||
NPCHandler.cpp \
|
||||
NPCHandler.h \
|
||||
NullCreatureAI.cpp \
|
||||
NullCreatureAI.h \
|
||||
ObjectAccessor.cpp \
|
||||
ObjectAccessor.h \
|
||||
Object.cpp \
|
||||
ObjectDefines.h \
|
||||
ObjectGridLoader.cpp \
|
||||
ObjectGridLoader.h \
|
||||
Object.h \
|
||||
ObjectMgr.cpp \
|
||||
ObjectMgr.h \
|
||||
ObjectPosSelector.cpp \
|
||||
ObjectPosSelector.h \
|
||||
Opcodes.cpp \
|
||||
Opcodes.h \
|
||||
Path.h \
|
||||
PetAI.cpp \
|
||||
PetAI.h \
|
||||
Pet.cpp \
|
||||
Pet.h \
|
||||
PetHandler.cpp \
|
||||
PetitionsHandler.cpp \
|
||||
Player.cpp \
|
||||
Player.h \
|
||||
PlayerDump.cpp \
|
||||
PlayerDump.h \
|
||||
PointMovementGenerator.cpp \
|
||||
PointMovementGenerator.h \
|
||||
QueryHandler.cpp \
|
||||
QuestDef.cpp \
|
||||
QuestDef.h \
|
||||
QuestHandler.cpp \
|
||||
RandomMovementGenerator.cpp \
|
||||
RandomMovementGenerator.h \
|
||||
ReactorAI.cpp \
|
||||
ReactorAI.h \
|
||||
ScriptCalls.cpp \
|
||||
ScriptCalls.h \
|
||||
SharedDefines.h \
|
||||
SkillHandler.cpp \
|
||||
SpellAuraDefines.h \
|
||||
SpellAuras.cpp \
|
||||
SpellAuras.h \
|
||||
Spell.cpp \
|
||||
SpellEffects.cpp \
|
||||
Spell.h \
|
||||
SkillDiscovery.cpp \
|
||||
SkillDiscovery.h \
|
||||
SkillExtraItems.cpp \
|
||||
SkillExtraItems.h \
|
||||
SpellHandler.cpp \
|
||||
SocialMgr.cpp \
|
||||
SocialMgr.h \
|
||||
SpellMgr.cpp \
|
||||
SpellMgr.h \
|
||||
StatSystem.cpp \
|
||||
TargetedMovementGenerator.cpp \
|
||||
TargetedMovementGenerator.h \
|
||||
TaxiHandler.cpp \
|
||||
TemporarySummon.cpp \
|
||||
TemporarySummon.h \
|
||||
tools.cpp \
|
||||
Tools.h \
|
||||
TotemAI.cpp \
|
||||
TotemAI.h \
|
||||
Totem.cpp \
|
||||
Totem.h \
|
||||
TradeHandler.cpp \
|
||||
Transports.cpp \
|
||||
Transports.h \
|
||||
ThreatManager.cpp \
|
||||
ThreatManager.h \
|
||||
Traveller.h \
|
||||
Unit.cpp \
|
||||
Unit.h \
|
||||
UnitEvents.h \
|
||||
UpdateData.cpp \
|
||||
UpdateData.h \
|
||||
UpdateFields.h \
|
||||
UpdateMask.h \
|
||||
Vehicle.cpp \
|
||||
Vehicle.h \
|
||||
VoiceChatHandler.cpp \
|
||||
WaypointManager.cpp \
|
||||
WaypointManager.h \
|
||||
WaypointMovementGenerator.cpp \
|
||||
WaypointMovementGenerator.h \
|
||||
Weather.cpp \
|
||||
Weather.h \
|
||||
World.cpp \
|
||||
World.h \
|
||||
WorldLog.cpp \
|
||||
WorldLog.h \
|
||||
WorldSession.cpp \
|
||||
WorldSession.h \
|
||||
WorldSocket.cpp \
|
||||
WorldSocket.h \
|
||||
WorldSocketMgr.cpp \
|
||||
WorldSocketMgr.h \
|
||||
FollowerReference.cpp \
|
||||
FollowerReference.h \
|
||||
FollowerRefManager.h \
|
||||
GroupReference.cpp \
|
||||
GroupReference.h \
|
||||
GroupRefManager.h
|
||||
>>>>>>> upstream/master:src/game/Makefile.am
|
||||
|
||||
# libmangossgame library will later be reused by ...
|
||||
libgame_a_SOURCES = \
|
||||
|
||||
+3
-3
@@ -45,7 +45,7 @@
|
||||
#define MAX_GRID_LOAD_TIME 50
|
||||
|
||||
// magic *.map header
|
||||
const char MAP_MAGIC[] = "MAP_2.00";
|
||||
const char MAP_MAGIC[] = "MAP_2.01";
|
||||
|
||||
GridState* si_GridStates[MAX_GRID_STATE];
|
||||
|
||||
@@ -257,7 +257,7 @@ template<>
|
||||
void Map::AddToGrid(Creature* obj, NGridType *grid, Cell const& cell)
|
||||
{
|
||||
// add to world object registry in grid
|
||||
if(obj->isPet() || obj->isPossessedByPlayer())
|
||||
if(obj->isPet() || obj->isPossessedByPlayer() || obj->isVehicle())
|
||||
{
|
||||
(*grid)(cell.CellX(), cell.CellY()).AddWorldObject<Creature>(obj, obj->GetGUID());
|
||||
obj->SetCurrentCell(cell);
|
||||
@@ -301,7 +301,7 @@ template<>
|
||||
void Map::RemoveFromGrid(Creature* obj, NGridType *grid, Cell const& cell)
|
||||
{
|
||||
// remove from world object registry in grid
|
||||
if(obj->isPet() || obj->isPossessedByPlayer())
|
||||
if(obj->isPet() || obj->isPossessedByPlayer() || obj->isVehicle())
|
||||
{
|
||||
(*grid)(cell.CellX(), cell.CellY()).RemoveWorldObject<Creature>(obj, obj->GetGUID());
|
||||
}
|
||||
|
||||
@@ -224,6 +224,17 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O
|
||||
bool IsBattleGround() const { return i_mapEntry && i_mapEntry->IsBattleGround(); }
|
||||
bool IsBattleArena() const { return i_mapEntry && i_mapEntry->IsBattleArena(); }
|
||||
bool IsBattleGroundOrArena() const { return i_mapEntry && i_mapEntry->IsBattleGroundOrArena(); }
|
||||
bool GetEntrancePos(int32 &mapid, float &x, float &y)
|
||||
{
|
||||
if(!i_mapEntry)
|
||||
return false;
|
||||
if(i_mapEntry->entrance_map < 0)
|
||||
return false;
|
||||
mapid = i_mapEntry->entrance_map;
|
||||
x = i_mapEntry->entrance_x;
|
||||
y = i_mapEntry->entrance_y;
|
||||
return true;
|
||||
}
|
||||
|
||||
void AddObjectToRemoveList(WorldObject *obj);
|
||||
void DoDelayedMovesAndRemoves();
|
||||
|
||||
@@ -175,7 +175,8 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player)
|
||||
//The player has a heroic mode and tries to enter into instance which has no a heroic mode
|
||||
if (!entry->SupportsHeroicMode() && player->GetDifficulty() == DIFFICULTY_HEROIC)
|
||||
{
|
||||
player->SendTransferAborted(mapid, TRANSFER_ABORT_DIFFICULTY2); //Send aborted message
|
||||
//Send aborted message
|
||||
player->SendTransferAborted(mapid, TRANSFER_ABORT_DIFFICULTY, DIFFICULTY_HEROIC);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -280,7 +281,8 @@ bool MapManager::ExistMapAndVMap(uint32 mapid, float x,float y)
|
||||
bool MapManager::IsValidMAP(uint32 mapid)
|
||||
{
|
||||
MapEntry const* mEntry = sMapStore.LookupEntry(mapid);
|
||||
return mEntry && (!mEntry->Instanceable() || objmgr.GetInstanceTemplate(mapid));
|
||||
return mEntry && (!mEntry->IsDungeon() || objmgr.GetInstanceTemplate(mapid));
|
||||
// TODO: add check for battleground template
|
||||
}
|
||||
|
||||
void MapManager::LoadGrid(int mapid, float x, float y, const WorldObject* obj, bool no_unload)
|
||||
|
||||
+121
-29
@@ -45,6 +45,7 @@
|
||||
#include "Pet.h"
|
||||
#include "SocialMgr.h"
|
||||
#include "CellImpl.h"
|
||||
#include "Tools.h"
|
||||
|
||||
void WorldSession::HandleRepopRequestOpcode( WorldPacket & /*recv_data*/ )
|
||||
{
|
||||
@@ -312,7 +313,7 @@ void WorldSession::HandleLogoutRequestOpcode( WorldPacket & /*recv_data*/ )
|
||||
data.append(GetPlayer()->GetPackGUID());
|
||||
data << (uint32)2;
|
||||
SendPacket( &data );
|
||||
GetPlayer()->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE);
|
||||
GetPlayer()->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
|
||||
}
|
||||
|
||||
WorldPacket data( SMSG_LOGOUT_RESPONSE, 5 );
|
||||
@@ -349,7 +350,7 @@ void WorldSession::HandleLogoutCancelOpcode( WorldPacket & /*recv_data*/ )
|
||||
GetPlayer()->SetStandState(PLAYER_STATE_NONE);
|
||||
|
||||
//! DISABLE_ROTATE
|
||||
GetPlayer()->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE);
|
||||
GetPlayer()->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
|
||||
}
|
||||
|
||||
sLog.outDebug( "WORLD: sent SMSG_LOGOUT_CANCEL_ACK Message" );
|
||||
@@ -363,10 +364,12 @@ void WorldSession::HandleTogglePvP( WorldPacket & recv_data )
|
||||
bool newPvPStatus;
|
||||
recv_data >> newPvPStatus;
|
||||
GetPlayer()->ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP, newPvPStatus);
|
||||
GetPlayer()->ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_PVP_TIMER, !newPvPStatus);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetPlayer()->ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP);
|
||||
GetPlayer()->ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_PVP_TIMER);
|
||||
}
|
||||
|
||||
if(GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP))
|
||||
@@ -882,7 +885,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data)
|
||||
if(missingItem)
|
||||
SendAreaTriggerMessage(GetTrinityString(LANG_LEVEL_MINREQUIRED_AND_ITEM), at->requiredLevel, objmgr.GetItemPrototype(missingItem)->Name1);
|
||||
else if(missingKey)
|
||||
GetPlayer()->SendTransferAborted(at->target_mapId, TRANSFER_ABORT_DIFFICULTY2);
|
||||
GetPlayer()->SendTransferAborted(at->target_mapId, TRANSFER_ABORT_DIFFICULTY, DIFFICULTY_HEROIC);
|
||||
else if(missingQuest)
|
||||
SendAreaTriggerMessage(at->requiredFailedText.c_str());
|
||||
else if(missingLevel)
|
||||
@@ -894,16 +897,96 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data)
|
||||
GetPlayer()->TeleportTo(at->target_mapId,at->target_X,at->target_Y,at->target_Z,at->target_Orientation,TELE_TO_NOT_LEAVE_TRANSPORT);
|
||||
}
|
||||
|
||||
void WorldSession::HandleUpdateAccountData(WorldPacket &/*recv_data*/)
|
||||
void WorldSession::HandleUpdateAccountData(WorldPacket &recv_data)
|
||||
{
|
||||
sLog.outDetail("WORLD: Received CMSG_UPDATE_ACCOUNT_DATA");
|
||||
//recv_data.hexlike();
|
||||
|
||||
CHECK_PACKET_SIZE(recv_data, 4+4+4);
|
||||
|
||||
uint32 type, timestamp, decompressedSize;
|
||||
recv_data >> type >> timestamp >> decompressedSize;
|
||||
|
||||
sLog.outDebug("UAD: type %u, time %u, decompressedSize %u", type, timestamp, decompressedSize);
|
||||
|
||||
if(type > NUM_ACCOUNT_DATA_TYPES)
|
||||
return;
|
||||
|
||||
if(decompressedSize == 0) // erase
|
||||
{
|
||||
SetAccountData(type, timestamp, "");
|
||||
|
||||
WorldPacket data(SMSG_UPDATE_ACCOUNT_DATA_COMPLETE, 4+4);
|
||||
data << uint32(type);
|
||||
data << uint32(0);
|
||||
SendPacket(&data);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(decompressedSize > 0xFFFF)
|
||||
{
|
||||
sLog.outError("UAD: Account data packet too big, size %u", decompressedSize);
|
||||
return;
|
||||
}
|
||||
|
||||
ByteBuffer dest;
|
||||
dest.resize(decompressedSize);
|
||||
|
||||
uLongf realSize = decompressedSize;
|
||||
if(uncompress(const_cast<uint8*>(dest.contents()), &realSize, const_cast<uint8*>(recv_data.contents() + recv_data.rpos()), recv_data.size() - recv_data.rpos()) != Z_OK)
|
||||
{
|
||||
sLog.outError("UAD: Failed to decompress account data");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string adata;
|
||||
dest >> adata;
|
||||
|
||||
SetAccountData(type, timestamp, adata);
|
||||
|
||||
WorldPacket data(SMSG_UPDATE_ACCOUNT_DATA_COMPLETE, 4+4);
|
||||
data << uint32(type);
|
||||
data << uint32(0);
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::HandleRequestAccountData(WorldPacket& /*recv_data*/)
|
||||
void WorldSession::HandleRequestAccountData(WorldPacket& recv_data)
|
||||
{
|
||||
sLog.outDetail("WORLD: Received CMSG_REQUEST_ACCOUNT_DATA");
|
||||
//recv_data.hexlike();
|
||||
|
||||
CHECK_PACKET_SIZE(recv_data, 4);
|
||||
|
||||
uint32 type;
|
||||
recv_data >> type;
|
||||
|
||||
sLog.outDebug("RAD: type %u", type);
|
||||
|
||||
if(type > NUM_ACCOUNT_DATA_TYPES)
|
||||
return;
|
||||
|
||||
AccountData *adata = GetAccountData(type);
|
||||
|
||||
uint32 size = adata->Data.size();
|
||||
|
||||
ByteBuffer dest;
|
||||
dest.resize(size);
|
||||
|
||||
uLongf destSize = size;
|
||||
if(compress(const_cast<uint8*>(dest.contents()), &destSize, (uint8*)adata->Data.c_str(), size) != Z_OK)
|
||||
{
|
||||
sLog.outDebug("RAD: Failed to compress account data");
|
||||
return;
|
||||
}
|
||||
|
||||
dest.resize(destSize);
|
||||
|
||||
WorldPacket data (SMSG_UPDATE_ACCOUNT_DATA, 8+4+4+4+destSize);
|
||||
data << uint64(_player->GetGUID()); // player guid
|
||||
data << uint32(type); // type (0-7)
|
||||
data << uint32(adata->Time); // unix time
|
||||
data << uint32(size); // decompressed length
|
||||
data.append(dest); // compressed data
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::HandleSetActionButtonOpcode(WorldPacket& recv_data)
|
||||
@@ -1434,11 +1517,11 @@ void WorldSession::HandleChooseTitleOpcode( WorldPacket & recv_data )
|
||||
GetPlayer()->SetUInt32Value(PLAYER_CHOSEN_TITLE, title);
|
||||
}
|
||||
|
||||
void WorldSession::HandleAllowMoveAckOpcode( WorldPacket & recv_data )
|
||||
void WorldSession::HandleTimeSyncResp( WorldPacket & recv_data )
|
||||
{
|
||||
CHECK_PACKET_SIZE(recv_data, 4+4);
|
||||
|
||||
sLog.outDebug("CMSG_ALLOW_MOVE_ACK");
|
||||
sLog.outDebug("CMSG_TIME_SYNC_RESP");
|
||||
|
||||
uint32 counter, time_;
|
||||
recv_data >> counter >> time_;
|
||||
@@ -1508,26 +1591,6 @@ void WorldSession::HandleDungeonDifficultyOpcode( WorldPacket & recv_data )
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::HandleNewUnknownOpcode( WorldPacket & recv_data )
|
||||
{
|
||||
sLog.outDebug("New Unknown Opcode %u", recv_data.GetOpcode());
|
||||
recv_data.hexlike();
|
||||
/*
|
||||
New Unknown Opcode 837
|
||||
STORAGE_SIZE: 60
|
||||
02 00 00 00 00 00 00 00 | 00 00 00 00 01 20 00 00
|
||||
89 EB 33 01 71 5C 24 C4 | 15 03 35 45 74 47 8B 42
|
||||
BA B8 1B 40 00 00 00 00 | 00 00 00 00 77 66 42 BF
|
||||
23 91 26 3F 00 00 60 41 | 00 00 00 00
|
||||
|
||||
New Unknown Opcode 837
|
||||
STORAGE_SIZE: 44
|
||||
02 00 00 00 00 00 00 00 | 00 00 00 00 00 00 80 00
|
||||
7B 80 34 01 84 EA 2B C4 | 5F A1 36 45 C9 39 1C 42
|
||||
BA B8 1B 40 CE 06 00 00 | 00 00 80 3F
|
||||
*/
|
||||
}
|
||||
|
||||
void WorldSession::HandleDismountOpcode( WorldPacket & /*recv_data*/ )
|
||||
{
|
||||
sLog.outDebug("WORLD: CMSG_CANCEL_MOUNT_AURA");
|
||||
@@ -1594,3 +1657,32 @@ void WorldSession::HandleSetTaxiBenchmarkOpcode( WorldPacket & recv_data )
|
||||
|
||||
sLog.outDebug("Client used \"/timetest %d\" command", mode);
|
||||
}
|
||||
|
||||
void WorldSession::HandleSpellClick( WorldPacket & recv_data )
|
||||
{
|
||||
CHECK_PACKET_SIZE(recv_data, 8);
|
||||
|
||||
uint64 guid;
|
||||
recv_data >> guid;
|
||||
|
||||
Vehicle *vehicle = ObjectAccessor::GetVehicle(guid);
|
||||
|
||||
if(!vehicle)
|
||||
return;
|
||||
|
||||
_player->EnterVehicle(vehicle);
|
||||
}
|
||||
|
||||
void WorldSession::HandleInspectAchievements( WorldPacket & recv_data )
|
||||
{
|
||||
CHECK_PACKET_SIZE(recv_data, 1);
|
||||
uint64 guid;
|
||||
if(!readGUID(recv_data, guid))
|
||||
return;
|
||||
|
||||
Player *player = objmgr.GetPlayer(guid);
|
||||
if(!player)
|
||||
return;
|
||||
|
||||
player->GetAchievementMgr().SendRespondInspectAchievements(_player);
|
||||
}
|
||||
|
||||
+90
-125
@@ -178,64 +178,12 @@ void WorldSession::HandleMoveWorldportAckOpcode()
|
||||
|
||||
void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
|
||||
{
|
||||
CHECK_PACKET_SIZE(recv_data, 4+1+4+4+4+4+4);
|
||||
uint32 opcode = recv_data.GetOpcode();
|
||||
sLog.outDebug("WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(opcode), opcode, opcode);
|
||||
|
||||
/* extract packet */
|
||||
MovementInfo movementInfo;
|
||||
uint32 MovementFlags;
|
||||
|
||||
recv_data >> MovementFlags;
|
||||
recv_data >> movementInfo.unk1;
|
||||
recv_data >> movementInfo.time;
|
||||
recv_data >> movementInfo.x;
|
||||
recv_data >> movementInfo.y;
|
||||
recv_data >> movementInfo.z;
|
||||
recv_data >> movementInfo.o;
|
||||
|
||||
if(MovementFlags & MOVEMENTFLAG_ONTRANSPORT)
|
||||
{
|
||||
// recheck
|
||||
CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+8+4+4+4+4+4);
|
||||
|
||||
recv_data >> movementInfo.t_guid;
|
||||
recv_data >> movementInfo.t_x;
|
||||
recv_data >> movementInfo.t_y;
|
||||
recv_data >> movementInfo.t_z;
|
||||
recv_data >> movementInfo.t_o;
|
||||
recv_data >> movementInfo.t_time;
|
||||
}
|
||||
|
||||
if(MovementFlags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2))
|
||||
{
|
||||
// recheck
|
||||
CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4);
|
||||
|
||||
recv_data >> movementInfo.s_pitch; // pitch, -1.55=looking down, 0=looking straight forward, +1.55=looking up
|
||||
}
|
||||
|
||||
// recheck
|
||||
CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4);
|
||||
|
||||
recv_data >> movementInfo.fallTime; // duration of last jump (when in jump duration from jump begin to now)
|
||||
|
||||
if(MovementFlags & MOVEMENTFLAG_JUMPING)
|
||||
{
|
||||
// recheck
|
||||
CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4+4+4+4);
|
||||
|
||||
recv_data >> movementInfo.j_unk; // constant, but different when jumping in water and on land?
|
||||
recv_data >> movementInfo.j_sinAngle; // sin of angle between orientation0 and players orientation
|
||||
recv_data >> movementInfo.j_cosAngle; // cos of angle between orientation0 and players orientation
|
||||
recv_data >> movementInfo.j_xyspeed; // speed of xy movement
|
||||
}
|
||||
|
||||
if(MovementFlags & MOVEMENTFLAG_SPLINE)
|
||||
{
|
||||
// recheck
|
||||
CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4);
|
||||
|
||||
recv_data >> movementInfo.u_unk1; // unknown
|
||||
}
|
||||
ReadMovementInfo(recv_data, &movementInfo);
|
||||
/*----------------*/
|
||||
|
||||
if(recv_data.size() != recv_data.rpos())
|
||||
@@ -252,7 +200,7 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
|
||||
Unit* pos_unit = GetPlayer()->GetCharm();
|
||||
if (pos_unit && pos_unit->isPossessed()) // can be charmed but not possessed
|
||||
{
|
||||
HandlePossessedMovement(recv_data, movementInfo, MovementFlags);
|
||||
HandlePossessedMovement(recv_data, movementInfo, movementInfo.flags);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -260,10 +208,10 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
|
||||
return;
|
||||
|
||||
//Save movement flags
|
||||
GetPlayer()->SetUnitMovementFlags(MovementFlags);
|
||||
GetPlayer()->SetUnitMovementFlags(movementInfo.flags);
|
||||
|
||||
/* handle special cases */
|
||||
if (MovementFlags & MOVEMENTFLAG_ONTRANSPORT)
|
||||
if (movementInfo.flags & MOVEMENTFLAG_ONTRANSPORT)
|
||||
{
|
||||
// transports size limited
|
||||
// (also received at zeppelin leave by some reason with t_* as absolute in continent coordinates, can be safely skipped)
|
||||
@@ -282,9 +230,6 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
|
||||
{
|
||||
if ((*iter)->GetGUID() == movementInfo.t_guid)
|
||||
{
|
||||
// unmount before boarding
|
||||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
|
||||
|
||||
GetPlayer()->m_transport = (*iter);
|
||||
(*iter)->AddPassenger(GetPlayer());
|
||||
break;
|
||||
@@ -301,13 +246,14 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
|
||||
movementInfo.t_z = 0.0f;
|
||||
movementInfo.t_o = 0.0f;
|
||||
movementInfo.t_time = 0;
|
||||
movementInfo.t_seat = -1;
|
||||
}
|
||||
|
||||
// fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map).
|
||||
if (recv_data.GetOpcode() == MSG_MOVE_FALL_LAND && !GetPlayer()->isInFlight())
|
||||
if (opcode == MSG_MOVE_FALL_LAND && !GetPlayer()->isInFlight())
|
||||
GetPlayer()->HandleFallDamage(movementInfo);
|
||||
|
||||
if(((MovementFlags & MOVEMENTFLAG_SWIMMING) != 0) != GetPlayer()->IsInWater())
|
||||
if(((movementInfo.flags & MOVEMENTFLAG_SWIMMING) != 0) != GetPlayer()->IsInWater())
|
||||
{
|
||||
// now client not include swimming flag in case jumping under water
|
||||
GetPlayer()->SetInWater( !GetPlayer()->IsInWater() || GetPlayer()->GetBaseMap()->IsUnderWater(movementInfo.x, movementInfo.y, movementInfo.z) );
|
||||
@@ -316,14 +262,35 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
|
||||
/*----------------------*/
|
||||
|
||||
/* process position-change */
|
||||
recv_data.put<uint32>(5, getMSTime()); // offset flags(4) + unk(1)
|
||||
WorldPacket data(recv_data.GetOpcode(), (GetPlayer()->GetPackGUID().size()+recv_data.size()));
|
||||
data.append(GetPlayer()->GetPackGUID());
|
||||
Unit *mover = _player->m_mover;
|
||||
recv_data.put<uint32>(6, getMSTime()); // fix time, offset flags(4) + unk(2)
|
||||
WorldPacket data(recv_data.GetOpcode(), (mover->GetPackGUID().size()+recv_data.size()));
|
||||
data.append(_player->m_mover->GetPackGUID()); // use mover guid
|
||||
data.append(recv_data.contents(), recv_data.size());
|
||||
GetPlayer()->SendMessageToSet(&data, false);
|
||||
|
||||
GetPlayer()->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
|
||||
GetPlayer()->m_movementInfo = movementInfo;
|
||||
if(!_player->GetCharmGUID()) // nothing is charmed
|
||||
{
|
||||
_player->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
|
||||
_player->m_movementInfo = movementInfo;
|
||||
_player->SetUnitMovementFlags(movementInfo.flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(mover->GetTypeId() != TYPEID_PLAYER) // unit, creature, pet, vehicle...
|
||||
{
|
||||
if(Map *map = mover->GetMap())
|
||||
map->CreatureRelocation((Creature*)mover, movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
|
||||
mover->SetUnitMovementFlags(movementInfo.flags);
|
||||
}
|
||||
else // player
|
||||
{
|
||||
((Player*)mover)->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
|
||||
((Player*)mover)->m_movementInfo = movementInfo;
|
||||
((Player*)mover)->SetUnitMovementFlags(movementInfo.flags);
|
||||
}
|
||||
}
|
||||
|
||||
if (GetPlayer()->m_lastFallTime >= movementInfo.fallTime || GetPlayer()->m_lastFallZ <=movementInfo.z || recv_data.GetOpcode() == MSG_MOVE_FALL_LAND)
|
||||
GetPlayer()->SetFallInformation(movementInfo.fallTime, movementInfo.z);
|
||||
|
||||
@@ -396,20 +363,13 @@ void WorldSession::HandlePossessedMovement(WorldPacket& recv_data, MovementInfo&
|
||||
|
||||
void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data)
|
||||
{
|
||||
CHECK_PACKET_SIZE(recv_data, 8+4+4+1+4+4+4+4+4);
|
||||
sLog.outDebug("WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(recv_data.GetOpcode()), recv_data.GetOpcode(), recv_data.GetOpcode());
|
||||
|
||||
CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+8+4);
|
||||
|
||||
/* extract packet */
|
||||
uint64 guid;
|
||||
uint8 unkB;
|
||||
uint32 unk1, flags, time, fallTime;
|
||||
float x, y, z, orientation;
|
||||
|
||||
uint64 t_GUID;
|
||||
float t_x, t_y, t_z, t_o;
|
||||
uint32 t_time;
|
||||
float s_pitch;
|
||||
float j_unk1, j_sinAngle, j_cosAngle, j_xyspeed;
|
||||
float u_unk1;
|
||||
uint32 unk1;
|
||||
float newspeed;
|
||||
|
||||
recv_data >> guid;
|
||||
@@ -420,47 +380,10 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data)
|
||||
|
||||
// continue parse packet
|
||||
|
||||
recv_data >> unk1;
|
||||
recv_data >> flags >> unkB >> time;
|
||||
recv_data >> x >> y >> z >> orientation;
|
||||
if (flags & MOVEMENTFLAG_ONTRANSPORT)
|
||||
{
|
||||
// recheck
|
||||
CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+8+4+4+4+4+4);
|
||||
recv_data >> unk1; // counter or moveEvent
|
||||
|
||||
recv_data >> t_GUID;
|
||||
recv_data >> t_x >> t_y >> t_z >> t_o >> t_time;
|
||||
}
|
||||
if (flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2))
|
||||
{
|
||||
// recheck
|
||||
CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4);
|
||||
|
||||
recv_data >> s_pitch; // pitch, -1.55=looking down, 0=looking straight forward, +1.55=looking up
|
||||
}
|
||||
|
||||
// recheck
|
||||
CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4);
|
||||
|
||||
recv_data >> fallTime; // duration of last jump (when in jump duration from jump begin to now)
|
||||
|
||||
if ((flags & MOVEMENTFLAG_JUMPING) || (flags & MOVEMENTFLAG_FALLING))
|
||||
{
|
||||
// recheck
|
||||
CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4+4+4+4);
|
||||
|
||||
recv_data >> j_unk1; // ?constant, but different when jumping in water and on land?
|
||||
recv_data >> j_sinAngle >> j_cosAngle; // sin + cos of angle between orientation0 and players orientation
|
||||
recv_data >> j_xyspeed; // speed of xy movement
|
||||
}
|
||||
|
||||
if(flags & MOVEMENTFLAG_SPLINE)
|
||||
{
|
||||
// recheck
|
||||
CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4);
|
||||
|
||||
recv_data >> u_unk1; // unknown
|
||||
}
|
||||
MovementInfo movementInfo;
|
||||
ReadMovementInfo(recv_data, &movementInfo);
|
||||
|
||||
// recheck
|
||||
CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4);
|
||||
@@ -473,7 +396,7 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data)
|
||||
UnitMoveType move_type;
|
||||
UnitMoveType force_move_type;
|
||||
|
||||
static char const* move_type_name[MAX_MOVE_TYPE] = { "Walk", "Run", "RunBack", "Swim", "SwimBack", "TurnRate", "Flight", "FlightBack" };
|
||||
static char const* move_type_name[MAX_MOVE_TYPE] = { "Walk", "Run", "RunBack", "Swim", "SwimBack", "TurnRate", "Flight", "FlightBack", "PitchRate" };
|
||||
|
||||
uint16 opcode = recv_data.GetOpcode();
|
||||
switch(opcode)
|
||||
@@ -486,6 +409,7 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data)
|
||||
case CMSG_FORCE_TURN_RATE_CHANGE_ACK: move_type = MOVE_TURN_RATE; force_move_type = MOVE_TURN_RATE; break;
|
||||
case CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK: move_type = MOVE_FLIGHT; force_move_type = MOVE_FLIGHT; break;
|
||||
case CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK: move_type = MOVE_FLIGHT_BACK; force_move_type = MOVE_FLIGHT_BACK; break;
|
||||
case CMSG_FORCE_PITCH_RATE_CHANGE_ACK: move_type = MOVE_PITCH_RATE; force_move_type = MOVE_PITCH_RATE; break;
|
||||
default:
|
||||
sLog.outError("WorldSession::HandleForceSpeedChangeAck: Unknown move type opcode: %u", opcode);
|
||||
return;
|
||||
@@ -520,20 +444,61 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data)
|
||||
void WorldSession::HandleSetActiveMoverOpcode(WorldPacket &recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: Recvd CMSG_SET_ACTIVE_MOVER");
|
||||
recv_data.hexlike();
|
||||
|
||||
CHECK_PACKET_SIZE(recv_data,8);
|
||||
CHECK_PACKET_SIZE(recv_data, 8);
|
||||
|
||||
uint64 guid;
|
||||
recv_data >> guid;
|
||||
|
||||
WorldPacket data(SMSG_TIME_SYNC_REQ, 4); // new 2.0.x, enable movement
|
||||
data << uint32(0x00000000); // on blizz it increments periodically
|
||||
SendPacket(&data);
|
||||
if(_player->m_mover->GetGUID() != guid)
|
||||
{
|
||||
sLog.outError("HandleSetActiveMoverOpcode: incorrect mover guid: mover is " I64FMT " and should be " I64FMT, _player->m_mover->GetGUID(), guid);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::HandleNotActiveMoverOpcode(WorldPacket& /*recv_data*/)
|
||||
void WorldSession::HandleMoveNotActiveMover(WorldPacket &recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: Recvd CMSG_MOVE_NOT_ACTIVE_MOVER");
|
||||
recv_data.hexlike();
|
||||
|
||||
CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+8);
|
||||
|
||||
uint64 old_mover_guid;
|
||||
recv_data >> old_mover_guid;
|
||||
|
||||
if(_player->m_mover->GetGUID() == old_mover_guid)
|
||||
{
|
||||
sLog.outError("HandleMoveNotActiveMover: incorrect mover guid: mover is " I64FMT " and should be " I64FMT " instead of " I64FMT, _player->m_mover->GetGUID(), _player->GetGUID(), old_mover_guid);
|
||||
return;
|
||||
}
|
||||
|
||||
MovementInfo mi;
|
||||
ReadMovementInfo(recv_data, &mi);
|
||||
_player->m_movementInfo = mi;
|
||||
}
|
||||
|
||||
void WorldSession::HandleDismissControlledVehicle(WorldPacket &recv_data)
|
||||
{
|
||||
sLog.outDebug("WORLD: Recvd CMSG_DISMISS_CONTROLLED_VEHICLE");
|
||||
recv_data.hexlike();
|
||||
|
||||
uint64 vehicleGUID = _player->GetCharmGUID();
|
||||
|
||||
if(!vehicleGUID) // something wrong here...
|
||||
return;
|
||||
|
||||
MovementInfo mi;
|
||||
ReadMovementInfo(recv_data, &mi);
|
||||
_player->m_movementInfo = mi;
|
||||
|
||||
// using charm guid, because we don't have vehicle guid...
|
||||
if(Vehicle *vehicle = ObjectAccessor::GetVehicle(vehicleGUID))
|
||||
{
|
||||
_player->ExitVehicle(vehicle);
|
||||
vehicle->Dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::HandleMountSpecialAnimOpcode(WorldPacket& /*recvdata*/)
|
||||
|
||||
@@ -524,13 +524,12 @@ void WorldSession::SendStablePet(uint64 guid )
|
||||
data << uint32(pet->GetEntry());
|
||||
data << uint32(pet->getLevel());
|
||||
data << pet->GetName(); // petname
|
||||
data << uint32(pet->GetLoyaltyLevel()); // loyalty
|
||||
data << uint8(0x01); // client slot 1 == current pet (0)
|
||||
data << uint8(0x01); // flags?, client slot 1 == current pet (0)
|
||||
++num;
|
||||
}
|
||||
|
||||
// 0 1 2 3 4 5 6
|
||||
QueryResult* result = CharacterDatabase.PQuery("SELECT owner, slot, id, entry, level, loyalty, name FROM character_pet WHERE owner = '%u' AND slot > 0 AND slot < 3",_player->GetGUIDLow());
|
||||
// 0 1 2 3 4 5
|
||||
QueryResult* result = CharacterDatabase.PQuery("SELECT owner, slot, id, entry, level, name FROM character_pet WHERE owner = '%u' AND slot > 0 AND slot < 5",_player->GetGUIDLow());
|
||||
|
||||
if(result)
|
||||
{
|
||||
@@ -541,8 +540,7 @@ void WorldSession::SendStablePet(uint64 guid )
|
||||
data << uint32(fields[2].GetUInt32()); // petnumber
|
||||
data << uint32(fields[3].GetUInt32()); // creature entry
|
||||
data << uint32(fields[4].GetUInt32()); // level
|
||||
data << fields[6].GetString(); // name
|
||||
data << uint32(fields[5].GetUInt32()); // loyalty
|
||||
data << fields[5].GetString(); // name
|
||||
data << uint8(fields[1].GetUInt32()+1); // slot
|
||||
|
||||
++num;
|
||||
@@ -592,7 +590,7 @@ void WorldSession::HandleStablePet( WorldPacket & recv_data )
|
||||
|
||||
uint32 free_slot = 1;
|
||||
|
||||
QueryResult *result = CharacterDatabase.PQuery("SELECT owner,slot,id FROM character_pet WHERE owner = '%u' AND slot > 0 AND slot < 3 ORDER BY slot ",_player->GetGUIDLow());
|
||||
QueryResult *result = CharacterDatabase.PQuery("SELECT owner,slot,id FROM character_pet WHERE owner = '%u' AND slot > 0 AND slot < 5 ORDER BY slot ",_player->GetGUIDLow());
|
||||
if(result)
|
||||
{
|
||||
do
|
||||
@@ -656,7 +654,7 @@ void WorldSession::HandleUnstablePet( WorldPacket & recv_data )
|
||||
|
||||
Pet *newpet = NULL;
|
||||
|
||||
QueryResult *result = CharacterDatabase.PQuery("SELECT entry FROM character_pet WHERE owner = '%u' AND id = '%u' AND slot > 0 AND slot < 3",_player->GetGUIDLow(),petnumber);
|
||||
QueryResult *result = CharacterDatabase.PQuery("SELECT entry FROM character_pet WHERE owner = '%u' AND id = '%u' AND slot > 0 AND slot < 5",_player->GetGUIDLow(),petnumber);
|
||||
if(result)
|
||||
{
|
||||
Field *fields = result->Fetch();
|
||||
@@ -700,7 +698,7 @@ void WorldSession::HandleBuyStableSlot( WorldPacket & recv_data )
|
||||
|
||||
WorldPacket data(SMSG_STABLE_RESULT, 200);
|
||||
|
||||
if(GetPlayer()->m_stableSlots < 2) // max slots amount = 2
|
||||
if(GetPlayer()->m_stableSlots < 4) // max slots amount = 4
|
||||
{
|
||||
StableSlotPricesEntry const *SlotPrice = sStableSlotPricesStore.LookupEntry(GetPlayer()->m_stableSlots+1);
|
||||
if(_player->GetMoney() >= SlotPrice->Price)
|
||||
|
||||
+51
-26
@@ -146,15 +146,9 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) c
|
||||
|
||||
/** lower flag1 **/
|
||||
if(target == this) // building packet for oneself
|
||||
{
|
||||
flags |= UPDATEFLAG_SELF;
|
||||
|
||||
/*** temporary reverted - until real source of stack corruption will not found
|
||||
updatetype = UPDATETYPE_CREATE_OBJECT2;
|
||||
****/
|
||||
}
|
||||
|
||||
if(flags & UPDATEFLAG_HASPOSITION)
|
||||
if(flags & UPDATEFLAG_HAS_POSITION)
|
||||
{
|
||||
// UPDATETYPE_CREATE_OBJECT2 dynamic objects, corpses...
|
||||
if(isType(TYPEMASK_DYNAMICOBJECT) || isType(TYPEMASK_CORPSE) || isType(TYPEMASK_PLAYER))
|
||||
@@ -180,6 +174,12 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) c
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(isType(TYPEMASK_UNIT))
|
||||
{
|
||||
if(((Unit*)this)->getVictim())
|
||||
flags |= UPDATEFLAG_HAS_TARGET;
|
||||
}
|
||||
}
|
||||
|
||||
//sLog.outDebug("BuildCreateUpdate: update-type: %u, object-type: %u got flags: %X, flags2: %X", updatetype, m_objectTypeId, flags, flags2);
|
||||
@@ -251,11 +251,18 @@ void Object::DestroyForPlayer(Player *target) const
|
||||
|
||||
WorldPacket data(SMSG_DESTROY_OBJECT, 8);
|
||||
data << GetGUID();
|
||||
data << uint8(0); // WotLK (bool)
|
||||
target->GetSession()->SendPacket( &data );
|
||||
}
|
||||
|
||||
void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2 ) const
|
||||
void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2) const
|
||||
{
|
||||
uint16 unk_flags = ((GetTypeId() == TYPEID_PLAYER) ? ((Player*)this)->m_movementInfo.unk1 : 0);
|
||||
|
||||
if(GetTypeId() == TYPEID_UNIT)
|
||||
if(((Creature*)this)->isVehicle())
|
||||
unk_flags |= 0x20; // always allow pitch
|
||||
|
||||
*data << (uint8)flags; // update flags
|
||||
|
||||
// 0x20
|
||||
@@ -292,12 +299,12 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2
|
||||
}
|
||||
|
||||
*data << uint32(flags2); // movement flags
|
||||
*data << uint8(0); // unk 2.3.0
|
||||
*data << uint16(unk_flags); // unknown 2.3.0
|
||||
*data << uint32(getMSTime()); // time (in milliseconds)
|
||||
}
|
||||
|
||||
// 0x40
|
||||
if (flags & UPDATEFLAG_HASPOSITION)
|
||||
if (flags & UPDATEFLAG_HAS_POSITION)
|
||||
{
|
||||
// 0x02
|
||||
if(flags & UPDATEFLAG_TRANSPORT && ((GameObject*)this)->GetGoType() == GAMEOBJECT_TYPE_MO_TRANSPORT)
|
||||
@@ -330,12 +337,13 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2
|
||||
*data << (float)((Player*)this)->GetTransOffsetZ();
|
||||
*data << (float)((Player*)this)->GetTransOffsetO();
|
||||
*data << (uint32)((Player*)this)->GetTransTime();
|
||||
*data << (int8)((Player*)this)->GetTransSeat();
|
||||
}
|
||||
//TrinIty currently not have support for other than player on transport
|
||||
}
|
||||
|
||||
// 0x02200000
|
||||
if(flags2 & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2))
|
||||
if((flags2 & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2)) || (unk_flags & 0x20))
|
||||
{
|
||||
if(GetTypeId() == TYPEID_PLAYER)
|
||||
*data << (float)((Player*)this)->m_movementInfo.s_pitch;
|
||||
@@ -384,6 +392,7 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2
|
||||
*data << ((Unit*)this)->GetSpeed( MOVE_FLIGHT );
|
||||
*data << ((Unit*)this)->GetSpeed( MOVE_FLIGHT_BACK );
|
||||
*data << ((Unit*)this)->GetSpeed( MOVE_TURN_RATE );
|
||||
*data << ((Unit*)this)->GetSpeed( MOVE_PITCH_RATE );
|
||||
|
||||
// 0x08000000
|
||||
if(flags2 & MOVEMENTFLAG_SPLINE2)
|
||||
@@ -485,7 +494,7 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2
|
||||
break;
|
||||
case TYPEID_PLAYER:
|
||||
if(flags & UPDATEFLAG_SELF)
|
||||
*data << uint32(0x00000015); // unk, can be 0x15 or 0x22
|
||||
*data << uint32(0x0000002F); // unk, can be 0x15 or 0x22
|
||||
else
|
||||
*data << uint32(0x00000008); // unk, can be 0x7 or 0x8
|
||||
break;
|
||||
@@ -508,6 +517,15 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2
|
||||
case TYPEID_CORPSE:
|
||||
*data << uint32(GetGUIDHigh()); // GetGUIDHigh()
|
||||
break;
|
||||
case TYPEID_UNIT:
|
||||
*data << uint32(0x0000000B); // unk, can be 0xB or 0xC
|
||||
break;
|
||||
case TYPEID_PLAYER:
|
||||
if(flags & UPDATEFLAG_SELF)
|
||||
*data << uint32(0x0000002F); // unk, can be 0x15 or 0x22
|
||||
else
|
||||
*data << uint32(0x00000008); // unk, can be 0x7 or 0x8
|
||||
break;
|
||||
default:
|
||||
*data << uint32(0x00000000); // unk
|
||||
break;
|
||||
@@ -515,9 +533,12 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2
|
||||
}
|
||||
|
||||
// 0x4
|
||||
if(flags & UPDATEFLAG_FULLGUID)
|
||||
if(flags & UPDATEFLAG_HAS_TARGET) // packed guid (current target guid)
|
||||
{
|
||||
*data << uint8(0); // packed guid (probably target guid)
|
||||
if(Unit *victim = ((Unit*)this)->getVictim())
|
||||
data->append(victim->GetPackGUID());
|
||||
else
|
||||
*data << uint8(0);
|
||||
}
|
||||
|
||||
// 0x2
|
||||
@@ -525,6 +546,13 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2
|
||||
{
|
||||
*data << uint32(getMSTime()); // ms time
|
||||
}
|
||||
|
||||
// 0x80
|
||||
if(flags & UPDATEFLAG_VEHICLE) // unused for now
|
||||
{
|
||||
*data << uint32(((Vehicle*)this)->GetVehicleId()); // vehicle id
|
||||
*data << float(0); // facing adjustment
|
||||
}
|
||||
}
|
||||
|
||||
void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask *updateMask, Player *target) const
|
||||
@@ -540,10 +568,8 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask
|
||||
if ( ((GameObject*)this)->ActivateToQuest(target) || target->isGameMaster())
|
||||
{
|
||||
IsActivateToQuest = true;
|
||||
updateMask->SetBit(GAMEOBJECT_DYN_FLAGS);
|
||||
updateMask->SetBit(GAMEOBJECT_DYNAMIC);
|
||||
}
|
||||
if (GetUInt32Value(GAMEOBJECT_ARTKIT))
|
||||
updateMask->SetBit(GAMEOBJECT_ARTKIT);
|
||||
}
|
||||
}
|
||||
else //case UPDATETYPE_VALUES
|
||||
@@ -554,8 +580,8 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask
|
||||
{
|
||||
IsActivateToQuest = true;
|
||||
}
|
||||
updateMask->SetBit(GAMEOBJECT_DYN_FLAGS);
|
||||
updateMask->SetBit(GAMEOBJECT_ANIMPROGRESS);
|
||||
updateMask->SetBit(GAMEOBJECT_DYNAMIC);
|
||||
updateMask->SetBit(GAMEOBJECT_BYTES_1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -572,7 +598,6 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask
|
||||
if( updateMask->GetBit( index ) )
|
||||
{
|
||||
// remove custom flag before send
|
||||
|
||||
if( index == UNIT_NPC_FLAGS )
|
||||
*data << uint32(m_uint32Values[ index ] & ~(UNIT_NPC_FLAG_GUARD + UNIT_NPC_FLAG_OUTDOORPVP));
|
||||
// FIXME: Some values at server stored in float format but must be sent to client in uint32 format
|
||||
@@ -641,7 +666,7 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask
|
||||
if( updateMask->GetBit( index ) )
|
||||
{
|
||||
// send in current format (float as float, uint32 as uint32)
|
||||
if ( index == GAMEOBJECT_DYN_FLAGS )
|
||||
if ( index == GAMEOBJECT_DYNAMIC )
|
||||
{
|
||||
if(IsActivateToQuest )
|
||||
{
|
||||
@@ -1093,7 +1118,7 @@ uint32 WorldObject::GetAreaId() const
|
||||
|
||||
InstanceData* WorldObject::GetInstanceData()
|
||||
{
|
||||
Map *map = MapManager::Instance().GetMap(m_mapId, this);
|
||||
Map *map = GetMap();
|
||||
return map->IsDungeon() ? ((InstanceMap*)map)->GetInstanceData() : NULL;
|
||||
}
|
||||
|
||||
@@ -1303,7 +1328,7 @@ namespace Trinity
|
||||
{
|
||||
public:
|
||||
MessageChatLocaleCacheDo(WorldObject const& obj, ChatMsg msgtype, int32 textId, uint32 language, uint64 targetGUID, float dist)
|
||||
: i_object(obj), i_msgtype(msgtype), i_textId(textId), i_language(language),
|
||||
: i_object(obj), i_msgtype(msgtype), i_textId(textId), i_language(language),
|
||||
i_targetGUID(targetGUID), i_dist(dist)
|
||||
{
|
||||
}
|
||||
@@ -1448,7 +1473,7 @@ void WorldObject::BuildHeartBeatMsg(WorldPacket *data) const
|
||||
data->Initialize(MSG_MOVE_HEARTBEAT, 32);
|
||||
data->append(GetPackGUID());
|
||||
*data << uint32(((Unit*)this)->GetUnitMovementFlags()); // movement flags
|
||||
*data << uint8(0); // 2.3.0
|
||||
*data << uint16(0); // 2.3.0
|
||||
*data << getMSTime(); // time
|
||||
*data << m_positionX;
|
||||
*data << m_positionY;
|
||||
@@ -1467,7 +1492,7 @@ void WorldObject::BuildTeleportAckMsg(WorldPacket *data, float x, float y, float
|
||||
data->append(GetPackGUID());
|
||||
*data << uint32(0); // this value increments every time
|
||||
*data << uint32(((Unit*)this)->GetUnitMovementFlags()); // movement flags
|
||||
*data << uint8(0); // 2.3.0
|
||||
*data << uint16(0); // 2.3.0
|
||||
*data << getMSTime(); // time
|
||||
*data << x;
|
||||
*data << y;
|
||||
@@ -1620,4 +1645,4 @@ void WorldObject::GetNearPoint(WorldObject const* searcher, float &x, float &y,
|
||||
z = GetPositionZ();
|
||||
|
||||
UpdateGroundPositionZ(x,y,z);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,6 +134,9 @@ ObjectAccessor::GetCreatureOrPet(WorldObject const &u, uint64 guid)
|
||||
if(Creature *unit = GetPet(guid))
|
||||
return unit;
|
||||
|
||||
if(Creature *unit = GetVehicle(guid))
|
||||
return unit;
|
||||
|
||||
return GetCreature(u, guid);
|
||||
}
|
||||
|
||||
@@ -351,6 +354,12 @@ ObjectAccessor::GetPet(uint64 guid)
|
||||
return GetObjectInWorld(guid, (Pet*)NULL);
|
||||
}
|
||||
|
||||
Vehicle*
|
||||
ObjectAccessor::GetVehicle(uint64 guid)
|
||||
{
|
||||
return GetObjectInWorld(guid, (Vehicle*)NULL);
|
||||
}
|
||||
|
||||
Corpse*
|
||||
ObjectAccessor::GetCorpseForPlayerGUID(uint64 guid)
|
||||
{
|
||||
@@ -602,6 +611,7 @@ template <class T> ZThread::FastMutex HashMapHolder<T>::i_lock;
|
||||
|
||||
template class HashMapHolder<Player>;
|
||||
template class HashMapHolder<Pet>;
|
||||
template class HashMapHolder<Vehicle>;
|
||||
template class HashMapHolder<GameObject>;
|
||||
template class HashMapHolder<DynamicObject>;
|
||||
template class HashMapHolder<Creature>;
|
||||
@@ -609,6 +619,7 @@ template class HashMapHolder<Corpse>;
|
||||
|
||||
template Player* ObjectAccessor::GetObjectInWorld<Player>(uint32 mapid, float x, float y, uint64 guid, Player* /*fake*/);
|
||||
template Pet* ObjectAccessor::GetObjectInWorld<Pet>(uint32 mapid, float x, float y, uint64 guid, Pet* /*fake*/);
|
||||
template Vehicle* ObjectAccessor::GetObjectInWorld<Vehicle>(uint32 mapid, float x, float y, uint64 guid, Vehicle* /*fake*/);
|
||||
template Creature* ObjectAccessor::GetObjectInWorld<Creature>(uint32 mapid, float x, float y, uint64 guid, Creature* /*fake*/);
|
||||
template Corpse* ObjectAccessor::GetObjectInWorld<Corpse>(uint32 mapid, float x, float y, uint64 guid, Corpse* /*fake*/);
|
||||
template GameObject* ObjectAccessor::GetObjectInWorld<GameObject>(uint32 mapid, float x, float y, uint64 guid, GameObject* /*fake*/);
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "GridDefines.h"
|
||||
#include "Object.h"
|
||||
#include "Player.h"
|
||||
#include "Vehicle.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
@@ -150,6 +151,7 @@ class TRINITY_DLL_DECL ObjectAccessor : public Trinity::Singleton<ObjectAccessor
|
||||
static DynamicObject* GetDynamicObject(Unit const &, uint64);
|
||||
static Corpse* GetCorpse(WorldObject const &u, uint64 guid);
|
||||
static Pet* GetPet(uint64 guid);
|
||||
static Vehicle* GetVehicle(uint64 guid);
|
||||
static Player* FindPlayer(uint64);
|
||||
|
||||
Player* FindPlayerByName(const char *name) ;
|
||||
|
||||
@@ -41,6 +41,7 @@ enum HighGuid
|
||||
HIGHGUID_TRANSPORT = 0xF120, // blizz F120 (for GAMEOBJECT_TYPE_TRANSPORT)
|
||||
HIGHGUID_UNIT = 0xF130, // blizz F130
|
||||
HIGHGUID_PET = 0xF140, // blizz F140
|
||||
HIGHGUID_VEHICLE = 0xF150, // blizz F550
|
||||
HIGHGUID_DYNAMICOBJECT = 0xF100, // blizz F100
|
||||
HIGHGUID_CORPSE = 0xF101, // blizz F100
|
||||
HIGHGUID_MO_TRANSPORT = 0x1FC0, // blizz 1FC0 (for GAMEOBJECT_TYPE_MO_TRANSPORT)
|
||||
@@ -50,6 +51,7 @@ enum HighGuid
|
||||
|
||||
#define IS_CREATURE_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_UNIT )
|
||||
#define IS_PET_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_PET )
|
||||
#define IS_VEHICLE_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_VEHICLE )
|
||||
#define IS_CREATURE_OR_PET_GUID(Guid)( IS_CREATURE_GUID(Guid) || IS_PET_GUID(Guid) )
|
||||
#define IS_PLAYER_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_PLAYER && Guid!=0 )
|
||||
#define IS_UNIT_GUID(Guid) ( IS_CREATURE_OR_PET_GUID(Guid) || IS_PLAYER_GUID(Guid) )
|
||||
@@ -87,6 +89,7 @@ inline bool IsGuidHaveEnPart(uint64 const& guid)
|
||||
case HIGHGUID_TRANSPORT:
|
||||
case HIGHGUID_UNIT:
|
||||
case HIGHGUID_PET:
|
||||
case HIGHGUID_VEHICLE:
|
||||
case HIGHGUID_MO_TRANSPORT:
|
||||
default:
|
||||
return true;
|
||||
@@ -106,6 +109,7 @@ inline char const* GetLogNameForGuid(uint64 guid)
|
||||
case HIGHGUID_TRANSPORT: return "transport";
|
||||
case HIGHGUID_UNIT: return "creature";
|
||||
case HIGHGUID_PET: return "pet";
|
||||
case HIGHGUID_VEHICLE: return "vehicle";
|
||||
case HIGHGUID_DYNAMICOBJECT:return "dynobject";
|
||||
case HIGHGUID_CORPSE: return "corpse";
|
||||
case HIGHGUID_MO_TRANSPORT: return "mo_transport";
|
||||
|
||||
@@ -59,7 +59,7 @@ ObjectGridRespawnMover::Visit(CreatureMapType &m)
|
||||
|
||||
Creature * c = iter->getSource();
|
||||
|
||||
assert(!c->isPet() && "ObjectGridRespawnMover don't must be called for pets");
|
||||
assert((!c->isPet() || !c->isVehicle()) && "ObjectGridRespawnMover don't must be called for pets");
|
||||
|
||||
Cell const& cur_cell = c->GetCurrentCell();
|
||||
|
||||
|
||||
+116
-34
@@ -116,6 +116,7 @@ ObjectMgr::ObjectMgr()
|
||||
m_hiCharGuid = 1;
|
||||
m_hiCreatureGuid = 1;
|
||||
m_hiPetGuid = 1;
|
||||
m_hiVehicleGuid = 1;
|
||||
m_hiItemGuid = 1;
|
||||
m_hiGoGuid = 1;
|
||||
m_hiDoGuid = 1;
|
||||
@@ -641,6 +642,22 @@ void ObjectMgr::LoadCreatureLocales()
|
||||
sLog.outString( ">> Loaded %u creature locale strings", mCreatureLocaleMap.size() );
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadCompletedAchievements()
|
||||
{
|
||||
QueryResult *result = CharacterDatabase.Query("SELECT achievement FROM character_achievement GROUP BY achievement");
|
||||
|
||||
if(!result)
|
||||
return;
|
||||
|
||||
do
|
||||
{
|
||||
Field *fields = result->Fetch();
|
||||
allCompletedAchievements.insert(fields[0].GetUInt32());
|
||||
} while(result->NextRow());
|
||||
|
||||
delete result;
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadNpcOptionLocales()
|
||||
{
|
||||
mNpcOptionLocaleMap.clear(); // need for reload case
|
||||
@@ -1003,8 +1020,47 @@ void ObjectMgr::LoadEquipmentTemplates()
|
||||
{
|
||||
sEquipmentStorage.Load();
|
||||
|
||||
for(uint32 i=0; i< sEquipmentStorage.MaxEntry; ++i)
|
||||
{
|
||||
EquipmentInfo const* eqInfo = sEquipmentStorage.LookupEntry<EquipmentInfo>(i);
|
||||
|
||||
if(!eqInfo)
|
||||
continue;
|
||||
|
||||
for(uint8 j=0; j<3; j++)
|
||||
{
|
||||
if(!eqInfo->equipentry[j])
|
||||
continue;
|
||||
|
||||
ItemEntry const *dbcitem = sItemStore.LookupEntry(eqInfo->equipentry[j]);
|
||||
|
||||
if(!dbcitem)
|
||||
{
|
||||
sLog.outErrorDb("Unknown item (entry=%u) in creature_equip_template.equipentry%u for entry = %u, forced to 0.", eqInfo->equipentry[j], j+1, i);
|
||||
const_cast<EquipmentInfo*>(eqInfo)->equipentry[j] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(dbcitem->InventoryType != INVTYPE_WEAPON &&
|
||||
dbcitem->InventoryType != INVTYPE_SHIELD &&
|
||||
dbcitem->InventoryType != INVTYPE_RANGED &&
|
||||
dbcitem->InventoryType != INVTYPE_2HWEAPON &&
|
||||
dbcitem->InventoryType != INVTYPE_WEAPONMAINHAND &&
|
||||
dbcitem->InventoryType != INVTYPE_WEAPONOFFHAND &&
|
||||
dbcitem->InventoryType != INVTYPE_HOLDABLE &&
|
||||
dbcitem->InventoryType != INVTYPE_THROWN &&
|
||||
dbcitem->InventoryType != INVTYPE_RANGEDRIGHT)
|
||||
{
|
||||
sLog.outErrorDb("Item (entry=%u) in creature_equip_template.equipentry%u for entry = %u is not equipable in a hand, forced to 0.", eqInfo->equipentry[j], j+1, i);
|
||||
const_cast<EquipmentInfo*>(eqInfo)->equipentry[j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
sLog.outString( ">> Loaded %u equipment template", sEquipmentStorage.RecordCount );
|
||||
sLog.outString();
|
||||
|
||||
// This DBC is currently only used for item templates and creature equipments checks.
|
||||
sItemStore.Clear();
|
||||
}
|
||||
|
||||
CreatureModelInfo const* ObjectMgr::GetCreatureModelInfo(uint32 modelid)
|
||||
@@ -1678,7 +1734,7 @@ void ObjectMgr::LoadItemPrototypes()
|
||||
if(proto->Class >= MAX_ITEM_CLASS)
|
||||
{
|
||||
sLog.outErrorDb("Item (Entry: %u) has wrong Class value (%u)",i,proto->Class);
|
||||
const_cast<ItemPrototype*>(proto)->Class = ITEM_CLASS_JUNK;
|
||||
const_cast<ItemPrototype*>(proto)->Class = ITEM_CLASS_MISC;
|
||||
}
|
||||
|
||||
if(proto->SubClass >= MaxItemSubclassValues[proto->Class])
|
||||
@@ -1775,7 +1831,7 @@ void ObjectMgr::LoadItemPrototypes()
|
||||
}
|
||||
|
||||
// special format
|
||||
if(proto->Spells[0].SpellId == SPELL_ID_GENERIC_LEARN)
|
||||
if((proto->Spells[0].SpellId == SPELL_ID_GENERIC_LEARN) || (proto->Spells[0].SpellId == SPELL_ID_GENERIC_LEARN_PET))
|
||||
{
|
||||
// spell_1
|
||||
if(proto->Spells[0].SpellTrigger != ITEM_SPELLTRIGGER_ON_USE)
|
||||
@@ -1812,7 +1868,7 @@ void ObjectMgr::LoadItemPrototypes()
|
||||
const_cast<ItemPrototype*>(proto)->Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
|
||||
}
|
||||
// allowed only in special format
|
||||
else if(proto->Spells[1].SpellId==SPELL_ID_GENERIC_LEARN)
|
||||
else if((proto->Spells[1].SpellId==SPELL_ID_GENERIC_LEARN) || (proto->Spells[1].SpellId==SPELL_ID_GENERIC_LEARN_PET))
|
||||
{
|
||||
sLog.outErrorDb("Item (Entry: %u) has broken spell in spellid_%d (%u)",i,1+1,proto->Spells[1].SpellId);
|
||||
const_cast<ItemPrototype*>(proto)->Spells[0].SpellId = 0;
|
||||
@@ -1858,7 +1914,7 @@ void ObjectMgr::LoadItemPrototypes()
|
||||
const_cast<ItemPrototype*>(proto)->Spells[j].SpellId = 0;
|
||||
}
|
||||
// allowed only in special format
|
||||
else if(proto->Spells[j].SpellId==SPELL_ID_GENERIC_LEARN)
|
||||
else if((proto->Spells[j].SpellId==SPELL_ID_GENERIC_LEARN) || (proto->Spells[j].SpellId==SPELL_ID_GENERIC_LEARN_PET))
|
||||
{
|
||||
sLog.outErrorDb("Item (Entry: %u) has broken spell in spellid_%d (%u)",i,j+1,proto->Spells[j].SpellId);
|
||||
const_cast<ItemPrototype*>(proto)->Spells[j].SpellId = 0;
|
||||
@@ -1927,9 +1983,6 @@ void ObjectMgr::LoadItemPrototypes()
|
||||
const_cast<ItemPrototype*>(proto)->FoodType = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// this DBC used currently only for check item templates in DB.
|
||||
sItemStore.Clear();
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadAuctionItems()
|
||||
@@ -2919,31 +2972,31 @@ void ObjectMgr::LoadQuests()
|
||||
QueryResult *result = WorldDatabase.Query("SELECT entry, Method, ZoneOrSort, SkillOrClass, MinLevel, QuestLevel, Type, RequiredRaces, RequiredSkillValue,"
|
||||
// 9 10 11 12 13 14 15 16
|
||||
"RepObjectiveFaction, RepObjectiveValue, RequiredMinRepFaction, RequiredMinRepValue, RequiredMaxRepFaction, RequiredMaxRepValue, SuggestedPlayers, LimitTime,"
|
||||
// 17 18 19 20 21 22 23 24 25 26
|
||||
"QuestFlags, SpecialFlags, CharTitleId, PrevQuestId, NextQuestId, ExclusiveGroup, NextQuestInChain, SrcItemId, SrcItemCount, SrcSpell,"
|
||||
// 27 28 29 30 31 32 33 34 35 36
|
||||
// 17 18 19 20 21 22 23 24 25 26 27 28
|
||||
"QuestFlags, SpecialFlags, CharTitleId, PlayersSlain, BonusTalents, PrevQuestId, NextQuestId, ExclusiveGroup, NextQuestInChain, SrcItemId, SrcItemCount, SrcSpell,"
|
||||
// 29 30 31 32 33 34 35 36 37 38
|
||||
"Title, Details, Objectives, OfferRewardText, RequestItemsText, EndText, ObjectiveText1, ObjectiveText2, ObjectiveText3, ObjectiveText4,"
|
||||
// 37 38 39 40 41 42 43 44
|
||||
// 39 40 41 42 43 44 45 46
|
||||
"ReqItemId1, ReqItemId2, ReqItemId3, ReqItemId4, ReqItemCount1, ReqItemCount2, ReqItemCount3, ReqItemCount4,"
|
||||
// 45 46 47 48 49 50 51 52 53 54 54 55
|
||||
// 47 48 49 50 51 52 53 54 55 56 57 58
|
||||
"ReqSourceId1, ReqSourceId2, ReqSourceId3, ReqSourceId4, ReqSourceCount1, ReqSourceCount2, ReqSourceCount3, ReqSourceCount4, ReqSourceRef1, ReqSourceRef2, ReqSourceRef3, ReqSourceRef4,"
|
||||
// 57 58 59 60 61 62 63 64
|
||||
// 59 60 61 62 63 64 65 66
|
||||
"ReqCreatureOrGOId1, ReqCreatureOrGOId2, ReqCreatureOrGOId3, ReqCreatureOrGOId4, ReqCreatureOrGOCount1, ReqCreatureOrGOCount2, ReqCreatureOrGOCount3, ReqCreatureOrGOCount4,"
|
||||
// 65 66 67 68
|
||||
// 67 68 69 70
|
||||
"ReqSpellCast1, ReqSpellCast2, ReqSpellCast3, ReqSpellCast4,"
|
||||
// 69 70 71 72 73 74
|
||||
// 71 72 73 74 75 76
|
||||
"RewChoiceItemId1, RewChoiceItemId2, RewChoiceItemId3, RewChoiceItemId4, RewChoiceItemId5, RewChoiceItemId6,"
|
||||
// 75 76 77 78 79 80
|
||||
// 77 78 79 80 81 82
|
||||
"RewChoiceItemCount1, RewChoiceItemCount2, RewChoiceItemCount3, RewChoiceItemCount4, RewChoiceItemCount5, RewChoiceItemCount6,"
|
||||
// 81 82 83 84 85 86 87 88
|
||||
// 83 84 85 86 87 88 89 90
|
||||
"RewItemId1, RewItemId2, RewItemId3, RewItemId4, RewItemCount1, RewItemCount2, RewItemCount3, RewItemCount4,"
|
||||
// 89 90 91 92 93 94 95 96 97 98
|
||||
// 91 92 93 94 95 96 97 98 99 100
|
||||
"RewRepFaction1, RewRepFaction2, RewRepFaction3, RewRepFaction4, RewRepFaction5, RewRepValue1, RewRepValue2, RewRepValue3, RewRepValue4, RewRepValue5,"
|
||||
// 99 100 101 102 103 104 105 106 107 108 109
|
||||
// 101 102 103 104 105 106 107 108 109 110 111
|
||||
"RewHonorableKills, RewOrReqMoney, RewMoneyMaxLevel, RewSpell, RewSpellCast, RewMailTemplateId, RewMailDelaySecs, PointMapId, PointX, PointY, PointOpt,"
|
||||
// 110 111 112 113 114 115 116 117 118 119
|
||||
// 112 113 114 115 116 117 118 119 120 121
|
||||
"DetailsEmote1, DetailsEmote2, DetailsEmote3, DetailsEmote4,IncompleteEmote, CompleteEmote, OfferRewardEmote1, OfferRewardEmote2, OfferRewardEmote3, OfferRewardEmote4,"
|
||||
// 120 121
|
||||
// 122 123
|
||||
"StartScript, CompleteScript"
|
||||
" FROM quest_template");
|
||||
if(result == NULL)
|
||||
@@ -4776,17 +4829,19 @@ uint16 ObjectMgr::GetTaxiMount( uint32 id, uint32 team )
|
||||
TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(id);
|
||||
if(node)
|
||||
{
|
||||
if (team == ALLIANCE) mount_entry = node->alliance_mount_type;
|
||||
else mount_entry = node->horde_mount_type;
|
||||
|
||||
CreatureInfo const *cinfo = GetCreatureTemplate(mount_entry);
|
||||
if (cinfo)
|
||||
if (team == ALLIANCE)
|
||||
{
|
||||
if(! (mount_id = cinfo->GetRandomValidModelId()))
|
||||
{
|
||||
sLog.outErrorDb("No displayid found for the taxi mount with the entry %u! Can't load it!", mount_entry);
|
||||
return false;
|
||||
}
|
||||
mount_entry = node->MountCreatureID[1];
|
||||
CreatureInfo const *ci = GetCreatureTemplate(mount_entry);
|
||||
if(ci)
|
||||
mount_id = ci->Modelid1;
|
||||
}
|
||||
if (team == HORDE)
|
||||
{
|
||||
mount_entry = node->MountCreatureID[0];
|
||||
CreatureInfo const *ci = GetCreatureTemplate(mount_entry);
|
||||
if(ci)
|
||||
mount_id = ci->Modelid3;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5265,6 +5320,8 @@ void ObjectMgr::SetHighestGuids()
|
||||
|
||||
// pet guids are not saved to DB, set to 0 (pet guid != pet id)
|
||||
m_hiPetGuid = 0;
|
||||
// same for vehicles
|
||||
m_hiVehicleGuid = 0;
|
||||
|
||||
result = CharacterDatabase.Query( "SELECT MAX(guid) FROM item_instance" );
|
||||
if( result )
|
||||
@@ -5418,6 +5475,14 @@ uint32 ObjectMgr::GenerateLowGuid(HighGuid guidhigh)
|
||||
World::StopNow(ERROR_EXIT_CODE);
|
||||
}
|
||||
return m_hiPetGuid++;
|
||||
case HIGHGUID_VEHICLE:
|
||||
++m_hiVehicleGuid;
|
||||
if(m_hiVehicleGuid>=0x00FFFFFF)
|
||||
{
|
||||
sLog.outError("Vehicle guid overflow!! Can't continue, shutting down server. ");
|
||||
World::StopNow(ERROR_EXIT_CODE);
|
||||
}
|
||||
return m_hiVehicleGuid++;
|
||||
case HIGHGUID_PLAYER:
|
||||
if(m_hiCharGuid>=0xFFFFFFFE)
|
||||
{
|
||||
@@ -6380,6 +6445,23 @@ int ObjectMgr::GetOrNewIndexForLocale( LocaleConstant loc )
|
||||
return m_LocalForIndex.size()-1;
|
||||
}
|
||||
|
||||
AchievementCriteriaEntryList const& ObjectMgr::GetAchievementCriteriaByType(AchievementCriteriaTypes type)
|
||||
{
|
||||
return m_AchievementCriteriasByType[type];
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadAchievementCriteriaList()
|
||||
{
|
||||
for (uint32 entryId = 0; entryId<sAchievementCriteriaStore.GetNumRows(); entryId++)
|
||||
{
|
||||
AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(entryId);
|
||||
if(!criteria)
|
||||
continue;
|
||||
|
||||
m_AchievementCriteriasByType[criteria->requiredType].push_back(criteria);
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadBattleMastersEntry()
|
||||
{
|
||||
mBattleMastersMap.clear(); // need for reload case
|
||||
@@ -6756,7 +6838,7 @@ bool PlayerCondition::Meets(Player const * player) const
|
||||
{
|
||||
Unit::AuraMap const& auras = player->GetAuras();
|
||||
for(Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
|
||||
if((itr->second->GetSpellProto()->Attributes & 0x1000010) && itr->second->GetSpellProto()->SpellVisual==3580)
|
||||
if((itr->second->GetSpellProto()->Attributes & 0x1000010) && itr->second->GetSpellProto()->SpellVisual[0]==3580)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -6933,7 +7015,7 @@ SkillRangeType GetSkillRangeType(SkillLineEntry const *pSkill, bool racial)
|
||||
return SKILL_RANGE_MONO;
|
||||
case SKILL_CATEGORY_ARMOR:
|
||||
case SKILL_CATEGORY_CLASS:
|
||||
if(pSkill->id != SKILL_POISONS && pSkill->id != SKILL_LOCKPICKING)
|
||||
if(pSkill->id != SKILL_LOCKPICKING)
|
||||
return SKILL_RANGE_MONO;
|
||||
else
|
||||
return SKILL_RANGE_LEVEL;
|
||||
@@ -6948,7 +7030,7 @@ SkillRangeType GetSkillRangeType(SkillLineEntry const *pSkill, bool racial)
|
||||
return SKILL_RANGE_MONO;
|
||||
default:
|
||||
case SKILL_CATEGORY_ATTRIBUTES: //not found in dbc
|
||||
case SKILL_CATEGORY_NOT_DISPLAYED: //only GENEREC(DND)
|
||||
case SKILL_CATEGORY_GENERIC: //only GENERIC(DND)
|
||||
return SKILL_RANGE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,6 +264,8 @@ typedef std::list<GossipOption> CacheNpcOptionList;
|
||||
typedef UNORDERED_MAP<uint32, VendorItemData> CacheVendorItemMap;
|
||||
typedef UNORDERED_MAP<uint32, TrainerSpellData> CacheTrainerSpellMap;
|
||||
|
||||
typedef std::list<const AchievementCriteriaEntry*> AchievementCriteriaEntryList;
|
||||
|
||||
enum SkillRangeType
|
||||
{
|
||||
SKILL_RANGE_LANGUAGE, // 300..300
|
||||
@@ -588,6 +590,7 @@ class ObjectMgr
|
||||
void LoadNpcTextId();
|
||||
void LoadVendors();
|
||||
void LoadTrainerSpell();
|
||||
void LoadCompletedAchievements();
|
||||
|
||||
std::string GeneratePetName(uint32 entry);
|
||||
uint32 GetBaseXP(uint32 level);
|
||||
@@ -801,6 +804,10 @@ class ObjectMgr
|
||||
bool RemoveVendorItem(uint32 entry,uint32 item, bool savetodb = true); // for event
|
||||
bool IsVendorItemValid( uint32 vendor_entry, uint32 item, uint32 maxcount, uint32 ptime, uint32 ExtendedCost, Player* pl = NULL, std::set<uint32>* skip_vendors = NULL, uint32 ORnpcflag = 0 ) const;
|
||||
|
||||
void LoadAchievementCriteriaList();
|
||||
AchievementCriteriaEntryList const& GetAchievementCriteriaByType(AchievementCriteriaTypes type);
|
||||
std::set<uint32> allCompletedAchievements;
|
||||
|
||||
void LoadScriptNames();
|
||||
ScriptNameMap &GetScriptNames() { return m_scriptNames; }
|
||||
const char * GetScriptName(uint32 id) { return id < m_scriptNames.size() ? m_scriptNames[id].c_str() : ""; }
|
||||
@@ -819,6 +826,7 @@ class ObjectMgr
|
||||
uint32 m_hiCharGuid;
|
||||
uint32 m_hiCreatureGuid;
|
||||
uint32 m_hiPetGuid;
|
||||
uint32 m_hiVehicleGuid;
|
||||
uint32 m_hiItemGuid;
|
||||
uint32 m_hiGoGuid;
|
||||
uint32 m_hiDoGuid;
|
||||
@@ -929,6 +937,9 @@ class ObjectMgr
|
||||
CacheNpcTextIdMap m_mCacheNpcTextIdMap;
|
||||
CacheVendorItemMap m_mCacheVendorItemMap;
|
||||
CacheTrainerSpellMap m_mCacheTrainerSpellMap;
|
||||
|
||||
// store achievement criterias by type to speed up lookup
|
||||
AchievementCriteriaEntryList m_AchievementCriteriasByType[ACHIEVEMENT_CRITERIA_TYPE_TOTAL];
|
||||
};
|
||||
|
||||
#define objmgr Trinity::Singleton<ObjectMgr>::Instance()
|
||||
|
||||
+1190
-1060
File diff suppressed because it is too large
Load Diff
+262
-134
@@ -49,8 +49,8 @@ enum Opcodes
|
||||
CMSG_ZONE_MAP = 0x00A,
|
||||
SMSG_ZONE_MAP = 0x00B,
|
||||
CMSG_DEBUG_CHANGECELLZONE = 0x00C,
|
||||
CMSG_EMBLAZON_TABARD_OBSOLETE = 0x00D,
|
||||
CMSG_UNEMBLAZON_TABARD_OBSOLETE = 0x00E,
|
||||
CMSG_MOVE_CHARACTER_CHEAT = 0x00D,
|
||||
SMSG_MOVE_CHARACTER_CHEAT = 0x00E,
|
||||
CMSG_RECHARGE = 0x00F,
|
||||
CMSG_LEARN_SPELL = 0x010,
|
||||
CMSG_CREATEMONSTER = 0x011,
|
||||
@@ -66,7 +66,7 @@ enum Opcodes
|
||||
SMSG_FORCEACTIONSHOW = 0x01B,
|
||||
CMSG_PETGODMODE = 0x01C,
|
||||
SMSG_PETGODMODE = 0x01D,
|
||||
SMSG_DEBUGINFOSPELLMISS_OBSOLETE = 0x01E,
|
||||
SMSG_REFER_A_FRIEND_EXPIRED = 0x01E,
|
||||
CMSG_WEATHER_SPEED_CHEAT = 0x01F,
|
||||
CMSG_UNDRESSPLAYER = 0x020,
|
||||
CMSG_BEASTMASTER = 0x021,
|
||||
@@ -86,7 +86,7 @@ enum Opcodes
|
||||
SMSG_DEBUG_AISTATE = 0x02F,
|
||||
CMSG_DISABLE_PVP_CHEAT = 0x030,
|
||||
CMSG_ADVANCE_SPAWN_TIME = 0x031,
|
||||
CMSG_PVP_PORT_OBSOLETE = 0x032,
|
||||
SMSG_DESTRUCTIBLE_BUILDING_DAMAGE = 0x032,
|
||||
CMSG_AUTH_SRP6_BEGIN = 0x033,
|
||||
CMSG_AUTH_SRP6_PROOF = 0x034,
|
||||
CMSG_AUTH_SRP6_RECODE = 0x035,
|
||||
@@ -214,7 +214,7 @@ enum Opcodes
|
||||
SMSG_READ_ITEM_FAILED = 0x0AF,
|
||||
SMSG_ITEM_COOLDOWN = 0x0B0,
|
||||
CMSG_GAMEOBJ_USE = 0x0B1,
|
||||
CMSG_GAMEOBJ_CHAIR_USE_OBSOLETE = 0x0B2,
|
||||
CMSG_DESTROY_ITEMS = 0x0B2,
|
||||
SMSG_GAMEOBJECT_CUSTOM_ANIM = 0x0B3,
|
||||
CMSG_AREATRIGGER = 0x0B4,
|
||||
MSG_MOVE_START_FORWARD = 0x0B5,
|
||||
@@ -347,7 +347,7 @@ enum Opcodes
|
||||
SMSG_SPELL_COOLDOWN = 0x134,
|
||||
SMSG_COOLDOWN_EVENT = 0x135,
|
||||
CMSG_CANCEL_AURA = 0x136,
|
||||
SMSG_UPDATE_AURA_DURATION = 0x137,
|
||||
SMSG_UPDATE_AURA_DURATION_OBSOLETE = 0x137,
|
||||
SMSG_PET_CAST_FAILED = 0x138,
|
||||
MSG_CHANNEL_START = 0x139,
|
||||
MSG_CHANNEL_UPDATE = 0x13A,
|
||||
@@ -371,10 +371,10 @@ enum Opcodes
|
||||
SMSG_DAMAGE_DONE_OBSOLETE = 0x14C,
|
||||
SMSG_DAMAGE_TAKEN_OBSOLETE = 0x14D,
|
||||
SMSG_CANCEL_COMBAT = 0x14E,
|
||||
SMSG_PLAYER_COMBAT_XP_GAIN_OBSOLETE = 0x14F,
|
||||
SMSG_SPELLBREAKLOG = 0x14F,
|
||||
SMSG_SPELLHEALLOG = 0x150,
|
||||
SMSG_SPELLENERGIZELOG = 0x151,
|
||||
CMSG_SHEATHE_OBSOLETE = 0x152,
|
||||
SMSG_BREAK_TARGET = 0x152,
|
||||
CMSG_SAVE_PLAYER = 0x153,
|
||||
CMSG_SETDEATHBINDPOINT = 0x154,
|
||||
SMSG_BINDPOINTUPDATE = 0x155,
|
||||
@@ -578,7 +578,7 @@ enum Opcodes
|
||||
SMSG_GMTICKET_SYSTEMSTATUS = 0x21B,
|
||||
CMSG_SPIRIT_HEALER_ACTIVATE = 0x21C,
|
||||
CMSG_SET_STAT_CHEAT = 0x21D,
|
||||
SMSG_SET_REST_START = 0x21E,
|
||||
SMSG_SET_REST_START_OBSOLETE = 0x21E,
|
||||
CMSG_SKILL_BUY_STEP = 0x21F,
|
||||
CMSG_SKILL_BUY_RANK = 0x220,
|
||||
CMSG_XP_CHEAT = 0x221,
|
||||
@@ -733,8 +733,8 @@ enum Opcodes
|
||||
SMSG_SCRIPT_MESSAGE = 0x2B6,
|
||||
SMSG_DUEL_COUNTDOWN = 0x2B7,
|
||||
SMSG_AREA_TRIGGER_MESSAGE = 0x2B8,
|
||||
CMSG_TOGGLE_HELM = 0x2B9,
|
||||
CMSG_TOGGLE_CLOAK = 0x2BA,
|
||||
CMSG_SHOWING_HELM = 0x2B9,
|
||||
CMSG_SHOWING_CLOAK = 0x2BA,
|
||||
SMSG_MEETINGSTONE_JOINFAILED = 0x2BB,
|
||||
SMSG_PLAYER_SKINNED = 0x2BC,
|
||||
SMSG_DURABILITY_DAMAGE_DEATH = 0x2BD,
|
||||
@@ -967,10 +967,10 @@ enum Opcodes
|
||||
SMSG_VOICE_SESSION_ADJUST_PRIORITY = 0x3A0,
|
||||
CMSG_VOICE_SET_TALKER_MUTED_REQUEST = 0x3A1,
|
||||
SMSG_VOICE_SET_TALKER_MUTED = 0x3A2,
|
||||
SMSG_INIT_EXTRA_AURA_INFO = 0x3A3,
|
||||
SMSG_SET_EXTRA_AURA_INFO = 0x3A4,
|
||||
SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE = 0x3A5,
|
||||
SMSG_CLEAR_EXTRA_AURA_INFO = 0x3A6,
|
||||
SMSG_INIT_EXTRA_AURA_INFO_OBSOLETE = 0x3A3,
|
||||
SMSG_SET_EXTRA_AURA_INFO_OBSOLETE = 0x3A4,
|
||||
SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE_OBSOLETE = 0x3A5,
|
||||
SMSG_CLEAR_EXTRA_AURA_INFO_OBSOLETE = 0x3A6,
|
||||
MSG_MOVE_START_DESCEND = 0x3A7,
|
||||
CMSG_IGNORE_REQUIREMENTS_CHEAT = 0x3A8,
|
||||
SMSG_IGNORE_REQUIREMENTS_CHEAT = 0x3A9,
|
||||
@@ -980,127 +980,255 @@ enum Opcodes
|
||||
MSG_MOVE_UPDATE_CAN_FLY = 0x3AD,
|
||||
MSG_RAID_READY_CHECK_CONFIRM = 0x3AE,
|
||||
CMSG_VOICE_SESSION_ENABLE = 0x3AF,
|
||||
SMSG_VOICE_PARENTAL_CONTROLS = 0x3B0,
|
||||
CMSG_GM_WHISPER = 0x3B1,
|
||||
SMSG_GM_MESSAGECHAT = 0x3B2,
|
||||
MSG_GM_GEARRATING = 0x3B3,
|
||||
CMSG_COMMENTATOR_ENABLE = 0x3B4,
|
||||
SMSG_COMMENTATOR_STATE_CHANGED = 0x3B5,
|
||||
CMSG_COMMENTATOR_GET_MAP_INFO = 0x3B6,
|
||||
SMSG_COMMENTATOR_MAP_INFO = 0x3B7,
|
||||
CMSG_COMMENTATOR_GET_PLAYER_INFO = 0x3B8,
|
||||
SMSG_COMMENTATOR_GET_PLAYER_INFO = 0x3B9,
|
||||
SMSG_COMMENTATOR_PLAYER_INFO = 0x3BA,
|
||||
CMSG_COMMENTATOR_ENTER_INSTANCE = 0x3BB,
|
||||
CMSG_COMMENTATOR_EXIT_INSTANCE = 0x3BC,
|
||||
CMSG_COMMENTATOR_INSTANCE_COMMAND = 0x3BD,
|
||||
SMSG_CLEAR_TARGET = 0x3BE,
|
||||
CMSG_BOT_DETECTED = 0x3BF,
|
||||
SMSG_CROSSED_INEBRIATION_THRESHOLD = 0x3C0,
|
||||
CMSG_CHEAT_PLAYER_LOGIN = 0x3C1,
|
||||
CMSG_CHEAT_PLAYER_LOOKUP = 0x3C2,
|
||||
SMSG_CHEAT_PLAYER_LOOKUP = 0x3C3,
|
||||
SMSG_KICK_REASON = 0x3C4,
|
||||
MSG_RAID_READY_CHECK_FINISHED = 0x3C5,
|
||||
CMSG_COMPLAIN = 0x3C6,
|
||||
SMSG_COMPLAIN_RESULT = 0x3C7,
|
||||
SMSG_FEATURE_SYSTEM_STATUS = 0x3C8,
|
||||
CMSG_GM_SHOW_COMPLAINTS = 0x3C9,
|
||||
CMSG_GM_UNSQUELCH = 0x3CA,
|
||||
CMSG_CHANNEL_SILENCE_VOICE = 0x3CB,
|
||||
CMSG_CHANNEL_SILENCE_ALL = 0x3CC,
|
||||
CMSG_CHANNEL_UNSILENCE_VOICE = 0x3CD,
|
||||
CMSG_CHANNEL_UNSILENCE_ALL = 0x3CE,
|
||||
CMSG_TARGET_CAST = 0x3CF,
|
||||
CMSG_TARGET_SCRIPT_CAST = 0x3D0,
|
||||
CMSG_CHANNEL_DISPLAY_LIST = 0x3D1,
|
||||
CMSG_SET_ACTIVE_VOICE_CHANNEL = 0x3D2,
|
||||
CMSG_GET_CHANNEL_MEMBER_COUNT = 0x3D3,
|
||||
SMSG_CHANNEL_MEMBER_COUNT = 0x3D4,
|
||||
CMSG_CHANNEL_VOICE_ON = 0x3D5,
|
||||
CMSG_CHANNEL_VOICE_OFF = 0x3D6,
|
||||
CMSG_DEBUG_LIST_TARGETS = 0x3D7,
|
||||
SMSG_DEBUG_LIST_TARGETS = 0x3D8,
|
||||
SMSG_AVAILABLE_VOICE_CHANNEL = 0x3D9,
|
||||
CMSG_ADD_VOICE_IGNORE = 0x3DA,
|
||||
CMSG_DEL_VOICE_IGNORE = 0x3DB,
|
||||
CMSG_PARTY_SILENCE = 0x3DC,
|
||||
CMSG_PARTY_UNSILENCE = 0x3DD,
|
||||
MSG_NOTIFY_PARTY_SQUELCH = 0x3DE,
|
||||
SMSG_COMSAT_RECONNECT_TRY = 0x3DF,
|
||||
SMSG_COMSAT_DISCONNECT = 0x3E0,
|
||||
SMSG_COMSAT_CONNECT_FAIL = 0x3E1,
|
||||
SMSG_VOICE_CHAT_STATUS = 0x3E2,
|
||||
CMSG_REPORT_PVP_AFK = 0x3E3,
|
||||
CMSG_REPORT_PVP_AFK_RESULT = 0x3E4,
|
||||
CMSG_GUILD_BANKER_ACTIVATE = 0x3E5,
|
||||
CMSG_GUILD_BANK_QUERY_TAB = 0x3E6,
|
||||
SMSG_GUILD_BANK_LIST = 0x3E7,
|
||||
CMSG_GUILD_BANK_SWAP_ITEMS = 0x3E8,
|
||||
CMSG_GUILD_BANK_BUY_TAB = 0x3E9,
|
||||
CMSG_GUILD_BANK_UPDATE_TAB = 0x3EA,
|
||||
CMSG_GUILD_BANK_DEPOSIT_MONEY = 0x3EB,
|
||||
CMSG_GUILD_BANK_WITHDRAW_MONEY = 0x3EC,
|
||||
MSG_GUILD_BANK_LOG_QUERY = 0x3ED,
|
||||
CMSG_SET_CHANNEL_WATCH = 0x3EE,
|
||||
SMSG_USERLIST_ADD = 0x3EF,
|
||||
SMSG_USERLIST_REMOVE = 0x3F0,
|
||||
SMSG_USERLIST_UPDATE = 0x3F1,
|
||||
CMSG_CLEAR_CHANNEL_WATCH = 0x3F2,
|
||||
SMSG_INSPECT_TALENT = 0x3F3,
|
||||
SMSG_GOGOGO_OBSOLETE = 0x3F4,
|
||||
SMSG_ECHO_PARTY_SQUELCH = 0x3F5,
|
||||
CMSG_SET_TITLE_SUFFIX = 0x3F6,
|
||||
CMSG_SPELLCLICK = 0x3F7,
|
||||
SMSG_LOOT_LIST = 0x3F8,
|
||||
CMSG_GM_CHARACTER_RESTORE = 0x3F9,
|
||||
CMSG_GM_CHARACTER_SAVE = 0x3FA,
|
||||
SMSG_VOICESESSION_FULL = 0x3FB,
|
||||
MSG_GUILD_PERMISSIONS = 0x3FC,
|
||||
MSG_GUILD_BANK_MONEY_WITHDRAWN = 0x3FD,
|
||||
MSG_GUILD_EVENT_LOG_QUERY = 0x3FE,
|
||||
CMSG_MAELSTROM_RENAME_GUILD = 0x3FF,
|
||||
CMSG_GET_MIRRORIMAGE_DATA = 0x400,
|
||||
SMSG_MIRRORIMAGE_DATA = 0x401,
|
||||
SMSG_FORCE_DISPLAY_UPDATE = 0x402,
|
||||
SMSG_SPELL_CHANCE_RESIST_PUSHBACK = 0x403,
|
||||
CMSG_IGNORE_DIMINISHING_RETURNS_CHEAT = 0x404,
|
||||
SMSG_IGNORE_DIMINISHING_RETURNS_CHEAT = 0x405,
|
||||
CMSG_KEEP_ALIVE = 0x406,
|
||||
SMSG_RAID_READY_CHECK_ERROR = 0x407,
|
||||
CMSG_OPT_OUT_OF_LOOT = 0x408,
|
||||
MSG_QUERY_GUILD_BANK_TEXT = 0x409,
|
||||
CMSG_SET_GUILD_BANK_TEXT = 0x40A,
|
||||
CMSG_SET_GRANTABLE_LEVELS = 0x40B,
|
||||
CMSG_GRANT_LEVEL = 0x40C,
|
||||
CMSG_REFER_A_FRIEND = 0x40D,
|
||||
MSG_GM_CHANGE_ARENA_RATING = 0x40E,
|
||||
CMSG_DECLINE_CHANNEL_INVITE = 0x40F,
|
||||
CMSG_GROUPACTION_THROTTLED = 0x410,
|
||||
SMSG_OVERRIDE_LIGHT = 0x411,
|
||||
SMSG_TOTEM_CREATED = 0x412,
|
||||
CMSG_TOTEM_DESTROYED = 0x413,
|
||||
CMSG_EXPIRE_RAID_INSTANCE = 0x414,
|
||||
CMSG_NO_SPELL_VARIANCE = 0x415,
|
||||
CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY = 0x416,
|
||||
SMSG_QUESTGIVER_STATUS_MULTIPLE = 0x417,
|
||||
CMSG_SET_PLAYER_DECLINED_NAMES = 0x418,
|
||||
SMSG_SET_PLAYER_DECLINED_NAMES_RESULT = 0x419,
|
||||
CMSG_QUERY_SERVER_BUCK_DATA = 0x41A,
|
||||
CMSG_CLEAR_SERVER_BUCK_DATA = 0x41B,
|
||||
SMSG_SERVER_BUCK_DATA = 0x41C,
|
||||
SMSG_SEND_UNLEARN_SPELLS = 0x41D,
|
||||
SMSG_PROPOSE_LEVEL_GRANT = 0x41E,
|
||||
CMSG_ACCEPT_LEVEL_GRANT = 0x41F,
|
||||
SMSG_REFER_A_FRIEND_FAILURE = 0x420,
|
||||
SMSG_SPLINE_MOVE_SET_FLYING = 0x421,
|
||||
SMSG_SPLINE_MOVE_UNSET_FLYING = 0x422,
|
||||
SMSG_SUMMON_CANCEL = 0x423
|
||||
SMSG_VOICE_SESSION_ENABLE = 0x3B0,
|
||||
SMSG_VOICE_PARENTAL_CONTROLS = 0x3B1,
|
||||
CMSG_GM_WHISPER = 0x3B2,
|
||||
SMSG_GM_MESSAGECHAT = 0x3B3,
|
||||
MSG_GM_GEARRATING = 0x3B4,
|
||||
CMSG_COMMENTATOR_ENABLE = 0x3B5,
|
||||
SMSG_COMMENTATOR_STATE_CHANGED = 0x3B6,
|
||||
CMSG_COMMENTATOR_GET_MAP_INFO = 0x3B7,
|
||||
SMSG_COMMENTATOR_MAP_INFO = 0x3B8,
|
||||
CMSG_COMMENTATOR_GET_PLAYER_INFO = 0x3B9,
|
||||
SMSG_COMMENTATOR_GET_PLAYER_INFO = 0x3BA,
|
||||
SMSG_COMMENTATOR_PLAYER_INFO = 0x3BB,
|
||||
CMSG_COMMENTATOR_ENTER_INSTANCE = 0x3BC,
|
||||
CMSG_COMMENTATOR_EXIT_INSTANCE = 0x3BD,
|
||||
CMSG_COMMENTATOR_INSTANCE_COMMAND = 0x3BE,
|
||||
SMSG_CLEAR_TARGET = 0x3BF,
|
||||
CMSG_BOT_DETECTED = 0x3C0,
|
||||
SMSG_CROSSED_INEBRIATION_THRESHOLD = 0x3C1,
|
||||
CMSG_CHEAT_PLAYER_LOGIN = 0x3C2,
|
||||
CMSG_CHEAT_PLAYER_LOOKUP = 0x3C3,
|
||||
SMSG_CHEAT_PLAYER_LOOKUP = 0x3C4,
|
||||
SMSG_KICK_REASON = 0x3C5,
|
||||
MSG_RAID_READY_CHECK_FINISHED = 0x3C6,
|
||||
CMSG_COMPLAIN = 0x3C7,
|
||||
SMSG_COMPLAIN_RESULT = 0x3C8,
|
||||
SMSG_FEATURE_SYSTEM_STATUS = 0x3C9,
|
||||
CMSG_GM_SHOW_COMPLAINTS = 0x3CA,
|
||||
CMSG_GM_UNSQUELCH = 0x3CB,
|
||||
CMSG_CHANNEL_SILENCE_VOICE = 0x3CC,
|
||||
CMSG_CHANNEL_SILENCE_ALL = 0x3CD,
|
||||
CMSG_CHANNEL_UNSILENCE_VOICE = 0x3CE,
|
||||
CMSG_CHANNEL_UNSILENCE_ALL = 0x3CF,
|
||||
CMSG_TARGET_CAST = 0x3D0,
|
||||
CMSG_TARGET_SCRIPT_CAST = 0x3D1,
|
||||
CMSG_CHANNEL_DISPLAY_LIST = 0x3D2,
|
||||
CMSG_SET_ACTIVE_VOICE_CHANNEL = 0x3D3,
|
||||
CMSG_GET_CHANNEL_MEMBER_COUNT = 0x3D4,
|
||||
SMSG_CHANNEL_MEMBER_COUNT = 0x3D5,
|
||||
CMSG_CHANNEL_VOICE_ON = 0x3D6,
|
||||
CMSG_CHANNEL_VOICE_OFF = 0x3D7,
|
||||
CMSG_DEBUG_LIST_TARGETS = 0x3D8,
|
||||
SMSG_DEBUG_LIST_TARGETS = 0x3D9,
|
||||
SMSG_AVAILABLE_VOICE_CHANNEL = 0x3DA,
|
||||
CMSG_ADD_VOICE_IGNORE = 0x3DB,
|
||||
CMSG_DEL_VOICE_IGNORE = 0x3DC,
|
||||
CMSG_PARTY_SILENCE = 0x3DD,
|
||||
CMSG_PARTY_UNSILENCE = 0x3DE,
|
||||
MSG_NOTIFY_PARTY_SQUELCH = 0x3DF,
|
||||
SMSG_COMSAT_RECONNECT_TRY = 0x3E0,
|
||||
SMSG_COMSAT_DISCONNECT = 0x3E1,
|
||||
SMSG_COMSAT_CONNECT_FAIL = 0x3E2,
|
||||
SMSG_VOICE_CHAT_STATUS = 0x3E3,
|
||||
CMSG_REPORT_PVP_AFK = 0x3E4,
|
||||
CMSG_REPORT_PVP_AFK_RESULT = 0x3E5,
|
||||
CMSG_GUILD_BANKER_ACTIVATE = 0x3E6,
|
||||
CMSG_GUILD_BANK_QUERY_TAB = 0x3E7,
|
||||
SMSG_GUILD_BANK_LIST = 0x3E8,
|
||||
CMSG_GUILD_BANK_SWAP_ITEMS = 0x3E9,
|
||||
CMSG_GUILD_BANK_BUY_TAB = 0x3EA,
|
||||
CMSG_GUILD_BANK_UPDATE_TAB = 0x3EB,
|
||||
CMSG_GUILD_BANK_DEPOSIT_MONEY = 0x3EC,
|
||||
CMSG_GUILD_BANK_WITHDRAW_MONEY = 0x3ED,
|
||||
MSG_GUILD_BANK_LOG_QUERY = 0x3EE,
|
||||
CMSG_SET_CHANNEL_WATCH = 0x3EF,
|
||||
SMSG_USERLIST_ADD = 0x3F0,
|
||||
SMSG_USERLIST_REMOVE = 0x3F1,
|
||||
SMSG_USERLIST_UPDATE = 0x3F2,
|
||||
CMSG_CLEAR_CHANNEL_WATCH = 0x3F3,
|
||||
SMSG_INSPECT_TALENT = 0x3F4,
|
||||
SMSG_GOGOGO_OBSOLETE = 0x3F5,
|
||||
SMSG_ECHO_PARTY_SQUELCH = 0x3F6,
|
||||
CMSG_SET_TITLE_SUFFIX = 0x3F7,
|
||||
CMSG_SPELLCLICK = 0x3F8,
|
||||
SMSG_LOOT_LIST = 0x3F9,
|
||||
CMSG_GM_CHARACTER_RESTORE = 0x3FA,
|
||||
CMSG_GM_CHARACTER_SAVE = 0x3FB,
|
||||
SMSG_VOICESESSION_FULL = 0x3FC,
|
||||
MSG_GUILD_PERMISSIONS = 0x3FD,
|
||||
MSG_GUILD_BANK_MONEY_WITHDRAWN = 0x3FE,
|
||||
MSG_GUILD_EVENT_LOG_QUERY = 0x3FF,
|
||||
CMSG_MAELSTROM_RENAME_GUILD = 0x400,
|
||||
CMSG_GET_MIRRORIMAGE_DATA = 0x401,
|
||||
SMSG_MIRRORIMAGE_DATA = 0x402,
|
||||
SMSG_FORCE_DISPLAY_UPDATE = 0x403,
|
||||
SMSG_SPELL_CHANCE_RESIST_PUSHBACK = 0x404,
|
||||
CMSG_IGNORE_DIMINISHING_RETURNS_CHEAT = 0x405,
|
||||
SMSG_IGNORE_DIMINISHING_RETURNS_CHEAT = 0x406,
|
||||
CMSG_KEEP_ALIVE = 0x407,
|
||||
SMSG_RAID_READY_CHECK_ERROR = 0x408,
|
||||
CMSG_OPT_OUT_OF_LOOT = 0x409,
|
||||
MSG_QUERY_GUILD_BANK_TEXT = 0x40A,
|
||||
CMSG_SET_GUILD_BANK_TEXT = 0x40B,
|
||||
CMSG_SET_GRANTABLE_LEVELS = 0x40C,
|
||||
CMSG_GRANT_LEVEL = 0x40D,
|
||||
CMSG_REFER_A_FRIEND = 0x40E,
|
||||
MSG_GM_CHANGE_ARENA_RATING = 0x40F,
|
||||
CMSG_DECLINE_CHANNEL_INVITE = 0x410,
|
||||
CMSG_GROUPACTION_THROTTLED = 0x411,
|
||||
SMSG_OVERRIDE_LIGHT = 0x412,
|
||||
SMSG_TOTEM_CREATED = 0x413,
|
||||
CMSG_TOTEM_DESTROYED = 0x414,
|
||||
CMSG_EXPIRE_RAID_INSTANCE = 0x415,
|
||||
CMSG_NO_SPELL_VARIANCE = 0x416,
|
||||
CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY = 0x417,
|
||||
SMSG_QUESTGIVER_STATUS_MULTIPLE = 0x418,
|
||||
CMSG_SET_PLAYER_DECLINED_NAMES = 0x419,
|
||||
SMSG_SET_PLAYER_DECLINED_NAMES_RESULT = 0x41A,
|
||||
CMSG_QUERY_SERVER_BUCK_DATA = 0x41B,
|
||||
CMSG_CLEAR_SERVER_BUCK_DATA = 0x41C,
|
||||
SMSG_SERVER_BUCK_DATA = 0x41D,
|
||||
SMSG_SEND_UNLEARN_SPELLS = 0x41E,
|
||||
SMSG_PROPOSE_LEVEL_GRANT = 0x41F,
|
||||
CMSG_ACCEPT_LEVEL_GRANT = 0x420,
|
||||
SMSG_REFER_A_FRIEND_FAILURE = 0x421,
|
||||
SMSG_SPLINE_MOVE_SET_FLYING = 0x422,
|
||||
SMSG_SPLINE_MOVE_UNSET_FLYING = 0x423,
|
||||
SMSG_SUMMON_CANCEL = 0x424,
|
||||
CMSG_CHANGE_PERSONAL_ARENA_RATING = 0x425,
|
||||
CMSG_ALTER_APPEARANCE = 0x426,
|
||||
SMSG_ENABLE_BARBER_SHOP = 0x427,
|
||||
SMSG_BARBER_SHOP_RESULT = 0x428,
|
||||
CMSG_CALENDAR_GET_CALENDAR = 0x429,
|
||||
CMSG_CALENDAR_GET_EVENT = 0x42A,
|
||||
CMSG_CALENDAR_GUILD_FILTER = 0x42B,
|
||||
CMSG_CALENDAR_ARENA_TEAM = 0x42C,
|
||||
CMSG_CALENDAR_ADD_EVENT = 0x42D,
|
||||
CMSG_CALENDAR_UPDATE_EVENT = 0x42E,
|
||||
CMSG_CALENDAR_REMOVE_EVENT = 0x42F,
|
||||
CMSG_CALENDAR_COPY_EVENT = 0x430,
|
||||
CMSG_CALENDAR_EVENT_INVITE = 0x431,
|
||||
CMSG_CALENDAR_EVENT_RSVP = 0x432,
|
||||
CMSG_CALENDAR_EVENT_REMOVE_INVITE = 0x433,
|
||||
CMSG_CALENDAR_EVENT_STATUS = 0x434,
|
||||
CMSG_CALENDAR_EVENT_MODERATOR_STATUS = 0x435,
|
||||
SMSG_CALENDAR_SEND_CALENDAR = 0x436,
|
||||
SMSG_CALENDAR_SEND_EVENT = 0x437,
|
||||
SMSG_CALENDAR_FILTER_GUILD = 0x438,
|
||||
SMSG_CALENDAR_ARENA_TEAM = 0x439,
|
||||
SMSG_CALENDAR_EVENT_INVITE = 0x43A,
|
||||
SMSG_CALENDAR_EVENT_INVITE_REMOVED = 0x43B,
|
||||
SMSG_CALENDAR_EVENT_STATUS = 0x43C,
|
||||
SMSG_CALENDAR_COMMAND_RESULT = 0x43D,
|
||||
SMSG_CALENDAR_RAID_LOCKOUT_ADDED = 0x43E,
|
||||
SMSG_CALENDAR_RAID_LOCKOUT_REMOVED = 0x43F,
|
||||
SMSG_CALENDAR_EVENT_INVITE_ALERT = 0x440,
|
||||
SMSG_CALENDAR_EVENT_INVITE_REMOVED_ALERT = 0x441,
|
||||
SMSG_CALENDAR_EVENT_INVITE_STATUS_ALERT = 0x442,
|
||||
SMSG_CALENDAR_EVENT_REMOVED_ALERT = 0x443,
|
||||
SMSG_CALENDAR_EVENT_UPDATED_ALERT = 0x444,
|
||||
SMSG_CALENDAR_EVENT_MODERATOR_STATUS_ALERT = 0x445,
|
||||
CMSG_CALENDAR_COMPLAIN = 0x446,
|
||||
CMSG_CALENDAR_GET_NUM_PENDING = 0x447,
|
||||
SMSG_CALENDAR_SEND_NUM_PENDING = 0x448,
|
||||
CMSG_SAVE_DANCE = 0x449,
|
||||
SMSG_NOTIFY_DANCE = 0x44A,
|
||||
CMSG_PLAY_DANCE = 0x44B,
|
||||
SMSG_PLAY_DANCE = 0x44C,
|
||||
CMSG_LOAD_DANCES = 0x44D,
|
||||
CMSG_STOP_DANCE = 0x44E,
|
||||
SMSG_STOP_DANCE = 0x44F,
|
||||
CMSG_SYNC_DANCE = 0x450,
|
||||
CMSG_DANCE_QUERY = 0x451,
|
||||
SMSG_DANCE_QUERY_RESPONSE = 0x452,
|
||||
SMSG_INVALIDATE_DANCE = 0x453,
|
||||
CMSG_DELETE_DANCE = 0x454,
|
||||
SMSG_LEARNED_DANCE_MOVES = 0x455,
|
||||
CMSG_LEARN_DANCE_MOVE = 0x456,
|
||||
CMSG_UNLEARN_DANCE_MOVE = 0x457,
|
||||
CMSG_SET_RUNE_COUNT = 0x458,
|
||||
CMSG_SET_RUNE_COOLDOWN = 0x459,
|
||||
MSG_MOVE_SET_PITCH_RATE_CHEAT = 0x45A,
|
||||
MSG_MOVE_SET_PITCH_RATE = 0x45B,
|
||||
SMSG_FORCE_PITCH_RATE_CHANGE = 0x45C,
|
||||
CMSG_FORCE_PITCH_RATE_CHANGE_ACK = 0x45D,
|
||||
SMSG_SPLINE_SET_PITCH_RATE = 0x45E,
|
||||
SMSG_MOVE_ABANDON_TRANSPORT = 0x45F,
|
||||
MSG_MOVE_ABANDON_TRANSPORT = 0x460,
|
||||
CMSG_MOVE_ABANDON_TRANSPORT_ACK = 0x461,
|
||||
CMSG_UPDATE_MISSILE_TRAJECTORY = 0x462,
|
||||
SMSG_UPDATE_ACCOUNT_DATA_COMPLETE = 0x463,
|
||||
SMSG_TRIGGER_MOVIE = 0x464,
|
||||
CMSG_COMPLETE_MOVIE = 0x465,
|
||||
CMSG_SET_GLYPH_SLOT = 0x466,
|
||||
CMSG_SET_GLYPH = 0x467,
|
||||
SMSG_ACHIEVEMENT_EARNED = 0x468,
|
||||
SMSG_DYNAMIC_DROP_ROLL_RESULT = 0x469,
|
||||
SMSG_CRITERIA_UPDATE = 0x46A,
|
||||
CMSG_QUERY_INSPECT_ACHIEVEMENTS = 0x46B,
|
||||
SMSG_RESPOND_INSPECT_ACHIEVEMENTS = 0x46C,
|
||||
CMSG_DISMISS_CONTROLLED_VEHICLE = 0x46D,
|
||||
CMSG_COMPLETE_ACHIEVEMENT_CHEAT = 0x46E,
|
||||
SMSG_QUESTUPDATE_ADD_PVP_KILL = 0x46F,
|
||||
CMSG_SET_CRITERIA_CHEAT = 0x470,
|
||||
SMSG_GROUP_SWAP_FAILED = 0x471,
|
||||
CMSG_UNITANIMTIER_CHEAT = 0x472,
|
||||
CMSG_CHAR_CUSTOMIZE = 0x473,
|
||||
SMSG_CHAR_CUSTOMIZE = 0x474,
|
||||
SMSG_PET_RENAMEABLE = 0x475,
|
||||
CMSG_REQUEST_VEHICLE_EXIT = 0x476,
|
||||
CMSG_REQUEST_VEHICLE_PREV_SEAT = 0x477,
|
||||
CMSG_REQUEST_VEHICLE_NEXT_SEAT = 0x478,
|
||||
CMSG_REQUEST_VEHICLE_SWITCH_SEAT = 0x479,
|
||||
CMSG_PET_LEARN_TALENT = 0x47A,
|
||||
CMSG_PET_UNLEARN_TALENTS = 0x47B,
|
||||
SMSG_SET_PHASE_SHIFT = 0x47C,
|
||||
SMSG_ALL_ACHIEVEMENT_DATA = 0x47D,
|
||||
CMSG_FORCE_SAY_CHEAT = 0x47E,
|
||||
SMSG_HEALTH_UPDATE = 0x47F,
|
||||
SMSG_POWER_UPDATE = 0x480,
|
||||
CMSG_GAMEOBJ_REPORT_USE = 0x481,
|
||||
SMSG_HIGHEST_THREAT_UPDATE = 0x482,
|
||||
SMSG_THREAT_UPDATE = 0x483,
|
||||
SMSG_THREAT_REMOVE = 0x484,
|
||||
SMSG_THREAT_CLEAR = 0x485,
|
||||
SMSG_CONVERT_RUNE = 0x486,
|
||||
SMSG_RESYNC_RUNES = 0x487,
|
||||
SMSG_ADD_RUNE_POWER = 0x488,
|
||||
CMSG_START_QUEST = 0x489,
|
||||
CMSG_REMOVE_GLYPH = 0x48A,
|
||||
CMSG_DUMP_OBJECTS = 0x48B,
|
||||
SMSG_DUMP_OBJECTS_DATA = 0x48C,
|
||||
CMSG_DISMISS_CRITTER = 0x48D,
|
||||
SMSG_NOTIFY_DEST_LOC_SPELL_CAST = 0x48E,
|
||||
CMSG_AUCTION_LIST_PENDING_SALES = 0x48F,
|
||||
SMSG_AUCTION_LIST_PENDING_SALES = 0x490,
|
||||
SMSG_MODIFY_COOLDOWN = 0x491,
|
||||
SMSG_PET_UPDATE_COMBO_POINTS = 0x492,
|
||||
CMSG_ENABLETAXI = 0x493,
|
||||
SMSG_PRE_RESURRECT = 0x494,
|
||||
SMSG_AURA_UPDATE_ALL = 0x495,
|
||||
SMSG_AURA_UPDATE = 0x496,
|
||||
CMSG_FLOOD_GRACE_CHEAT = 0x497,
|
||||
SMSG_SERVER_FIRST_ACHIEVEMENT = 0x498,
|
||||
SMSG_PET_LEARNED_SPELL = 0x499,
|
||||
SMSG_PET_REMOVED_SPELL = 0x49A,
|
||||
CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE = 0x49B,
|
||||
CMSG_HEARTH_AND_RESURRECT = 0x49C,
|
||||
SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA = 0x49D,
|
||||
SMSG_CRITERIA_DELETED = 0x49E,
|
||||
SMSG_ACHIEVEMENT_DELETED = 0x49F,
|
||||
CMSG_SERVER_INFO_QUERY = 0x4A0,
|
||||
SMSG_SERVER_INFO_RESPONSE = 0x4A1,
|
||||
CMSG_CHECK_LOGIN_CRITERIA = 0x4A2,
|
||||
SMSG_SERVER_BUCK_DATA_START = 0x4A3,
|
||||
CMSG_QUERY_VEHICLE_STATUS = 0x4A4,
|
||||
SMSG_PET_GUIDS = 0x4A5,
|
||||
NUM_MSG_TYPES = 0x4A6
|
||||
};
|
||||
|
||||
// Don't forget to change this value and add opcode name to Opcodes.cpp when you add new opcode!
|
||||
#define NUM_MSG_TYPES 0x424
|
||||
|
||||
/// Player state
|
||||
enum SessionStatus
|
||||
{
|
||||
|
||||
+118
-277
@@ -41,27 +41,6 @@ char const* petTypeSuffix[MAX_PET_TYPE] =
|
||||
"'s Companion" // MINI_PET
|
||||
};
|
||||
|
||||
//numbers represent minutes * 100 while happy (you get 100 loyalty points per min while happy)
|
||||
uint32 const LevelUpLoyalty[6] =
|
||||
{
|
||||
5500,
|
||||
11500,
|
||||
17000,
|
||||
23500,
|
||||
31000,
|
||||
39500,
|
||||
};
|
||||
|
||||
uint32 const LevelStartLoyalty[6] =
|
||||
{
|
||||
2000,
|
||||
4500,
|
||||
7000,
|
||||
10000,
|
||||
13500,
|
||||
17500,
|
||||
};
|
||||
|
||||
Pet::Pet(PetType type) : Creature()
|
||||
{
|
||||
m_isPet = true;
|
||||
@@ -71,17 +50,16 @@ Pet::Pet(PetType type) : Creature()
|
||||
m_removed = false;
|
||||
m_regenTimer = 4000;
|
||||
m_happinessTimer = 7500;
|
||||
m_loyaltyTimer = 12000;
|
||||
m_duration = 0;
|
||||
m_bonusdamage = 0;
|
||||
|
||||
m_loyaltyPoints = 0;
|
||||
m_TrainingPoints = 0;
|
||||
m_resetTalentsCost = 0;
|
||||
m_resetTalentsTime = 0;
|
||||
|
||||
m_auraUpdateMask = 0;
|
||||
|
||||
m_loading = false;
|
||||
|
||||
// pets always have a charminfo, even if they are not actually charmed
|
||||
CharmInfo* charmInfo = InitCharmInfo(this);
|
||||
|
||||
@@ -128,24 +106,26 @@ void Pet::RemoveFromWorld()
|
||||
|
||||
bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool current )
|
||||
{
|
||||
m_loading = true;
|
||||
|
||||
uint32 ownerid = owner->GetGUIDLow();
|
||||
|
||||
QueryResult *result;
|
||||
|
||||
if(petnumber)
|
||||
// known petnumber entry 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
||||
result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, loyaltypoints, loyalty, trainpoint, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND id = '%u'",ownerid, petnumber);
|
||||
// known petnumber entry 0 1 2(?) 3 4 5 6 7 8(?) 9 10 11 12 13 14 15 16 17 18 19 20
|
||||
result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND id = '%u'",ownerid, petnumber);
|
||||
else if(current)
|
||||
// current pet (slot 0) 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
||||
result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, loyaltypoints, loyalty, trainpoint, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND slot = '0'",ownerid );
|
||||
// current pet (slot 0) 0 1 2(?) 3 4 5 6 7 8(?) 9 10 11 12 13 14 15 16 17 18 19 20
|
||||
result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND slot = '0'",ownerid );
|
||||
else if(petentry)
|
||||
// known petentry entry (unique for summoned pet, but non unique for hunter pet (only from current or not stabled pets)
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
||||
result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, loyaltypoints, loyalty, trainpoint, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND entry = '%u' AND (slot = '0' OR slot = '3') ",ownerid, petentry );
|
||||
// 0 1 2(?) 3 4 5 6 7 8(?) 9 10 11 12 13 14 15 16 17 18 19 20
|
||||
result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND entry = '%u' AND (slot = '0' OR slot = '3') ",ownerid, petentry );
|
||||
else
|
||||
// any current or other non-stabled pet (for hunter "call pet")
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
||||
result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, loyaltypoints, loyalty, trainpoint, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND (slot = '0' OR slot = '3') ",ownerid);
|
||||
// 0 1 2(?) 3 4 5 6 7 8(?) 9 10 11 12 13 14 15 16 17 18 19 20
|
||||
result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND (slot = '0' OR slot = '3') ",ownerid);
|
||||
|
||||
if(!result)
|
||||
return false;
|
||||
@@ -160,7 +140,7 @@ bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool cu
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 summon_spell_id = fields[21].GetUInt32();
|
||||
uint32 summon_spell_id = fields[19].GetUInt32();
|
||||
SpellEntry const* spellInfo = sSpellStore.LookupEntry(summon_spell_id);
|
||||
|
||||
bool is_temporary_summoned = spellInfo && GetSpellDuration(spellInfo) > 0;
|
||||
@@ -194,8 +174,8 @@ bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool cu
|
||||
return false;
|
||||
}
|
||||
|
||||
setPetType(PetType(fields[22].GetUInt8()));
|
||||
SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,owner->getFaction());
|
||||
setPetType(PetType(fields[20].GetUInt8()));
|
||||
SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, owner->getFaction());
|
||||
SetUInt32Value(UNIT_CREATED_BY_SPELL, summon_spell_id);
|
||||
|
||||
CreatureInfo const *cinfo = GetCreatureInfo();
|
||||
@@ -206,72 +186,67 @@ bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool cu
|
||||
delete result;
|
||||
return true;
|
||||
}
|
||||
if(getPetType()==HUNTER_PET || (getPetType()==SUMMON_PET && cinfo->type == CREATURE_TYPE_DEMON && owner->getClass() == CLASS_WARLOCK))
|
||||
|
||||
if(getPetType() == HUNTER_PET || (getPetType() == SUMMON_PET && cinfo->type == CREATURE_TYPE_DEMON && owner->getClass() == CLASS_WARLOCK))
|
||||
m_charmInfo->SetPetNumber(pet_number, true);
|
||||
else
|
||||
m_charmInfo->SetPetNumber(pet_number, false);
|
||||
SetUInt64Value(UNIT_FIELD_SUMMONEDBY, owner->GetGUID());
|
||||
|
||||
SetOwnerGUID(owner->GetGUID());
|
||||
SetDisplayId(fields[3].GetUInt32());
|
||||
SetNativeDisplayId(fields[3].GetUInt32());
|
||||
uint32 petlevel=fields[4].GetUInt32();
|
||||
SetUInt32Value(UNIT_NPC_FLAGS , 0);
|
||||
SetName(fields[11].GetString());
|
||||
uint32 petlevel = fields[4].GetUInt32();
|
||||
SetUInt32Value(UNIT_NPC_FLAGS, 0);
|
||||
SetName(fields[9].GetString());
|
||||
|
||||
switch(getPetType())
|
||||
{
|
||||
|
||||
case SUMMON_PET:
|
||||
petlevel=owner->getLevel();
|
||||
|
||||
SetUInt32Value(UNIT_FIELD_BYTES_0,2048);
|
||||
SetUInt32Value(UNIT_FIELD_BYTES_0, 2048);
|
||||
SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
|
||||
// this enables popup window (pet dismiss, cancel)
|
||||
break;
|
||||
case HUNTER_PET:
|
||||
SetUInt32Value(UNIT_FIELD_BYTES_0, 0x02020100);
|
||||
SetByteValue(UNIT_FIELD_BYTES_1, 1, fields[8].GetUInt32());
|
||||
SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE );
|
||||
SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_UNK3 | UNIT_BYTE2_FLAG_AURAS | UNIT_BYTE2_FLAG_UNK5 );
|
||||
|
||||
if(fields[12].GetBool())
|
||||
SetByteValue(UNIT_FIELD_BYTES_2, 2, UNIT_RENAME_NOT_ALLOWED);
|
||||
else
|
||||
SetByteValue(UNIT_FIELD_BYTES_2, 2, UNIT_RENAME_ALLOWED);
|
||||
SetByteValue(UNIT_FIELD_BYTES_1, 1, fields[7].GetUInt32());
|
||||
SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE);
|
||||
SetByteValue(UNIT_FIELD_BYTES_2, 2, fields[10].GetBool() ? UNIT_RENAME_NOT_ALLOWED : UNIT_RENAME_ALLOWED);
|
||||
|
||||
SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
|
||||
// this enables popup window (pet abandon, cancel)
|
||||
SetTP(fields[9].GetInt32());
|
||||
SetMaxPower(POWER_HAPPINESS,GetCreatePowers(POWER_HAPPINESS));
|
||||
SetPower( POWER_HAPPINESS,fields[15].GetUInt32());
|
||||
SetMaxPower(POWER_HAPPINESS, GetCreatePowers(POWER_HAPPINESS));
|
||||
SetPower(POWER_HAPPINESS, fields[13].GetUInt32());
|
||||
setPowerType(POWER_FOCUS);
|
||||
break;
|
||||
default:
|
||||
sLog.outError("Pet have incorrect type (%u) for pet loading.",getPetType());
|
||||
sLog.outError("Pet have incorrect type (%u) for pet loading.", getPetType());
|
||||
}
|
||||
InitStatsForLevel( petlevel);
|
||||
|
||||
InitStatsForLevel(petlevel);
|
||||
SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL));
|
||||
SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, fields[5].GetUInt32());
|
||||
SetUInt64Value(UNIT_FIELD_CREATEDBY, owner->GetGUID());
|
||||
SetCreatorGUID(owner->GetGUID());
|
||||
|
||||
m_charmInfo->SetReactState( ReactStates( fields[6].GetUInt8() ));
|
||||
m_loyaltyPoints = fields[7].GetInt32();
|
||||
m_charmInfo->SetReactState(ReactStates(fields[6].GetUInt8()));
|
||||
|
||||
uint32 savedhealth = fields[13].GetUInt32();
|
||||
uint32 savedmana = fields[14].GetUInt32();
|
||||
uint32 savedhealth = fields[11].GetUInt32();
|
||||
uint32 savedmana = fields[12].GetUInt32();
|
||||
|
||||
// set current pet as current
|
||||
if(fields[10].GetUInt32() != 0)
|
||||
if(fields[8].GetUInt32() != 0)
|
||||
{
|
||||
CharacterDatabase.BeginTransaction();
|
||||
CharacterDatabase.PExecute("UPDATE character_pet SET slot = '3' WHERE owner = '%u' AND slot = '0' AND id <> '%u'",ownerid, m_charmInfo->GetPetNumber());
|
||||
CharacterDatabase.PExecute("UPDATE character_pet SET slot = '0' WHERE owner = '%u' AND id = '%u'",ownerid, m_charmInfo->GetPetNumber());
|
||||
CharacterDatabase.PExecute("UPDATE character_pet SET slot = '3' WHERE owner = '%u' AND slot = '0' AND id <> '%u'", ownerid, m_charmInfo->GetPetNumber());
|
||||
CharacterDatabase.PExecute("UPDATE character_pet SET slot = '0' WHERE owner = '%u' AND id = '%u'", ownerid, m_charmInfo->GetPetNumber());
|
||||
CharacterDatabase.CommitTransaction();
|
||||
}
|
||||
|
||||
if(!is_temporary_summoned)
|
||||
{
|
||||
// permanent controlled pets store state in DB
|
||||
Tokens tokens = StrSplit(fields[16].GetString(), " ");
|
||||
Tokens tokens = StrSplit(fields[14].GetString(), " ");
|
||||
|
||||
if(tokens.size() != 20)
|
||||
{
|
||||
@@ -290,11 +265,11 @@ bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool cu
|
||||
// patch for old data where some spells have ACT_DECIDE but should have ACT_CAST
|
||||
// so overwrite old state
|
||||
SpellEntry const *spellInfo = sSpellStore.LookupEntry(m_charmInfo->GetActionBarEntry(index)->SpellOrAction);
|
||||
if (spellInfo && spellInfo->AttributesEx & SPELL_ATTR_EX_UNAUTOCASTABLE_BY_PET) m_charmInfo->GetActionBarEntry(index)->Type = ACT_CAST;
|
||||
if (spellInfo && spellInfo->AttributesEx & SPELL_ATTR_EX_UNAUTOCASTABLE_BY_PET) m_charmInfo->GetActionBarEntry(index)->Type = ACT_ENABLED;
|
||||
}
|
||||
|
||||
//init teach spells
|
||||
tokens = StrSplit(fields[17].GetString(), " ");
|
||||
tokens = StrSplit(fields[15].GetString(), " ");
|
||||
for (iter = tokens.begin(), index = 0; index < 4; ++iter, ++index)
|
||||
{
|
||||
uint32 tmp = atol((*iter).c_str());
|
||||
@@ -309,7 +284,10 @@ bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool cu
|
||||
}
|
||||
|
||||
// since last save (in seconds)
|
||||
uint32 timediff = (time(NULL) - fields[18].GetUInt32());
|
||||
uint32 timediff = (time(NULL) - fields[16].GetUInt32());
|
||||
|
||||
m_resetTalentsCost = fields[17].GetUInt32();
|
||||
m_resetTalentsTime = fields[18].GetUInt64();
|
||||
|
||||
delete result;
|
||||
|
||||
@@ -375,6 +353,7 @@ bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool cu
|
||||
}
|
||||
}
|
||||
|
||||
m_loading = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -417,10 +396,6 @@ void Pet::SavePetToDB(PetSaveMode mode)
|
||||
case PET_SAVE_IN_STABLE_SLOT_2:
|
||||
case PET_SAVE_NOT_IN_SLOT:
|
||||
{
|
||||
uint32 loyalty =1;
|
||||
if(getPetType()!=HUNTER_PET)
|
||||
loyalty = GetLoyaltyLevel();
|
||||
|
||||
uint32 owner = GUID_LOPART(GetOwnerGUID());
|
||||
std::string name = m_name;
|
||||
CharacterDatabase.escape_string(name);
|
||||
@@ -437,7 +412,7 @@ void Pet::SavePetToDB(PetSaveMode mode)
|
||||
CharacterDatabase.PExecute("DELETE FROM character_pet WHERE owner = '%u' AND (slot = '0' OR slot = '3')", owner );
|
||||
// save pet
|
||||
std::ostringstream ss;
|
||||
ss << "INSERT INTO character_pet ( id, entry, owner, modelid, level, exp, Reactstate, loyaltypoints, loyalty, trainpoint, slot, name, renamed, curhealth, curmana, curhappiness, abdata,TeachSpelldata,savetime,resettalents_cost,resettalents_time,CreatedBySpell,PetType) "
|
||||
ss << "INSERT INTO character_pet ( id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType) "
|
||||
<< "VALUES ("
|
||||
<< m_charmInfo->GetPetNumber() << ", "
|
||||
<< GetEntry() << ", "
|
||||
@@ -446,9 +421,7 @@ void Pet::SavePetToDB(PetSaveMode mode)
|
||||
<< getLevel() << ", "
|
||||
<< GetUInt32Value(UNIT_FIELD_PETEXPERIENCE) << ", "
|
||||
<< uint32(m_charmInfo->GetReactState()) << ", "
|
||||
<< m_loyaltyPoints << ", "
|
||||
<< GetLoyaltyLevel() << ", "
|
||||
<< m_TrainingPoints << ", "
|
||||
<< uint32(GetFreeTalentPoints()) << ", "
|
||||
<< uint32(mode) << ", '"
|
||||
<< name.c_str() << "', "
|
||||
<< uint32((GetByteValue(UNIT_FIELD_BYTES_2, 2) == UNIT_RENAME_ALLOWED)?0:1) << ", "
|
||||
@@ -521,12 +494,12 @@ void Pet::setDeathState(DeathState s) // overwrite virtual
|
||||
if(!mapEntry || (mapEntry->map_type != MAP_ARENA && mapEntry->map_type != MAP_BATTLEGROUND))
|
||||
ModifyPower(POWER_HAPPINESS, -HAPPINESS_LEVEL_SIZE);
|
||||
|
||||
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE);
|
||||
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
|
||||
}
|
||||
}
|
||||
else if(getDeathState()==ALIVE)
|
||||
{
|
||||
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE);
|
||||
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
|
||||
CastPetAuras(true);
|
||||
}
|
||||
}
|
||||
@@ -553,6 +526,7 @@ void Pet::Update(uint32 diff)
|
||||
// unsummon pet that lost owner
|
||||
Unit* owner = GetOwner();
|
||||
if(!owner || (!IsWithinDistInMap(owner, OWNER_MAX_DISTANCE) && !isPossessed()) || isControlled() && !owner->GetPetGUID())
|
||||
//if(!owner || (!IsWithinDistInMap(owner, OWNER_MAX_DISTANCE) && (owner->GetCharmGUID() && (owner->GetCharmGUID() != GetGUID()))) || (isControlled() && !owner->GetPetGUID()))
|
||||
{
|
||||
Remove(PET_SAVE_NOT_IN_SLOT, true);
|
||||
return;
|
||||
@@ -598,14 +572,6 @@ void Pet::Update(uint32 diff)
|
||||
else
|
||||
m_happinessTimer -= diff;
|
||||
|
||||
if(m_loyaltyTimer <= diff)
|
||||
{
|
||||
TickLoyaltyChange();
|
||||
m_loyaltyTimer = 12000;
|
||||
}
|
||||
else
|
||||
m_loyaltyTimer -= diff;
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -637,83 +603,12 @@ void Pet::LooseHappiness()
|
||||
uint32 curValue = GetPower(POWER_HAPPINESS);
|
||||
if (curValue <= 0)
|
||||
return;
|
||||
int32 addvalue = (140 >> GetLoyaltyLevel()) * 125; //value is 70/35/17/8/4 (per min) * 1000 / 8 (timer 7.5 secs)
|
||||
int32 addvalue = 670; //value is 70/35/17/8/4 (per min) * 1000 / 8 (timer 7.5 secs)
|
||||
if(isInCombat()) //we know in combat happiness fades faster, multiplier guess
|
||||
addvalue = int32(addvalue * 1.5);
|
||||
ModifyPower(POWER_HAPPINESS, -addvalue);
|
||||
}
|
||||
|
||||
void Pet::ModifyLoyalty(int32 addvalue)
|
||||
{
|
||||
uint32 loyaltylevel = GetLoyaltyLevel();
|
||||
|
||||
if(addvalue > 0) //only gain influenced, not loss
|
||||
addvalue = int32((float)addvalue * sWorld.getRate(RATE_LOYALTY));
|
||||
|
||||
if(loyaltylevel >= BEST_FRIEND && (addvalue + m_loyaltyPoints) > int32(GetMaxLoyaltyPoints(loyaltylevel)))
|
||||
return;
|
||||
|
||||
m_loyaltyPoints += addvalue;
|
||||
|
||||
if(m_loyaltyPoints < 0)
|
||||
{
|
||||
if(loyaltylevel > REBELLIOUS)
|
||||
{
|
||||
//level down
|
||||
--loyaltylevel;
|
||||
SetLoyaltyLevel(LoyaltyLevel(loyaltylevel));
|
||||
m_loyaltyPoints = GetStartLoyaltyPoints(loyaltylevel);
|
||||
SetTP(m_TrainingPoints - int32(getLevel()));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_loyaltyPoints = 0;
|
||||
Unit* owner = GetOwner();
|
||||
if(owner && owner->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
WorldPacket data(SMSG_PET_BROKEN, 0);
|
||||
((Player*)owner)->GetSession()->SendPacket(&data);
|
||||
|
||||
//run away
|
||||
((Player*)owner)->RemovePet(this,PET_SAVE_AS_DELETED);
|
||||
}
|
||||
}
|
||||
}
|
||||
//level up
|
||||
else if(m_loyaltyPoints > int32(GetMaxLoyaltyPoints(loyaltylevel)))
|
||||
{
|
||||
++loyaltylevel;
|
||||
SetLoyaltyLevel(LoyaltyLevel(loyaltylevel));
|
||||
m_loyaltyPoints = GetStartLoyaltyPoints(loyaltylevel);
|
||||
SetTP(m_TrainingPoints + getLevel());
|
||||
}
|
||||
}
|
||||
|
||||
void Pet::TickLoyaltyChange()
|
||||
{
|
||||
int32 addvalue;
|
||||
|
||||
switch(GetHappinessState())
|
||||
{
|
||||
case HAPPY: addvalue = 20; break;
|
||||
case CONTENT: addvalue = 10; break;
|
||||
case UNHAPPY: addvalue = -20; break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
ModifyLoyalty(addvalue);
|
||||
}
|
||||
|
||||
void Pet::KillLoyaltyBonus(uint32 level)
|
||||
{
|
||||
if(level > 100)
|
||||
return;
|
||||
|
||||
//at lower levels gain is faster | the lower loyalty the more loyalty is gained
|
||||
uint32 bonus = uint32(((100 - level) / 10) + (6 - GetLoyaltyLevel()));
|
||||
ModifyLoyalty(bonus);
|
||||
}
|
||||
|
||||
HappinessState Pet::GetHappinessState()
|
||||
{
|
||||
if(GetPower(POWER_HAPPINESS) < HAPPINESS_LEVEL_SIZE)
|
||||
@@ -724,11 +619,6 @@ HappinessState Pet::GetHappinessState()
|
||||
return CONTENT;
|
||||
}
|
||||
|
||||
void Pet::SetLoyaltyLevel(LoyaltyLevel level)
|
||||
{
|
||||
SetByteValue(UNIT_FIELD_BYTES_1, 1, level);
|
||||
}
|
||||
|
||||
bool Pet::CanTakeMoreActiveSpells(uint32 spellid)
|
||||
{
|
||||
uint8 activecount = 1;
|
||||
@@ -765,82 +655,6 @@ bool Pet::CanTakeMoreActiveSpells(uint32 spellid)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Pet::HasTPForSpell(uint32 spellid)
|
||||
{
|
||||
int32 neededtrainp = GetTPForSpell(spellid);
|
||||
if((m_TrainingPoints - neededtrainp < 0 || neededtrainp < 0) && neededtrainp != 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
int32 Pet::GetTPForSpell(uint32 spellid)
|
||||
{
|
||||
uint32 basetrainp = 0;
|
||||
|
||||
SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(spellid);
|
||||
SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(spellid);
|
||||
for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx)
|
||||
{
|
||||
if(!_spell_idx->second->reqtrainpoints)
|
||||
return 0;
|
||||
|
||||
basetrainp = _spell_idx->second->reqtrainpoints;
|
||||
break;
|
||||
}
|
||||
|
||||
uint32 spenttrainp = 0;
|
||||
uint32 chainstart = spellmgr.GetFirstSpellInChain(spellid);
|
||||
|
||||
for (PetSpellMap::iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr)
|
||||
{
|
||||
if(itr->second->state == PETSPELL_REMOVED)
|
||||
continue;
|
||||
|
||||
if(spellmgr.GetFirstSpellInChain(itr->first) == chainstart)
|
||||
{
|
||||
SkillLineAbilityMap::const_iterator _lower = spellmgr.GetBeginSkillLineAbilityMap(itr->first);
|
||||
SkillLineAbilityMap::const_iterator _upper = spellmgr.GetEndSkillLineAbilityMap(itr->first);
|
||||
|
||||
for(SkillLineAbilityMap::const_iterator _spell_idx2 = _lower; _spell_idx2 != _upper; ++_spell_idx2)
|
||||
{
|
||||
if(_spell_idx2->second->reqtrainpoints > spenttrainp)
|
||||
{
|
||||
spenttrainp = _spell_idx2->second->reqtrainpoints;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return int32(basetrainp) - int32(spenttrainp);
|
||||
}
|
||||
|
||||
uint32 Pet::GetMaxLoyaltyPoints(uint32 level)
|
||||
{
|
||||
return LevelUpLoyalty[level - 1];
|
||||
}
|
||||
|
||||
uint32 Pet::GetStartLoyaltyPoints(uint32 level)
|
||||
{
|
||||
return LevelStartLoyalty[level - 1];
|
||||
}
|
||||
|
||||
void Pet::SetTP(int32 TP)
|
||||
{
|
||||
m_TrainingPoints = TP;
|
||||
SetUInt32Value(UNIT_TRAINING_POINTS, (uint32)GetDispTP());
|
||||
}
|
||||
|
||||
int32 Pet::GetDispTP()
|
||||
{
|
||||
if(getPetType()!= HUNTER_PET)
|
||||
return(0);
|
||||
if(m_TrainingPoints < 0)
|
||||
return -m_TrainingPoints;
|
||||
else
|
||||
return -(m_TrainingPoints + 1);
|
||||
}
|
||||
|
||||
void Pet::Remove(PetSaveMode mode, bool returnreagent)
|
||||
{
|
||||
Unit* owner = GetOwner();
|
||||
@@ -903,9 +717,6 @@ void Pet::GivePetXP(uint32 xp)
|
||||
}
|
||||
|
||||
SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, newXP);
|
||||
|
||||
if(getPetType() == HUNTER_PET)
|
||||
KillLoyaltyBonus(level);
|
||||
}
|
||||
|
||||
void Pet::GivePetLevel(uint32 level)
|
||||
@@ -913,9 +724,7 @@ void Pet::GivePetLevel(uint32 level)
|
||||
if(!level)
|
||||
return;
|
||||
|
||||
InitStatsForLevel( level);
|
||||
|
||||
SetTP(m_TrainingPoints + (GetLoyaltyLevel() - 1));
|
||||
InitStatsForLevel(level);
|
||||
}
|
||||
|
||||
bool Pet::CreateBaseAtCreature(Creature* creature)
|
||||
@@ -973,16 +782,12 @@ bool Pet::CreateBaseAtCreature(Creature* creature)
|
||||
else
|
||||
SetName(creature->GetName());
|
||||
|
||||
m_loyaltyPoints = 1000;
|
||||
if(cinfo->type == CREATURE_TYPE_BEAST)
|
||||
{
|
||||
SetUInt32Value(UNIT_FIELD_BYTES_0, 0x02020100);
|
||||
SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE );
|
||||
SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_UNK3 | UNIT_BYTE2_FLAG_AURAS | UNIT_BYTE2_FLAG_UNK5 );
|
||||
SetByteValue(UNIT_FIELD_BYTES_2, 2, UNIT_RENAME_ALLOWED);
|
||||
|
||||
SetUInt32Value(UNIT_MOD_CAST_SPEED, creature->GetUInt32Value(UNIT_MOD_CAST_SPEED) );
|
||||
SetLoyaltyLevel(REBELLIOUS);
|
||||
SetUInt32Value(UNIT_MOD_CAST_SPEED, creature->GetUInt32Value(UNIT_MOD_CAST_SPEED));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1112,7 +917,7 @@ bool Pet::InitStatsForLevel(uint32 petlevel)
|
||||
case HUNTER_PET:
|
||||
{
|
||||
SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, uint32((Trinity::XP::xp_to_level(petlevel))/4));
|
||||
|
||||
learnLevelupSpells();
|
||||
//these formula may not be correct; however, it is designed to be close to what it should be
|
||||
//this makes dps 0.5 of pets level
|
||||
SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4)) );
|
||||
@@ -1323,10 +1128,6 @@ void Pet::_LoadAuras(uint32 timediff)
|
||||
for (int i = 0; i < TOTAL_AURAS; i++)
|
||||
m_modAuras[i].clear();
|
||||
|
||||
// all aura related fields
|
||||
for(int i = UNIT_FIELD_AURA; i <= UNIT_FIELD_AURASTATE; ++i)
|
||||
SetUInt32Value(i, 0);
|
||||
|
||||
QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges FROM pet_aura WHERE guid = '%u'",m_charmInfo->GetPetNumber());
|
||||
|
||||
if(result)
|
||||
@@ -1467,7 +1268,7 @@ bool Pet::addSpell(uint16 spell_id, uint16 active, PetSpellState state, uint16 s
|
||||
|
||||
// same spells don't have autocast option
|
||||
if (spellInfo->AttributesEx & SPELL_ATTR_EX_UNAUTOCASTABLE_BY_PET)
|
||||
active = ACT_CAST;
|
||||
active = ACT_ENABLED;
|
||||
|
||||
PetSpellMap::iterator itr = m_spells.find(spell_id);
|
||||
if (itr != m_spells.end())
|
||||
@@ -1519,11 +1320,12 @@ bool Pet::addSpell(uint16 spell_id, uint16 active, PetSpellState state, uint16 s
|
||||
ToggleAutocast(itr->first, false);
|
||||
|
||||
oldspell_id = itr->first;
|
||||
removeSpell(itr->first);
|
||||
unlearnSpell(itr->first);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint16 tmpslot=slot_id;
|
||||
uint16 tmpslot = slot_id;
|
||||
|
||||
if (tmpslot == 0xffff)
|
||||
{
|
||||
@@ -1557,20 +1359,65 @@ bool Pet::learnSpell(uint16 spell_id)
|
||||
if (!addSpell(spell_id))
|
||||
return false;
|
||||
|
||||
if(GetOwner()->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
if(!m_loading)
|
||||
{
|
||||
WorldPacket data(SMSG_PET_LEARNED_SPELL, 2);
|
||||
data << uint16(spell_id);
|
||||
((Player*)GetOwner())->GetSession()->SendPacket(&data);
|
||||
}
|
||||
}
|
||||
|
||||
Unit* owner = GetOwner();
|
||||
if(owner->GetTypeId()==TYPEID_PLAYER)
|
||||
if(owner->GetTypeId() == TYPEID_PLAYER)
|
||||
((Player*)owner)->PetSpellInitialize();
|
||||
return true;
|
||||
}
|
||||
|
||||
void Pet::removeSpell(uint16 spell_id)
|
||||
void Pet::learnLevelupSpells()
|
||||
{
|
||||
PetLevelupSpellSet const *levelupSpells = spellmgr.GetPetLevelupSpellList(GetCreatureInfo()->family);
|
||||
if(!levelupSpells)
|
||||
return;
|
||||
|
||||
uint32 level = getLevel();
|
||||
|
||||
for(PetLevelupSpellSet::const_iterator itr = levelupSpells->begin(); itr != levelupSpells->end(); ++itr)
|
||||
{
|
||||
if(itr->first <= level)
|
||||
learnSpell(itr->second);
|
||||
else
|
||||
unlearnSpell(itr->second);
|
||||
}
|
||||
}
|
||||
|
||||
bool Pet::unlearnSpell(uint16 spell_id)
|
||||
{
|
||||
if(removeSpell(spell_id))
|
||||
{
|
||||
if(GetOwner()->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
if(!m_loading)
|
||||
{
|
||||
WorldPacket data(SMSG_PET_REMOVED_SPELL, 2);
|
||||
data << uint16(spell_id);
|
||||
((Player*)GetOwner())->GetSession()->SendPacket(&data);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Pet::removeSpell(uint16 spell_id)
|
||||
{
|
||||
PetSpellMap::iterator itr = m_spells.find(spell_id);
|
||||
if (itr == m_spells.end())
|
||||
return;
|
||||
return false;
|
||||
|
||||
if(itr->second->state == PETSPELL_REMOVED)
|
||||
return;
|
||||
return false;
|
||||
|
||||
if(itr->second->state == PETSPELL_NEW)
|
||||
{
|
||||
@@ -1581,6 +1428,8 @@ void Pet::removeSpell(uint16 spell_id)
|
||||
itr->second->state = PETSPELL_REMOVED;
|
||||
|
||||
RemoveAurasDueToSpell(spell_id);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Pet::_removeSpell(uint16 spell_id)
|
||||
@@ -1600,7 +1449,7 @@ void Pet::InitPetCreateSpells()
|
||||
m_charmInfo->InitPetActionBar();
|
||||
|
||||
m_spells.clear();
|
||||
int32 usedtrainpoints = 0, petspellid;
|
||||
int32 petspellid;
|
||||
PetCreateSpellEntry const* CreateSpells = objmgr.GetPetCreateSpellEntry(GetEntry());
|
||||
if(CreateSpells)
|
||||
{
|
||||
@@ -1629,23 +1478,12 @@ void Pet::InitPetCreateSpells()
|
||||
petspellid = learn_spellproto->Id;
|
||||
|
||||
addSpell(petspellid);
|
||||
|
||||
SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(learn_spellproto->EffectTriggerSpell[0]);
|
||||
SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(learn_spellproto->EffectTriggerSpell[0]);
|
||||
|
||||
for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx)
|
||||
{
|
||||
usedtrainpoints += _spell_idx->second->reqtrainpoints;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LearnPetPassives();
|
||||
|
||||
CastPetAuras(false);
|
||||
|
||||
SetTP(-usedtrainpoints);
|
||||
}
|
||||
|
||||
void Pet::CheckLearning(uint32 spellid)
|
||||
@@ -1704,7 +1542,9 @@ void Pet::ToggleAutocast(uint32 spellid, bool apply)
|
||||
|
||||
if(apply)
|
||||
{
|
||||
for (i = 0; i < m_autospells.size() && m_autospells[i] != spellid; i++);
|
||||
for (i = 0; i < m_autospells.size() && m_autospells[i] != spellid; i++)
|
||||
; // just search
|
||||
|
||||
if (i == m_autospells.size())
|
||||
{
|
||||
m_autospells.push_back(spellid);
|
||||
@@ -1715,7 +1555,9 @@ void Pet::ToggleAutocast(uint32 spellid, bool apply)
|
||||
else
|
||||
{
|
||||
AutoSpellList::iterator itr2 = m_autospells.begin();
|
||||
for (i = 0; i < m_autospells.size() && m_autospells[i] != spellid; i++, itr2++);
|
||||
for (i = 0; i < m_autospells.size() && m_autospells[i] != spellid; i++, itr2++)
|
||||
; // just search
|
||||
|
||||
if (i < m_autospells.size())
|
||||
{
|
||||
m_autospells.erase(itr2);
|
||||
@@ -1738,8 +1580,7 @@ bool Pet::Create(uint32 guidlow, Map *map, uint32 Entry, uint32 pet_number)
|
||||
if(!InitEntry(Entry))
|
||||
return false;
|
||||
|
||||
SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE );
|
||||
SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_UNK3 | UNIT_BYTE2_FLAG_AURAS | UNIT_BYTE2_FLAG_UNK5 );
|
||||
SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE);
|
||||
|
||||
if(getPetType() == MINI_PET) // always non-attackable
|
||||
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
|
||||
+9
-32
@@ -52,16 +52,6 @@ enum HappinessState
|
||||
HAPPY = 3
|
||||
};
|
||||
|
||||
enum LoyaltyLevel
|
||||
{
|
||||
REBELLIOUS = 1,
|
||||
UNRULY = 2,
|
||||
SUBMISSIVE = 3,
|
||||
DEPENDABLE = 4,
|
||||
FAITHFUL = 5,
|
||||
BEST_FRIEND = 6
|
||||
};
|
||||
|
||||
enum PetSpellState
|
||||
{
|
||||
PETSPELL_UNCHANGED = 0,
|
||||
@@ -122,9 +112,6 @@ typedef std::vector<uint32> AutoSpellList;
|
||||
|
||||
#define HAPPINESS_LEVEL_SIZE 333000
|
||||
|
||||
extern const uint32 LevelUpLoyalty[6];
|
||||
extern const uint32 LevelStartLoyalty[6];
|
||||
|
||||
#define ACTIVE_SPELLS_MAX 4
|
||||
|
||||
#define OWNER_MAX_DISTANCE 100
|
||||
@@ -167,14 +154,7 @@ class Pet : public Creature
|
||||
|
||||
void RegenerateFocus();
|
||||
void LooseHappiness();
|
||||
void TickLoyaltyChange();
|
||||
void ModifyLoyalty(int32 addvalue);
|
||||
HappinessState GetHappinessState();
|
||||
uint32 GetMaxLoyaltyPoints(uint32 level);
|
||||
uint32 GetStartLoyaltyPoints(uint32 level);
|
||||
void KillLoyaltyBonus(uint32 level);
|
||||
uint32 GetLoyaltyLevel() { return GetByteValue(UNIT_FIELD_BYTES_1, 1); }
|
||||
void SetLoyaltyLevel(LoyaltyLevel level);
|
||||
void GivePetXP(uint32 xp);
|
||||
void GivePetLevel(uint32 level);
|
||||
bool InitStatsForLevel(uint32 level);
|
||||
@@ -194,10 +174,8 @@ class Pet : public Creature
|
||||
void UpdateAttackPowerAndDamage(bool ranged = false);
|
||||
void UpdateDamagePhysical(WeaponAttackType attType);
|
||||
|
||||
bool CanTakeMoreActiveSpells(uint32 SpellIconID);
|
||||
void ToggleAutocast(uint32 spellid, bool apply);
|
||||
bool HasTPForSpell(uint32 spellid);
|
||||
int32 GetTPForSpell(uint32 spellid);
|
||||
bool CanTakeMoreActiveSpells(uint32 SpellIconID);
|
||||
void ToggleAutocast(uint32 spellid, bool apply);
|
||||
|
||||
bool HasSpell(uint32 spell) const;
|
||||
void AddTeachSpell(uint32 learned_id, uint32 source_id) { m_teachspells[learned_id] = source_id; }
|
||||
@@ -215,7 +193,9 @@ class Pet : public Creature
|
||||
|
||||
bool addSpell(uint16 spell_id,uint16 active = ACT_DECIDE, PetSpellState state = PETSPELL_NEW, uint16 slot_id=0xffff, PetSpellType type = PETSPELL_NORMAL);
|
||||
bool learnSpell(uint16 spell_id);
|
||||
void removeSpell(uint16 spell_id);
|
||||
void learnLevelupSpells();
|
||||
bool unlearnSpell(uint16 spell_id);
|
||||
bool removeSpell(uint16 spell_id);
|
||||
bool _removeSpell(uint16 spell_id);
|
||||
|
||||
PetSpellMap m_spells;
|
||||
@@ -225,11 +205,10 @@ class Pet : public Creature
|
||||
void InitPetCreateSpells();
|
||||
void CheckLearning(uint32 spellid);
|
||||
uint32 resetTalentsCost() const;
|
||||
uint8 GetMaxTalentPointsForLevel(uint32 level) { return (level >= 20) ? ((level - 16) / 4) : 0; }
|
||||
uint8 GetFreeTalentPoints() { return GetByteValue(UNIT_FIELD_BYTES_1, 1); }
|
||||
void SetFreeTalentPoints(uint8 points) { SetByteValue(UNIT_FIELD_BYTES_1, 1, points); }
|
||||
|
||||
void SetTP(int32 TP);
|
||||
int32 GetDispTP();
|
||||
|
||||
int32 m_TrainingPoints;
|
||||
uint32 m_resetTalentsCost;
|
||||
time_t m_resetTalentsTime;
|
||||
|
||||
@@ -241,14 +220,12 @@ class Pet : public Creature
|
||||
|
||||
bool m_removed; // prevent overwrite pet state in DB at next Pet::Update if pet already removed(saved)
|
||||
protected:
|
||||
uint32 m_regenTimer;
|
||||
uint32 m_happinessTimer;
|
||||
uint32 m_loyaltyTimer;
|
||||
PetType m_petType;
|
||||
int32 m_duration; // time until unsummon (used mostly for summoned guardians and not used for controlled pets)
|
||||
int32 m_loyaltyPoints;
|
||||
int32 m_bonusdamage;
|
||||
uint64 m_auraUpdateMask;
|
||||
bool m_loading;
|
||||
|
||||
DeclinedName *m_declinedname;
|
||||
|
||||
|
||||
+143
-10
@@ -174,9 +174,9 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ACT_DISABLED: //0x8100 spell (disabled), ignore
|
||||
case ACT_CAST: //0x0100
|
||||
case ACT_ENABLED: //0xc100 spell
|
||||
case ACT_DISABLED: // 0x8100 spell (disabled), ignore
|
||||
case ACT_PASSIVE: // 0x0100
|
||||
case ACT_ENABLED: // 0xC100 spell
|
||||
{
|
||||
Unit* unit_target;
|
||||
if(guid2)
|
||||
@@ -257,7 +257,7 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
|
||||
if(pet->isPossessed())
|
||||
{
|
||||
WorldPacket data(SMSG_CAST_FAILED, (4+1+1));
|
||||
data << uint32(spellid) << uint8(2) << uint8(result);
|
||||
data << uint8(0) << uint32(spellid) << uint8(result);
|
||||
switch (result)
|
||||
{
|
||||
case SPELL_FAILED_REQUIRES_SPELL_FOCUS:
|
||||
@@ -369,7 +369,7 @@ void WorldSession::HandlePetSetAction( WorldPacket & recv_data )
|
||||
sLog.outDetail( "Player %s has changed pet spell action. Position: %u, Spell: %u, State: 0x%X\n", _player->GetName(), position, spell_id, act_state);
|
||||
|
||||
//if it's act for spell (en/disable/cast) and there is a spell given (0 = remove spell) which pet doesn't know, don't add
|
||||
if(!((act_state == ACT_ENABLED || act_state == ACT_DISABLED || act_state == ACT_CAST) && spell_id && !pet->HasSpell(spell_id)))
|
||||
if(!((act_state == ACT_ENABLED || act_state == ACT_DISABLED || act_state == ACT_PASSIVE) && spell_id && !pet->HasSpell(spell_id)))
|
||||
{
|
||||
//sign for autocast
|
||||
if(act_state == ACT_ENABLED && spell_id)
|
||||
@@ -542,11 +542,10 @@ void WorldSession::HandlePetUnlearnOpcode(WorldPacket& recvPacket)
|
||||
{
|
||||
uint32 spell_id = itr->first; // Pet::removeSpell can invalidate iterator at erase NEW spell
|
||||
++itr;
|
||||
pet->removeSpell(spell_id);
|
||||
//pet->removeSpell(spell_id);
|
||||
pet->unlearnSpell(spell_id);
|
||||
}
|
||||
|
||||
pet->SetTP(pet->getLevel() * (pet->GetLoyaltyLevel() - 1));
|
||||
|
||||
for(uint8 i = 0; i < 10; i++)
|
||||
{
|
||||
if(charmInfo->GetActionBarEntry(i)->SpellOrAction && charmInfo->GetActionBarEntry(i)->Type == ACT_ENABLED || charmInfo->GetActionBarEntry(i)->Type == ACT_DISABLED)
|
||||
@@ -616,11 +615,15 @@ void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket )
|
||||
{
|
||||
sLog.outDetail("WORLD: CMSG_PET_CAST_SPELL");
|
||||
|
||||
CHECK_PACKET_SIZE(recvPacket,8+4);
|
||||
CHECK_PACKET_SIZE(recvPacket,8+1+4+1);
|
||||
uint64 guid;
|
||||
uint32 spellid;
|
||||
uint8 cast_count;
|
||||
uint8 unk_flags; // flags (if 0x02 - some additional data are received)
|
||||
|
||||
recvPacket >> guid >> spellid;
|
||||
recvPacket >> guid >> cast_count >> spellid >> unk_flags;
|
||||
|
||||
sLog.outDebug("WORLD: CMSG_PET_CAST_SPELL, cast_count: %u, spellid %u, unk_flags %u", cast_count, spellid, unk_flags);
|
||||
|
||||
// This opcode is also sent from charmed and possessed units (players and creatures)
|
||||
if(!_player->GetPet() && !_player->GetCharm())
|
||||
@@ -655,6 +658,7 @@ void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket )
|
||||
caster->clearUnitState(UNIT_STAT_FOLLOW);
|
||||
|
||||
Spell *spell = new Spell(caster, spellInfo, false);
|
||||
spell->m_cast_count = cast_count; // probably pending spell cast
|
||||
spell->m_targets = targets;
|
||||
|
||||
int16 result = spell->PetCanCast(NULL);
|
||||
@@ -713,3 +717,132 @@ void WorldSession::SendPetNameInvalid(uint32 error, const std::string& name, Dec
|
||||
data << uint8(0);
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::HandlePetLearnTalent( WorldPacket & recv_data )
|
||||
{
|
||||
sLog.outDebug("WORLD: CMSG_PET_LEARN_TALENT");
|
||||
recv_data.hexlike();
|
||||
|
||||
CHECK_PACKET_SIZE(recv_data, 8+4+4);
|
||||
|
||||
uint64 guid;
|
||||
uint32 talent_id, requested_rank;
|
||||
recv_data >> guid >> talent_id >> requested_rank;
|
||||
|
||||
Pet *pet = _player->GetPet();
|
||||
|
||||
if(!pet)
|
||||
return;
|
||||
|
||||
if(guid != pet->GetGUID())
|
||||
return;
|
||||
|
||||
uint32 CurTalentPoints = pet->GetFreeTalentPoints();
|
||||
|
||||
if(CurTalentPoints == 0)
|
||||
return;
|
||||
|
||||
if (requested_rank > 4)
|
||||
return;
|
||||
|
||||
TalentEntry const *talentInfo = sTalentStore.LookupEntry(talent_id);
|
||||
|
||||
if(!talentInfo)
|
||||
return;
|
||||
|
||||
TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry(talentInfo->TalentTab);
|
||||
|
||||
if(!talentTabInfo)
|
||||
return;
|
||||
|
||||
CreatureInfo const *ci = pet->GetCreatureInfo();
|
||||
|
||||
if(!ci)
|
||||
return;
|
||||
|
||||
CreatureFamilyEntry const *pet_family = sCreatureFamilyStore.LookupEntry(ci->family);
|
||||
|
||||
if(!pet_family)
|
||||
return;
|
||||
|
||||
if(pet_family->petTalentType < 0) // not hunter pet
|
||||
return;
|
||||
|
||||
// prevent learn talent for different family (cheating)
|
||||
if(!((1 << pet_family->petTalentType) & talentTabInfo->petTalentMask))
|
||||
return;
|
||||
|
||||
// prevent skip talent ranks (cheating)
|
||||
if(requested_rank > 0 && !pet->HasSpell(talentInfo->RankID[requested_rank-1]))
|
||||
return;
|
||||
|
||||
// Check if it requires another talent
|
||||
if (talentInfo->DependsOn > 0)
|
||||
{
|
||||
if(TalentEntry const *depTalentInfo = sTalentStore.LookupEntry(talentInfo->DependsOn))
|
||||
{
|
||||
bool hasEnoughRank = false;
|
||||
for (int i = talentInfo->DependsOnRank; i <= 4; i++)
|
||||
{
|
||||
if (depTalentInfo->RankID[i] != 0)
|
||||
if (pet->HasSpell(depTalentInfo->RankID[i]))
|
||||
hasEnoughRank = true;
|
||||
}
|
||||
if (!hasEnoughRank)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Find out how many points we have in this field
|
||||
uint32 spentPoints = 0;
|
||||
|
||||
uint32 tTab = talentInfo->TalentTab;
|
||||
if (talentInfo->Row > 0)
|
||||
{
|
||||
unsigned int numRows = sTalentStore.GetNumRows();
|
||||
for (unsigned int i = 0; i < numRows; i++) // Loop through all talents.
|
||||
{
|
||||
// Someday, someone needs to revamp
|
||||
const TalentEntry *tmpTalent = sTalentStore.LookupEntry(i);
|
||||
if (tmpTalent) // the way talents are tracked
|
||||
{
|
||||
if (tmpTalent->TalentTab == tTab)
|
||||
{
|
||||
for (int j = 0; j <= 4; j++)
|
||||
{
|
||||
if (tmpTalent->RankID[j] != 0)
|
||||
{
|
||||
if (pet->HasSpell(tmpTalent->RankID[j]))
|
||||
{
|
||||
spentPoints += j + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// not have required min points spent in talent tree
|
||||
if(spentPoints < (talentInfo->Row * 3))
|
||||
return;
|
||||
|
||||
// spell not set in talent.dbc
|
||||
uint32 spellid = talentInfo->RankID[requested_rank];
|
||||
if( spellid == 0 )
|
||||
{
|
||||
sLog.outError("Talent.dbc have for talent: %u Rank: %u spell id = 0", talent_id, requested_rank);
|
||||
return;
|
||||
}
|
||||
|
||||
// already known
|
||||
if(pet->HasSpell(spellid))
|
||||
return;
|
||||
|
||||
// learn! (other talent ranks will unlearned at learning)
|
||||
pet->learnSpell(spellid);
|
||||
sLog.outDetail("TalentID: %u Rank: %u Spell: %u\n", talent_id, requested_rank, spellid);
|
||||
|
||||
// update free talent points
|
||||
pet->SetFreeTalentPoints(CurTalentPoints - 1);
|
||||
}
|
||||
|
||||
@@ -199,9 +199,9 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket & recv_data)
|
||||
if(!charter)
|
||||
return;
|
||||
|
||||
charter->SetUInt32Value(ITEM_FIELD_ENCHANTMENT, charter->GetGUIDLow());
|
||||
// ITEM_FIELD_ENCHANTMENT is guild/arenateam id
|
||||
// ITEM_FIELD_ENCHANTMENT+1 is current signatures count (showed on item)
|
||||
charter->SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1, charter->GetGUIDLow());
|
||||
// ITEM_FIELD_ENCHANTMENT_1_1 is guild/arenateam id
|
||||
// ITEM_FIELD_ENCHANTMENT_1_1+1 is current signatures count (showed on item)
|
||||
charter->SetState(ITEM_CHANGED, _player);
|
||||
_player->SendNewItem(charter, 1, true, false);
|
||||
|
||||
@@ -565,7 +565,7 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket & recv_data)
|
||||
// update signs count on charter, required testing...
|
||||
//Item *item = _player->GetItemByGuid(petitionguid));
|
||||
//if(item)
|
||||
// item->SetUInt32Value(ITEM_FIELD_ENCHANTMENT+1, signs);
|
||||
// item->SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1+1, signs);
|
||||
|
||||
// update for owner if online
|
||||
if(Player *owner = objmgr.GetPlayer(ownerguid))
|
||||
|
||||
+1011
-368
File diff suppressed because it is too large
Load Diff
+130
-28
@@ -35,6 +35,7 @@
|
||||
#include "Pet.h"
|
||||
#include "MapReference.h"
|
||||
#include "Util.h" // for Tokens typedef
|
||||
#include "AchievementMgr.h"
|
||||
|
||||
#include<string>
|
||||
#include<vector>
|
||||
@@ -49,6 +50,8 @@ class Transport;
|
||||
class UpdateMask;
|
||||
class PlayerSocial;
|
||||
class OutdoorPvP;
|
||||
class AchievementMgr;
|
||||
class Vehicle;
|
||||
|
||||
typedef std::deque<Mail*> PlayerMails;
|
||||
|
||||
@@ -80,15 +83,17 @@ struct PlayerSpell
|
||||
|
||||
#define SPELL_WITHOUT_SLOT_ID uint16(-1)
|
||||
|
||||
// Spell modifier (used for modify other spells)
|
||||
struct SpellModifier
|
||||
{
|
||||
SpellModifier() : charges(0), lastAffected(NULL) {}
|
||||
SpellModOp op : 8;
|
||||
SpellModType type : 8;
|
||||
int16 charges : 16;
|
||||
int32 value;
|
||||
uint64 mask;
|
||||
uint64 mask2;
|
||||
uint32 spellId;
|
||||
uint32 effectId;
|
||||
Spell const* lastAffected;
|
||||
};
|
||||
|
||||
@@ -224,6 +229,39 @@ struct Areas
|
||||
float y2;
|
||||
};
|
||||
|
||||
#define MAX_RUNES 6
|
||||
#define RUNE_COOLDOWN 5 // 5*2=10 sec
|
||||
|
||||
enum RuneType
|
||||
{
|
||||
RUNE_BLOOD = 0,
|
||||
RUNE_UNHOLY = 1,
|
||||
RUNE_FROST = 2,
|
||||
RUNE_DEATH = 3,
|
||||
NUM_RUNE_TYPES = 4
|
||||
};
|
||||
|
||||
struct RuneInfo
|
||||
{
|
||||
uint8 BaseRune;
|
||||
uint8 CurrentRune;
|
||||
uint8 Cooldown;
|
||||
};
|
||||
|
||||
struct Runes
|
||||
{
|
||||
RuneInfo runes[MAX_RUNES];
|
||||
uint8 runeState; // mask of available runes
|
||||
|
||||
void SetRuneState(uint8 index, bool set = true)
|
||||
{
|
||||
if(set)
|
||||
runeState |= (1 << index); // usable
|
||||
else
|
||||
runeState &= ~(1 << index); // on cooldown
|
||||
}
|
||||
};
|
||||
|
||||
enum FactionFlags
|
||||
{
|
||||
FACTION_FLAG_VISIBLE = 0x01, // makes visible in client (set or can be set at interaction with target of this faction)
|
||||
@@ -392,7 +430,7 @@ enum PlayerFlags
|
||||
PLAYER_FLAGS_UNK3 = 0x00008000, // strange visual effect (2.0.1), looks like PLAYER_FLAGS_GHOST flag
|
||||
PLAYER_FLAGS_SANCTUARY = 0x00010000, // player entered sanctuary
|
||||
PLAYER_FLAGS_UNK4 = 0x00020000, // taxi benchmark mode (on/off) (2.0.1)
|
||||
PLAYER_UNK = 0x00040000, // 2.0.8...
|
||||
PLAYER_FLAGS_PVP_TIMER = 0x00040000, // 3.0.2, pvp timer active (after you disable pvp manually)
|
||||
};
|
||||
|
||||
// used for PLAYER__FIELD_KNOWN_TITLES field (uint64), (1<<bit_index) without (-1)
|
||||
@@ -481,7 +519,8 @@ enum LootType
|
||||
LOOT_DISENCHANTING = 5, // unsupported by client, sending LOOT_SKINNING instead
|
||||
LOOT_PROSPECTING = 6, // unsupported by client, sending LOOT_SKINNING instead
|
||||
LOOT_INSIGNIA = 7, // unsupported by client, sending LOOT_SKINNING instead
|
||||
LOOT_FISHINGHOLE = 8 // unsupported by client, sending LOOT_FISHING instead
|
||||
LOOT_FISHINGHOLE = 8, // unsupported by client, sending LOOT_FISHING instead
|
||||
LOOT_MILLING = 9 // unsupported by client, sending LOOT_SKINNING instead
|
||||
};
|
||||
|
||||
enum MirrorTimerType
|
||||
@@ -512,7 +551,8 @@ enum AtLoginFlags
|
||||
AT_LOGIN_NONE = 0,
|
||||
AT_LOGIN_RENAME = 1,
|
||||
AT_LOGIN_RESET_SPELLS = 2,
|
||||
AT_LOGIN_RESET_TALENTS = 4
|
||||
AT_LOGIN_RESET_TALENTS = 4,
|
||||
AT_LOGIN_CUSTOMIZE = 8
|
||||
};
|
||||
|
||||
typedef std::map<uint32, QuestStatusData> QuestStatusMap;
|
||||
@@ -544,7 +584,7 @@ enum PlayerSlots
|
||||
// first slot for item stored (in any way in player m_items data)
|
||||
PLAYER_SLOT_START = 0,
|
||||
// last+1 slot for item stored (in any way in player m_items data)
|
||||
PLAYER_SLOT_END = 118,
|
||||
PLAYER_SLOT_END = 200,
|
||||
PLAYER_SLOTS_COUNT = (PLAYER_SLOT_END - PLAYER_SLOT_START)
|
||||
};
|
||||
|
||||
@@ -672,6 +712,24 @@ enum KeyRingSlots
|
||||
KEYRING_SLOT_END = 118
|
||||
};
|
||||
|
||||
enum VanityPetSlots
|
||||
{
|
||||
VANITYPET_SLOT_START = 118,
|
||||
VANITYPET_SLOT_END = 136
|
||||
};
|
||||
|
||||
enum CurrencyTokenSlots
|
||||
{
|
||||
CURRENCYTOKEN_SLOT_START = 136,
|
||||
CURRENCYTOKEN_SLOT_END = 168
|
||||
};
|
||||
|
||||
enum QuestBagSlots
|
||||
{
|
||||
QUESTBAG_SLOT_START = 168,
|
||||
QUESTBAG_SLOT_END = 200
|
||||
};
|
||||
|
||||
struct ItemPosCount
|
||||
{
|
||||
ItemPosCount(uint16 _pos, uint8 _count) : pos(_pos), count(_count) {}
|
||||
@@ -690,14 +748,15 @@ enum TradeSlots
|
||||
|
||||
enum TransferAbortReason
|
||||
{
|
||||
TRANSFER_ABORT_MAX_PLAYERS = 0x0001, // Transfer Aborted: instance is full
|
||||
TRANSFER_ABORT_NOT_FOUND = 0x0002, // Transfer Aborted: instance not found
|
||||
TRANSFER_ABORT_TOO_MANY_INSTANCES = 0x0003, // You have entered too many instances recently.
|
||||
TRANSFER_ABORT_ZONE_IN_COMBAT = 0x0005, // Unable to zone in while an encounter is in progress.
|
||||
TRANSFER_ABORT_INSUF_EXPAN_LVL1 = 0x0106, // You must have TBC expansion installed to access this area.
|
||||
TRANSFER_ABORT_DIFFICULTY1 = 0x0007, // Normal difficulty mode is not available for %s.
|
||||
TRANSFER_ABORT_DIFFICULTY2 = 0x0107, // Heroic difficulty mode is not available for %s.
|
||||
TRANSFER_ABORT_DIFFICULTY3 = 0x0207 // Epic difficulty mode is not available for %s.
|
||||
TRANSFER_ABORT_ERROR = 0x00,
|
||||
TRANSFER_ABORT_MAX_PLAYERS = 0x01, // Transfer Aborted: instance is full
|
||||
TRANSFER_ABORT_NOT_FOUND = 0x02, // Transfer Aborted: instance not found
|
||||
TRANSFER_ABORT_TOO_MANY_INSTANCES = 0x03, // You have entered too many instances recently.
|
||||
TRANSFER_ABORT_ZONE_IN_COMBAT = 0x05, // Unable to zone in while an encounter is in progress.
|
||||
TRANSFER_ABORT_INSUF_EXPAN_LVL = 0x06, // You must have <TBC,WotLK> expansion installed to access this area.
|
||||
TRANSFER_ABORT_DIFFICULTY = 0x07, // <Normal,Heroic,Epic> difficulty mode is not available for %s.
|
||||
TRANSFER_ABORT_UNIQUE_MESSAGE = 0x08, // Until you've escaped TLK's grasp, you cannot leave this place!
|
||||
TRANSFER_ABORT_TOO_MANY_REALM_INSTANCES = 0x09 // Additional instances cannot be launched, please try again later.
|
||||
};
|
||||
|
||||
enum InstanceResetWarningType
|
||||
@@ -711,15 +770,16 @@ enum InstanceResetWarningType
|
||||
struct MovementInfo
|
||||
{
|
||||
// common
|
||||
//uint32 flags;
|
||||
uint8 unk1;
|
||||
uint32 flags;
|
||||
uint16 unk1;
|
||||
uint32 time;
|
||||
float x, y, z, o;
|
||||
// transport
|
||||
uint64 t_guid;
|
||||
float t_x, t_y, t_z, t_o;
|
||||
uint32 t_time;
|
||||
// swimming and unk
|
||||
int8 t_seat;
|
||||
// swimming and unknown
|
||||
float s_pitch;
|
||||
// last fall time
|
||||
uint32 fallTime;
|
||||
@@ -730,17 +790,17 @@ struct MovementInfo
|
||||
|
||||
MovementInfo()
|
||||
{
|
||||
//flags =
|
||||
flags = 0;
|
||||
time = t_time = fallTime = 0;
|
||||
unk1 = 0;
|
||||
x = y = z = o = t_x = t_y = t_z = t_o = s_pitch = j_unk = j_sinAngle = j_cosAngle = j_xyspeed = u_unk1 = 0.0f;
|
||||
t_guid = 0;
|
||||
}
|
||||
|
||||
/*void SetMovementFlags(uint32 _flags)
|
||||
void SetMovementFlags(uint32 _flags)
|
||||
{
|
||||
flags = _flags;
|
||||
}*/
|
||||
}
|
||||
};
|
||||
|
||||
// flags that use in movement check for example at spell casting
|
||||
@@ -813,10 +873,12 @@ enum PlayerLoginQueryIndex
|
||||
PLAYER_LOGIN_QUERY_LOADDECLINEDNAMES = 16,
|
||||
PLAYER_LOGIN_QUERY_LOADGUILD = 17,
|
||||
PLAYER_LOGIN_QUERY_LOADARENAINFO = 18,
|
||||
|
||||
MAX_PLAYER_LOGIN_QUERY
|
||||
PLAYER_LOGIN_QUERY_LOADACHIEVEMENTS = 19,
|
||||
PLAYER_LOGIN_QUERY_LOADCRITERIAPROGRESS = 20,
|
||||
MAX_PLAYER_LOGIN_QUERY = 21
|
||||
};
|
||||
|
||||
|
||||
// Player summoning auto-decline time (in secs)
|
||||
#define MAX_PLAYER_SUMMON_DELAY (2*MINUTE)
|
||||
#define MAX_MONEY_AMOUNT (0x7FFFFFFF-1)
|
||||
@@ -837,7 +899,7 @@ class TRINITY_DLL_SPEC PlayerTaxi
|
||||
PlayerTaxi();
|
||||
~PlayerTaxi() {}
|
||||
// Nodes
|
||||
void InitTaxiNodesForLevel(uint32 race, uint32 level);
|
||||
void InitTaxiNodesForLevel(uint32 race, uint32 chrClass, uint32 level);
|
||||
void LoadTaxiMask(const char* data);
|
||||
void SaveTaxiMask(const char* data);
|
||||
|
||||
@@ -940,7 +1002,7 @@ class TRINITY_DLL_SPEC Player : public Unit
|
||||
|
||||
void SendInitialPacketsBeforeAddToMap();
|
||||
void SendInitialPacketsAfterAddToMap();
|
||||
void SendTransferAborted(uint32 mapid, uint16 reason);
|
||||
void SendTransferAborted(uint32 mapid, uint8 reason, uint8 arg = 0);
|
||||
void SendInstanceResetWarning(uint32 mapid, uint32 time);
|
||||
|
||||
bool CanInteractWithNPCs(bool alive = true) const;
|
||||
@@ -953,10 +1015,12 @@ class TRINITY_DLL_SPEC Player : public Unit
|
||||
std::string afkMsg;
|
||||
std::string dndMsg;
|
||||
|
||||
uint32 GetBarberShopCost(uint8 newhairstyle, uint8 newhaircolor, uint8 newfacialhair);
|
||||
|
||||
PlayerSocial *GetSocial() { return m_social; }
|
||||
|
||||
PlayerTaxi m_taxi;
|
||||
void InitTaxiNodesForLevel() { m_taxi.InitTaxiNodesForLevel(getRace(),getLevel()); }
|
||||
void InitTaxiNodesForLevel() { m_taxi.InitTaxiNodesForLevel(getRace(), getClass(), getLevel()); }
|
||||
bool ActivateTaxiPathTo(std::vector<uint32> const& nodes, uint32 mount_id = 0 , Creature* npc = NULL);
|
||||
// mount_id can be used in scripting calls
|
||||
bool isAcceptTickets() const { return GetSession()->GetSecurity() >= SEC_GAMEMASTER && (m_ExtraFlags & PLAYER_EXTRA_GM_ACCEPT_TICKETS); }
|
||||
@@ -1052,6 +1116,7 @@ class TRINITY_DLL_SPEC Player : public Unit
|
||||
bool HasBankBagSlot( uint8 slot ) const;
|
||||
bool HasItemCount( uint32 item, uint32 count, bool inBankAlso = false ) const;
|
||||
bool HasItemFitToSpellReqirements(SpellEntry const* spellInfo, Item const* ignoreItem = NULL);
|
||||
bool CanNoReagentCast(SpellEntry const* spellInfo) const;
|
||||
Item* GetItemOrItemWithGemEquipped( uint32 item ) const;
|
||||
uint8 CanTakeMoreSimilarItems(Item* pItem) const { return _CanTakeMoreSimilarItems(pItem->GetEntry(),pItem->GetCount(),pItem); }
|
||||
uint8 CanTakeMoreSimilarItems(uint32 entry, uint32 count) const { return _CanTakeMoreSimilarItems(entry,count,NULL); }
|
||||
@@ -1130,6 +1195,11 @@ class TRINITY_DLL_SPEC Player : public Unit
|
||||
// disarm applied only to mainhand weapon
|
||||
return !IsInFeralForm() && (!mainhand || !HasFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISARMED) );
|
||||
}
|
||||
bool IsTwoHandUsed() const
|
||||
{
|
||||
Item* mainItem = GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND);
|
||||
return mainItem && mainItem->GetProto()->InventoryType == INVTYPE_2HWEAPON && !CanTitanGrip();
|
||||
}
|
||||
void SendNewItem( Item *item, uint32 count, bool received, bool created, bool broadcast = false );
|
||||
bool BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint64 bagguid, uint8 slot);
|
||||
|
||||
@@ -1285,6 +1355,7 @@ class TRINITY_DLL_SPEC Player : public Unit
|
||||
static void SetFloatValueInArray(Tokens& data,uint16 index, float value);
|
||||
static void SetUInt32ValueInDB(uint16 index, uint32 value, uint64 guid);
|
||||
static void SetFloatValueInDB(uint16 index, float value, uint64 guid);
|
||||
static void Customize(uint64 guid, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair);
|
||||
static void SavePositionInDB(uint32 mapid, float x,float y,float z,float o,uint32 zone,uint64 guid);
|
||||
|
||||
bool m_mailsLoaded;
|
||||
@@ -1423,6 +1494,12 @@ class TRINITY_DLL_SPEC Player : public Unit
|
||||
uint32 resetTalentsCost() const;
|
||||
void InitTalentForLevel();
|
||||
|
||||
void InitGlyphsForLevel();
|
||||
void SetGlyphSlot(uint8 slot, uint32 slottype) { SetUInt32Value(PLAYER_FIELD_GLYPH_SLOTS_1 + slot, slottype); }
|
||||
uint32 GetGlyphSlot(uint8 slot) { return GetUInt32Value(PLAYER_FIELD_GLYPH_SLOTS_1 + slot); }
|
||||
void SetGlyph(uint8 slot, uint32 glyph) { SetUInt32Value(PLAYER_FIELD_GLYPHS_1 + slot, glyph); }
|
||||
uint32 GetGlyph(uint8 slot) { return GetUInt32Value(PLAYER_FIELD_GLYPHS_1 + slot); }
|
||||
|
||||
uint32 GetFreePrimaryProffesionPoints() const { return GetUInt32Value(PLAYER_CHARACTER_POINTS2); }
|
||||
void SetFreePrimaryProffesions(uint16 profs) { SetUInt32Value(PLAYER_CHARACTER_POINTS2,profs); }
|
||||
void InitPrimaryProffesions();
|
||||
@@ -1431,8 +1508,6 @@ class TRINITY_DLL_SPEC Player : public Unit
|
||||
PlayerSpellMap & GetSpellMap() { return m_spells; }
|
||||
|
||||
void AddSpellMod(SpellModifier* mod, bool apply);
|
||||
int32 GetTotalFlatMods(uint32 spellId, SpellModOp op);
|
||||
int32 GetTotalPctMods(uint32 spellId, SpellModOp op);
|
||||
bool IsAffectedBySpellmod(SpellEntry const *spellInfo, SpellModifier *mod, Spell const* spell = NULL);
|
||||
template <class T> T ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell const* spell = NULL);
|
||||
void RemoveSpellMods(Spell const* spell);
|
||||
@@ -1589,6 +1664,10 @@ class TRINITY_DLL_SPEC Player : public Unit
|
||||
void UpdateAllCritPercentages();
|
||||
void UpdateParryPercentage();
|
||||
void UpdateDodgePercentage();
|
||||
void UpdateMeleeHitChances();
|
||||
void UpdateRangedHitChances();
|
||||
void UpdateSpellHitChances();
|
||||
|
||||
void UpdateAllSpellCritChances();
|
||||
void UpdateSpellCritChance(uint32 school);
|
||||
void UpdateExpertise(WeaponAttackType attType);
|
||||
@@ -1759,6 +1838,8 @@ class TRINITY_DLL_SPEC Player : public Unit
|
||||
void SetCanParry(bool value);
|
||||
bool CanBlock() const { return m_canBlock; }
|
||||
void SetCanBlock(bool value);
|
||||
bool CanTitanGrip() const { return m_canTitanGrip ; }
|
||||
void SetCanTitanGrip(bool value) { m_canTitanGrip = value; }
|
||||
|
||||
void SetRegularAttackTime();
|
||||
void SetBaseModValue(BaseModGroup modGroup, BaseModType modType, float value) { m_auraBaseMod[modGroup][modType] = value; }
|
||||
@@ -1792,7 +1873,7 @@ class TRINITY_DLL_SPEC Player : public Unit
|
||||
void SendUpdateWorldState(uint32 Field, uint32 Value);
|
||||
void SendDirectMessage(WorldPacket *data);
|
||||
|
||||
void SendAuraDurationsForTarget(Unit* target);
|
||||
void SendAurasForTarget(Unit *target);
|
||||
|
||||
PlayerMenu* PlayerTalkClass;
|
||||
std::vector<ItemSetEffect *> ItemSetEff;
|
||||
@@ -1953,6 +2034,7 @@ class TRINITY_DLL_SPEC Player : public Unit
|
||||
MovementInfo m_movementInfo;
|
||||
uint32 m_lastFallTime;
|
||||
float m_lastFallZ;
|
||||
Unit *m_mover;
|
||||
void SetFallInformation(uint32 time, float z)
|
||||
{
|
||||
m_lastFallTime = time;
|
||||
@@ -1970,6 +2052,9 @@ class TRINITY_DLL_SPEC Player : public Unit
|
||||
|
||||
void SetClientControl(Unit* target, uint8 allowMove);
|
||||
|
||||
void EnterVehicle(Vehicle *vehicle);
|
||||
void ExitVehicle(Vehicle *vehicle);
|
||||
|
||||
uint64 GetFarSight() const { return GetUInt64Value(PLAYER_FARSIGHT); }
|
||||
void SetFarSight(uint64 guid) { SetUInt64Value(PLAYER_FARSIGHT, guid); }
|
||||
|
||||
@@ -1982,6 +2067,7 @@ class TRINITY_DLL_SPEC Player : public Unit
|
||||
float GetTransOffsetZ() const { return m_movementInfo.t_z; }
|
||||
float GetTransOffsetO() const { return m_movementInfo.t_o; }
|
||||
uint32 GetTransTime() const { return m_movementInfo.t_time; }
|
||||
int8 GetTransSeat() const { return m_movementInfo.t_seat; }
|
||||
|
||||
uint32 GetSaveTimer() const { return m_nextSave; }
|
||||
void SetSaveTimer(uint32 timer) { m_nextSave = timer; }
|
||||
@@ -2080,6 +2166,18 @@ class TRINITY_DLL_SPEC Player : public Unit
|
||||
WorldLocation& GetTeleportDest() { return m_teleport_dest; }
|
||||
|
||||
DeclinedName const* GetDeclinedNames() const { return m_declinedname; }
|
||||
uint8 GetRunesState() const { return m_runes->runeState; }
|
||||
uint8 GetBaseRune(uint8 index) const { return m_runes->runes[index].BaseRune; }
|
||||
uint8 GetCurrentRune(uint8 index) const { return m_runes->runes[index].CurrentRune; }
|
||||
uint8 GetRuneCooldown(uint8 index) const { return m_runes->runes[index].Cooldown; }
|
||||
void SetBaseRune(uint8 index, uint8 baseRune) { m_runes->runes[index].BaseRune = baseRune; }
|
||||
void SetCurrentRune(uint8 index, uint8 currentRune) { m_runes->runes[index].CurrentRune = currentRune; }
|
||||
void SetRuneCooldown(uint8 index, uint8 cooldown) { m_runes->runes[index].Cooldown = cooldown; m_runes->SetRuneState(index, (cooldown == 0) ? true : false); }
|
||||
void ConvertRune(uint8 index, uint8 newType);
|
||||
void ResyncRunes(uint8 count);
|
||||
void AddRunePower(uint8 index);
|
||||
void InitRunes();
|
||||
AchievementMgr& GetAchievementMgr() { return m_achievementMgr; }
|
||||
bool HasTitle(uint32 bitIndex);
|
||||
bool HasTitle(CharTitlesEntry const* title) { return HasTitle(title->bit_index); }
|
||||
void SetTitle(CharTitlesEntry const* title);
|
||||
@@ -2216,6 +2314,7 @@ class TRINITY_DLL_SPEC Player : public Unit
|
||||
ActionButtonList m_actionButtons;
|
||||
|
||||
float m_auraBaseMod[BASEMOD_END][MOD_END];
|
||||
int16 m_baseRatingValue[MAX_COMBAT_RATING];
|
||||
|
||||
SpellModList m_spellMods[MAX_SPELLMOD];
|
||||
int32 m_SpellModRemoveCount;
|
||||
@@ -2249,7 +2348,6 @@ class TRINITY_DLL_SPEC Player : public Unit
|
||||
bool m_DailyQuestChanged;
|
||||
time_t m_lastDailyQuestTime;
|
||||
|
||||
uint32 m_regenTimer;
|
||||
uint32 m_breathTimer;
|
||||
uint32 m_drunkTimer;
|
||||
uint16 m_drunk;
|
||||
@@ -2268,8 +2366,10 @@ class TRINITY_DLL_SPEC Player : public Unit
|
||||
uint32 m_ArmorProficiency;
|
||||
bool m_canParry;
|
||||
bool m_canBlock;
|
||||
bool m_canTitanGrip;
|
||||
uint8 m_swingErrorMsg;
|
||||
float m_ammoDPS;
|
||||
|
||||
////////////////////Rest System/////////////////////
|
||||
int time_inn_enter;
|
||||
uint32 inn_pos_mapid;
|
||||
@@ -2316,6 +2416,8 @@ class TRINITY_DLL_SPEC Player : public Unit
|
||||
bool m_farsightVision;
|
||||
|
||||
DeclinedName *m_declinedname;
|
||||
Runes *m_runes;
|
||||
AchievementMgr m_achievementMgr;
|
||||
private:
|
||||
// internal common parts for CanStore/StoreItem functions
|
||||
uint8 _CanStoreItem_InSpecificSlot( uint8 bag, uint8 slot, ItemPosCountVec& dest, ItemPrototype const *pProto, uint32& count, bool swap, Item *pSrcItem ) const;
|
||||
|
||||
+35
-12
@@ -33,6 +33,7 @@
|
||||
#include "NPCHandler.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "Pet.h"
|
||||
#include "MapManager.h"
|
||||
|
||||
void WorldSession::SendNameQueryOpcode(Player *p)
|
||||
{
|
||||
@@ -185,7 +186,6 @@ void WorldSession::HandleCreatureQueryOpcode( WorldPacket & recv_data )
|
||||
data << (uint32)ci->type;
|
||||
data << (uint32)ci->family; // family wdbFeild9
|
||||
data << (uint32)ci->rank; // rank wdbFeild10
|
||||
data << (uint32)0; // unknown wdbFeild11
|
||||
data << (uint32)ci->PetSpellDataId; // Id from CreatureSpellData.dbc wdbField12
|
||||
data << (uint32)ci->Modelid1; // Modelid1
|
||||
data << (uint32)ci->Modelid2; // Modelid2
|
||||
@@ -276,20 +276,43 @@ void WorldSession::HandleCorpseQueryOpcode(WorldPacket & /*recv_data*/)
|
||||
|
||||
Corpse *corpse = GetPlayer()->GetCorpse();
|
||||
|
||||
uint8 found = 1;
|
||||
if(!corpse)
|
||||
found = 0;
|
||||
|
||||
WorldPacket data(MSG_CORPSE_QUERY, (1+found*(5*4)));
|
||||
data << uint8(found);
|
||||
if(found)
|
||||
{
|
||||
data << corpse->GetMapId();
|
||||
data << corpse->GetPositionX();
|
||||
data << corpse->GetPositionY();
|
||||
data << corpse->GetPositionZ();
|
||||
data << _player->GetMapId();
|
||||
WorldPacket data(MSG_CORPSE_QUERY, 1);
|
||||
data << uint8(0); // corpse not found
|
||||
SendPacket(&data);
|
||||
return;
|
||||
}
|
||||
|
||||
int32 mapid = corpse->GetMapId();
|
||||
float x = corpse->GetPositionX();
|
||||
float y = corpse->GetPositionY();
|
||||
float z = corpse->GetPositionZ();
|
||||
int32 corpsemapid = _player->GetMapId();
|
||||
|
||||
if(Map *map = corpse->GetMap())
|
||||
{
|
||||
if(map->IsDungeon())
|
||||
{
|
||||
if(!map->GetEntrancePos(mapid, x, y))
|
||||
return;
|
||||
|
||||
Map *entrance_map = MapManager::Instance().GetMap(mapid, _player);
|
||||
if(!entrance_map)
|
||||
return;
|
||||
|
||||
z = entrance_map->GetHeight(x, y, MAX_HEIGHT);
|
||||
corpsemapid = corpse->GetMapId();
|
||||
}
|
||||
}
|
||||
|
||||
WorldPacket data(MSG_CORPSE_QUERY, 1+(5*4));
|
||||
data << uint8(1); // corpse found
|
||||
data << int32(mapid);
|
||||
data << float(x);
|
||||
data << float(y);
|
||||
data << float(z);
|
||||
data << int32(corpsemapid);
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
|
||||
+47
-45
@@ -44,88 +44,90 @@ Quest::Quest(Field * questRecord)
|
||||
QuestFlags = questRecord[17].GetUInt16();
|
||||
uint32 SpecialFlags = questRecord[18].GetUInt16();
|
||||
CharTitleId = questRecord[19].GetUInt32();
|
||||
PrevQuestId = questRecord[20].GetInt32();
|
||||
NextQuestId = questRecord[21].GetInt32();
|
||||
ExclusiveGroup = questRecord[22].GetInt32();
|
||||
NextQuestInChain = questRecord[23].GetUInt32();
|
||||
SrcItemId = questRecord[24].GetUInt32();
|
||||
SrcItemCount = questRecord[25].GetUInt32();
|
||||
SrcSpell = questRecord[26].GetUInt32();
|
||||
Title = questRecord[27].GetCppString();
|
||||
Details = questRecord[28].GetCppString();
|
||||
Objectives = questRecord[29].GetCppString();
|
||||
OfferRewardText = questRecord[30].GetCppString();
|
||||
RequestItemsText = questRecord[31].GetCppString();
|
||||
EndText = questRecord[32].GetCppString();
|
||||
PlayersSlain = questRecord[20].GetUInt32();
|
||||
BonusTalents = questRecord[21].GetUInt32();
|
||||
PrevQuestId = questRecord[22].GetInt32();
|
||||
NextQuestId = questRecord[23].GetInt32();
|
||||
ExclusiveGroup = questRecord[24].GetInt32();
|
||||
NextQuestInChain = questRecord[25].GetUInt32();
|
||||
SrcItemId = questRecord[26].GetUInt32();
|
||||
SrcItemCount = questRecord[27].GetUInt32();
|
||||
SrcSpell = questRecord[28].GetUInt32();
|
||||
Title = questRecord[29].GetCppString();
|
||||
Details = questRecord[30].GetCppString();
|
||||
Objectives = questRecord[31].GetCppString();
|
||||
OfferRewardText = questRecord[32].GetCppString();
|
||||
RequestItemsText = questRecord[33].GetCppString();
|
||||
EndText = questRecord[34].GetCppString();
|
||||
|
||||
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
|
||||
ObjectiveText[i] = questRecord[33+i].GetCppString();
|
||||
ObjectiveText[i] = questRecord[35+i].GetCppString();
|
||||
|
||||
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
|
||||
ReqItemId[i] = questRecord[37+i].GetUInt32();
|
||||
ReqItemId[i] = questRecord[39+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
|
||||
ReqItemCount[i] = questRecord[41+i].GetUInt32();
|
||||
ReqItemCount[i] = questRecord[43+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
|
||||
ReqSourceId[i] = questRecord[45+i].GetUInt32();
|
||||
ReqSourceId[i] = questRecord[47+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
|
||||
ReqSourceCount[i] = questRecord[49+i].GetUInt32();
|
||||
ReqSourceCount[i] = questRecord[51+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
|
||||
ReqSourceRef[i] = questRecord[53+i].GetUInt32();
|
||||
ReqSourceRef[i] = questRecord[55+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
|
||||
ReqCreatureOrGOId[i] = questRecord[57+i].GetInt32();
|
||||
ReqCreatureOrGOId[i] = questRecord[59+i].GetInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
|
||||
ReqCreatureOrGOCount[i] = questRecord[61+i].GetUInt32();
|
||||
ReqCreatureOrGOCount[i] = questRecord[63+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
|
||||
ReqSpell[i] = questRecord[65+i].GetUInt32();
|
||||
ReqSpell[i] = questRecord[67+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
|
||||
RewChoiceItemId[i] = questRecord[69+i].GetUInt32();
|
||||
RewChoiceItemId[i] = questRecord[71+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
|
||||
RewChoiceItemCount[i] = questRecord[75+i].GetUInt32();
|
||||
RewChoiceItemCount[i] = questRecord[77+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_REWARDS_COUNT; ++i)
|
||||
RewItemId[i] = questRecord[81+i].GetUInt32();
|
||||
RewItemId[i] = questRecord[83+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_REWARDS_COUNT; ++i)
|
||||
RewItemCount[i] = questRecord[85+i].GetUInt32();
|
||||
RewItemCount[i] = questRecord[87+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i)
|
||||
RewRepFaction[i] = questRecord[89+i].GetUInt32();
|
||||
RewRepFaction[i] = questRecord[91+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i)
|
||||
RewRepValue[i] = questRecord[94+i].GetInt32();
|
||||
RewRepValue[i] = questRecord[96+i].GetInt32();
|
||||
|
||||
RewHonorableKills = questRecord[99].GetUInt32();
|
||||
RewOrReqMoney = questRecord[100].GetInt32();
|
||||
RewMoneyMaxLevel = questRecord[101].GetUInt32();
|
||||
RewSpell = questRecord[102].GetUInt32();
|
||||
RewSpellCast = questRecord[103].GetUInt32();
|
||||
RewMailTemplateId = questRecord[104].GetUInt32();
|
||||
RewMailDelaySecs = questRecord[105].GetUInt32();
|
||||
PointMapId = questRecord[106].GetUInt32();
|
||||
PointX = questRecord[107].GetFloat();
|
||||
PointY = questRecord[108].GetFloat();
|
||||
PointOpt = questRecord[109].GetUInt32();
|
||||
RewHonorableKills = questRecord[101].GetUInt32();
|
||||
RewOrReqMoney = questRecord[102].GetInt32();
|
||||
RewMoneyMaxLevel = questRecord[103].GetUInt32();
|
||||
RewSpell = questRecord[104].GetUInt32();
|
||||
RewSpellCast = questRecord[105].GetUInt32();
|
||||
RewMailTemplateId = questRecord[106].GetUInt32();
|
||||
RewMailDelaySecs = questRecord[107].GetUInt32();
|
||||
PointMapId = questRecord[108].GetUInt32();
|
||||
PointX = questRecord[109].GetFloat();
|
||||
PointY = questRecord[110].GetFloat();
|
||||
PointOpt = questRecord[111].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_EMOTE_COUNT; ++i)
|
||||
DetailsEmote[i] = questRecord[110+i].GetUInt32();
|
||||
DetailsEmote[i] = questRecord[112+i].GetUInt32();
|
||||
|
||||
IncompleteEmote = questRecord[114].GetUInt32();
|
||||
CompleteEmote = questRecord[115].GetUInt32();
|
||||
IncompleteEmote = questRecord[116].GetUInt32();
|
||||
CompleteEmote = questRecord[117].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_EMOTE_COUNT; ++i)
|
||||
OfferRewardEmote[i] = questRecord[116+i].GetInt32();
|
||||
OfferRewardEmote[i] = questRecord[118+i].GetInt32();
|
||||
|
||||
QuestStartScript = questRecord[120].GetUInt32();
|
||||
QuestCompleteScript = questRecord[121].GetUInt32();
|
||||
QuestStartScript = questRecord[122].GetUInt32();
|
||||
QuestCompleteScript = questRecord[123].GetUInt32();
|
||||
|
||||
QuestFlags |= SpecialFlags << 16;
|
||||
|
||||
|
||||
+27
-20
@@ -44,30 +44,33 @@ class ObjectMgr;
|
||||
enum QuestFailedReasons
|
||||
{
|
||||
INVALIDREASON_DONT_HAVE_REQ = 0,
|
||||
INVALIDREASON_QUEST_FAILED_LOW_LEVEL = 1, //You are not high enough level for that quest.
|
||||
INVALIDREASON_QUEST_FAILED_WRONG_RACE = 6, //That quest is not available to your race.
|
||||
INVALIDREASON_QUEST_ALREADY_DONE = 7, //You have completed that quest.
|
||||
INVALIDREASON_QUEST_ONLY_ONE_TIMED = 12, //You can only be on one timed quest at a time.
|
||||
INVALIDREASON_QUEST_ALREADY_ON = 13, //You are already on that quest
|
||||
INVALIDREASON_QUEST_FAILED_EXPANSION = 16, //This quest requires an expansion enabled account.
|
||||
INVALIDREASON_QUEST_ALREADY_ON2 = 18, //You are already on that quest
|
||||
INVALIDREASON_QUEST_FAILED_MISSING_ITEMS = 21, //You don't have the required items with you. Check storage.
|
||||
INVALIDREASON_QUEST_FAILED_NOT_ENOUGH_MONEY = 23, //You don't have enough money for that quest.
|
||||
INVALIDREASON_DAILY_QUESTS_REMAINING = 26, //You have already completed 10 daily quests today
|
||||
INVALIDREASON_QUEST_FAILED_CAIS = 27, //You cannot complete quests once you have reached tired time
|
||||
INVALIDREASON_QUEST_FAILED_LOW_LEVEL = 1, // You are not high enough level for that quest.
|
||||
INVALIDREASON_QUEST_FAILED_WRONG_RACE = 6, // That quest is not available to your race.
|
||||
INVALIDREASON_QUEST_ALREADY_DONE = 7, // You have completed that quest.
|
||||
INVALIDREASON_QUEST_ONLY_ONE_TIMED = 12, // You can only be on one timed quest at a time.
|
||||
INVALIDREASON_QUEST_ALREADY_ON = 13, // You are already on that quest.
|
||||
INVALIDREASON_QUEST_FAILED_EXPANSION = 16, // This quest requires an expansion enabled account.
|
||||
INVALIDREASON_QUEST_ALREADY_ON2 = 18, // You are already on that quest.
|
||||
INVALIDREASON_QUEST_FAILED_MISSING_ITEMS = 21, // You don't have the required items with you. Check storage.
|
||||
INVALIDREASON_QUEST_FAILED_NOT_ENOUGH_MONEY = 23, // You don't have enough money for that quest.
|
||||
INVALIDREASON_DAILY_QUESTS_REMAINING = 26, // You have already completed 25 daily quests today.
|
||||
INVALIDREASON_QUEST_FAILED_CAIS = 27, // You cannot complete quests once you have reached tired time.
|
||||
INVALIDREASON_DAILY_QUEST_COMPLETED_TODAY = 29 // You have completed that daily quest today.
|
||||
};
|
||||
|
||||
enum QuestShareMessages
|
||||
{
|
||||
QUEST_PARTY_MSG_SHARING_QUEST = 0,
|
||||
QUEST_PARTY_MSG_CANT_TAKE_QUEST = 1,
|
||||
QUEST_PARTY_MSG_ACCEPT_QUEST = 2,
|
||||
QUEST_PARTY_MSG_REFUSE_QUEST = 3,
|
||||
QUEST_PARTY_MSG_TOO_FAR = 4,
|
||||
QUEST_PARTY_MSG_BUSY = 5,
|
||||
QUEST_PARTY_MSG_LOG_FULL = 6,
|
||||
QUEST_PARTY_MSG_HAVE_QUEST = 7,
|
||||
QUEST_PARTY_MSG_FINISH_QUEST = 8,
|
||||
QUEST_PARTY_MSG_SHARING_QUEST = 0,
|
||||
QUEST_PARTY_MSG_CANT_TAKE_QUEST = 1,
|
||||
QUEST_PARTY_MSG_ACCEPT_QUEST = 2,
|
||||
QUEST_PARTY_MSG_DECLINE_QUEST = 3,
|
||||
QUEST_PARTY_MSG_BUSY = 4,
|
||||
QUEST_PARTY_MSG_LOG_FULL = 5,
|
||||
QUEST_PARTY_MSG_HAVE_QUEST = 6,
|
||||
QUEST_PARTY_MSG_FINISH_QUEST = 7,
|
||||
QUEST_PARTY_MSG_CANT_BE_SHARED_TODAY = 8,
|
||||
QUEST_PARTY_MSG_SHARING_TIMER_EXPIRED = 9,
|
||||
QUEST_PARTY_MSG_NOT_IN_PARTY = 10
|
||||
};
|
||||
|
||||
enum __QuestTradeSkill
|
||||
@@ -190,6 +193,8 @@ class Quest
|
||||
int32 GetExclusiveGroup() const { return ExclusiveGroup; }
|
||||
uint32 GetNextQuestInChain() const { return NextQuestInChain; }
|
||||
uint32 GetCharTitleId() const { return CharTitleId; }
|
||||
uint32 GetPlayersSlain() const { return PlayersSlain; }
|
||||
uint32 GetBonusTalents() const { return BonusTalents; }
|
||||
uint32 GetSrcItemId() const { return SrcItemId; }
|
||||
uint32 GetSrcItemCount() const { return SrcItemCount; }
|
||||
uint32 GetSrcSpell() const { return SrcSpell; }
|
||||
@@ -277,6 +282,8 @@ class Quest
|
||||
uint32 LimitTime;
|
||||
uint32 QuestFlags;
|
||||
uint32 CharTitleId;
|
||||
uint32 PlayersSlain;
|
||||
uint32 BonusTalents;
|
||||
int32 PrevQuestId;
|
||||
int32 NextQuestId;
|
||||
int32 ExclusiveGroup;
|
||||
|
||||
@@ -451,12 +451,6 @@ void WorldSession::HandleQuestPushToParty(WorldPacket& recvPacket)
|
||||
|
||||
_player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_SHARING_QUEST);
|
||||
|
||||
if( _player->GetDistance( pPlayer ) > 10 )
|
||||
{
|
||||
_player->SendPushToPartyResponse( pPlayer, QUEST_PARTY_MSG_TOO_FAR );
|
||||
continue;
|
||||
}
|
||||
|
||||
if( !pPlayer->SatisfyQuestStatus( pQuest, false ) )
|
||||
{
|
||||
_player->SendPushToPartyResponse( pPlayer, QUEST_PARTY_MSG_HAVE_QUEST );
|
||||
|
||||
+187
-122
@@ -88,7 +88,8 @@ enum Classes
|
||||
#define CLASSMASK_ALL_PLAYABLE \
|
||||
((1<<(CLASS_WARRIOR-1))|(1<<(CLASS_PALADIN-1))|(1<<(CLASS_HUNTER-1))| \
|
||||
(1<<(CLASS_ROGUE-1)) |(1<<(CLASS_PRIEST-1)) |(1<<(CLASS_SHAMAN-1))| \
|
||||
(1<<(CLASS_MAGE-1)) |(1<<(CLASS_WARLOCK-1))|(1<<(CLASS_DRUID-1)) )
|
||||
(1<<(CLASS_MAGE-1)) |(1<<(CLASS_WARLOCK-1))|(1<<(CLASS_DRUID-1)) | \
|
||||
(1<<(CLASS_DEATH_KNIGHT-1)) )
|
||||
|
||||
#define CLASSMASK_WAND_USERS ((1<<(CLASS_PRIEST-1))|(1<<(CLASS_MAGE-1))|(1<<(CLASS_WARLOCK-1)))
|
||||
|
||||
@@ -134,11 +135,12 @@ enum Powers
|
||||
POWER_FOCUS = 2,
|
||||
POWER_ENERGY = 3,
|
||||
POWER_HAPPINESS = 4,
|
||||
POWER_RUNES = 5,
|
||||
POWER_RUNE = 5,
|
||||
POWER_RUNIC_POWER = 6,
|
||||
POWER_HEALTH = 0xFFFFFFFE // (-2 as signed value)
|
||||
};
|
||||
|
||||
#define MAX_POWERS 5 // not count POWER_RUNES for now
|
||||
#define MAX_POWERS 7
|
||||
|
||||
enum SpellSchools
|
||||
{
|
||||
@@ -199,10 +201,11 @@ enum ItemQualities
|
||||
ITEM_QUALITY_RARE = 3, //BLUE
|
||||
ITEM_QUALITY_EPIC = 4, //PURPLE
|
||||
ITEM_QUALITY_LEGENDARY = 5, //ORANGE
|
||||
ITEM_QUALITY_ARTIFACT = 6 //LIGHT YELLOW
|
||||
ITEM_QUALITY_ARTIFACT = 6, //LIGHT YELLOW
|
||||
ITEM_QUALITY_HEIRLOOM = 7
|
||||
};
|
||||
|
||||
#define MAX_ITEM_QUALITY 7
|
||||
#define MAX_ITEM_QUALITY 8
|
||||
|
||||
enum SpellCategory
|
||||
{
|
||||
@@ -217,7 +220,7 @@ enum SpellCategory
|
||||
#define SPELL_ATTR_UNK0 0x00000001 // 0
|
||||
#define SPELL_ATTR_RANGED 0x00000002 // 1 All ranged abilities have this flag
|
||||
#define SPELL_ATTR_ON_NEXT_SWING_1 0x00000004 // 2 on next swing
|
||||
#define SPELL_ATTR_UNK3 0x00000008 // 3 not set in 2.4.2
|
||||
#define SPELL_ATTR_UNK3 0x00000008 // 3 not set in 3.0.3
|
||||
#define SPELL_ATTR_UNK4 0x00000010 // 4
|
||||
#define SPELL_ATTR_UNK5 0x00000020 // 5 trade spells?
|
||||
#define SPELL_ATTR_PASSIVE 0x00000040 // 6 Passive spell
|
||||
@@ -272,7 +275,7 @@ enum SpellCategory
|
||||
#define SPELL_ATTR_EX_REQ_COMBO_POINTS2 0x00400000 // 22 Req combo points on target
|
||||
#define SPELL_ATTR_EX_UNK23 0x00800000 // 23
|
||||
#define SPELL_ATTR_EX_UNK24 0x01000000 // 24 Req fishing pole??
|
||||
#define SPELL_ATTR_EX_UNK25 0x02000000 // 25 not set in 2.4.2
|
||||
#define SPELL_ATTR_EX_UNK25 0x02000000 // 25
|
||||
#define SPELL_ATTR_EX_UNK26 0x04000000 // 26
|
||||
#define SPELL_ATTR_EX_UNK27 0x08000000 // 27
|
||||
#define SPELL_ATTR_EX_UNK28 0x10000000 // 28
|
||||
@@ -288,14 +291,14 @@ enum SpellCategory
|
||||
#define SPELL_ATTR_EX2_UNK5 0x00000020 // 5
|
||||
#define SPELL_ATTR_EX2_UNK6 0x00000040 // 6
|
||||
#define SPELL_ATTR_EX2_UNK7 0x00000080 // 7
|
||||
#define SPELL_ATTR_EX2_UNK8 0x00000100 // 8 not set in 2.4.2
|
||||
#define SPELL_ATTR_EX2_UNK8 0x00000100 // 8 not set in 3.0.3
|
||||
#define SPELL_ATTR_EX2_UNK9 0x00000200 // 9
|
||||
#define SPELL_ATTR_EX2_UNK10 0x00000400 // 10
|
||||
#define SPELL_ATTR_EX2_HEALTH_FUNNEL 0x00000800 // 11
|
||||
#define SPELL_ATTR_EX2_UNK12 0x00001000 // 12
|
||||
#define SPELL_ATTR_EX2_UNK13 0x00002000 // 13
|
||||
#define SPELL_ATTR_EX2_UNK14 0x00004000 // 14
|
||||
#define SPELL_ATTR_EX2_UNK15 0x00008000 // 15 not set in 2.4.2
|
||||
#define SPELL_ATTR_EX2_UNK15 0x00008000 // 15 not set in 3.0.3
|
||||
#define SPELL_ATTR_EX2_TAME_BEAST 0x00010000 // 16
|
||||
#define SPELL_ATTR_EX2_NOT_RESET_AUTOSHOT 0x00020000 // 17 Hunters Shot and Stings only have this flag
|
||||
#define SPELL_ATTR_EX2_UNK18 0x00040000 // 18 Only Revive pet - possible req dead pet
|
||||
@@ -413,37 +416,37 @@ enum SpellCategory
|
||||
#define SPELL_ATTR_EX5_UNK31 0x80000000 // 31 Forces all nearby enemies to focus attacks caster
|
||||
|
||||
#define SPELL_ATTR_EX6_UNK0 0x00000001 // 0 Only Move spell have this flag
|
||||
#define SPELL_ATTR_EX6_UNK1 0x00000002 // 1 not set in 2.4.2
|
||||
#define SPELL_ATTR_EX6_UNK1 0x00000002 // 1 not set in 3.0.3
|
||||
#define SPELL_ATTR_EX6_UNK2 0x00000004 // 2
|
||||
#define SPELL_ATTR_EX6_UNK3 0x00000008 // 3
|
||||
#define SPELL_ATTR_EX6_UNK4 0x00000010 // 4 not set in 2.4.2
|
||||
#define SPELL_ATTR_EX6_UNK4 0x00000010 // 4
|
||||
#define SPELL_ATTR_EX6_UNK5 0x00000020 // 5
|
||||
#define SPELL_ATTR_EX6_UNK6 0x00000040 // 6
|
||||
#define SPELL_ATTR_EX6_UNK7 0x00000080 // 7
|
||||
#define SPELL_ATTR_EX6_UNK8 0x00000100 // 8
|
||||
#define SPELL_ATTR_EX6_UNK9 0x00000200 // 9 not set in 2.4.2
|
||||
#define SPELL_ATTR_EX6_UNK9 0x00000200 // 9
|
||||
#define SPELL_ATTR_EX6_UNK10 0x00000400 // 10
|
||||
#define SPELL_ATTR_EX6_UNK11 0x00000800 // 11
|
||||
#define SPELL_ATTR_EX6_UNK12 0x00001000 // 12 not set in 2.4.2
|
||||
#define SPELL_ATTR_EX6_UNK13 0x00002000 // 13 not set in 2.4.2
|
||||
#define SPELL_ATTR_EX6_UNK14 0x00004000 // 14 not set in 2.4.2
|
||||
#define SPELL_ATTR_EX6_UNK15 0x00008000 // 15 not set in 2.4.2
|
||||
#define SPELL_ATTR_EX6_UNK16 0x00010000 // 16 not set in 2.4.2
|
||||
#define SPELL_ATTR_EX6_UNK17 0x00020000 // 17 not set in 2.4.2
|
||||
#define SPELL_ATTR_EX6_UNK18 0x00040000 // 18 not set in 2.4.2
|
||||
#define SPELL_ATTR_EX6_UNK19 0x00080000 // 19 not set in 2.4.2
|
||||
#define SPELL_ATTR_EX6_UNK20 0x00100000 // 20 not set in 2.4.2
|
||||
#define SPELL_ATTR_EX6_UNK21 0x00200000 // 21 not set in 2.4.2
|
||||
#define SPELL_ATTR_EX6_UNK22 0x00400000 // 22 not set in 2.4.2
|
||||
#define SPELL_ATTR_EX6_UNK23 0x00800000 // 23 not set in 2.4.2
|
||||
#define SPELL_ATTR_EX6_UNK24 0x01000000 // 24 not set in 2.4.2
|
||||
#define SPELL_ATTR_EX6_UNK25 0x02000000 // 25 not set in 2.4.2
|
||||
#define SPELL_ATTR_EX6_UNK26 0x04000000 // 26 not set in 2.4.2
|
||||
#define SPELL_ATTR_EX6_UNK27 0x08000000 // 27 not set in 2.4.2
|
||||
#define SPELL_ATTR_EX6_UNK28 0x10000000 // 28 not set in 2.4.2
|
||||
#define SPELL_ATTR_EX6_UNK29 0x20000000 // 29 not set in 2.4.2
|
||||
#define SPELL_ATTR_EX6_UNK30 0x40000000 // 30 not set in 2.4.2
|
||||
#define SPELL_ATTR_EX6_UNK31 0x80000000 // 31 not set in 2.4.2
|
||||
#define SPELL_ATTR_EX6_UNK12 0x00001000 // 12
|
||||
#define SPELL_ATTR_EX6_UNK13 0x00002000 // 13
|
||||
#define SPELL_ATTR_EX6_UNK14 0x00004000 // 14
|
||||
#define SPELL_ATTR_EX6_UNK15 0x00008000 // 15 not set in 3.0.3
|
||||
#define SPELL_ATTR_EX6_UNK16 0x00010000 // 16
|
||||
#define SPELL_ATTR_EX6_UNK17 0x00020000 // 17
|
||||
#define SPELL_ATTR_EX6_UNK18 0x00040000 // 18
|
||||
#define SPELL_ATTR_EX6_UNK19 0x00080000 // 19
|
||||
#define SPELL_ATTR_EX6_UNK20 0x00100000 // 20
|
||||
#define SPELL_ATTR_EX6_UNK21 0x00200000 // 21
|
||||
#define SPELL_ATTR_EX6_UNK22 0x00400000 // 22
|
||||
#define SPELL_ATTR_EX6_UNK23 0x00800000 // 23 not set in 3.0.3
|
||||
#define SPELL_ATTR_EX6_UNK24 0x01000000 // 24 not set in 3.0.3
|
||||
#define SPELL_ATTR_EX6_UNK25 0x02000000 // 25 not set in 3.0.3
|
||||
#define SPELL_ATTR_EX6_UNK26 0x04000000 // 26 not set in 3.0.3
|
||||
#define SPELL_ATTR_EX6_UNK27 0x08000000 // 27 not set in 3.0.3
|
||||
#define SPELL_ATTR_EX6_UNK28 0x10000000 // 28 not set in 3.0.3
|
||||
#define SPELL_ATTR_EX6_UNK29 0x20000000 // 29 not set in 3.0.3
|
||||
#define SPELL_ATTR_EX6_UNK30 0x40000000 // 30 not set in 3.0.3
|
||||
#define SPELL_ATTR_EX6_UNK31 0x80000000 // 31 not set in 3.0.3
|
||||
|
||||
enum SheathTypes
|
||||
{
|
||||
@@ -566,7 +569,7 @@ enum SpellEffects
|
||||
SPELL_EFFECT_SUMMON_GUARDIAN = 42,
|
||||
SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER= 43,
|
||||
SPELL_EFFECT_SKILL_STEP = 44,
|
||||
SPELL_EFFECT_UNDEFINED_45 = 45,
|
||||
SPELL_EFFECT_ADD_HONOR = 45,
|
||||
SPELL_EFFECT_SPAWN = 46,
|
||||
SPELL_EFFECT_TRADE_SKILL = 47,
|
||||
SPELL_EFFECT_STEALTH = 48,
|
||||
@@ -586,16 +589,16 @@ enum SpellEffects
|
||||
SPELL_EFFECT_POWER_BURN = 62,
|
||||
SPELL_EFFECT_THREAT = 63,
|
||||
SPELL_EFFECT_TRIGGER_SPELL = 64,
|
||||
SPELL_EFFECT_HEALTH_FUNNEL = 65,
|
||||
SPELL_EFFECT_POWER_FUNNEL = 66,
|
||||
SPELL_EFFECT_APPLY_AREA_AURA_RAID = 65,
|
||||
SPELL_EFFECT_CREATE_MANA_GEM = 66,
|
||||
SPELL_EFFECT_HEAL_MAX_HEALTH = 67,
|
||||
SPELL_EFFECT_INTERRUPT_CAST = 68,
|
||||
SPELL_EFFECT_DISTRACT = 69,
|
||||
SPELL_EFFECT_PULL = 70,
|
||||
SPELL_EFFECT_PICKPOCKET = 71,
|
||||
SPELL_EFFECT_ADD_FARSIGHT = 72,
|
||||
SPELL_EFFECT_SUMMON_POSSESSED = 73,
|
||||
SPELL_EFFECT_SUMMON_TOTEM = 74,
|
||||
SPELL_EFFECT_UNTRAIN_TALENTS = 73,
|
||||
SPELL_EFFECT_APPLY_GLYPH = 74,
|
||||
SPELL_EFFECT_HEAL_MECHANICAL = 75,
|
||||
SPELL_EFFECT_SUMMON_OBJECT_WILD = 76,
|
||||
SPELL_EFFECT_SCRIPT_EFFECT = 77,
|
||||
@@ -608,10 +611,10 @@ enum SpellEffects
|
||||
SPELL_EFFECT_STUCK = 84,
|
||||
SPELL_EFFECT_SUMMON_PLAYER = 85,
|
||||
SPELL_EFFECT_ACTIVATE_OBJECT = 86,
|
||||
SPELL_EFFECT_SUMMON_TOTEM_SLOT1 = 87,
|
||||
SPELL_EFFECT_SUMMON_TOTEM_SLOT2 = 88,
|
||||
SPELL_EFFECT_SUMMON_TOTEM_SLOT3 = 89,
|
||||
SPELL_EFFECT_SUMMON_TOTEM_SLOT4 = 90,
|
||||
SPELL_EFFECT_WMO_DAMAGE = 87,
|
||||
SPELL_EFFECT_WMO_REPAIR = 88,
|
||||
SPELL_EFFECT_WMO_CHANGE = 89,
|
||||
SPELL_EFFECT_KILL_CREDIT = 90,
|
||||
SPELL_EFFECT_THREAT_ALL = 91,
|
||||
SPELL_EFFECT_ENCHANT_HELD_ITEM = 92,
|
||||
SPELL_EFFECT_SUMMON_PHANTASM = 93, //unused
|
||||
@@ -655,19 +658,19 @@ enum SpellEffects
|
||||
SPELL_EFFECT_131 = 131,
|
||||
SPELL_EFFECT_132 = 132,
|
||||
SPELL_EFFECT_UNLEARN_SPECIALIZATION = 133,
|
||||
SPELL_EFFECT_KILL_CREDIT = 134,
|
||||
SPELL_EFFECT_KILL_CREDIT2 = 134,
|
||||
SPELL_EFFECT_135 = 135,
|
||||
SPELL_EFFECT_HEAL_PCT = 136,
|
||||
SPELL_EFFECT_ENERGIZE_PCT = 137,
|
||||
SPELL_EFFECT_138 = 138,
|
||||
SPELL_EFFECT_139 = 139,
|
||||
SPELL_EFFECT_CLEAR_QUEST = 139,
|
||||
SPELL_EFFECT_FORCE_CAST = 140,
|
||||
SPELL_EFFECT_141 = 141,
|
||||
SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE = 142,
|
||||
SPELL_EFFECT_APPLY_AREA_AURA_OWNER = 143,
|
||||
SPELL_EFFECT_144 = 144,
|
||||
SPELL_EFFECT_145 = 145,
|
||||
SPELL_EFFECT_146 = 146,
|
||||
SPELL_EFFECT_ACTIVATE_RUNE = 146,
|
||||
SPELL_EFFECT_QUEST_FAIL = 147,
|
||||
SPELL_EFFECT_148 = 148,
|
||||
SPELL_EFFECT_149 = 149,
|
||||
@@ -675,7 +678,13 @@ enum SpellEffects
|
||||
SPELL_EFFECT_TRIGGER_SPELL_2 = 151,
|
||||
SPELL_EFFECT_152 = 152,
|
||||
SPELL_EFFECT_153 = 153,
|
||||
TOTAL_SPELL_EFFECTS = 154
|
||||
SPELL_EFFECT_154 = 154,
|
||||
SPELL_EFFECT_TITAN_GRIP = 155,
|
||||
SPELL_EFFECT_ADD_SOCKET = 156,
|
||||
SPELL_EFFECT_157 = 157,
|
||||
SPELL_EFFECT_MILLING = 158,
|
||||
SPELL_EFFECT_ALLOW_RENAME_PET = 159,
|
||||
TOTAL_SPELL_EFFECTS = 160
|
||||
};
|
||||
|
||||
// Spell aura states
|
||||
@@ -703,7 +712,8 @@ enum AuraState
|
||||
AURA_STATE_DEADLY_POISON = 16, // T |
|
||||
AURA_STATE_FORBEARANCE = 17, // c t|
|
||||
AURA_STATE_WEAKENED_SOUL = 18, // t|
|
||||
AURA_STATE_HYPOTHERMIA = 19 // c |
|
||||
AURA_STATE_HYPOTHERMIA = 19, // c |
|
||||
AURA_STATE_HEALTH_ABOVE_75_PERCENT = 23, // C | not implemented yet
|
||||
};
|
||||
|
||||
// Spell mechanics
|
||||
@@ -711,11 +721,11 @@ enum Mechanics
|
||||
{
|
||||
MECHANIC_NONE = 0,
|
||||
MECHANIC_CHARM = 1,
|
||||
MECHANIC_CONFUSED = 2,
|
||||
MECHANIC_DISORIENTED = 2,
|
||||
MECHANIC_DISARM = 3,
|
||||
MECHANIC_DISTRACT = 4,
|
||||
MECHANIC_FEAR = 5,
|
||||
MECHANIC_FUMBLE = 6,
|
||||
MECHANIC_GRIP = 6,
|
||||
MECHANIC_ROOT = 7,
|
||||
MECHANIC_PACIFY = 8, //0 spells use this mechanic
|
||||
MECHANIC_SILENCE = 9,
|
||||
@@ -731,7 +741,7 @@ enum Mechanics
|
||||
MECHANIC_SHIELD = 19,
|
||||
MECHANIC_SHACKLE = 20,
|
||||
MECHANIC_MOUNT = 21,
|
||||
MECHANIC_PERSUADE = 22, //0 spells use this mechanic
|
||||
MECHANIC_INFECTED = 22,
|
||||
MECHANIC_TURN = 23,
|
||||
MECHANIC_HORROR = 24,
|
||||
MECHANIC_INVULNERABILITY = 25,
|
||||
@@ -739,12 +749,13 @@ enum Mechanics
|
||||
MECHANIC_DAZE = 27,
|
||||
MECHANIC_DISCOVERY = 28,
|
||||
MECHANIC_IMMUNE_SHIELD = 29, // Divine (Blessing) Shield/Protection and Ice Block
|
||||
MECHANIC_SAPPED = 30
|
||||
MECHANIC_SAPPED = 30,
|
||||
MECHANIC_ENRAGED = 31
|
||||
};
|
||||
|
||||
// Used for spell 42292 Immune Movement Impairment and Loss of Control (0x49967da6)
|
||||
#define IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK ( \
|
||||
(1<<MECHANIC_CHARM )|(1<<MECHANIC_CONFUSED )|(1<<MECHANIC_FEAR )| \
|
||||
(1<<MECHANIC_CHARM )|(1<<MECHANIC_DISORIENTED )|(1<<MECHANIC_FEAR )| \
|
||||
(1<<MECHANIC_ROOT )|(1<<MECHANIC_PACIFY )|(1<<MECHANIC_SLEEP )| \
|
||||
(1<<MECHANIC_SNARE )|(1<<MECHANIC_STUN )|(1<<MECHANIC_FREEZE)| \
|
||||
(1<<MECHANIC_KNOCKOUT)|(1<<MECHANIC_POLYMORPH)|(1<<MECHANIC_BANISH)| \
|
||||
@@ -764,7 +775,8 @@ enum DispelType
|
||||
DISPEL_ALL = 7,
|
||||
DISPEL_SPE_NPC_ONLY = 8,
|
||||
DISPEL_ENRAGE = 9,
|
||||
DISPEL_ZG_TICKET = 10
|
||||
DISPEL_ZG_TICKET = 10,
|
||||
DESPEL_OLD_UNUSED = 11
|
||||
};
|
||||
|
||||
#define DISPEL_ALL_MASK ( (1<<DISPEL_MAGIC) | (1<<DISPEL_CURSE) | (1<<DISPEL_DISEASE) | (1<<DISPEL_POISON) )
|
||||
@@ -978,9 +990,10 @@ enum GameobjectTypes
|
||||
GAMEOBJECT_TYPE_BARBER_CHAIR = 32,
|
||||
GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING = 33,
|
||||
GAMEOBJECT_TYPE_GUILD_BANK = 34,
|
||||
GAMEOBJECT_TYPE_TRAPDOOR = 35
|
||||
};
|
||||
|
||||
#define MAX_GAMEOBJECT_TYPE 35 // sending to client this or greater value can crash client.
|
||||
#define MAX_GAMEOBJECT_TYPE 36 // sending to client this or greater value can crash client.
|
||||
|
||||
#define GAMEOBJECT_FISHINGNODE_ENTRY 35591 // Better to define it somewhere instead of hardcoding everywhere
|
||||
|
||||
@@ -1547,7 +1560,9 @@ enum LockType
|
||||
LOCKTYPE_BLASTING = 16,
|
||||
LOCKTYPE_SLOW_OPEN = 17,
|
||||
LOCKTYPE_SLOW_CLOSE = 18,
|
||||
LOCKTYPE_FISHING = 19
|
||||
LOCKTYPE_FISHING = 19,
|
||||
LOCKTYPE_INSCRIPTION = 20,
|
||||
LOCKTYPE_OPEN_FROM_VEHICLE = 21
|
||||
};
|
||||
|
||||
enum TrainerType // this is important type for npcs!
|
||||
@@ -1601,7 +1616,7 @@ enum CreatureFamily
|
||||
CREATURE_FAMILY_IMP = 23,
|
||||
CREATURE_FAMILY_BAT = 24,
|
||||
CREATURE_FAMILY_HYENA = 25,
|
||||
CREATURE_FAMILY_OWL = 26,
|
||||
CREATURE_FAMILY_BIRD_OF_PREY = 26,
|
||||
CREATURE_FAMILY_WIND_SERPENT = 27,
|
||||
CREATURE_FAMILY_REMOTE_CONTROL = 28,
|
||||
CREATURE_FAMILY_FELGUARD = 29,
|
||||
@@ -1611,7 +1626,16 @@ enum CreatureFamily
|
||||
CREATURE_FAMILY_SPOREBAT = 33,
|
||||
CREATURE_FAMILY_NETHER_RAY = 34,
|
||||
CREATURE_FAMILY_SERPENT = 35,
|
||||
CREATURE_FAMILY_SEA_LION = 36
|
||||
CREATURE_FAMILY_MOTH = 37,
|
||||
CREATURE_FAMILY_CHIMAERA = 38,
|
||||
CREATURE_FAMILY_DEVILSAUR = 39,
|
||||
CREATURE_FAMILY_GHOUL = 40,
|
||||
CREATURE_FAMILY_SILITHID = 41,
|
||||
CREATURE_FAMILY_WORM = 42,
|
||||
CREATURE_FAMILY_RHINO = 43,
|
||||
CREATURE_FAMILY_WASP = 44,
|
||||
CREATURE_FAMILY_CORE_HOUND = 45,
|
||||
CREATURE_FAMILY_SPIRIT_BEAST = 46
|
||||
};
|
||||
|
||||
enum CreatureTypeFlags
|
||||
@@ -1643,6 +1667,8 @@ enum QuestTypes
|
||||
QUEST_TYPE_LEGENDARY = 83,
|
||||
QUEST_TYPE_ESCORT = 84,
|
||||
QUEST_TYPE_HEROIC = 85,
|
||||
QUEST_TYPE_RAID_10 = 88,
|
||||
QUEST_TYPE_RAID_25 = 89
|
||||
};
|
||||
|
||||
// values based at QuestSort.dbc
|
||||
@@ -1653,7 +1679,7 @@ enum QuestSort
|
||||
QUEST_SORT_SEASONAL = 22,
|
||||
QUEST_SORT_UNDERCITY_OLD = 23,
|
||||
QUEST_SORT_HERBALISM = 24,
|
||||
QUEST_SORT_SCARLET_MONASTERY_OLD= 25,
|
||||
QUEST_SORT_BATTLEGROUNDS = 25,
|
||||
QUEST_SORT_ULDAMN_OLD = 41,
|
||||
QUEST_SORT_WARLOCK = 61,
|
||||
QUEST_SORT_WARRIOR = 81,
|
||||
@@ -1682,22 +1708,26 @@ enum QuestSort
|
||||
QUEST_SORT_REPUTATION = 367,
|
||||
QUEST_SORT_INVASION = 368,
|
||||
QUEST_SORT_MIDSUMMER = 369,
|
||||
QUEST_SORT_BREWFEST = 370
|
||||
QUEST_SORT_BREWFEST = 370,
|
||||
QUEST_SORT_INSCRIPTION = 371,
|
||||
QUEST_SORT_DEATH_KNIGHT = 372,
|
||||
QUEST_SORT_JEWELCRAFTING = 373
|
||||
};
|
||||
|
||||
inline uint8 ClassByQuestSort(int32 QuestSort)
|
||||
{
|
||||
switch(QuestSort)
|
||||
{
|
||||
case QUEST_SORT_WARLOCK: return CLASS_WARLOCK;
|
||||
case QUEST_SORT_WARRIOR: return CLASS_WARRIOR;
|
||||
case QUEST_SORT_SHAMAN: return CLASS_SHAMAN;
|
||||
case QUEST_SORT_PALADIN: return CLASS_PALADIN;
|
||||
case QUEST_SORT_MAGE: return CLASS_MAGE;
|
||||
case QUEST_SORT_ROGUE: return CLASS_ROGUE;
|
||||
case QUEST_SORT_HUNTER: return CLASS_HUNTER;
|
||||
case QUEST_SORT_PRIEST: return CLASS_PRIEST;
|
||||
case QUEST_SORT_DRUID: return CLASS_DRUID;
|
||||
case QUEST_SORT_WARLOCK: return CLASS_WARLOCK;
|
||||
case QUEST_SORT_WARRIOR: return CLASS_WARRIOR;
|
||||
case QUEST_SORT_SHAMAN: return CLASS_SHAMAN;
|
||||
case QUEST_SORT_PALADIN: return CLASS_PALADIN;
|
||||
case QUEST_SORT_MAGE: return CLASS_MAGE;
|
||||
case QUEST_SORT_ROGUE: return CLASS_ROGUE;
|
||||
case QUEST_SORT_HUNTER: return CLASS_HUNTER;
|
||||
case QUEST_SORT_PRIEST: return CLASS_PRIEST;
|
||||
case QUEST_SORT_DRUID: return CLASS_DRUID;
|
||||
case QUEST_SORT_DEATH_KNIGHT: return CLASS_DEATH_KNIGHT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1709,7 +1739,6 @@ enum SkillType
|
||||
SKILL_ARMS = 26,
|
||||
SKILL_COMBAT = 38,
|
||||
SKILL_SUBTLETY = 39,
|
||||
SKILL_POISONS = 40,
|
||||
SKILL_SWORDS = 43,
|
||||
SKILL_AXES = 44,
|
||||
SKILL_BOWS = 45,
|
||||
@@ -1717,8 +1746,8 @@ enum SkillType
|
||||
SKILL_BEAST_MASTERY = 50,
|
||||
SKILL_SURVIVAL = 51,
|
||||
SKILL_MACES = 54,
|
||||
SKILL_HOLY = 56,
|
||||
SKILL_2H_SWORDS = 55,
|
||||
SKILL_HOLY = 56,
|
||||
SKILL_SHADOW = 78,
|
||||
SKILL_DEFENSE = 95,
|
||||
SKILL_LANG_COMMON = 98,
|
||||
@@ -1774,24 +1803,20 @@ enum SkillType
|
||||
SKILL_PET_BOAR = 211,
|
||||
SKILL_PET_CROCILISK = 212,
|
||||
SKILL_PET_CARRION_BIRD = 213,
|
||||
SKILL_PET_GORILLA = 215,
|
||||
SKILL_PET_CRAB = 214,
|
||||
SKILL_PET_GORILLA = 215,
|
||||
SKILL_PET_RAPTOR = 217,
|
||||
SKILL_PET_TALLSTRIDER = 218,
|
||||
SKILL_RACIAL_UNDED = 220,
|
||||
SKILL_WEAPON_TALENTS = 222,
|
||||
SKILL_CROSSBOWS = 226,
|
||||
SKILL_SPEARS = 227,
|
||||
SKILL_WANDS = 228,
|
||||
SKILL_POLEARMS = 229,
|
||||
SKILL_PET_SCORPID = 236,
|
||||
SKILL_ARCANE = 237,
|
||||
SKILL_OPEN_LOCK = 242,
|
||||
SKILL_PET_TURTLE = 251,
|
||||
SKILL_ASSASSINATION = 253,
|
||||
SKILL_FURY = 256,
|
||||
SKILL_PROTECTION = 257,
|
||||
SKILL_BEAST_TRAINING = 261,
|
||||
SKILL_PROTECTION2 = 267,
|
||||
SKILL_PET_TALENTS = 270,
|
||||
SKILL_PLATE_MAIL = 293,
|
||||
@@ -1821,7 +1846,7 @@ enum SkillType
|
||||
SKILL_LOCKPICKING = 633,
|
||||
SKILL_PET_BAT = 653,
|
||||
SKILL_PET_HYENA = 654,
|
||||
SKILL_PET_OWL = 655,
|
||||
SKILL_PET_BIRD_OF_PREY = 655,
|
||||
SKILL_PET_WIND_SERPENT = 656,
|
||||
SKILL_LANG_GUTTERSPEAK = 673,
|
||||
SKILL_RIDING_KODO = 713,
|
||||
@@ -1841,10 +1866,27 @@ enum SkillType
|
||||
SKILL_PET_WARP_STALKER = 766,
|
||||
SKILL_PET_RAVAGER = 767,
|
||||
SKILL_PET_SERPENT = 768,
|
||||
SKILL_INTERNAL = 769
|
||||
SKILL_INTERNAL = 769,
|
||||
SKILL_DK_BLOOD = 770,
|
||||
SKILL_DK_FROST = 771,
|
||||
SKILL_DK_UNHOLY = 772,
|
||||
SKILL_INSCRIPTION = 773,
|
||||
SKILL_PET_MOTH = 775,
|
||||
SKILL_RUNEFORGING = 776,
|
||||
SKILL_MOUNTS = 777,
|
||||
SKILL_COMPANIONS = 778,
|
||||
SKILL_PET_EXOTIC_CHIMAERA = 780,
|
||||
SKILL_PET_EXOTIC_DEVILSAUR = 781,
|
||||
SKILL_PET_GHOUL = 782,
|
||||
SKILL_PET_EXOTIC_SILITHID = 783,
|
||||
SKILL_PET_EXOTIC_WORM = 784,
|
||||
SKILL_PET_WASP = 785,
|
||||
SKILL_PET_EXOTIC_RHINO = 786,
|
||||
SKILL_PET_EXOTIC_CORE_HOUND = 787,
|
||||
SKILL_PET_EXOTIC_SPIRIT_BEAST = 788
|
||||
};
|
||||
|
||||
#define MAX_SKILL_TYPE 770
|
||||
#define MAX_SKILL_TYPE 789
|
||||
|
||||
inline uint32 SkillByQuestSort(int32 QuestSort)
|
||||
{
|
||||
@@ -1859,25 +1901,27 @@ inline uint32 SkillByQuestSort(int32 QuestSort)
|
||||
case QUEST_SORT_TAILORING: return SKILL_TAILORING;
|
||||
case QUEST_SORT_COOKING: return SKILL_COOKING;
|
||||
case QUEST_SORT_FIRST_AID: return SKILL_FIRST_AID;
|
||||
case QUEST_SORT_JEWELCRAFTING: return SKILL_JEWELCRAFTING;
|
||||
case QUEST_SORT_INSCRIPTION: return SKILL_INSCRIPTION;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum SkillCategory
|
||||
{
|
||||
SKILL_CATEGORY_ATTRIBUTES = 5,
|
||||
SKILL_CATEGORY_WEAPON = 6,
|
||||
SKILL_CATEGORY_CLASS = 7,
|
||||
SKILL_CATEGORY_ARMOR = 8,
|
||||
SKILL_CATEGORY_SECONDARY = 9, // secondary professions
|
||||
SKILL_CATEGORY_ATTRIBUTES = 5,
|
||||
SKILL_CATEGORY_WEAPON = 6,
|
||||
SKILL_CATEGORY_CLASS = 7,
|
||||
SKILL_CATEGORY_ARMOR = 8,
|
||||
SKILL_CATEGORY_SECONDARY = 9, // secondary professions
|
||||
SKILL_CATEGORY_LANGUAGES = 10,
|
||||
SKILL_CATEGORY_PROFESSION = 11, // primary professions
|
||||
SKILL_CATEGORY_NOT_DISPLAYED = 12
|
||||
SKILL_CATEGORY_GENERIC = 12
|
||||
};
|
||||
|
||||
enum TotemCategory
|
||||
{
|
||||
TC_SKINNING_SKIFE = 1,
|
||||
TC_SKINNING_SKIFE_OLD = 1,
|
||||
TC_EARTH_TOTEM = 2,
|
||||
TC_AIR_TOTEM = 3,
|
||||
TC_FIRE_TOTEM = 4,
|
||||
@@ -1887,15 +1931,28 @@ enum TotemCategory
|
||||
TC_GOLDEN_ROD = 8,
|
||||
TC_TRUESILVER_ROD = 9,
|
||||
TC_ARCANITE_ROD = 10,
|
||||
TC_MINING_PICK = 11,
|
||||
TC_MINING_PICK_OLD = 11,
|
||||
TC_PHILOSOPHERS_STONE = 12,
|
||||
TC_BLACKSMITH_HAMMER = 13,
|
||||
TC_BLACKSMITH_HAMMER_OLD = 13,
|
||||
TC_ARCLIGHT_SPANNER = 14,
|
||||
TC_GYROMATIC_MA = 15,
|
||||
TC_MASTER_TOTEM = 21,
|
||||
TC_FEL_IRON_ROD = 41,
|
||||
TC_ADAMANTITE_ROD = 62,
|
||||
TC_ETERNIUM_ROD = 63
|
||||
TC_ETERNIUM_ROD = 63,
|
||||
TC_HOLLOW_QUILL = 81,
|
||||
TC_RUNED_AZURITE_ROD = 101,
|
||||
TC_VIRTUOSO_INKING_SET = 121,
|
||||
TC_DRUMS = 141,
|
||||
TC_GNOMISH_ARMY_KNIFE = 161,
|
||||
TC_BLACKSMITH_HAMMER = 162,
|
||||
TC_MINING_PICK = 165,
|
||||
TC_SKINNING_KNIFE = 166,
|
||||
TC_HAMMER_PICK = 167,
|
||||
TC_BLADED_PICKAXE = 168,
|
||||
TC_FLINT_AND_TINDER = 169,
|
||||
TC_RUNED_COBALT_ROD = 189,
|
||||
TC_RUNED_TITANIUM_ROD = 190
|
||||
};
|
||||
|
||||
enum UnitDynFlags
|
||||
@@ -1905,7 +1962,8 @@ enum UnitDynFlags
|
||||
UNIT_DYNFLAG_OTHER_TAGGER = 0x0004,
|
||||
UNIT_DYNFLAG_ROOTED = 0x0008,
|
||||
UNIT_DYNFLAG_SPECIALINFO = 0x0010,
|
||||
UNIT_DYNFLAG_DEAD = 0x0020
|
||||
UNIT_DYNFLAG_DEAD = 0x0020,
|
||||
UNIT_DYNFLAG_REFER_A_FRIEND = 0x0040
|
||||
};
|
||||
|
||||
enum CorpseDynFlags
|
||||
@@ -1915,6 +1973,7 @@ enum CorpseDynFlags
|
||||
|
||||
// Passive Spell codes explicit used in code
|
||||
#define SPELL_ID_GENERIC_LEARN 483
|
||||
#define SPELL_ID_GENERIC_LEARN_PET 55884 // used for learning mounts and companions
|
||||
#define SPELL_ID_PASSIVE_BATTLE_STANCE 2457
|
||||
#define SPELL_ID_PASSIVE_RESURRECTION_SICKNESS 15007
|
||||
#define SPELL_ID_WEAPON_SWITCH_COOLDOWN_1_5s 6119
|
||||
@@ -1982,9 +2041,12 @@ enum ChatMsg
|
||||
CHAT_MSG_BATTLEGROUND = 0x2C,
|
||||
CHAT_MSG_BATTLEGROUND_LEADER = 0x2D,
|
||||
CHAT_MSG_RESTRICTED = 0x2E,
|
||||
CHAT_MSG_BN = 0x2F,
|
||||
CHAT_MSG_ACHIEVEMENT = 0x30,
|
||||
CHAT_MSG_GUILD_ACHIEVEMENT = 0x31
|
||||
};
|
||||
|
||||
#define MAX_CHAT_MSG_TYPE 0x2F
|
||||
#define MAX_CHAT_MSG_TYPE 0x32
|
||||
|
||||
// Values from ItemPetFood (power of (value-1) used for compare with CreatureFamilyEntry.petDietMask
|
||||
enum PetDiet
|
||||
@@ -2153,42 +2215,45 @@ enum ResponseCodes
|
||||
CHAR_CREATE_SERVER_QUEUE = 0x37,
|
||||
CHAR_CREATE_ONLY_EXISTING = 0x38,
|
||||
CHAR_CREATE_EXPANSION = 0x39,
|
||||
CHAR_CREATE_EXPANSION_CLASS = 0x3A,
|
||||
CHAR_CREATE_LEVEL_REQUIREMENT = 0x3B,
|
||||
CHAR_CREATE_UNIQUE_CLASS_LIMIT = 0x3C,
|
||||
|
||||
CHAR_DELETE_IN_PROGRESS = 0x3A,
|
||||
CHAR_DELETE_SUCCESS = 0x3B,
|
||||
CHAR_DELETE_FAILED = 0x3C,
|
||||
CHAR_DELETE_FAILED_LOCKED_FOR_TRANSFER = 0x3D,
|
||||
CHAR_DELETE_FAILED_GUILD_LEADER = 0x3E,
|
||||
CHAR_DELETE_FAILED_ARENA_CAPTAIN = 0x3F,
|
||||
CHAR_DELETE_IN_PROGRESS = 0x3D,
|
||||
CHAR_DELETE_SUCCESS = 0x3E,
|
||||
CHAR_DELETE_FAILED = 0x3F,
|
||||
CHAR_DELETE_FAILED_LOCKED_FOR_TRANSFER = 0x40,
|
||||
CHAR_DELETE_FAILED_GUILD_LEADER = 0x41,
|
||||
CHAR_DELETE_FAILED_ARENA_CAPTAIN = 0x42,
|
||||
|
||||
CHAR_LOGIN_IN_PROGRESS = 0x40,
|
||||
CHAR_LOGIN_SUCCESS = 0x41,
|
||||
CHAR_LOGIN_NO_WORLD = 0x42,
|
||||
CHAR_LOGIN_DUPLICATE_CHARACTER = 0x43,
|
||||
CHAR_LOGIN_NO_INSTANCES = 0x44,
|
||||
CHAR_LOGIN_FAILED = 0x45,
|
||||
CHAR_LOGIN_DISABLED = 0x46,
|
||||
CHAR_LOGIN_NO_CHARACTER = 0x47,
|
||||
CHAR_LOGIN_LOCKED_FOR_TRANSFER = 0x48,
|
||||
CHAR_LOGIN_LOCKED_BY_BILLING = 0x49,
|
||||
CHAR_LOGIN_IN_PROGRESS = 0x43,
|
||||
CHAR_LOGIN_SUCCESS = 0x44,
|
||||
CHAR_LOGIN_NO_WORLD = 0x45,
|
||||
CHAR_LOGIN_DUPLICATE_CHARACTER = 0x46,
|
||||
CHAR_LOGIN_NO_INSTANCES = 0x47,
|
||||
CHAR_LOGIN_FAILED = 0x48,
|
||||
CHAR_LOGIN_DISABLED = 0x49,
|
||||
CHAR_LOGIN_NO_CHARACTER = 0x4A,
|
||||
CHAR_LOGIN_LOCKED_FOR_TRANSFER = 0x4B,
|
||||
CHAR_LOGIN_LOCKED_BY_BILLING = 0x4C,
|
||||
|
||||
CHAR_NAME_SUCCESS = 0x4A,
|
||||
CHAR_NAME_FAILURE = 0x4B,
|
||||
CHAR_NAME_NO_NAME = 0x4C,
|
||||
CHAR_NAME_TOO_SHORT = 0x4D,
|
||||
CHAR_NAME_TOO_LONG = 0x4E,
|
||||
CHAR_NAME_INVALID_CHARACTER = 0x4F,
|
||||
CHAR_NAME_MIXED_LANGUAGES = 0x50,
|
||||
CHAR_NAME_PROFANE = 0x51,
|
||||
CHAR_NAME_RESERVED = 0x52,
|
||||
CHAR_NAME_INVALID_APOSTROPHE = 0x53,
|
||||
CHAR_NAME_MULTIPLE_APOSTROPHES = 0x54,
|
||||
CHAR_NAME_THREE_CONSECUTIVE = 0x55,
|
||||
CHAR_NAME_INVALID_SPACE = 0x56,
|
||||
CHAR_NAME_CONSECUTIVE_SPACES = 0x57,
|
||||
CHAR_NAME_RUSSIAN_CONSECUTIVE_SILENT_CHARACTERS = 0x58,
|
||||
CHAR_NAME_RUSSIAN_SILENT_CHARACTER_AT_BEGINNING_OR_END = 0x59,
|
||||
CHAR_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME = 0x5A,
|
||||
CHAR_NAME_SUCCESS = 0x4D,
|
||||
CHAR_NAME_FAILURE = 0x4E,
|
||||
CHAR_NAME_NO_NAME = 0x4F,
|
||||
CHAR_NAME_TOO_SHORT = 0x50,
|
||||
CHAR_NAME_TOO_LONG = 0x51,
|
||||
CHAR_NAME_INVALID_CHARACTER = 0x52,
|
||||
CHAR_NAME_MIXED_LANGUAGES = 0x53,
|
||||
CHAR_NAME_PROFANE = 0x54,
|
||||
CHAR_NAME_RESERVED = 0x55,
|
||||
CHAR_NAME_INVALID_APOSTROPHE = 0x56,
|
||||
CHAR_NAME_MULTIPLE_APOSTROPHES = 0x57,
|
||||
CHAR_NAME_THREE_CONSECUTIVE = 0x58,
|
||||
CHAR_NAME_INVALID_SPACE = 0x59,
|
||||
CHAR_NAME_CONSECUTIVE_SPACES = 0x5A,
|
||||
CHAR_NAME_RUSSIAN_CONSECUTIVE_SILENT_CHARACTERS = 0x5B,
|
||||
CHAR_NAME_RUSSIAN_SILENT_CHARACTER_AT_BEGINNING_OR_END = 0x5C,
|
||||
CHAR_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME = 0x5D
|
||||
};
|
||||
|
||||
/// Ban function modes
|
||||
|
||||
@@ -82,10 +82,6 @@ void WorldSession::HandleLearnTalentOpcode( WorldPacket & recv_data )
|
||||
}
|
||||
}
|
||||
|
||||
// Check if it requires spell
|
||||
if( talentInfo->DependsOnSpell && !player->HasSpell(talentInfo->DependsOnSpell) )
|
||||
return;
|
||||
|
||||
// Find out how many points we have in this field
|
||||
uint32 spentPoints = 0;
|
||||
|
||||
|
||||
+323
-79
@@ -237,7 +237,7 @@ void SpellCastTargets::write ( WorldPacket * data )
|
||||
{
|
||||
*data << uint32(m_targetMask);
|
||||
|
||||
if( m_targetMask & ( TARGET_FLAG_UNIT | TARGET_FLAG_PVP_CORPSE | TARGET_FLAG_OBJECT | TARGET_FLAG_CORPSE | TARGET_FLAG_UNK2 ) )
|
||||
if( m_targetMask & ( TARGET_FLAG_UNIT | TARGET_FLAG_PVP_CORPSE | TARGET_FLAG_OBJECT | TARGET_FLAG_OBJECT_UNK | TARGET_FLAG_CORPSE | TARGET_FLAG_UNK2 ) )
|
||||
{
|
||||
if(m_targetMask & TARGET_FLAG_UNIT)
|
||||
{
|
||||
@@ -357,6 +357,7 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi
|
||||
gameObjTarget = NULL;
|
||||
focusObject = NULL;
|
||||
m_cast_count = 0;
|
||||
m_glyphIndex = 0;
|
||||
m_triggeredByAuraSpell = NULL;
|
||||
|
||||
//Auto Shot & Shoot
|
||||
@@ -365,6 +366,7 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi
|
||||
else
|
||||
m_autoRepeat = false;
|
||||
|
||||
m_runesState = 0;
|
||||
m_powerCost = 0; // setup to correct value in Spell::prepare, don't must be used before.
|
||||
m_casttime = 0; // setup to correct value in Spell::prepare, don't must be used before.
|
||||
m_timer = 0; // will set to castime in prepare
|
||||
@@ -502,6 +504,8 @@ void Spell::FillTargetMap()
|
||||
case SPELL_EFFECT_TRIGGER_SPELL:
|
||||
//case SPELL_EFFECT_TRIGGER_MISSILE: ??
|
||||
case SPELL_EFFECT_SKILL_STEP:
|
||||
case SPELL_EFFECT_PROFICIENCY:
|
||||
case SPELL_EFFECT_SUMMON_OBJECT_WILD:
|
||||
case SPELL_EFFECT_SELF_RESURRECT:
|
||||
case SPELL_EFFECT_REPUTATION:
|
||||
if(m_targets.getUnitTarget())
|
||||
@@ -533,6 +537,7 @@ void Spell::FillTargetMap()
|
||||
break;
|
||||
case SPELL_EFFECT_SUMMON_CHANGE_ITEM:
|
||||
case SPELL_EFFECT_ADD_FARSIGHT:
|
||||
case SPELL_EFFECT_APPLY_GLYPH:
|
||||
case SPELL_EFFECT_STUCK:
|
||||
case SPELL_EFFECT_DESTROY_ALL_TOTEMS:
|
||||
tmpUnitMap.push_back(m_caster);
|
||||
@@ -546,6 +551,7 @@ void Spell::FillTargetMap()
|
||||
case SPELL_EFFECT_DISENCHANT:
|
||||
case SPELL_EFFECT_FEED_PET:
|
||||
case SPELL_EFFECT_PROSPECTING:
|
||||
case SPELL_EFFECT_MILLING:
|
||||
if(m_targets.getItemTarget())
|
||||
AddItemTarget(m_targets.getItemTarget(), i);
|
||||
break;
|
||||
@@ -1110,6 +1116,17 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
|
||||
return;
|
||||
}
|
||||
|
||||
if (unit->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
((Player*)unit)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, m_spellInfo->Id);
|
||||
((Player*)unit)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, m_spellInfo->Id);
|
||||
}
|
||||
|
||||
if(m_caster->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
((Player*)m_caster)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2, m_spellInfo->Id, 0, unit);
|
||||
}
|
||||
|
||||
if( m_caster != unit )
|
||||
{
|
||||
if( !m_caster->IsFriendlyTo(unit) )
|
||||
@@ -1320,6 +1337,16 @@ void Spell::SearchChainTarget(std::list<Unit*> &TagUnitMap, Unit* pUnitTarget, f
|
||||
if(!pUnitTarget)
|
||||
return;
|
||||
|
||||
// Get spell max affected targets
|
||||
/*uint32 unMaxTargets = m_spellInfo->MaxAffectedTargets;
|
||||
Unit::AuraList const& mod = m_caster->GetAurasByType(SPELL_AURA_MOD_MAX_AFFECTED_TARGETS);
|
||||
for(Unit::AuraList::const_iterator m = mod.begin(); m != mod.end(); ++m)
|
||||
{
|
||||
if (!(*m)->isAffectedOnSpell(m_spellInfo))
|
||||
continue;
|
||||
unMaxTargets+=(*m)->GetModifier()->m_amount;
|
||||
}*/
|
||||
|
||||
//FIXME: This very like horrible hack and wrong for most spells
|
||||
if(m_spellInfo->DmgClass != SPELL_DAMAGE_CLASS_MELEE)
|
||||
max_range += unMaxTargets * CHAIN_SPELL_JUMP_RADIUS;
|
||||
@@ -2226,6 +2253,14 @@ void Spell::cast(bool skipCheck)
|
||||
// set to real guid to be sent later to the client
|
||||
m_targets.updateTradeSlotItem();
|
||||
|
||||
if (m_caster->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
if (m_CastItem)
|
||||
((Player*)m_caster)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM, m_CastItem->GetEntry());
|
||||
|
||||
((Player*)m_caster)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, m_spellInfo->Id);
|
||||
}
|
||||
|
||||
// CAST SPELL
|
||||
SendSpellCooldown();
|
||||
|
||||
@@ -2668,7 +2703,7 @@ void Spell::finish(bool ok)
|
||||
{
|
||||
SpellEntry const *auraSpellInfo = (*i)->GetSpellProto();
|
||||
uint32 auraSpellIdx = (*i)->GetEffIndex();
|
||||
if (IsAffectedBy(auraSpellInfo, auraSpellIdx))
|
||||
if (IsAffectedByAura((*i)))
|
||||
{
|
||||
for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit)
|
||||
if( ihit->effectMask & (1<<auraSpellIdx) )
|
||||
@@ -2724,9 +2759,9 @@ void Spell::SendCastResult(uint8 result)
|
||||
if(result != 0)
|
||||
{
|
||||
WorldPacket data(SMSG_CAST_FAILED, (4+1+1));
|
||||
data << uint8(m_cast_count); // single cast or multi 2.3 (0/1)
|
||||
data << uint32(m_spellInfo->Id);
|
||||
data << uint8(result); // problem
|
||||
data << uint8(m_cast_count); // single cast or multi 2.3 (0/1)
|
||||
switch (result)
|
||||
{
|
||||
case SPELL_FAILED_REQUIRES_SPELL_FOCUS:
|
||||
@@ -2767,18 +2802,11 @@ void Spell::SendCastResult(uint8 result)
|
||||
case SPELL_FAILED_EQUIPPED_ITEM_CLASS:
|
||||
data << uint32(m_spellInfo->EquippedItemClass);
|
||||
data << uint32(m_spellInfo->EquippedItemSubClassMask);
|
||||
data << uint32(m_spellInfo->EquippedItemInventoryTypeMask);
|
||||
//data << uint32(m_spellInfo->EquippedItemInventoryTypeMask);
|
||||
break;
|
||||
}
|
||||
((Player*)m_caster)->GetSession()->SendPacket(&data);
|
||||
}
|
||||
else
|
||||
{
|
||||
WorldPacket data(SMSG_CLEAR_EXTRA_AURA_INFO, (8+4));
|
||||
data.append(m_caster->GetPackGUID());
|
||||
data << uint32(m_spellInfo->Id);
|
||||
((Player*)m_caster)->GetSession()->SendPacket(&data);
|
||||
}
|
||||
}
|
||||
|
||||
void Spell::SendSpellStart()
|
||||
@@ -2792,6 +2820,9 @@ void Spell::SendSpellStart()
|
||||
if(IsRangedSpell())
|
||||
castFlags |= CAST_FLAG_AMMO;
|
||||
|
||||
if(m_spellInfo->runeCostID)
|
||||
castFlags |= CAST_FLAG_UNKNOWN10;
|
||||
|
||||
Unit *target = m_targets.getUnitTarget() ? m_targets.getUnitTarget() : m_caster;
|
||||
|
||||
WorldPacket data(SMSG_SPELL_START, (8+8+4+4+2));
|
||||
@@ -2801,14 +2832,32 @@ void Spell::SendSpellStart()
|
||||
data.append(m_caster->GetPackGUID());
|
||||
|
||||
data.append(m_caster->GetPackGUID());
|
||||
data << uint32(m_spellInfo->Id);
|
||||
data << uint8(m_cast_count); // single cast or multi 2.3 (0/1)
|
||||
data << uint16(castFlags);
|
||||
data << uint32(m_timer);
|
||||
data << uint8(m_cast_count); // pending spell cast?
|
||||
data << uint32(m_spellInfo->Id); // spellId
|
||||
data << uint32(castFlags); // cast flags
|
||||
data << uint32(m_timer); // delay?
|
||||
|
||||
m_targets.write(&data);
|
||||
|
||||
if( castFlags & CAST_FLAG_AMMO )
|
||||
if ( castFlags & CAST_FLAG_UNKNOWN6 ) // predicted power?
|
||||
data << uint32(0);
|
||||
|
||||
if ( castFlags & CAST_FLAG_UNKNOWN7 ) // rune cooldowns list
|
||||
{
|
||||
uint8 v1 = 0;//m_runesState;
|
||||
uint8 v2 = 0;//((Player*)m_caster)->GetRunesState();
|
||||
data << uint8(v1); // runes state before
|
||||
data << uint8(v2); // runes state after
|
||||
for(uint8 i = 0; i < MAX_RUNES; ++i)
|
||||
{
|
||||
uint8 m = (1 << i);
|
||||
if(m & v1) // usable before...
|
||||
if(!(m & v2)) // ...but on cooldown now...
|
||||
data << uint8(0); // some unknown byte (time?)
|
||||
}
|
||||
}
|
||||
|
||||
if ( castFlags & CAST_FLAG_AMMO )
|
||||
WriteAmmoToPacket(&data);
|
||||
|
||||
m_caster->SendMessageToSet(&data, true);
|
||||
@@ -2828,6 +2877,13 @@ void Spell::SendSpellGo()
|
||||
if(IsRangedSpell())
|
||||
castFlags |= CAST_FLAG_AMMO; // arrows/bullets visual
|
||||
|
||||
if((m_caster->GetTypeId() == TYPEID_PLAYER) && (m_caster->getClass() == CLASS_DEATH_KNIGHT) && m_spellInfo->runeCostID)
|
||||
{
|
||||
castFlags |= CAST_FLAG_UNKNOWN10; // same as in SMSG_SPELL_START
|
||||
castFlags |= CAST_FLAG_UNKNOWN6; // makes cooldowns visible
|
||||
castFlags |= CAST_FLAG_UNKNOWN7; // rune cooldowns list
|
||||
}
|
||||
|
||||
WorldPacket data(SMSG_SPELL_GO, 50); // guess size
|
||||
if(m_CastItem)
|
||||
data.append(m_CastItem->GetPackGUID());
|
||||
@@ -2835,17 +2891,53 @@ void Spell::SendSpellGo()
|
||||
data.append(m_caster->GetPackGUID());
|
||||
|
||||
data.append(m_caster->GetPackGUID());
|
||||
data << uint32(m_spellInfo->Id);
|
||||
data << uint16(castFlags);
|
||||
data << uint8(m_cast_count); // pending spell cast?
|
||||
data << uint32(m_spellInfo->Id); // spellId
|
||||
data << uint32(castFlags); // cast flags
|
||||
data << uint32(getMSTime()); // timestamp
|
||||
|
||||
WriteSpellGoTargets(&data);
|
||||
|
||||
m_targets.write(&data);
|
||||
|
||||
if( castFlags & CAST_FLAG_AMMO )
|
||||
if ( castFlags & CAST_FLAG_UNKNOWN6 ) // unknown wotlk, predicted power?
|
||||
data << uint32(0);
|
||||
|
||||
if ( castFlags & CAST_FLAG_UNKNOWN7 ) // rune cooldowns list
|
||||
{
|
||||
uint8 v1 = m_runesState;
|
||||
uint8 v2 = ((Player*)m_caster)->GetRunesState();
|
||||
data << uint8(v1); // runes state before
|
||||
data << uint8(v2); // runes state after
|
||||
for(uint8 i = 0; i < MAX_RUNES; ++i)
|
||||
{
|
||||
uint8 m = (1 << i);
|
||||
if(m & v1) // usable before...
|
||||
if(!(m & v2)) // ...but on cooldown now...
|
||||
data << uint8(0); // some unknown byte (time?)
|
||||
}
|
||||
}
|
||||
|
||||
if ( castFlags & CAST_FLAG_UNKNOWN4 ) // unknown wotlk
|
||||
{
|
||||
data << float(0);
|
||||
data << uint32(0);
|
||||
}
|
||||
|
||||
if ( castFlags & CAST_FLAG_AMMO )
|
||||
WriteAmmoToPacket(&data);
|
||||
|
||||
if ( castFlags & CAST_FLAG_UNKNOWN5 ) // unknown wotlk
|
||||
{
|
||||
data << uint32(0);
|
||||
data << uint32(0);
|
||||
}
|
||||
|
||||
if ( m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION )
|
||||
{
|
||||
data << uint8(0);
|
||||
}
|
||||
|
||||
m_caster->SendMessageToSet(&data, true);
|
||||
}
|
||||
|
||||
@@ -2973,30 +3065,19 @@ void Spell::SendLogExecute()
|
||||
data << uint8(0);
|
||||
break;
|
||||
case SPELL_EFFECT_CREATE_ITEM:
|
||||
case SPELL_EFFECT_157:
|
||||
data << uint32(m_spellInfo->EffectItemType[0]);
|
||||
break;
|
||||
case SPELL_EFFECT_SUMMON:
|
||||
case SPELL_EFFECT_SUMMON_WILD:
|
||||
case SPELL_EFFECT_SUMMON_GUARDIAN:
|
||||
case SPELL_EFFECT_TRANS_DOOR:
|
||||
case SPELL_EFFECT_SUMMON_PET:
|
||||
case SPELL_EFFECT_SUMMON_POSSESSED:
|
||||
case SPELL_EFFECT_SUMMON_TOTEM:
|
||||
case SPELL_EFFECT_SUMMON_OBJECT_WILD:
|
||||
case SPELL_EFFECT_CREATE_HOUSE:
|
||||
case SPELL_EFFECT_DUEL:
|
||||
case SPELL_EFFECT_SUMMON_TOTEM_SLOT1:
|
||||
case SPELL_EFFECT_SUMMON_TOTEM_SLOT2:
|
||||
case SPELL_EFFECT_SUMMON_TOTEM_SLOT3:
|
||||
case SPELL_EFFECT_SUMMON_TOTEM_SLOT4:
|
||||
case SPELL_EFFECT_SUMMON_PHANTASM:
|
||||
case SPELL_EFFECT_SUMMON_CRITTER:
|
||||
case SPELL_EFFECT_SUMMON_OBJECT_SLOT1:
|
||||
case SPELL_EFFECT_SUMMON_OBJECT_SLOT2:
|
||||
case SPELL_EFFECT_SUMMON_OBJECT_SLOT3:
|
||||
case SPELL_EFFECT_SUMMON_OBJECT_SLOT4:
|
||||
case SPELL_EFFECT_SUMMON_DEMON:
|
||||
case SPELL_EFFECT_150:
|
||||
if(Unit *unit = m_targets.getUnitTarget())
|
||||
data.append(unit->GetPackGUID());
|
||||
else if(m_targets.getItemTargetGUID())
|
||||
@@ -3015,6 +3096,13 @@ void Spell::SendLogExecute()
|
||||
else
|
||||
data << uint8(0);
|
||||
break;
|
||||
case SPELL_EFFECT_RESURRECT:
|
||||
case SPELL_EFFECT_RESURRECT_NEW:
|
||||
if(Unit *unit = m_targets.getUnitTarget())
|
||||
data.append(unit->GetPackGUID());
|
||||
else
|
||||
data << uint8(0);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
@@ -3028,13 +3116,16 @@ void Spell::SendInterrupted(uint8 result)
|
||||
{
|
||||
WorldPacket data(SMSG_SPELL_FAILURE, (8+4+1));
|
||||
data.append(m_caster->GetPackGUID());
|
||||
data << m_spellInfo->Id;
|
||||
data << result;
|
||||
data << uint8(m_cast_count);
|
||||
data << uint32(m_spellInfo->Id);
|
||||
data << uint8(result);
|
||||
m_caster->SendMessageToSet(&data, true);
|
||||
|
||||
data.Initialize(SMSG_SPELL_FAILED_OTHER, (8+4));
|
||||
data.append(m_caster->GetPackGUID());
|
||||
data << m_spellInfo->Id;
|
||||
data << uint8(m_cast_count);
|
||||
data << uint32(m_spellInfo->Id);
|
||||
data << uint8(result);
|
||||
m_caster->SendMessageToSet(&data, true);
|
||||
}
|
||||
|
||||
@@ -3102,10 +3193,19 @@ void Spell::SendChannelStart(uint32 duration)
|
||||
|
||||
void Spell::SendResurrectRequest(Player* target)
|
||||
{
|
||||
WorldPacket data(SMSG_RESURRECT_REQUEST, (8+4+2+4));
|
||||
data << m_caster->GetGUID();
|
||||
data << uint32(1) << uint16(0) << uint32(1);
|
||||
// Both players and NPCs can resurrect using spells - have a look at creature 28487 for example
|
||||
// However, the packet structure differs slightly
|
||||
|
||||
const char* sentName = m_caster->GetTypeId()==TYPEID_PLAYER ?"":m_caster->GetNameForLocaleIdx(target->GetSession()->GetSessionDbLocaleIndex());
|
||||
|
||||
WorldPacket data(SMSG_RESURRECT_REQUEST, (8+4+strlen(sentName)+1+1+1));
|
||||
data << uint64(m_caster->GetGUID());
|
||||
data << uint32(strlen(sentName)+1);
|
||||
|
||||
data << sentName;
|
||||
data << uint8(0);
|
||||
|
||||
data << uint8(m_caster->GetTypeId()==TYPEID_PLAYER ?0:1);
|
||||
target->GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
||||
@@ -3202,6 +3302,12 @@ void Spell::TakePower()
|
||||
|
||||
Powers powerType = Powers(m_spellInfo->powerType);
|
||||
|
||||
if(powerType == POWER_RUNE)
|
||||
{
|
||||
TakeRunePower();
|
||||
return;
|
||||
}
|
||||
|
||||
m_caster->ModifyPower(powerType, -(int32)m_powerCost);
|
||||
|
||||
// Set the five second timer
|
||||
@@ -3209,6 +3315,116 @@ void Spell::TakePower()
|
||||
m_caster->SetLastManaUse(getMSTime());
|
||||
}
|
||||
|
||||
uint8 Spell::CheckRuneCost(uint32 runeCostID)
|
||||
{
|
||||
if(m_caster->GetTypeId() != TYPEID_PLAYER)
|
||||
return 0;
|
||||
|
||||
Player *plr = (Player*)m_caster;
|
||||
|
||||
if(plr->getClass() != CLASS_DEATH_KNIGHT)
|
||||
return 0;
|
||||
|
||||
SpellRuneCostEntry const *src = sSpellRuneCostStore.LookupEntry(runeCostID);
|
||||
|
||||
if(!src)
|
||||
return 0;
|
||||
|
||||
if(src->NoRuneCost())
|
||||
return 0;
|
||||
|
||||
int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
|
||||
|
||||
for(uint32 i = 0; i < RUNE_DEATH; ++i)
|
||||
{
|
||||
runeCost[i] = src->RuneCost[i];
|
||||
}
|
||||
|
||||
runeCost[RUNE_DEATH] = 0; // calculated later
|
||||
|
||||
for(uint32 i = 0; i < MAX_RUNES; ++i)
|
||||
{
|
||||
uint8 rune = plr->GetCurrentRune(i);
|
||||
if((plr->GetRuneCooldown(i) == 0) && (runeCost[rune] > 0))
|
||||
{
|
||||
runeCost[rune]--;
|
||||
}
|
||||
}
|
||||
|
||||
for(uint32 i = 0; i < RUNE_DEATH; ++i)
|
||||
{
|
||||
if(runeCost[i] > 0)
|
||||
{
|
||||
runeCost[RUNE_DEATH] += runeCost[i];
|
||||
}
|
||||
}
|
||||
|
||||
if(runeCost[RUNE_DEATH] > 0)
|
||||
return SPELL_FAILED_NO_POWER; // not sure if result code is correct
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Spell::TakeRunePower()
|
||||
{
|
||||
if(m_caster->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
Player *plr = (Player*)m_caster;
|
||||
|
||||
if(plr->getClass() != CLASS_DEATH_KNIGHT)
|
||||
return;
|
||||
|
||||
SpellRuneCostEntry const *src = sSpellRuneCostStore.LookupEntry(m_spellInfo->runeCostID);
|
||||
|
||||
if(!src || (src->NoRuneCost() && src->NoRunicPowerGain()))
|
||||
return;
|
||||
|
||||
m_runesState = plr->GetRunesState(); // store previous state
|
||||
|
||||
int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
|
||||
|
||||
for(uint32 i = 0; i < RUNE_DEATH; ++i)
|
||||
{
|
||||
runeCost[i] = src->RuneCost[i];
|
||||
}
|
||||
|
||||
runeCost[RUNE_DEATH] = 0; // calculated later
|
||||
|
||||
for(uint32 i = 0; i < MAX_RUNES; ++i)
|
||||
{
|
||||
uint8 rune = plr->GetCurrentRune(i);
|
||||
if((plr->GetRuneCooldown(i) == 0) && (runeCost[rune] > 0))
|
||||
{
|
||||
plr->SetRuneCooldown(i, RUNE_COOLDOWN); // 5*2=10 sec
|
||||
runeCost[rune]--;
|
||||
}
|
||||
}
|
||||
|
||||
runeCost[RUNE_DEATH] = runeCost[RUNE_BLOOD] + runeCost[RUNE_UNHOLY] + runeCost[RUNE_FROST];
|
||||
|
||||
if(runeCost[RUNE_DEATH] > 0)
|
||||
{
|
||||
for(uint32 i = 0; i < MAX_RUNES; ++i)
|
||||
{
|
||||
uint8 rune = plr->GetCurrentRune(i);
|
||||
if((plr->GetRuneCooldown(i) == 0) && (rune == RUNE_DEATH))
|
||||
{
|
||||
plr->SetRuneCooldown(i, RUNE_COOLDOWN); // 5*2=10 sec
|
||||
runeCost[rune]--;
|
||||
plr->ConvertRune(i, plr->GetBaseRune(i));
|
||||
if(runeCost[RUNE_DEATH] == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// you can gain some runic power when use runes
|
||||
float rp = src->runePowerGain;;
|
||||
rp *= sWorld.getRate(RATE_POWER_RUNICPOWER_INCOME);
|
||||
plr->ModifyPower(POWER_RUNIC_POWER, (int32)rp);
|
||||
}
|
||||
|
||||
void Spell::TakeReagents()
|
||||
{
|
||||
if(m_IsTriggeredSpell) // reagents used in triggered spell removed by original spell or don't must be removed.
|
||||
@@ -3217,11 +3433,9 @@ void Spell::TakeReagents()
|
||||
if (m_caster->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
if (m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP &&
|
||||
m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION))
|
||||
return;
|
||||
|
||||
Player* p_caster = (Player*)m_caster;
|
||||
if (p_caster->CanNoReagentCast(m_spellInfo))
|
||||
return;
|
||||
|
||||
for(uint32 x=0;x<8;x++)
|
||||
{
|
||||
@@ -3344,12 +3558,25 @@ uint8 Spell::CanCast(bool strict)
|
||||
// for now, ignore triggered spells
|
||||
if( strict && !m_IsTriggeredSpell)
|
||||
{
|
||||
// Cannot be used in this stance/form
|
||||
if(uint8 shapeError = GetErrorAtShapeshiftedCast(m_spellInfo, m_caster->m_form))
|
||||
return shapeError;
|
||||
bool checkForm = true;
|
||||
// Ignore form req aura
|
||||
Unit::AuraList const& ignore = m_caster->GetAurasByType(SPELL_AURA_MOD_IGNORE_SHAPESHIFT);
|
||||
for(Unit::AuraList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
|
||||
{
|
||||
if (!(*i)->isAffectedOnSpell(m_spellInfo))
|
||||
continue;
|
||||
checkForm = false;
|
||||
break;
|
||||
}
|
||||
if (checkForm)
|
||||
{
|
||||
// Cannot be used in this stance/form
|
||||
if(uint8 shapeError = GetErrorAtShapeshiftedCast(m_spellInfo, m_caster->m_form))
|
||||
return shapeError;
|
||||
|
||||
if ((m_spellInfo->Attributes & SPELL_ATTR_ONLY_STEALTHED) && !(m_caster->HasStealthAura()))
|
||||
return SPELL_FAILED_ONLY_STEALTHED;
|
||||
if ((m_spellInfo->Attributes & SPELL_ATTR_ONLY_STEALTHED) && !(m_caster->HasStealthAura()))
|
||||
return SPELL_FAILED_ONLY_STEALTHED;
|
||||
}
|
||||
}
|
||||
|
||||
// caster state requirements
|
||||
@@ -3686,7 +3913,7 @@ uint8 Spell::CanCast(bool strict)
|
||||
case SPELL_EFFECT_SCHOOL_DAMAGE:
|
||||
{
|
||||
// Hammer of Wrath
|
||||
if(m_spellInfo->SpellVisual == 7250)
|
||||
if(m_spellInfo->SpellVisual[0] == 7250)
|
||||
{
|
||||
if (!m_targets.getUnitTarget())
|
||||
return SPELL_FAILED_BAD_IMPLICIT_TARGETS;
|
||||
@@ -3711,15 +3938,9 @@ uint8 Spell::CanCast(bool strict)
|
||||
if(!learn_spellproto)
|
||||
return SPELL_FAILED_NOT_KNOWN;
|
||||
|
||||
if(!pet->CanTakeMoreActiveSpells(learn_spellproto->Id))
|
||||
return SPELL_FAILED_TOO_MANY_SKILLS;
|
||||
|
||||
if(m_spellInfo->spellLevel > pet->getLevel())
|
||||
return SPELL_FAILED_LOWLEVEL;
|
||||
|
||||
if(!pet->HasTPForSpell(learn_spellproto->Id))
|
||||
return SPELL_FAILED_TRAINING_POINTS;
|
||||
|
||||
break;
|
||||
}
|
||||
case SPELL_EFFECT_LEARN_PET_SPELL:
|
||||
@@ -3734,15 +3955,9 @@ uint8 Spell::CanCast(bool strict)
|
||||
if(!learn_spellproto)
|
||||
return SPELL_FAILED_NOT_KNOWN;
|
||||
|
||||
if(!pet->CanTakeMoreActiveSpells(learn_spellproto->Id))
|
||||
return SPELL_FAILED_TOO_MANY_SKILLS;
|
||||
|
||||
if(m_spellInfo->spellLevel > pet->getLevel())
|
||||
return SPELL_FAILED_LOWLEVEL;
|
||||
|
||||
if(!pet->HasTPForSpell(learn_spellproto->Id))
|
||||
return SPELL_FAILED_TRAINING_POINTS;
|
||||
|
||||
break;
|
||||
}
|
||||
case SPELL_EFFECT_FEED_PET:
|
||||
@@ -3845,27 +4060,27 @@ uint8 Spell::CanCast(bool strict)
|
||||
{
|
||||
// check for lock - key pair (checked by client also, just prevent cheating
|
||||
bool ok_key = false;
|
||||
for(int it = 0; it < 5; ++it)
|
||||
for(int it = 0; it < 8; ++it)
|
||||
{
|
||||
switch(lockInfo->keytype[it])
|
||||
switch(lockInfo->Type[it])
|
||||
{
|
||||
case LOCK_KEY_NONE:
|
||||
break;
|
||||
case LOCK_KEY_ITEM:
|
||||
{
|
||||
if(lockInfo->key[it])
|
||||
if(lockInfo->Index[it])
|
||||
{
|
||||
if(m_CastItem && m_CastItem->GetEntry()==lockInfo->key[it])
|
||||
if(m_CastItem && m_CastItem->GetEntry()==lockInfo->Index[it])
|
||||
ok_key =true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
case LOCK_KEY_SKILL:
|
||||
{
|
||||
if(uint32(m_spellInfo->EffectMiscValue[i])!=lockInfo->key[it])
|
||||
if(uint32(m_spellInfo->EffectMiscValue[i])!=lockInfo->Index[it])
|
||||
break;
|
||||
|
||||
switch(lockInfo->key[it])
|
||||
switch(lockInfo->Index[it])
|
||||
{
|
||||
case LOCKTYPE_HERBALISM:
|
||||
if(((Player*)m_caster)->HasSkill(SKILL_HERBALISM))
|
||||
@@ -3922,9 +4137,9 @@ uint8 Spell::CanCast(bool strict)
|
||||
{
|
||||
// check for lock - key pair
|
||||
bool ok = false;
|
||||
for(int it = 0; it < 5; ++it)
|
||||
for(int it = 0; it < 8; ++it)
|
||||
{
|
||||
if(lockInfo->keytype[it]==LOCK_KEY_ITEM && lockInfo->key[it] && m_CastItem && m_CastItem->GetEntry()==lockInfo->key[it])
|
||||
if(lockInfo->Type[it]==LOCK_KEY_ITEM && lockInfo->Index[it] && m_CastItem && m_CastItem->GetEntry()==lockInfo->Index[it])
|
||||
{
|
||||
// if so, we're good to go
|
||||
ok = true;
|
||||
@@ -3935,9 +4150,9 @@ uint8 Spell::CanCast(bool strict)
|
||||
break;
|
||||
|
||||
if (m_spellInfo->EffectMiscValue[i] == LOCKTYPE_PICKLOCK)
|
||||
ReqValue = lockInfo->requiredlockskill;
|
||||
ReqValue = lockInfo->Skill[1];
|
||||
else
|
||||
ReqValue = lockInfo->requiredminingskill;
|
||||
ReqValue = lockInfo->Skill[0];
|
||||
}
|
||||
|
||||
// skill doesn't meet the required value
|
||||
@@ -3986,7 +4201,6 @@ uint8 Spell::CanCast(bool strict)
|
||||
}
|
||||
// Don't make this check for SPELL_EFFECT_SUMMON_CRITTER, SPELL_EFFECT_SUMMON_WILD or SPELL_EFFECT_SUMMON_GUARDIAN.
|
||||
// These won't show up in m_caster->GetPetGUID()
|
||||
case SPELL_EFFECT_SUMMON_POSSESSED:
|
||||
case SPELL_EFFECT_SUMMON_PHANTASM:
|
||||
case SPELL_EFFECT_SUMMON_DEMON:
|
||||
{
|
||||
@@ -4143,7 +4357,7 @@ uint8 Spell::CanCast(bool strict)
|
||||
if( form == FORM_CAT || form == FORM_TREE || form == FORM_TRAVEL ||
|
||||
form == FORM_AQUA || form == FORM_BEAR || form == FORM_DIREBEAR ||
|
||||
form == FORM_CREATUREBEAR || form == FORM_GHOSTWOLF || form == FORM_FLIGHT ||
|
||||
form == FORM_FLIGHT_EPIC || form == FORM_MOONKIN )
|
||||
form == FORM_FLIGHT_EPIC || form == FORM_MOONKIN || form == FORM_METAMORPHOSIS )
|
||||
return SPELL_FAILED_NOT_SHAPESHIFT;
|
||||
|
||||
break;
|
||||
@@ -4165,8 +4379,8 @@ uint8 Spell::CanCast(bool strict)
|
||||
// not allow cast fly spells at old maps by players (all spells is self target)
|
||||
if(m_caster->GetTypeId()==TYPEID_PLAYER)
|
||||
{
|
||||
if( !((Player*)m_caster)->isGameMaster() &&
|
||||
GetVirtualMapForMapAndZone(m_caster->GetMapId(),m_caster->GetZoneId()) != 530)
|
||||
uint32 v_map = GetVirtualMapForMapAndZone(m_caster->GetMapId(), m_caster->GetZoneId());
|
||||
if( !((Player*)m_caster)->isGameMaster() && v_map != 530 && !(v_map == 571 && ((Player*)m_caster)->HasSpell(54197)))
|
||||
return SPELL_FAILED_NOT_HERE;
|
||||
}
|
||||
|
||||
@@ -4481,9 +4695,12 @@ int32 Spell::CalculatePowerCost()
|
||||
case POWER_FOCUS:
|
||||
case POWER_ENERGY:
|
||||
case POWER_HAPPINESS:
|
||||
// case POWER_RUNES:
|
||||
powerCost += m_spellInfo->ManaCostPercentage * m_caster->GetMaxPower(Powers(m_spellInfo->powerType)) / 100;
|
||||
break;
|
||||
case POWER_RUNE:
|
||||
case POWER_RUNIC_POWER:
|
||||
sLog.outDebug("Spell::CalculateManaCost: Not implemented yet!");
|
||||
break;
|
||||
default:
|
||||
sLog.outError("Spell::CalculateManaCost: Unknown power type '%d' in spell %d", m_spellInfo->powerType, m_spellInfo->Id);
|
||||
return 0;
|
||||
@@ -4528,6 +4745,11 @@ uint8 Spell::CheckPower()
|
||||
sLog.outError("Spell::CheckMana: Unknown power type '%d'", m_spellInfo->powerType);
|
||||
return SPELL_FAILED_UNKNOWN;
|
||||
}
|
||||
|
||||
uint8 failReason = CheckRuneCost(m_spellInfo->runeCostID);
|
||||
if(failReason)
|
||||
return failReason;
|
||||
|
||||
// Check power amount
|
||||
Powers powerType = Powers(m_spellInfo->powerType);
|
||||
if(m_caster->GetPower(powerType) < m_powerCost)
|
||||
@@ -4655,8 +4877,7 @@ uint8 Spell::CheckItems()
|
||||
focusObject = ok; // game object found in range
|
||||
}
|
||||
|
||||
if (!(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP &&
|
||||
m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION)))
|
||||
if (!p_caster->CanNoReagentCast(m_spellInfo))
|
||||
{
|
||||
for(uint32 i=0;i<8;i++)
|
||||
{
|
||||
@@ -4824,13 +5045,36 @@ uint8 Spell::CheckItems()
|
||||
return SPELL_FAILED_LOW_CASTLEVEL;
|
||||
//make sure the player has the required ores in inventory
|
||||
if(m_targets.getItemTarget()->GetCount() < 5)
|
||||
return SPELL_FAILED_PROSPECT_NEED_MORE;
|
||||
return SPELL_FAILED_NEED_MORE_ITEMS;
|
||||
|
||||
if(!LootTemplates_Prospecting.HaveLootFor(m_targets.getItemTargetEntry()))
|
||||
return SPELL_FAILED_CANT_BE_PROSPECTED;
|
||||
|
||||
break;
|
||||
}
|
||||
case SPELL_EFFECT_MILLING:
|
||||
{
|
||||
if(!m_targets.getItemTarget())
|
||||
return SPELL_FAILED_CANT_BE_MILLED;
|
||||
//ensure item is a millable herb
|
||||
if(!(m_targets.getItemTarget()->GetProto()->BagFamily & BAG_FAMILY_MASK_HERBS) || m_targets.getItemTarget()->GetProto()->Class != ITEM_CLASS_TRADE_GOODS)
|
||||
return SPELL_FAILED_CANT_BE_MILLED;
|
||||
//prevent milling in trade slot
|
||||
if( m_targets.getItemTarget()->GetOwnerGUID() != m_caster->GetGUID() )
|
||||
return SPELL_FAILED_CANT_BE_MILLED;
|
||||
//Check for enough skill in inscription
|
||||
uint32 item_millingskilllevel = m_targets.getItemTarget()->GetProto()->RequiredSkillRank;
|
||||
if(item_millingskilllevel >p_caster->GetSkillValue(SKILL_INSCRIPTION))
|
||||
return SPELL_FAILED_LOW_CASTLEVEL;
|
||||
//make sure the player has the required herbs in inventory
|
||||
if(m_targets.getItemTarget()->GetCount() < 5)
|
||||
return SPELL_FAILED_NEED_MORE_ITEMS;
|
||||
|
||||
if(!LootTemplates_Milling.HaveLootFor(m_targets.getItemTargetEntry()))
|
||||
return SPELL_FAILED_CANT_BE_MILLED;
|
||||
|
||||
break;
|
||||
}
|
||||
case SPELL_EFFECT_WEAPON_DAMAGE:
|
||||
case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL:
|
||||
{
|
||||
@@ -5003,9 +5247,9 @@ void Spell::UpdatePointers()
|
||||
m_targets.Update(m_caster);
|
||||
}
|
||||
|
||||
bool Spell::IsAffectedBy(SpellEntry const *spellInfo, uint32 effectId)
|
||||
bool Spell::IsAffectedByAura(Aura *aura)
|
||||
{
|
||||
return spellmgr.IsAffectedBySpell(m_spellInfo,spellInfo->Id,effectId,spellInfo->EffectItemType[effectId]);
|
||||
return spellmgr.IsAffectedByMod(m_spellInfo, aura->getAuraSpellMod());
|
||||
}
|
||||
|
||||
bool Spell::CheckTargetCreatureType(Unit* target) const
|
||||
|
||||
+43
-10
@@ -47,26 +47,51 @@ enum SpellCastTargetFlags
|
||||
TARGET_FLAG_RESURRECTABLE = 0x8000*/
|
||||
|
||||
TARGET_FLAG_SELF = 0x00000000,
|
||||
TARGET_FLAG_UNUSED1 = 0x00000001, // not used in any spells as of 3.0.3 (can be set dynamically)
|
||||
TARGET_FLAG_UNIT = 0x00000002, // pguid
|
||||
TARGET_FLAG_UNUSED2 = 0x00000004, // not used in any spells as of 3.0.3 (can be set dynamically)
|
||||
TARGET_FLAG_UNUSED3 = 0x00000008, // not used in any spells as of 3.0.3 (can be set dynamically)
|
||||
TARGET_FLAG_ITEM = 0x00000010, // pguid
|
||||
TARGET_FLAG_SOURCE_LOCATION = 0x00000020, // 3 float
|
||||
TARGET_FLAG_DEST_LOCATION = 0x00000040, // 3 float
|
||||
TARGET_FLAG_OBJECT_UNK = 0x00000080, // ?
|
||||
TARGET_FLAG_OBJECT_UNK = 0x00000080, // used in 7 spells only
|
||||
TARGET_FLAG_UNIT_UNK = 0x00000100, // looks like self target (480 spells)
|
||||
TARGET_FLAG_PVP_CORPSE = 0x00000200, // pguid
|
||||
TARGET_FLAG_OBJECT = 0x00000800, // pguid
|
||||
TARGET_FLAG_TRADE_ITEM = 0x00001000, // pguid
|
||||
TARGET_FLAG_STRING = 0x00002000, // string
|
||||
TARGET_FLAG_UNK1 = 0x00004000, // ?
|
||||
TARGET_FLAG_CORPSE = 0x00008000, // pguid
|
||||
TARGET_FLAG_UNK2 = 0x00010000 // pguid
|
||||
TARGET_FLAG_UNIT_CORPSE = 0x00000400, // 10 spells (gathering professions)
|
||||
TARGET_FLAG_OBJECT = 0x00000800, // pguid, 2 spells
|
||||
TARGET_FLAG_TRADE_ITEM = 0x00001000, // pguid, 0 spells
|
||||
TARGET_FLAG_STRING = 0x00002000, // string, 0 spells
|
||||
TARGET_FLAG_UNK1 = 0x00004000, // 199 spells, opening object/lock
|
||||
TARGET_FLAG_CORPSE = 0x00008000, // pguid, resurrection spells
|
||||
TARGET_FLAG_UNK2 = 0x00010000, // pguid, not used in any spells as of 3.0.3 (can be set dynamically)
|
||||
TARGET_FLAG_GLYPH = 0x00020000 // used in glyph spells
|
||||
};
|
||||
|
||||
enum SpellCastFlags
|
||||
{
|
||||
CAST_FLAG_NONE = 0x00000000,
|
||||
CAST_FLAG_UNKNOWN0 = 0x00000001, // may be pending spell cast
|
||||
CAST_FLAG_UNKNOWN1 = 0x00000002,
|
||||
CAST_FLAG_UNKNOWN11 = 0x00000004,
|
||||
CAST_FLAG_UNKNOWN12 = 0x00000008,
|
||||
CAST_FLAG_UNKNOWN2 = 0x00000010,
|
||||
CAST_FLAG_AMMO = 0x00000020,
|
||||
CAST_FLAG_UNKNOWN3 = 0x00000100
|
||||
CAST_FLAG_AMMO = 0x00000020, // Projectiles visual
|
||||
CAST_FLAG_UNKNOWN8 = 0x00000040,
|
||||
CAST_FLAG_UNKNOWN9 = 0x00000080,
|
||||
CAST_FLAG_UNKNOWN3 = 0x00000100,
|
||||
CAST_FLAG_UNKNOWN13 = 0x00000200,
|
||||
CAST_FLAG_UNKNOWN14 = 0x00000400,
|
||||
CAST_FLAG_UNKNOWN6 = 0x00000800, // wotlk, trigger rune cooldown
|
||||
CAST_FLAG_UNKNOWN15 = 0x00001000,
|
||||
CAST_FLAG_UNKNOWN16 = 0x00002000,
|
||||
CAST_FLAG_UNKNOWN17 = 0x00004000,
|
||||
CAST_FLAG_UNKNOWN18 = 0x00008000,
|
||||
CAST_FLAG_UNKNOWN19 = 0x00010000,
|
||||
CAST_FLAG_UNKNOWN4 = 0x00020000, // wotlk
|
||||
CAST_FLAG_UNKNOWN10 = 0x00040000,
|
||||
CAST_FLAG_UNKNOWN5 = 0x00080000, // wotlk
|
||||
CAST_FLAG_UNKNOWN20 = 0x00100000,
|
||||
CAST_FLAG_UNKNOWN7 = 0x00200000 // wotlk, rune cooldown list
|
||||
};
|
||||
|
||||
enum SpellRangeFlag
|
||||
@@ -275,6 +300,7 @@ class Spell
|
||||
void EffectStuck(uint32 i);
|
||||
void EffectSummonPlayer(uint32 i);
|
||||
void EffectActivateObject(uint32 i);
|
||||
void EffectApplyGlyph(uint32 i);
|
||||
void EffectSummonTotem(uint32 i);
|
||||
void EffectEnchantHeldItem(uint32 i);
|
||||
void EffectSummonObject(uint32 i);
|
||||
@@ -292,6 +318,7 @@ class Spell
|
||||
void EffectSkinning(uint32 i);
|
||||
void EffectCharge(uint32 i);
|
||||
void EffectProspecting(uint32 i);
|
||||
void EffectMilling(uint32 i);
|
||||
void EffectSendTaxi(uint32 i);
|
||||
void EffectSummonCritter(uint32 i);
|
||||
void EffectKnockBack(uint32 i);
|
||||
@@ -318,6 +345,8 @@ class Spell
|
||||
void EffectKillCredit(uint32 i);
|
||||
void EffectQuestFail(uint32 i);
|
||||
void EffectRedirectThreat(uint32 i);
|
||||
void EffectActivateRune(uint32 i);
|
||||
void EffectTitanGrip(uint32 i);
|
||||
|
||||
Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 originalCasterGUID = 0, Spell** triggeringContainer = NULL );
|
||||
~Spell();
|
||||
@@ -328,6 +357,8 @@ class Spell
|
||||
void cast(bool skipCheck = false);
|
||||
void finish(bool ok = true);
|
||||
void TakePower();
|
||||
uint8 CheckRuneCost(uint32 runeCostID);
|
||||
void TakeRunePower();
|
||||
void TakeReagents();
|
||||
void TakeCastItem();
|
||||
void TriggerSpell();
|
||||
@@ -386,6 +417,7 @@ class Spell
|
||||
int32 m_currentBasePoints[3]; // cache SpellEntry::EffectBasePoints and use for set custom base points
|
||||
Item* m_CastItem;
|
||||
uint8 m_cast_count;
|
||||
uint32 m_glyphIndex;
|
||||
SpellCastTargets m_targets;
|
||||
|
||||
int32 GetCastTime() const { return m_casttime; }
|
||||
@@ -422,7 +454,7 @@ class Spell
|
||||
|
||||
void UpdatePointers(); // must be used at call Spell code after time delay (non triggered spell cast/update spell call/etc)
|
||||
|
||||
bool IsAffectedBy(SpellEntry const *spellInfo, uint32 effectId);
|
||||
bool IsAffectedByAura(Aura *aura);
|
||||
|
||||
bool CheckTargetCreatureType(Unit* target) const;
|
||||
|
||||
@@ -449,6 +481,7 @@ class Spell
|
||||
int32 m_casttime; // Calculated spell cast time initialized only in Spell::prepare
|
||||
bool m_canReflect; // can reflect this spell?
|
||||
bool m_autoRepeat;
|
||||
uint8 m_runesState;
|
||||
|
||||
uint8 m_delayAtDamageCount;
|
||||
int32 GetNextDelayAtDamageMsTime() { return m_delayAtDamageCount < 5 ? 1000 - (m_delayAtDamageCount++)* 200 : 200; }
|
||||
|
||||
+43
-15
@@ -20,14 +20,19 @@
|
||||
#ifndef TRINITY_SPELLAURADEFINES_H
|
||||
#define TRINITY_SPELLAURADEFINES_H
|
||||
|
||||
#define MAX_AURAS 56
|
||||
#define MAX_POSITIVE_AURAS 40
|
||||
#define MAX_AURAS 64 // client support up to 255, but it will cause problems with group auras updating
|
||||
|
||||
enum AURA_FLAGS
|
||||
{
|
||||
AFLAG_NEGATIVE = 0x09,
|
||||
AFLAG_POSITIVE = 0x1F,
|
||||
AFLAG_MASK = 0xFF
|
||||
AFLAG_NONE = 0x00,
|
||||
AFLAG_EFF_INDEX_0 = 0x01,
|
||||
AFLAG_EFF_INDEX_1 = 0x02,
|
||||
AFLAG_EFF_INDEX_2 = 0x04,
|
||||
AFLAG_NOT_CASTER = 0x08,
|
||||
AFLAG_POSITIVE = 0x10,
|
||||
AFLAG_DURATION = 0x20,
|
||||
AFLAG_UNK2 = 0x40,
|
||||
AFLAG_NEGATIVE = 0x80
|
||||
};
|
||||
|
||||
//m_schoolAbsorb
|
||||
@@ -233,7 +238,7 @@ enum AuraType
|
||||
SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED = 191,
|
||||
SPELL_AURA_HASTE_MELEE = 192,
|
||||
SPELL_AURA_MELEE_SLOW = 193,
|
||||
SPELL_AURA_MOD_DEPRICATED_1 = 194, // not used now, old SPELL_AURA_MOD_SPELL_DAMAGE_OF_INTELLECT
|
||||
SPELL_AURA_MOD_IGNORE_ABSORB_SCHOOL = 194,
|
||||
SPELL_AURA_MOD_DEPRICATED_2 = 195, // not used now, old SPELL_AURA_MOD_SPELL_HEALING_OF_INTELLECT
|
||||
SPELL_AURA_MOD_COOLDOWN = 196, // only 24818 Noxious Breath
|
||||
SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE = 197,
|
||||
@@ -275,7 +280,7 @@ enum AuraType
|
||||
SPELL_AURA_233 = 233,
|
||||
SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK = 234,
|
||||
SPELL_AURA_MOD_DISPEL_RESIST = 235,
|
||||
SPELL_AURA_236 = 236,
|
||||
SPELL_AURA_CONTROL_VEHICLE = 236,
|
||||
SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER = 237,
|
||||
SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER = 238,
|
||||
SPELL_AURA_MOD_SCALE_2 = 239,
|
||||
@@ -285,28 +290,51 @@ enum AuraType
|
||||
SPELL_AURA_243 = 243,
|
||||
SPELL_AURA_COMPREHEND_LANGUAGE = 244,
|
||||
SPELL_AURA_MOD_DURATION_OF_MAGIC_EFFECTS = 245,
|
||||
SPELL_AURA_246 = 246,
|
||||
SPELL_AURA_MOD_DURATION_OF_EFFECTS_BY_DISPEL = 246,
|
||||
SPELL_AURA_247 = 247,
|
||||
SPELL_AURA_MOD_COMBAT_RESULT_CHANCE = 248,
|
||||
SPELL_AURA_249 = 249,
|
||||
SPELL_AURA_CONVERT_RUNE = 249,
|
||||
SPELL_AURA_MOD_INCREASE_HEALTH_2 = 250,
|
||||
SPELL_AURA_MOD_ENEMY_DODGE = 251,
|
||||
SPELL_AURA_252 = 252,
|
||||
SPELL_AURA_253 = 253,
|
||||
SPELL_AURA_254 = 254,
|
||||
SPELL_AURA_255 = 255,
|
||||
SPELL_AURA_256 = 256,
|
||||
SPELL_AURA_257 = 257,
|
||||
SPELL_AURA_MOD_BLOCK_CRIT_CHANCE = 253,
|
||||
SPELL_AURA_MOD_DISARM_SHIELD = 254,
|
||||
SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT = 255,
|
||||
SPELL_AURA_NO_REAGENT_USE = 256,
|
||||
SPELL_AURA_MOD_TARGET_RESIST_BY_SPELL_CLASS = 257,
|
||||
SPELL_AURA_258 = 258,
|
||||
SPELL_AURA_259 = 259,
|
||||
SPELL_AURA_260 = 260,
|
||||
SPELL_AURA_261 = 261,
|
||||
TOTAL_AURAS=262
|
||||
SPELL_AURA_262 = 262,
|
||||
SPELL_AURA_ALLOW_ONLY_ABILITY = 263,
|
||||
SPELL_AURA_264 = 264,
|
||||
SPELL_AURA_265 = 265,
|
||||
SPELL_AURA_266 = 266,
|
||||
SPELL_AURA_267 = 267,
|
||||
SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT = 268,
|
||||
SPELL_AURA_269 = 269,
|
||||
SPELL_AURA_270 = 270,
|
||||
SPELL_AURA_271 = 271,
|
||||
SPELL_AURA_272 = 272,
|
||||
SPELL_AURA_273 = 273,
|
||||
SPELL_AURA_274 = 274,
|
||||
SPELL_AURA_MOD_IGNORE_SHAPESHIFT = 275,
|
||||
SPELL_AURA_276 = 276, // Only "Test Mod Damage % Mechanic" spell, possible mod damage done
|
||||
SPELL_AURA_MOD_MAX_AFFECTED_TARGETS = 277,
|
||||
SPELL_AURA_MOD_DISARM_RANGED = 278,
|
||||
SPELL_AURA_279 = 279,
|
||||
SPELL_AURA_MOD_TARGET_ARMOR_PCT = 280,
|
||||
SPELL_AURA_MOD_HONOR_GAIN = 281,
|
||||
SPELL_AURA_MOD_BASE_HEALTH_PCT = 282,
|
||||
SPELL_AURA_MOD_HEALING_RECEIVED = 283, // Possibly only for some spell family class spells
|
||||
TOTAL_AURAS = 284
|
||||
};
|
||||
|
||||
enum AreaAuraType
|
||||
{
|
||||
AREA_AURA_PARTY,
|
||||
AREA_AURA_RAID,
|
||||
AREA_AURA_FRIEND,
|
||||
AREA_AURA_ENEMY,
|
||||
AREA_AURA_PET,
|
||||
|
||||
+648
-241
File diff suppressed because it is too large
Load Diff
+24
-8
@@ -100,6 +100,7 @@ class TRINITY_DLL_SPEC Aura
|
||||
void HandleAuraFeatherFall(bool Apply, bool Real);
|
||||
void HandleAuraHover(bool Apply, bool Real);
|
||||
void HandleAddModifier(bool Apply, bool Real);
|
||||
void HandleAddTargetTrigger(bool Apply, bool Real);
|
||||
void HandleAuraModStun(bool Apply, bool Real);
|
||||
void HandleModDamageDone(bool Apply, bool Real);
|
||||
void HandleAuraUntrackable(bool Apply, bool Real);
|
||||
@@ -184,10 +185,12 @@ class TRINITY_DLL_SPEC Aura
|
||||
void HandleAuraGhost(bool Apply, bool Real);
|
||||
void HandleAuraAllowFlight(bool Apply, bool Real);
|
||||
void HandleModRating(bool apply, bool Real);
|
||||
void HandleModRatingFromStat(bool apply, bool Real);
|
||||
void HandleModTargetResistance(bool apply, bool Real);
|
||||
void HandleAuraModAttackPowerPercent(bool apply, bool Real);
|
||||
void HandleAuraModRangedAttackPowerPercent(bool apply, bool Real);
|
||||
void HandleAuraModRangedAttackPowerOfStatPercent(bool apply, bool Real);
|
||||
void HandleAuraModAttackPowerOfStatPercent(bool apply, bool Real);
|
||||
void HandleSpiritOfRedemption(bool apply, bool Real);
|
||||
void HandleModManaRegen(bool apply, bool Real);
|
||||
void HandleComprehendLanguage(bool apply, bool Real);
|
||||
@@ -197,6 +200,7 @@ class TRINITY_DLL_SPEC Aura
|
||||
void HandleModSpellDamagePercentFromStat(bool apply, bool Real);
|
||||
void HandleModSpellHealingPercentFromStat(bool apply, bool Real);
|
||||
void HandleAuraModDispelResist(bool apply, bool Real);
|
||||
void HandleAuraControlVehicle(bool apply, bool Real);
|
||||
void HandleModSpellDamagePercentFromAttackPower(bool apply, bool Real);
|
||||
void HandleModSpellHealingPercentFromAttackPower(bool apply, bool Real);
|
||||
void HandleAuraModPacifyAndSilence(bool Apply, bool Real);
|
||||
@@ -209,6 +213,9 @@ class TRINITY_DLL_SPEC Aura
|
||||
void HandlePreventFleeing(bool apply, bool Real);
|
||||
void HandleManaShield(bool apply, bool Real);
|
||||
void HandleArenaPreparation(bool apply, bool Real);
|
||||
void HandleAuraConvertRune(bool apply, bool Real);
|
||||
void HandleAuraIncreaseBaseHealthPercent(bool Apply, bool Real);
|
||||
void HandleNoReagentUseAura(bool Apply, bool Real);
|
||||
void HandleModAttackerSpellHitChance(bool apply, bool Real);
|
||||
|
||||
virtual ~Aura();
|
||||
@@ -231,6 +238,8 @@ class TRINITY_DLL_SPEC Aura
|
||||
int32 GetAuraDuration() const { return m_duration; }
|
||||
void SetAuraDuration(int32 duration) { m_duration = duration; }
|
||||
time_t GetAuraApplyTime() { return m_applyTime; }
|
||||
SpellModifier *getAuraSpellMod() {return m_spellmod; }
|
||||
|
||||
void UpdateAuraDuration();
|
||||
void SendAuraDurationForCaster(Player* caster);
|
||||
void UpdateSlotCounterAndDuration();
|
||||
@@ -250,13 +259,19 @@ class TRINITY_DLL_SPEC Aura
|
||||
|
||||
uint8 GetAuraSlot() const { return m_auraSlot; }
|
||||
void SetAuraSlot(uint8 slot) { m_auraSlot = slot; }
|
||||
uint8 GetAuraFlags() const { return m_auraFlags; }
|
||||
void SetAuraFlags(uint8 flags) { m_auraFlags = flags; }
|
||||
uint8 GetAuraLevel() const { return m_auraLevel; }
|
||||
void SetAuraLevel(uint8 level) { m_auraLevel = level; }
|
||||
uint8 GetAuraCharges() const { return m_procCharges; }
|
||||
void SetAuraCharges(uint8 charges) { m_procCharges = charges; }
|
||||
void SetAura(bool remove) { m_target->SetVisibleAura(m_auraSlot, remove ? 0 : GetId()); }
|
||||
void SendAuraUpdate(bool remove);
|
||||
void UpdateAuraCharges()
|
||||
{
|
||||
uint8 slot = GetAuraSlot();
|
||||
|
||||
// only aura in slot with charges and without stack limitation
|
||||
if (slot < MAX_AURAS && m_procCharges >= 1 && GetSpellProto()->StackAmount==0)
|
||||
SetAuraApplication(slot, m_procCharges - 1);
|
||||
if (m_auraSlot < MAX_AURAS && m_procCharges >= 1 && GetSpellProto()->StackAmount==0)
|
||||
SendAuraUpdate(false);
|
||||
}
|
||||
|
||||
bool IsPositive() { return m_positive; }
|
||||
@@ -300,6 +315,9 @@ class TRINITY_DLL_SPEC Aura
|
||||
void PeriodicTick();
|
||||
void PeriodicDummyTick();
|
||||
|
||||
uint32 const *getAuraSpellClassMask() const { return m_spellProto->EffectSpellClassMaskA + m_effIndex * 3; }
|
||||
bool isAffectedOnSpell(SpellEntry const *spell) const;
|
||||
|
||||
int32 GetStackAmount() {return m_stackAmount;}
|
||||
void SetStackAmount(int32 amount) {m_stackAmount=amount;}
|
||||
protected:
|
||||
@@ -321,6 +339,8 @@ class TRINITY_DLL_SPEC Aura
|
||||
AuraRemoveMode m_removeMode;
|
||||
|
||||
uint8 m_auraSlot;
|
||||
uint8 m_auraFlags;
|
||||
uint8 m_auraLevel;
|
||||
|
||||
bool m_positive:1;
|
||||
bool m_permanent:1;
|
||||
@@ -341,10 +361,6 @@ class TRINITY_DLL_SPEC Aura
|
||||
int32 m_stackAmount;
|
||||
private:
|
||||
void CleanupTriggeredSpells();
|
||||
void SetAura(uint32 slot, bool remove) { m_target->SetUInt32Value(UNIT_FIELD_AURA + slot, remove ? 0 : GetId()); }
|
||||
void SetAuraFlag(uint32 slot, bool add);
|
||||
void SetAuraLevel(uint32 slot, uint32 level);
|
||||
void SetAuraApplication(uint32 slot, int8 count);
|
||||
};
|
||||
|
||||
class TRINITY_DLL_SPEC AreaAura : public Aura
|
||||
|
||||
+276
-54
@@ -128,16 +128,16 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
|
||||
&Spell::EffectPowerBurn, // 62 SPELL_EFFECT_POWER_BURN
|
||||
&Spell::EffectThreat, // 63 SPELL_EFFECT_THREAT
|
||||
&Spell::EffectTriggerSpell, // 64 SPELL_EFFECT_TRIGGER_SPELL
|
||||
&Spell::EffectUnused, // 65 SPELL_EFFECT_HEALTH_FUNNEL unused
|
||||
&Spell::EffectUnused, // 66 SPELL_EFFECT_POWER_FUNNEL unused
|
||||
&Spell::EffectApplyAreaAura, // 65 SPELL_EFFECT_APPLY_AREA_AURA_RAID
|
||||
&Spell::EffectUnused, // 66 SPELL_EFFECT_CREATE_MANA_GEM (possibly recharge it, misc - is item ID)
|
||||
&Spell::EffectHealMaxHealth, // 67 SPELL_EFFECT_HEAL_MAX_HEALTH
|
||||
&Spell::EffectInterruptCast, // 68 SPELL_EFFECT_INTERRUPT_CAST
|
||||
&Spell::EffectDistract, // 69 SPELL_EFFECT_DISTRACT
|
||||
&Spell::EffectPull, // 70 SPELL_EFFECT_PULL one spell: Distract Move
|
||||
&Spell::EffectPickPocket, // 71 SPELL_EFFECT_PICKPOCKET
|
||||
&Spell::EffectAddFarsight, // 72 SPELL_EFFECT_ADD_FARSIGHT
|
||||
&Spell::EffectSummonPossessed, // 73 SPELL_EFFECT_SUMMON_POSSESSED
|
||||
&Spell::EffectSummonTotem, // 74 SPELL_EFFECT_SUMMON_TOTEM
|
||||
&Spell::EffectUnused, // 73 SPELL_EFFECT_UNTRAIN_TALENTS
|
||||
&Spell::EffectApplyGlyph, // 74 SPELL_EFFECT_APPLY_GLYPH
|
||||
&Spell::EffectHealMechanical, // 75 SPELL_EFFECT_HEAL_MECHANICAL one spell: Mechanical Patch Kit
|
||||
&Spell::EffectSummonObjectWild, // 76 SPELL_EFFECT_SUMMON_OBJECT_WILD
|
||||
&Spell::EffectScriptEffect, // 77 SPELL_EFFECT_SCRIPT_EFFECT
|
||||
@@ -150,10 +150,10 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
|
||||
&Spell::EffectStuck, // 84 SPELL_EFFECT_STUCK
|
||||
&Spell::EffectSummonPlayer, // 85 SPELL_EFFECT_SUMMON_PLAYER
|
||||
&Spell::EffectActivateObject, // 86 SPELL_EFFECT_ACTIVATE_OBJECT
|
||||
&Spell::EffectSummonTotem, // 87 SPELL_EFFECT_SUMMON_TOTEM_SLOT1
|
||||
&Spell::EffectSummonTotem, // 88 SPELL_EFFECT_SUMMON_TOTEM_SLOT2
|
||||
&Spell::EffectSummonTotem, // 89 SPELL_EFFECT_SUMMON_TOTEM_SLOT3
|
||||
&Spell::EffectSummonTotem, // 90 SPELL_EFFECT_SUMMON_TOTEM_SLOT4
|
||||
&Spell::EffectUnused, // 87 SPELL_EFFECT_WMO_DAMAGE
|
||||
&Spell::EffectUnused, // 88 SPELL_EFFECT_WMO_REPAIR
|
||||
&Spell::EffectUnused, // 89 SPELL_EFFECT_WMO_CHANGE
|
||||
&Spell::EffectUnused, // 90 SPELL_EFFECT_KILL_CREDIT
|
||||
&Spell::EffectUnused, // 91 SPELL_EFFECT_THREAT_ALL one spell: zzOLDBrainwash
|
||||
&Spell::EffectEnchantHeldItem, // 92 SPELL_EFFECT_ENCHANT_HELD_ITEM
|
||||
&Spell::EffectUnused, // 93 SPELL_EFFECT_SUMMON_PHANTASM
|
||||
@@ -195,21 +195,21 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
|
||||
&Spell::EffectApplyAreaAura, //129 SPELL_EFFECT_APPLY_AREA_AURA_ENEMY
|
||||
&Spell::EffectRedirectThreat, //130 SPELL_EFFECT_REDIRECT_THREAT
|
||||
&Spell::EffectUnused, //131 SPELL_EFFECT_131 used in some test spells
|
||||
&Spell::EffectNULL, //132 SPELL_EFFECT_PLAY_MUSIC sound id in misc value
|
||||
&Spell::EffectNULL, //132 SPELL_EFFECT_PLAY_MUSIC sound id in misc value (SoundEntries.dbc)
|
||||
&Spell::EffectUnlearnSpecialization, //133 SPELL_EFFECT_UNLEARN_SPECIALIZATION unlearn profession specialization
|
||||
&Spell::EffectKillCredit, //134 SPELL_EFFECT_KILL_CREDIT misc value is creature entry
|
||||
&Spell::EffectNULL, //135 SPELL_EFFECT_CALL_PET
|
||||
&Spell::EffectHealPct, //136 SPELL_EFFECT_HEAL_PCT
|
||||
&Spell::EffectEnergisePct, //137 SPELL_EFFECT_ENERGIZE_PCT
|
||||
&Spell::EffectNULL, //138 SPELL_EFFECT_138 Leap
|
||||
&Spell::EffectUnused, //139 SPELL_EFFECT_139 unused
|
||||
&Spell::EffectUnused, //139 SPELL_EFFECT_CLEAR_QUEST (misc - is quest ID)
|
||||
&Spell::EffectForceCast, //140 SPELL_EFFECT_FORCE_CAST
|
||||
&Spell::EffectNULL, //141 SPELL_EFFECT_141 damage and reduce speed?
|
||||
&Spell::EffectTriggerSpellWithValue, //142 SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE
|
||||
&Spell::EffectApplyAreaAura, //143 SPELL_EFFECT_APPLY_AREA_AURA_OWNER
|
||||
&Spell::EffectNULL, //144 SPELL_EFFECT_144 Spectral Blast
|
||||
&Spell::EffectNULL, //145 SPELL_EFFECT_145 Black Hole Effect
|
||||
&Spell::EffectUnused, //146 SPELL_EFFECT_146 unused
|
||||
&Spell::EffectActivateRune, //146 SPELL_EFFECT_ACTIVATE_RUNE
|
||||
&Spell::EffectQuestFail, //147 SPELL_EFFECT_QUEST_FAIL quest fail
|
||||
&Spell::EffectUnused, //148 SPELL_EFFECT_148 unused
|
||||
&Spell::EffectNULL, //149 SPELL_EFFECT_149 swoop
|
||||
@@ -217,6 +217,12 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
|
||||
&Spell::EffectTriggerRitualOfSummoning, //151 SPELL_EFFECT_TRIGGER_SPELL_2
|
||||
&Spell::EffectNULL, //152 SPELL_EFFECT_152 summon Refer-a-Friend
|
||||
&Spell::EffectNULL, //153 SPELL_EFFECT_CREATE_PET misc value is creature entry
|
||||
&Spell::EffectNULL, //154 unused
|
||||
&Spell::EffectTitanGrip, //155 SPELL_EFFECT_TITAN_GRIP Allows you to equip two-handed axes, maces and swords in one hand, but you attack $49152s1% slower than normal.
|
||||
&Spell::EffectNULL, //156 Add Socket
|
||||
&Spell::EffectNULL, //157 create/learn random item/spell for profession
|
||||
&Spell::EffectMilling, //158 milling
|
||||
&Spell::EffectNULL //159 allow rename pet once again
|
||||
};
|
||||
|
||||
void Spell::EffectNULL(uint32 /*i*/)
|
||||
@@ -335,6 +341,13 @@ void Spell::EffectSchoolDMG(uint32 effect_idx)
|
||||
damage = 200;
|
||||
break;
|
||||
}
|
||||
// Intercept (warrior spell trigger)
|
||||
case 20253:
|
||||
case 61491:
|
||||
{
|
||||
damage+= uint32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.12f);
|
||||
break;
|
||||
}
|
||||
// arcane charge. must only affect demons (also undead?)
|
||||
case 45072:
|
||||
{
|
||||
@@ -384,6 +397,12 @@ void Spell::EffectSchoolDMG(uint32 effect_idx)
|
||||
damage = uint32(damage * m_caster->GetTotalAttackPowerValue(BASE_ATTACK) / 100);
|
||||
m_caster->ModifyAuraState(AURA_STATE_WARRIOR_VICTORY_RUSH, false);
|
||||
}
|
||||
// Revenge ${$m1+$AP*0.207} to ${$M1+$AP*0.207}
|
||||
else if(m_spellInfo->SpellFamilyFlags & 0x0000000000000400LL)
|
||||
damage+= uint32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.207f);
|
||||
// Heroic Throw ${$m1+$AP*.50}
|
||||
else if(m_spellInfo->SpellFamilyFlags & 0x0000000100000000LL)
|
||||
damage+= uint32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.5f);
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_WARLOCK:
|
||||
@@ -393,18 +412,20 @@ void Spell::EffectSchoolDMG(uint32 effect_idx)
|
||||
{
|
||||
// Incinerate does more dmg (dmg*0.25) if the target is Immolated.
|
||||
if(unitTarget->HasAuraState(AURA_STATE_IMMOLATE))
|
||||
damage += int32(damage*0.25);
|
||||
damage += int32(damage*0.25f);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_DRUID:
|
||||
{
|
||||
// Ferocious Bite
|
||||
if((m_spellInfo->SpellFamilyFlags & 0x000800000) && m_spellInfo->SpellVisual==6587)
|
||||
if(m_caster->GetTypeId()==TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags & 0x000800000) && m_spellInfo->SpellVisual[0]==6587)
|
||||
{
|
||||
// converts each extra point of energy into ($f1+$AP/630) additional damage
|
||||
float multiple = m_caster->GetTotalAttackPowerValue(BASE_ATTACK) / 630 + m_spellInfo->DmgMultiplier[effect_idx];
|
||||
// converts each extra point of energy into ($f1+$AP/410) additional damage
|
||||
float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
|
||||
float multiple = ap / 410 + m_spellInfo->DmgMultiplier[effect_idx];
|
||||
damage += int32(m_caster->GetPower(POWER_ENERGY) * multiple);
|
||||
damage += int32(((Player*)m_caster)->GetComboPoints() * ap * 7 / 100);
|
||||
m_caster->SetPower(POWER_ENERGY,0);
|
||||
}
|
||||
// Rake
|
||||
@@ -480,7 +501,7 @@ void Spell::EffectSchoolDMG(uint32 effect_idx)
|
||||
{
|
||||
// Deadly poison (only attacker applied)
|
||||
if( (*itr)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_ROGUE && ((*itr)->GetSpellProto()->SpellFamilyFlags & 0x10000) &&
|
||||
(*itr)->GetSpellProto()->SpellVisual==5100 && (*itr)->GetCasterGUID()==m_caster->GetGUID() )
|
||||
(*itr)->GetSpellProto()->SpellVisual[0]==5100 && (*itr)->GetCasterGUID()==m_caster->GetGUID() )
|
||||
{
|
||||
--combo;
|
||||
++doses;
|
||||
@@ -506,26 +527,47 @@ void Spell::EffectSchoolDMG(uint32 effect_idx)
|
||||
{
|
||||
if(uint32 combo = ((Player*)m_caster)->GetComboPoints())
|
||||
{
|
||||
damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * combo * 0.03f);
|
||||
float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
|
||||
damage += irand(int32(ap * combo * 0.03f), int32(ap * combo * 0.07f));
|
||||
|
||||
// Eviscerate and Envenom Bonus Damage (item set effect)
|
||||
if(m_caster->GetDummyAura(37169))
|
||||
damage += combo*40;
|
||||
}
|
||||
}
|
||||
// Gouge
|
||||
else if(m_spellInfo->SpellFamilyFlags & 0x0000000000000008LL)
|
||||
{
|
||||
damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.02f);
|
||||
}
|
||||
// Instant Poison
|
||||
else if(m_spellInfo->SpellFamilyFlags & 0x0000000000002000LL)
|
||||
{
|
||||
damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.10f);
|
||||
}
|
||||
// Wound Poison
|
||||
else if(m_spellInfo->SpellFamilyFlags & 0x0000000010000000LL)
|
||||
{
|
||||
damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.04f);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_HUNTER:
|
||||
{
|
||||
// Mongoose Bite
|
||||
if((m_spellInfo->SpellFamilyFlags & 0x000000002) && m_spellInfo->SpellVisual==342)
|
||||
if((m_spellInfo->SpellFamilyFlags & 0x000000002) && m_spellInfo->SpellVisual[0]==342)
|
||||
{
|
||||
damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.2);
|
||||
damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.2f);
|
||||
}
|
||||
// Counterattack
|
||||
else if(m_spellInfo->SpellFamilyFlags & 0x0008000000000000LL)
|
||||
{
|
||||
damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.2f);
|
||||
}
|
||||
// Arcane Shot
|
||||
else if((m_spellInfo->SpellFamilyFlags & 0x00000800) && m_spellInfo->maxLevel > 0)
|
||||
{
|
||||
damage += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.15);
|
||||
damage += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.15f);
|
||||
}
|
||||
// Steady Shot
|
||||
else if(m_spellInfo->SpellFamilyFlags & 0x100000000LL)
|
||||
@@ -533,16 +575,16 @@ void Spell::EffectSchoolDMG(uint32 effect_idx)
|
||||
int32 base = irand((int32)m_caster->GetWeaponDamageRange(RANGED_ATTACK, MINDAMAGE),(int32)m_caster->GetWeaponDamageRange(RANGED_ATTACK, MAXDAMAGE));
|
||||
damage += int32(float(base)/m_caster->GetAttackTime(RANGED_ATTACK)*2800 + m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.2f);
|
||||
}
|
||||
//Explosive Trap Effect
|
||||
// Explosive Trap Effect
|
||||
else if(m_spellInfo->SpellFamilyFlags & 0x00000004)
|
||||
{
|
||||
damage += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.1);
|
||||
damage += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.1f);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_PALADIN:
|
||||
{
|
||||
//Judgement of Vengeance
|
||||
// Judgement of Vengeance
|
||||
if((m_spellInfo->SpellFamilyFlags & 0x800000000LL) && m_spellInfo->SpellIconID==2292)
|
||||
{
|
||||
uint32 stacks = 0;
|
||||
@@ -556,6 +598,38 @@ void Spell::EffectSchoolDMG(uint32 effect_idx)
|
||||
else
|
||||
damage *= stacks;
|
||||
}
|
||||
// Avenger's Shield ($m1+0.07*$SPH+0.07*$AP)
|
||||
else if(m_spellInfo->SpellFamilyFlags & 0x0000000000004000LL)
|
||||
{
|
||||
float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
|
||||
int32 holy = m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)) +
|
||||
m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget);
|
||||
damage += int32(ap * 0.07f) + int32(holy * 7 / 100);
|
||||
}
|
||||
// Exorcism ($m1+0.15*$SPH+0.15*$AP)
|
||||
else if(m_spellInfo->SpellFamilyFlags & 0x0000000200000000LL)
|
||||
{
|
||||
float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
|
||||
int32 holy = m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)) +
|
||||
m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget);
|
||||
damage += int32(ap * 0.15f) + int32(holy * 15 / 100);
|
||||
}
|
||||
// Hammer of Wrath ($m1+0.15*$SPH+0.15*$AP)
|
||||
else if(m_spellInfo->SpellFamilyFlags & 0x0000008000000000LL)
|
||||
{
|
||||
float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
|
||||
int32 holy = m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)) +
|
||||
m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget);
|
||||
damage += int32(ap * 0.15f) + int32(holy * 15 / 100);
|
||||
}
|
||||
// Holy Wrath ($m1+0.07*$SPH+0.07*$AP)
|
||||
else if(m_spellInfo->SpellFamilyFlags & 0x0020000000000000LL)
|
||||
{
|
||||
float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
|
||||
int32 holy = m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)) +
|
||||
m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget);
|
||||
damage += int32(ap * 0.15f) + int32(holy * 15 / 100);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1155,6 +1229,12 @@ void Spell::EffectDummy(uint32 i)
|
||||
m_caster->CastSpell(m_caster, 30452, true, NULL);
|
||||
return;
|
||||
}
|
||||
case 53341:
|
||||
case 53343:
|
||||
{
|
||||
m_caster->CastSpell(m_caster,54586,true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//All IconID Check in there
|
||||
@@ -1228,7 +1308,7 @@ void Spell::EffectDummy(uint32 i)
|
||||
break;
|
||||
case SPELLFAMILY_WARRIOR:
|
||||
// Charge
|
||||
if(m_spellInfo->SpellFamilyFlags & 0x1 && m_spellInfo->SpellVisual == 867)
|
||||
if(m_spellInfo->SpellFamilyFlags & 0x1 && m_spellInfo->SpellVisual[0] == 867)
|
||||
{
|
||||
int32 chargeBasePoints0 = damage;
|
||||
m_caster->CastCustomSpell(m_caster,34846,&chargeBasePoints0,NULL,NULL,true);
|
||||
@@ -1515,10 +1595,8 @@ void Spell::EffectDummy(uint32 i)
|
||||
mod->value = -50;
|
||||
mod->type = SPELLMOD_PCT;
|
||||
mod->spellId = m_spellInfo->Id;
|
||||
mod->effectId = i;
|
||||
mod->lastAffected = NULL;
|
||||
mod->mask = 0x0000020000000000LL;
|
||||
mod->charges = 0;
|
||||
mod->mask2= 0LL;
|
||||
|
||||
((Player*)m_caster)->AddSpellMod(mod, true);
|
||||
m_caster->CastSpell(unitTarget,spell_proto,true,NULL);
|
||||
@@ -2877,10 +2955,10 @@ void Spell::EffectOpenLock(uint32 /*i*/)
|
||||
}
|
||||
|
||||
// check key
|
||||
for(int i = 0; i < 5; ++i)
|
||||
for(int i = 0; i < 8; ++i)
|
||||
{
|
||||
// type==1 This means lockInfo->key[i] is an item
|
||||
if(lockInfo->keytype[i]==LOCK_KEY_ITEM && lockInfo->key[i] && m_CastItem && m_CastItem->GetEntry()==lockInfo->key[i])
|
||||
// Type==1 This means lockInfo->Index[i] is an item
|
||||
if(lockInfo->Type[i]==LOCK_KEY_ITEM && lockInfo->Index[i] && m_CastItem && m_CastItem->GetEntry()==lockInfo->Index[i])
|
||||
{
|
||||
SendLoot(guid, loottype);
|
||||
return;
|
||||
@@ -2898,9 +2976,9 @@ void Spell::EffectOpenLock(uint32 /*i*/)
|
||||
// skill bonus provided by casting spell (mostly item spells)
|
||||
uint32 spellSkillBonus = uint32(m_currentBasePoints[0]/*+1*/);
|
||||
|
||||
uint32 reqSkillValue = lockInfo->requiredminingskill;
|
||||
uint32 reqSkillValue = lockInfo->Skill[0];
|
||||
|
||||
if(lockInfo->requiredlockskill) // required pick lock skill applying
|
||||
if(lockInfo->Skill[1]) // required pick lock skill applying
|
||||
{
|
||||
if(SkillId != SKILL_LOCKPICKING) // wrong skill (cheating?)
|
||||
{
|
||||
@@ -2908,7 +2986,7 @@ void Spell::EffectOpenLock(uint32 /*i*/)
|
||||
return;
|
||||
}
|
||||
|
||||
reqSkillValue = lockInfo->requiredlockskill;
|
||||
reqSkillValue = lockInfo->Skill[1];
|
||||
}
|
||||
else if(SkillId == SKILL_LOCKPICKING) // apply picklock skill to wrong target
|
||||
{
|
||||
@@ -3235,7 +3313,7 @@ void Spell::EffectLearnSpell(uint32 i)
|
||||
|
||||
Player *player = (Player*)unitTarget;
|
||||
|
||||
uint32 spellToLearn = (m_spellInfo->Id==SPELL_ID_GENERIC_LEARN) ? damage : m_spellInfo->EffectTriggerSpell[i];
|
||||
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);
|
||||
|
||||
sLog.outDebug( "Spell: Player %u have learned spell %u from NpcGUID=%u", player->GetGUIDLow(), spellToLearn, m_caster->GetGUIDLow() );
|
||||
@@ -3877,13 +3955,13 @@ void Spell::EffectEnchantItemTmp(uint32 i)
|
||||
else if(m_spellInfo->SpellFamilyName==SPELLFAMILY_SHAMAN)
|
||||
duration = 1800; // 30 mins
|
||||
// other cases with this SpellVisual already selected
|
||||
else if(m_spellInfo->SpellVisual==215)
|
||||
else if(m_spellInfo->SpellVisual[0]==215)
|
||||
duration = 1800; // 30 mins
|
||||
// some fishing pole bonuses
|
||||
else if(m_spellInfo->SpellVisual==563)
|
||||
else if(m_spellInfo->SpellVisual[0]==563)
|
||||
duration = 600; // 10 mins
|
||||
// shaman rockbiter enchantments
|
||||
else if(m_spellInfo->SpellVisual==0)
|
||||
else if(m_spellInfo->SpellVisual[0]==0)
|
||||
duration = 1800; // 30 mins
|
||||
else if(m_spellInfo->Id==29702)
|
||||
duration = 300; // 5 mins
|
||||
@@ -3946,14 +4024,16 @@ void Spell::EffectTameCreature(uint32 /*i*/)
|
||||
creatureTarget->RemoveCorpse();
|
||||
creatureTarget->SetHealth(0); // just for nice GM-mode view
|
||||
|
||||
uint32 level = (creatureTarget->getLevel() < (m_caster->getLevel() - 5)) ? (m_caster->getLevel() - 5) : creatureTarget->getLevel();
|
||||
|
||||
// prepare visual effect for levelup
|
||||
pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel()-1);
|
||||
pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1);
|
||||
|
||||
// add to world
|
||||
pet->GetMap()->Add((Creature*)pet);
|
||||
|
||||
// visual effect for levelup
|
||||
pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel());
|
||||
pet->SetUInt32Value(UNIT_FIELD_LEVEL, level);
|
||||
|
||||
// caster have pet now
|
||||
m_caster->SetPet(pet);
|
||||
@@ -4152,7 +4232,6 @@ void Spell::EffectLearnPetSpell(uint32 i)
|
||||
if(!learn_spellproto)
|
||||
return;
|
||||
|
||||
pet->SetTP(pet->m_TrainingPoints - pet->GetTPForSpell(learn_spellproto->Id));
|
||||
pet->learnSpell(learn_spellproto->Id);
|
||||
|
||||
pet->SavePetToDB(PET_SAVE_AS_CURRENT);
|
||||
@@ -4212,7 +4291,7 @@ void Spell::EffectWeaponDmg(uint32 i)
|
||||
case SPELLFAMILY_WARRIOR:
|
||||
{
|
||||
// Devastate bonus and sunder armor refresh
|
||||
if(m_spellInfo->SpellVisual == 671 && m_spellInfo->SpellIconID == 1508)
|
||||
if(m_spellInfo->SpellVisual[0] == 671 && m_spellInfo->SpellIconID == 1508)
|
||||
{
|
||||
uint32 stack = 0;
|
||||
|
||||
@@ -4225,7 +4304,7 @@ void Spell::EffectWeaponDmg(uint32 i)
|
||||
{
|
||||
int32 duration = GetSpellDuration(proto);
|
||||
(*itr)->SetAuraDuration(duration);
|
||||
(*itr)->UpdateAuraDuration();
|
||||
(*itr)->SendAuraUpdate(false);
|
||||
stack = (*itr)->GetStackAmount();
|
||||
break;
|
||||
}
|
||||
@@ -4936,9 +5015,69 @@ void Spell::EffectScriptEffect(uint32 effIndex)
|
||||
((Player*)unitTarget)->ModifyMoney(50000000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
case 51770:
|
||||
{
|
||||
if(!unitTarget)
|
||||
return;
|
||||
|
||||
if( m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN )
|
||||
unitTarget->CastSpell(unitTarget,51771,false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( m_spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER )
|
||||
{
|
||||
switch(m_spellInfo->Id)
|
||||
{
|
||||
// Chimera Shot
|
||||
case 53209:
|
||||
{
|
||||
uint32 spellId = 0;
|
||||
int32 basePoint = 0;
|
||||
Unit::AuraMap& Auras = unitTarget->GetAuras();
|
||||
for(Unit::AuraMap::iterator i = Auras.begin(); i != Auras.end(); ++i)
|
||||
{
|
||||
Aura *aura = (*i).second;
|
||||
if (aura->GetCasterGUID() != m_caster->GetGUID())
|
||||
continue;
|
||||
// Search only Serpent Sting, Viper Sting, Scorpid Sting auras
|
||||
uint64 familyFlag = aura->GetSpellProto()->SpellFamilyFlags;
|
||||
if (!(familyFlag & 0x000000800000C000LL))
|
||||
continue;
|
||||
// Refresh aura duration
|
||||
aura->SetAuraDuration(aura->GetAuraMaxDuration());
|
||||
aura->SendAuraUpdate(false);
|
||||
|
||||
// Serpent Sting - Instantly deals 40% of the damage done by your Serpent Sting.
|
||||
if (familyFlag & 0x0000000000004000LL && aura->GetEffIndex() == 0)
|
||||
{
|
||||
spellId = 53353; // 53353 Chimera Shot - Serpent
|
||||
basePoint = aura->GetModifier()->m_amount * 5 * 40 / 100;
|
||||
}
|
||||
// Viper Sting - Instantly restores mana to you equal to 60% of the total amount drained by your Viper Sting.
|
||||
if (familyFlag & 0x0000008000000000LL && aura->GetEffIndex() == 0)
|
||||
{
|
||||
spellId = 53358; // 53358 Chimera Shot - Viper
|
||||
basePoint = aura->GetModifier()->m_amount * 4 * 60 / 100;
|
||||
}
|
||||
// Scorpid Sting - Attempts to Disarm the target for 10 sec. This effect cannot occur more than once per 1 minute.
|
||||
if (familyFlag & 0x0000000000008000LL)
|
||||
spellId = 53359; // 53359 Chimera Shot - Scorpid
|
||||
// ?? nothing say in spell desc (possibly need addition check)
|
||||
//if (familyFlag & 0x0000010000000000LL || // dot
|
||||
// familyFlag & 0x0000100000000000LL) // stun
|
||||
//{
|
||||
// spellId = 53366; // 53366 Chimera Shot - Wyvern
|
||||
//}
|
||||
}
|
||||
if (spellId)
|
||||
m_caster->CastCustomSpell(unitTarget, spellId, &basePoint, 0, 0, false);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if( m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN )
|
||||
{
|
||||
switch(m_spellInfo->SpellFamilyFlags)
|
||||
{
|
||||
@@ -5060,7 +5199,8 @@ void Spell::EffectDuel(uint32 i)
|
||||
|
||||
// Players can only fight a duel with each other outside (=not inside dungeons and not in capital cities)
|
||||
// Don't have to check the target's map since you cannot challenge someone across maps
|
||||
if( caster->GetMapId() != 0 && caster->GetMapId() != 1 && caster->GetMapId() != 530)
|
||||
uint32 mapid = caster->GetMapId();
|
||||
if( mapid != 0 && mapid != 1 && mapid != 530 && mapid != 571 && mapid != 609)
|
||||
{
|
||||
SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
|
||||
return;
|
||||
@@ -5199,6 +5339,45 @@ void Spell::EffectActivateObject(uint32 effect_idx)
|
||||
sWorld.ScriptCommandStart(activateCommand, delay_secs, m_caster, gameObjTarget);
|
||||
}
|
||||
|
||||
void Spell::EffectApplyGlyph(uint32 i)
|
||||
{
|
||||
if(m_caster->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
Player *player = (Player*)m_caster;
|
||||
|
||||
// remove old glyph
|
||||
if(uint32 oldglyph = player->GetGlyph(m_glyphIndex))
|
||||
{
|
||||
if(GlyphPropertiesEntry const *old_gp = sGlyphPropertiesStore.LookupEntry(oldglyph))
|
||||
{
|
||||
player->RemoveAurasDueToSpell(old_gp->SpellId);
|
||||
player->SetGlyph(m_glyphIndex, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// apply new one
|
||||
if(uint32 glyph = m_spellInfo->EffectMiscValue[i])
|
||||
{
|
||||
if(GlyphPropertiesEntry const *gp = sGlyphPropertiesStore.LookupEntry(glyph))
|
||||
{
|
||||
if(GlyphSlotEntry const *gs = sGlyphSlotStore.LookupEntry(player->GetGlyphSlot(m_glyphIndex)))
|
||||
{
|
||||
if(gp->TypeFlags != gs->TypeFlags)
|
||||
{
|
||||
SendCastResult(SPELL_FAILED_INVALID_GLYPH);
|
||||
return; // glyph slot missmatch
|
||||
}
|
||||
}
|
||||
|
||||
player->CastSpell(m_caster, gp->SpellId, true);
|
||||
player->SetGlyph(m_glyphIndex, glyph);
|
||||
if(m_CastItem)
|
||||
player->DestroyItemCount(m_CastItem->GetEntry(), 1, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Spell::EffectSummonTotem(uint32 i)
|
||||
{
|
||||
uint8 slot = 0;
|
||||
@@ -5522,18 +5701,14 @@ void Spell::EffectAddExtraAttacks(uint32 /*i*/)
|
||||
|
||||
void Spell::EffectParry(uint32 /*i*/)
|
||||
{
|
||||
if (unitTarget->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
if (unitTarget && unitTarget->GetTypeId() == TYPEID_PLAYER)
|
||||
((Player*)unitTarget)->SetCanParry(true);
|
||||
}
|
||||
}
|
||||
|
||||
void Spell::EffectBlock(uint32 /*i*/)
|
||||
{
|
||||
if (unitTarget->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
((Player*)unitTarget)->SetCanBlock(true);
|
||||
if (unitTarget && unitTarget->GetTypeId() == TYPEID_PLAYER)
|
||||
((Player*)unitTarget)->SetCanBlock(true);
|
||||
}
|
||||
|
||||
void Spell::EffectMomentMove(uint32 i)
|
||||
@@ -6083,9 +6258,9 @@ void Spell::EffectTransmitted(uint32 effIndex)
|
||||
{
|
||||
m_caster->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT,pGameObj->GetGUID());
|
||||
// Orientation3
|
||||
pGameObj->SetFloatValue(GAMEOBJECT_ROTATION + 2, 0.88431775569915771 );
|
||||
pGameObj->SetFloatValue(GAMEOBJECT_PARENTROTATION + 2, 0.88431775569915771 );
|
||||
// Orientation4
|
||||
pGameObj->SetFloatValue(GAMEOBJECT_ROTATION + 3, -0.4668855369091033 );
|
||||
pGameObj->SetFloatValue(GAMEOBJECT_PARENTROTATION + 3, -0.4668855369091033 );
|
||||
m_caster->AddGameObject(pGameObj); // will removed at spell cancel
|
||||
|
||||
// end time of range when possible catch fish (FISHING_BOBBER_READY_TIME..GetDuration(m_spellInfo))
|
||||
@@ -6180,6 +6355,28 @@ void Spell::EffectProspecting(uint32 /*i*/)
|
||||
((Player*)m_caster)->SendLoot(itemTarget->GetGUID(), LOOT_PROSPECTING);
|
||||
}
|
||||
|
||||
void Spell::EffectMilling(uint32 /*i*/)
|
||||
{
|
||||
if(m_caster->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
Player* p_caster = (Player*)m_caster;
|
||||
if(!itemTarget || !(itemTarget->GetProto()->BagFamily & BAG_FAMILY_MASK_HERBS))
|
||||
return;
|
||||
|
||||
if(itemTarget->GetCount() < 5)
|
||||
return;
|
||||
|
||||
if( sWorld.getConfig(CONFIG_SKILL_MILLING))
|
||||
{
|
||||
uint32 SkillValue = p_caster->GetPureSkillValue(SKILL_INSCRIPTION);
|
||||
uint32 reqSkillValue = itemTarget->GetProto()->RequiredSkillRank;
|
||||
p_caster->UpdateGatherSkill(SKILL_INSCRIPTION, SkillValue, reqSkillValue);
|
||||
}
|
||||
|
||||
((Player*)m_caster)->SendLoot(itemTarget->GetGUID(), LOOT_MILLING);
|
||||
}
|
||||
|
||||
void Spell::EffectSkill(uint32 /*i*/)
|
||||
{
|
||||
sLog.outDebug("WORLD: SkillEFFECT");
|
||||
@@ -6327,6 +6524,31 @@ void Spell::EffectQuestFail(uint32 i)
|
||||
((Player*)unitTarget)->FailQuest(m_spellInfo->EffectMiscValue[i]);
|
||||
}
|
||||
|
||||
void Spell::EffectActivateRune(uint32 i)
|
||||
{
|
||||
if(m_caster->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
Player *plr = (Player*)m_caster;
|
||||
|
||||
if(plr->getClass() != CLASS_DEATH_KNIGHT)
|
||||
return;
|
||||
|
||||
for(uint32 j = 0; j < MAX_RUNES; ++j)
|
||||
{
|
||||
if(plr->GetRuneCooldown(j) && plr->GetCurrentRune(j) == m_spellInfo->EffectMiscValue[i])
|
||||
{
|
||||
plr->SetRuneCooldown(j, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Spell::EffectTitanGrip(uint32 i)
|
||||
{
|
||||
if (unitTarget && unitTarget->GetTypeId() == TYPEID_PLAYER)
|
||||
((Player*)unitTarget)->SetCanTitanGrip(true);
|
||||
}
|
||||
|
||||
void Spell::EffectRedirectThreat(uint32 /*i*/)
|
||||
{
|
||||
if(unitTarget)
|
||||
|
||||
+23
-15
@@ -38,15 +38,17 @@
|
||||
void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
|
||||
{
|
||||
// TODO: add targets.read() check
|
||||
CHECK_PACKET_SIZE(recvPacket,1+1+1+1+8);
|
||||
CHECK_PACKET_SIZE(recvPacket,1+1+1+4+8+4+1);
|
||||
|
||||
Player* pUser = _player;
|
||||
uint8 bagIndex, slot;
|
||||
uint8 spell_count; // number of spells at item, not used
|
||||
uint8 unk_flags; // flags (if 0x02 - some additional data are received)
|
||||
uint8 cast_count; // next cast if exists (single or not)
|
||||
uint64 item_guid;
|
||||
uint32 glyphIndex; // something to do with glyphs?
|
||||
uint32 spellid; // casted spell id
|
||||
|
||||
recvPacket >> bagIndex >> slot >> spell_count >> cast_count >> item_guid;
|
||||
recvPacket >> bagIndex >> slot >> cast_count >> spellid >> item_guid >> glyphIndex >> unk_flags;
|
||||
|
||||
Item *pItem = pUser->GetItemByPos(bagIndex, slot);
|
||||
if(!pItem)
|
||||
@@ -61,7 +63,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
|
||||
return;
|
||||
}
|
||||
|
||||
sLog.outDetail("WORLD: CMSG_USE_ITEM packet, bagIndex: %u, slot: %u, spell_count: %u , cast_count: %u, Item: %u, data length = %i", bagIndex, slot, spell_count, cast_count, pItem->GetEntry(), recvPacket.size());
|
||||
sLog.outDetail("WORLD: CMSG_USE_ITEM packet, bagIndex: %u, slot: %u, cast_count: %u, spellid: %u, Item: %u, glyphIndex: %u, unk_flags: %u, data length = %i", bagIndex, slot, cast_count, spellid, pItem->GetEntry(), glyphIndex, unk_flags, recvPacket.size());
|
||||
|
||||
ItemPrototype const *proto = pItem->GetProto();
|
||||
if(!proto)
|
||||
@@ -128,14 +130,15 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
|
||||
// no script or script not process request by self
|
||||
|
||||
// special learning case
|
||||
if(pItem->GetProto()->Spells[0].SpellId==SPELL_ID_GENERIC_LEARN)
|
||||
if((pItem->GetProto()->Spells[0].SpellId==SPELL_ID_GENERIC_LEARN) || (pItem->GetProto()->Spells[0].SpellId==SPELL_ID_GENERIC_LEARN_PET))
|
||||
{
|
||||
uint32 learn_spell_id = pItem->GetProto()->Spells[0].SpellId;
|
||||
uint32 learning_spell_id = pItem->GetProto()->Spells[1].SpellId;
|
||||
|
||||
SpellEntry const *spellInfo = sSpellStore.LookupEntry(SPELL_ID_GENERIC_LEARN);
|
||||
SpellEntry const *spellInfo = sSpellStore.LookupEntry(learn_spell_id);
|
||||
if(!spellInfo)
|
||||
{
|
||||
sLog.outError("Item (Entry: %u) in have wrong spell id %u, ignoring ",proto->ItemId, SPELL_ID_GENERIC_LEARN);
|
||||
sLog.outError("Item (Entry: %u) in have wrong spell id %u, ignoring ",proto->ItemId, learn_spell_id);
|
||||
pUser->SendEquipError(EQUIP_ERR_NONE,pItem,NULL);
|
||||
return;
|
||||
}
|
||||
@@ -172,7 +175,8 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
|
||||
|
||||
Spell *spell = new Spell(pUser, spellInfo, (count > 0));
|
||||
spell->m_CastItem = pItem;
|
||||
spell->m_cast_count = cast_count; //set count of casts
|
||||
spell->m_cast_count = cast_count; // set count of casts
|
||||
spell->m_glyphIndex = glyphIndex; // glyph index
|
||||
spell->prepare(&targets);
|
||||
|
||||
++count;
|
||||
@@ -227,7 +231,7 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket)
|
||||
}
|
||||
|
||||
// required picklocking
|
||||
if(lockInfo->requiredlockskill || lockInfo->requiredminingskill)
|
||||
if(lockInfo->Skill[1] || lockInfo->Skill[0])
|
||||
{
|
||||
pUser->SendEquipError(EQUIP_ERR_ITEM_LOCKED, pItem, NULL );
|
||||
return;
|
||||
@@ -283,15 +287,16 @@ void WorldSession::HandleGameObjectUseOpcode( WorldPacket & recv_data )
|
||||
|
||||
void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
|
||||
{
|
||||
CHECK_PACKET_SIZE(recvPacket,4+1+2);
|
||||
CHECK_PACKET_SIZE(recvPacket,1+4+1);
|
||||
|
||||
uint32 spellId;
|
||||
uint8 cast_count;
|
||||
recvPacket >> spellId;
|
||||
uint8 cast_count, unk_flags;
|
||||
recvPacket >> cast_count;
|
||||
recvPacket >> spellId;
|
||||
recvPacket >> unk_flags; // flags (if 0x02 - some additional data are received)
|
||||
|
||||
sLog.outDebug("WORLD: got cast spell packet, spellId - %u, cast_count: %u data length = %i",
|
||||
spellId, cast_count, recvPacket.size());
|
||||
sLog.outDebug("WORLD: got cast spell packet, spellId - %u, cast_count: %u, unk_flags %u, data length = %i",
|
||||
spellId, cast_count, unk_flags, recvPacket.size());
|
||||
|
||||
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId );
|
||||
|
||||
@@ -334,9 +339,12 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
|
||||
|
||||
void WorldSession::HandleCancelCastOpcode(WorldPacket& recvPacket)
|
||||
{
|
||||
CHECK_PACKET_SIZE(recvPacket,4);
|
||||
CHECK_PACKET_SIZE(recvPacket,5);
|
||||
|
||||
// increments with every CANCEL packet, don't use for now
|
||||
uint8 counter;
|
||||
uint32 spellId;
|
||||
recvPacket >> counter;
|
||||
recvPacket >> spellId;
|
||||
|
||||
//FIXME: hack, ignore unexpected client cancel Deadly Throw cast
|
||||
|
||||
+234
-53
@@ -41,13 +41,13 @@ SpellMgr::SpellMgr()
|
||||
case SPELL_EFFECT_TRANS_DOOR: //50 summon object
|
||||
case SPELL_EFFECT_SUMMON_PET: //56
|
||||
case SPELL_EFFECT_ADD_FARSIGHT: //72
|
||||
case SPELL_EFFECT_SUMMON_POSSESSED: //73
|
||||
case SPELL_EFFECT_SUMMON_TOTEM: //74
|
||||
//case SPELL_EFFECT_SUMMON_POSSESSED: //73
|
||||
//case SPELL_EFFECT_SUMMON_TOTEM: //74
|
||||
case SPELL_EFFECT_SUMMON_OBJECT_WILD: //76
|
||||
case SPELL_EFFECT_SUMMON_TOTEM_SLOT1: //87
|
||||
case SPELL_EFFECT_SUMMON_TOTEM_SLOT2: //88
|
||||
case SPELL_EFFECT_SUMMON_TOTEM_SLOT3: //89
|
||||
case SPELL_EFFECT_SUMMON_TOTEM_SLOT4: //90
|
||||
//case SPELL_EFFECT_SUMMON_TOTEM_SLOT1: //87
|
||||
//case SPELL_EFFECT_SUMMON_TOTEM_SLOT2: //88
|
||||
//case SPELL_EFFECT_SUMMON_TOTEM_SLOT3: //89
|
||||
//case SPELL_EFFECT_SUMMON_TOTEM_SLOT4: //90
|
||||
case SPELL_EFFECT_SUMMON_CRITTER: //97
|
||||
case SPELL_EFFECT_SUMMON_OBJECT_SLOT1: //104
|
||||
case SPELL_EFFECT_SUMMON_OBJECT_SLOT2: //105
|
||||
@@ -318,10 +318,10 @@ SpellSpecific GetSpellSpecific(uint32 spellId)
|
||||
if ((spellInfo->SpellFamilyFlags & 0x00000820180400LL) && (spellInfo->AttributesEx3 & 0x200))
|
||||
return SPELL_JUDGEMENT;
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
for (int i = 0; i < 3; i++) // TODO: fix it for WotLK!!!
|
||||
{
|
||||
// only paladin auras have this
|
||||
if (spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PARTY)
|
||||
if (spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_RAID)
|
||||
return SPELL_AURA;
|
||||
}
|
||||
break;
|
||||
@@ -339,7 +339,7 @@ SpellSpecific GetSpellSpecific(uint32 spellId)
|
||||
}
|
||||
|
||||
// only warlock armor/skin have this (in additional to family cases)
|
||||
if( spellInfo->SpellVisual == 130 && spellInfo->SpellIconID == 89)
|
||||
if( spellInfo->SpellVisual[0] == 130 && spellInfo->SpellIconID == 89)
|
||||
{
|
||||
return SPELL_WARLOCK_ARMOR;
|
||||
}
|
||||
@@ -828,8 +828,8 @@ void SpellMgr::LoadSpellAffects()
|
||||
|
||||
uint32 count = 0;
|
||||
|
||||
// 0 1 2
|
||||
QueryResult *result = WorldDatabase.Query("SELECT entry, effectId, SpellFamilyMask FROM spell_affect");
|
||||
// 0 1 2 3 4
|
||||
QueryResult *result = WorldDatabase.Query("SELECT entry, effectId, SpellClassMask0, SpellClassMask1, SpellClassMask2 FROM spell_affect");
|
||||
if( !result )
|
||||
{
|
||||
|
||||
@@ -876,26 +876,29 @@ void SpellMgr::LoadSpellAffects()
|
||||
continue;
|
||||
}
|
||||
|
||||
uint64 spellAffectMask = fields[2].GetUInt64();
|
||||
SpellAffectEntry affect;
|
||||
affect.SpellClassMask[0] = fields[2].GetUInt32();
|
||||
affect.SpellClassMask[1] = fields[3].GetUInt32();
|
||||
affect.SpellClassMask[2] = fields[4].GetUInt32();
|
||||
|
||||
// Spell.dbc have own data for low part of SpellFamilyMask
|
||||
if( spellInfo->EffectItemType[effectId])
|
||||
// Spell.dbc have own data
|
||||
uint32 const *ptr = 0;
|
||||
switch (effectId)
|
||||
{
|
||||
if(spellInfo->EffectItemType[effectId] == spellAffectMask)
|
||||
{
|
||||
sLog.outErrorDb("Spell %u listed in `spell_affect` have redundant (same with EffectItemType%d) data for effect index (%u) and not needed, skipped.", entry,effectId+1,effectId);
|
||||
case 0: ptr = &spellInfo->EffectSpellClassMaskA[0]; break;
|
||||
case 1: ptr = &spellInfo->EffectSpellClassMaskB[0]; break;
|
||||
case 2: ptr = &spellInfo->EffectSpellClassMaskC[0]; break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
// 24429 have wrong data in EffectItemType and overwrites by DB, possible bug in client
|
||||
if(spellInfo->Id!=24429 && spellInfo->EffectItemType[effectId] != spellAffectMask)
|
||||
{
|
||||
sLog.outErrorDb("Spell %u listed in `spell_affect` have different low part from EffectItemType%d for effect index (%u) and not needed, skipped.", entry,effectId+1,effectId);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(ptr[0] == affect.SpellClassMask[0] || ptr[1] == affect.SpellClassMask[1] || ptr[2] == affect.SpellClassMask[2])
|
||||
{
|
||||
char text[]="ABC";
|
||||
sLog.outErrorDb("Spell %u listed in `spell_affect` have redundant (same with EffectSpellClassMask%c) data for effect index (%u) and not needed, skipped.", entry, text[effectId], effectId);
|
||||
continue;
|
||||
}
|
||||
|
||||
mSpellAffectMap.insert(SpellAffectMap::value_type((entry<<8) + effectId,spellAffectMask));
|
||||
mSpellAffectMap[(entry<<8) + effectId] = affect;
|
||||
|
||||
++count;
|
||||
} while( result->NextRow() );
|
||||
@@ -903,7 +906,7 @@ void SpellMgr::LoadSpellAffects()
|
||||
delete result;
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString( ">> Loaded %u spell affect definitions", count );
|
||||
sLog.outString( ">> Loaded %u custom spell affect definitions", count );
|
||||
|
||||
for (uint32 id = 0; id < sSpellStore.GetNumRows(); ++id)
|
||||
{
|
||||
@@ -919,7 +922,16 @@ void SpellMgr::LoadSpellAffects()
|
||||
spellInfo->EffectApplyAuraName[effectId] != SPELL_AURA_ADD_TARGET_TRIGGER) )
|
||||
continue;
|
||||
|
||||
if(spellInfo->EffectItemType[effectId] != 0)
|
||||
uint32 const *ptr = 0;
|
||||
switch (effectId)
|
||||
{
|
||||
case 0: ptr = &spellInfo->EffectSpellClassMaskA[0]; break;
|
||||
case 1: ptr = &spellInfo->EffectSpellClassMaskB[0]; break;
|
||||
case 2: ptr = &spellInfo->EffectSpellClassMaskC[0]; break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
if(ptr[0] || ptr[1] || ptr[2])
|
||||
continue;
|
||||
|
||||
if(mSpellAffectMap.find((id<<8) + effectId) != mSpellAffectMap.end())
|
||||
@@ -930,33 +942,20 @@ void SpellMgr::LoadSpellAffects()
|
||||
}
|
||||
}
|
||||
|
||||
bool SpellMgr::IsAffectedBySpell(SpellEntry const *spellInfo, uint32 spellId, uint8 effectId, uint64 familyFlags) const
|
||||
bool SpellMgr::IsAffectedByMod(SpellEntry const *spellInfo, SpellModifier *mod) const
|
||||
{
|
||||
// false for spellInfo == NULL
|
||||
if (!spellInfo)
|
||||
if (!spellInfo || !mod)
|
||||
return false;
|
||||
|
||||
SpellEntry const *affect_spell = sSpellStore.LookupEntry(spellId);
|
||||
// false for affect_spell == NULL
|
||||
if (!affect_spell)
|
||||
SpellEntry const *affect_spell = sSpellStore.LookupEntry(mod->spellId);
|
||||
// False if affect_spell == NULL or spellFamily not equal
|
||||
if (!affect_spell || affect_spell->SpellFamilyName != spellInfo->SpellFamilyName)
|
||||
return false;
|
||||
|
||||
// False if spellFamily not equal
|
||||
if (affect_spell->SpellFamilyName != spellInfo->SpellFamilyName)
|
||||
return false;
|
||||
|
||||
// If familyFlags == 0
|
||||
if (!familyFlags)
|
||||
{
|
||||
// Get it from spellAffect table
|
||||
familyFlags = GetSpellAffectMask(spellId,effectId);
|
||||
// false if familyFlags == 0
|
||||
if (!familyFlags)
|
||||
return false;
|
||||
}
|
||||
|
||||
// true
|
||||
if (familyFlags & spellInfo->SpellFamilyFlags)
|
||||
if (mod->mask & spellInfo->SpellFamilyFlags ||
|
||||
mod->mask2 & spellInfo->SpellFamilyFlags2)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@@ -1250,7 +1249,7 @@ bool SpellMgr::canStackSpellRanks(SpellEntry const *spellInfo)
|
||||
{
|
||||
// Paladin aura Spell
|
||||
if(spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN
|
||||
&& spellInfo->Effect[i]==SPELL_EFFECT_APPLY_AREA_AURA_PARTY)
|
||||
&& spellInfo->Effect[i]==SPELL_EFFECT_APPLY_AREA_AURA_RAID)
|
||||
return false;
|
||||
// Druid form Spell
|
||||
if(spellInfo->SpellFamilyName == SPELLFAMILY_DRUID
|
||||
@@ -1387,7 +1386,8 @@ SpellEntry const* SpellMgr::SelectAuraRankForPlayerLevel(SpellEntry const* spell
|
||||
{
|
||||
if( IsPositiveEffect(spellInfo->Id, i) && (
|
||||
spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA ||
|
||||
spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PARTY
|
||||
spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PARTY ||
|
||||
spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_RAID
|
||||
) )
|
||||
{
|
||||
needRankSelection = true;
|
||||
@@ -1519,7 +1519,7 @@ void SpellMgr::LoadSpellChains()
|
||||
entry.ProcFlags=SpellInfo->procFlags;
|
||||
entry.SpellFamilyFlags=SpellInfo->SpellFamilyFlags;
|
||||
entry.TargetAuraState=SpellInfo->TargetAuraState;
|
||||
entry.SpellVisual=SpellInfo->SpellVisual;
|
||||
entry.SpellVisual=SpellInfo->SpellVisual[0];
|
||||
entry.ManaCost=SpellInfo->manaCost;
|
||||
|
||||
value.Id=spell_id;
|
||||
@@ -2042,7 +2042,7 @@ void SpellMgr::LoadSpellCustomAttr()
|
||||
}
|
||||
}
|
||||
|
||||
if(spellInfo->SpellVisual == 3879)
|
||||
if(spellInfo->SpellVisual[0] == 3879)
|
||||
mSpellCustomAttr[i] |= SPELL_ATTR_CU_CONE_BACK;
|
||||
|
||||
switch(i)
|
||||
@@ -2146,6 +2146,187 @@ void SpellMgr::LoadSpellLinked()
|
||||
}
|
||||
|
||||
/// Some checks for spells, to prevent adding depricated/broken spells for trainers, spell book, etc
|
||||
void SpellMgr::LoadPetLevelupSpellMap()
|
||||
{
|
||||
CreatureFamilyEntry const *creatureFamily;
|
||||
SpellEntry const *spell;
|
||||
uint32 count = 0;
|
||||
|
||||
for (uint32 i = 0; i < sCreatureFamilyStore.GetNumRows(); ++i)
|
||||
{
|
||||
creatureFamily = sCreatureFamilyStore.LookupEntry(i);
|
||||
|
||||
if(!creatureFamily) // not exist
|
||||
continue;
|
||||
|
||||
if(creatureFamily->petTalentType < 0) // not hunter pet family
|
||||
continue;
|
||||
|
||||
for(uint32 j = 0; j < sSpellStore.GetNumRows(); ++j)
|
||||
{
|
||||
spell = sSpellStore.LookupEntry(j);
|
||||
|
||||
// not exist
|
||||
if(!spell)
|
||||
continue;
|
||||
|
||||
// not hunter spell
|
||||
if(spell->SpellFamilyName != SPELLFAMILY_HUNTER)
|
||||
continue;
|
||||
|
||||
// not pet spell
|
||||
if(!(spell->SpellFamilyFlags & 0x1000000000000000LL))
|
||||
continue;
|
||||
|
||||
// not Growl or Cower (generics)
|
||||
if(spell->SpellIconID != 201 && spell->SpellIconID != 958)
|
||||
{
|
||||
switch(creatureFamily->ID)
|
||||
{
|
||||
case CREATURE_FAMILY_BAT: // Bite and Sonic Blast
|
||||
if(spell->SpellIconID != 1680 && spell->SpellIconID != 1577)
|
||||
continue;
|
||||
break;
|
||||
case CREATURE_FAMILY_BEAR: // Claw and Swipe
|
||||
if(spell->SpellIconID != 262 && spell->SpellIconID != 1562)
|
||||
continue;
|
||||
break;
|
||||
case CREATURE_FAMILY_BIRD_OF_PREY: // Claw and Snatch
|
||||
if(spell->SpellIconID != 262 && spell->SpellIconID != 168)
|
||||
continue;
|
||||
break;
|
||||
case CREATURE_FAMILY_BOAR: // Bite and Gore
|
||||
if(spell->SpellIconID != 1680 && spell->SpellIconID != 1578)
|
||||
continue;
|
||||
break;
|
||||
case CREATURE_FAMILY_CARRION_BIRD: // Bite and Demoralizing Screech
|
||||
if(spell->SpellIconID != 1680 && spell->SpellIconID != 1579)
|
||||
continue;
|
||||
break;
|
||||
case CREATURE_FAMILY_CAT: // Claw and Prowl and Rake
|
||||
if(spell->SpellIconID != 262 && spell->SpellIconID != 495 && spell->SpellIconID != 494)
|
||||
continue;
|
||||
break;
|
||||
case CREATURE_FAMILY_CHIMAERA: // Bite and Froststorm Breath
|
||||
if(spell->SpellIconID != 1680 && spell->SpellIconID != 62)
|
||||
continue;
|
||||
break;
|
||||
case CREATURE_FAMILY_CORE_HOUND: // Bite and Lava Breath
|
||||
if(spell->SpellIconID != 1680 && spell->SpellIconID != 1197)
|
||||
continue;
|
||||
break;
|
||||
case CREATURE_FAMILY_CRAB: // Claw and Pin
|
||||
if(spell->SpellIconID != 262 && spell->SpellIconID != 2679)
|
||||
continue;
|
||||
break;
|
||||
case CREATURE_FAMILY_CROCOLISK: // Bite and Bad Attitude
|
||||
if(spell->SpellIconID != 1680 && spell->SpellIconID != 1581)
|
||||
continue;
|
||||
break;
|
||||
case CREATURE_FAMILY_DEVILSAUR: // Bite and Monstrous Bite
|
||||
if(spell->SpellIconID != 1680 && spell->SpellIconID != 599)
|
||||
continue;
|
||||
break;
|
||||
case CREATURE_FAMILY_DRAGONHAWK: // Bite and Fire Breath
|
||||
if(spell->SpellIconID != 1680 && spell->SpellIconID != 2128)
|
||||
continue;
|
||||
break;
|
||||
case CREATURE_FAMILY_GORILLA: // Smack and Thunderstomp
|
||||
if(spell->SpellIconID != 473 && spell->SpellIconID != 148)
|
||||
continue;
|
||||
break;
|
||||
case CREATURE_FAMILY_HYENA: // Bite and Tendon Rip
|
||||
if(spell->SpellIconID != 1680 && spell->SpellIconID != 138)
|
||||
continue;
|
||||
break;
|
||||
case CREATURE_FAMILY_MOTH: // Serenity Dust and Smack
|
||||
if(spell->SpellIconID != 1714 && spell->SpellIconID != 473)
|
||||
continue;
|
||||
break;
|
||||
case CREATURE_FAMILY_NETHER_RAY: // Bite and Nether Shock
|
||||
if(spell->SpellIconID != 1680 && spell->SpellIconID != 2027)
|
||||
continue;
|
||||
break;
|
||||
case CREATURE_FAMILY_RAPTOR: // Claw and Savage Rend
|
||||
if(spell->SpellIconID != 262 && spell->SpellIconID != 245)
|
||||
continue;
|
||||
break;
|
||||
case CREATURE_FAMILY_RAVAGER: // Bite and Ravage
|
||||
if(spell->SpellIconID != 1680 && spell->SpellIconID != 2253)
|
||||
continue;
|
||||
break;
|
||||
case CREATURE_FAMILY_RHINO: // Smack and Stampede
|
||||
if(spell->SpellIconID != 473 && spell->SpellIconID != 3066)
|
||||
continue;
|
||||
break;
|
||||
case CREATURE_FAMILY_SCORPID: // Claw and Scorpid Poison
|
||||
if(spell->SpellIconID != 262 && spell->SpellIconID != 163)
|
||||
continue;
|
||||
break;
|
||||
case CREATURE_FAMILY_SERPENT: // Bite and Poison Spit
|
||||
if(spell->SpellIconID != 1680 && spell->SpellIconID != 68)
|
||||
continue;
|
||||
break;
|
||||
case CREATURE_FAMILY_SILITHID: // Claw and Venom Web Spray
|
||||
if(spell->SpellIconID != 262 && (spell->SpellIconID != 272 && spell->SpellVisual[0] != 12013))
|
||||
continue;
|
||||
break;
|
||||
case CREATURE_FAMILY_SPIDER: // Bite and Web
|
||||
if(spell->SpellIconID != 1680 && (spell->SpellIconID != 272 && spell->SpellVisual[0] != 684))
|
||||
continue;
|
||||
break;
|
||||
case CREATURE_FAMILY_SPIRIT_BEAST: // Claw and Prowl and Spirit Strike
|
||||
if(spell->SpellIconID != 262 && spell->SpellIconID != 495 && spell->SpellIconID != 255)
|
||||
continue;
|
||||
break;
|
||||
case CREATURE_FAMILY_SPOREBAT: // Smack and Spore Cloud
|
||||
if(spell->SpellIconID != 473 && spell->SpellIconID != 2681)
|
||||
continue;
|
||||
break;
|
||||
case CREATURE_FAMILY_TALLSTRIDER: // Claw and Dust Cloud
|
||||
if(spell->SpellIconID != 262 && (spell->SpellIconID != 157 && !(spell->Attributes & 0x4000000)))
|
||||
continue;
|
||||
break;
|
||||
case CREATURE_FAMILY_TURTLE: // Bite and Shell Shield
|
||||
if(spell->SpellIconID != 1680 && spell->SpellIconID != 1588)
|
||||
continue;
|
||||
break;
|
||||
case CREATURE_FAMILY_WARP_STALKER: // Bite and Warp
|
||||
if(spell->SpellIconID != 1680 && spell->SpellIconID != 1952)
|
||||
continue;
|
||||
break;
|
||||
case CREATURE_FAMILY_WASP: // Smack and Sting
|
||||
if(spell->SpellIconID != 473 && spell->SpellIconID != 110)
|
||||
continue;
|
||||
break;
|
||||
case CREATURE_FAMILY_WIND_SERPENT: // Bite and Lightning Breath
|
||||
if(spell->SpellIconID != 1680 && spell->SpellIconID != 62)
|
||||
continue;
|
||||
break;
|
||||
case CREATURE_FAMILY_WOLF: // Bite and Furious Howl
|
||||
if(spell->SpellIconID != 1680 && spell->SpellIconID != 1573)
|
||||
continue;
|
||||
break;
|
||||
case CREATURE_FAMILY_WORM: // Acid Spit and Bite
|
||||
if(spell->SpellIconID != 636 && spell->SpellIconID != 1680)
|
||||
continue;
|
||||
break;
|
||||
default:
|
||||
sLog.outError("LoadPetLevelupSpellMap: Unhandled creature family %u", creatureFamily->ID);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
mPetLevelupSpellMap[creatureFamily->ID][spell->spellLevel] = spell->Id;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString( ">> Loaded %u pet levelup spells", count );
|
||||
}
|
||||
|
||||
/// Some checks for spells, to prevent adding deprecated/broken spells for trainers, spell book, etc
|
||||
bool SpellMgr::IsSpellValid(SpellEntry const* spellInfo, Player* pl, bool msg)
|
||||
{
|
||||
// not exist
|
||||
@@ -2223,7 +2404,7 @@ bool SpellMgr::IsSpellValid(SpellEntry const* spellInfo, Player* pl, bool msg)
|
||||
bool IsSpellAllowedInLocation(SpellEntry const *spellInfo,uint32 map_id,uint32 zone_id,uint32 area_id)
|
||||
{
|
||||
// normal case
|
||||
if( spellInfo->AreaId && spellInfo->AreaId != zone_id && spellInfo->AreaId != area_id )
|
||||
if( spellInfo->AreaId > 0 && spellInfo->AreaId != zone_id && spellInfo->AreaId != area_id )
|
||||
return false;
|
||||
|
||||
// elixirs (all area dependent elixirs have family SPELLFAMILY_POTION, use this for speedup)
|
||||
|
||||
+214
-180
@@ -29,6 +29,9 @@
|
||||
#include "Database/SQLStorage.h"
|
||||
|
||||
#include "Utilities/UnorderedMap.h"
|
||||
|
||||
#include "Player.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
class Player;
|
||||
@@ -38,175 +41,188 @@ extern SQLStorage sSpellThreatStore;
|
||||
|
||||
enum SpellFailedReason
|
||||
{
|
||||
SPELL_FAILED_AFFECTING_COMBAT = 0x00,
|
||||
SPELL_FAILED_ALREADY_AT_FULL_HEALTH = 0x01,
|
||||
SPELL_FAILED_ALREADY_AT_FULL_MANA = 0x02,
|
||||
SPELL_FAILED_ALREADY_AT_FULL_POWER = 0x03,
|
||||
SPELL_FAILED_ALREADY_BEING_TAMED = 0x04,
|
||||
SPELL_FAILED_ALREADY_HAVE_CHARM = 0x05,
|
||||
SPELL_FAILED_ALREADY_HAVE_SUMMON = 0x06,
|
||||
SPELL_FAILED_ALREADY_OPEN = 0x07,
|
||||
SPELL_FAILED_AURA_BOUNCED = 0x08,
|
||||
SPELL_FAILED_AUTOTRACK_INTERRUPTED = 0x09,
|
||||
SPELL_FAILED_BAD_IMPLICIT_TARGETS = 0x0A,
|
||||
SPELL_FAILED_BAD_TARGETS = 0x0B,
|
||||
SPELL_FAILED_CANT_BE_CHARMED = 0x0C,
|
||||
SPELL_FAILED_CANT_BE_DISENCHANTED = 0x0D,
|
||||
SPELL_FAILED_CANT_BE_DISENCHANTED_SKILL = 0x0E,
|
||||
SPELL_FAILED_CANT_BE_PROSPECTED = 0x0F,
|
||||
SPELL_FAILED_CANT_CAST_ON_TAPPED = 0x10,
|
||||
SPELL_FAILED_CANT_DUEL_WHILE_INVISIBLE = 0x11,
|
||||
SPELL_FAILED_CANT_DUEL_WHILE_STEALTHED = 0x12,
|
||||
SPELL_FAILED_CANT_STEALTH = 0x13,
|
||||
SPELL_FAILED_CASTER_AURASTATE = 0x14,
|
||||
SPELL_FAILED_CASTER_DEAD = 0x15,
|
||||
SPELL_FAILED_CHARMED = 0x16,
|
||||
SPELL_FAILED_CHEST_IN_USE = 0x17,
|
||||
SPELL_FAILED_CONFUSED = 0x18,
|
||||
SPELL_FAILED_DONT_REPORT = 0x19,
|
||||
SPELL_FAILED_EQUIPPED_ITEM = 0x1A,
|
||||
SPELL_FAILED_EQUIPPED_ITEM_CLASS = 0x1B,
|
||||
SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND = 0x1C,
|
||||
SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND = 0x1D,
|
||||
SPELL_FAILED_ERROR = 0x1E,
|
||||
SPELL_FAILED_FIZZLE = 0x1F,
|
||||
SPELL_FAILED_FLEEING = 0x20,
|
||||
SPELL_FAILED_FOOD_LOWLEVEL = 0x21,
|
||||
SPELL_FAILED_HIGHLEVEL = 0x22,
|
||||
SPELL_FAILED_HUNGER_SATIATED = 0x23,
|
||||
SPELL_FAILED_IMMUNE = 0x24,
|
||||
SPELL_FAILED_INTERRUPTED = 0x25,
|
||||
SPELL_FAILED_INTERRUPTED_COMBAT = 0x26,
|
||||
SPELL_FAILED_ITEM_ALREADY_ENCHANTED = 0x27,
|
||||
SPELL_FAILED_ITEM_GONE = 0x28,
|
||||
SPELL_FAILED_ITEM_NOT_FOUND = 0x29,
|
||||
SPELL_FAILED_ITEM_NOT_READY = 0x2A,
|
||||
SPELL_FAILED_LEVEL_REQUIREMENT = 0x2B,
|
||||
SPELL_FAILED_LINE_OF_SIGHT = 0x2C,
|
||||
SPELL_FAILED_LOWLEVEL = 0x2D,
|
||||
SPELL_FAILED_LOW_CASTLEVEL = 0x2E,
|
||||
SPELL_FAILED_MAINHAND_EMPTY = 0x2F,
|
||||
SPELL_FAILED_MOVING = 0x30,
|
||||
SPELL_FAILED_NEED_AMMO = 0x31,
|
||||
SPELL_FAILED_NEED_AMMO_POUCH = 0x32,
|
||||
SPELL_FAILED_NEED_EXOTIC_AMMO = 0x33,
|
||||
SPELL_FAILED_NOPATH = 0x34,
|
||||
SPELL_FAILED_NOT_BEHIND = 0x35,
|
||||
SPELL_FAILED_NOT_FISHABLE = 0x36,
|
||||
SPELL_FAILED_NOT_FLYING = 0x37,
|
||||
SPELL_FAILED_NOT_HERE = 0x38,
|
||||
SPELL_FAILED_NOT_INFRONT = 0x39,
|
||||
SPELL_FAILED_NOT_IN_CONTROL = 0x3A,
|
||||
SPELL_FAILED_NOT_KNOWN = 0x3B,
|
||||
SPELL_FAILED_NOT_MOUNTED = 0x3C,
|
||||
SPELL_FAILED_NOT_ON_TAXI = 0x3D,
|
||||
SPELL_FAILED_NOT_ON_TRANSPORT = 0x3E,
|
||||
SPELL_FAILED_NOT_READY = 0x3F,
|
||||
SPELL_FAILED_NOT_SHAPESHIFT = 0x40,
|
||||
SPELL_FAILED_NOT_STANDING = 0x41,
|
||||
SPELL_FAILED_NOT_TRADEABLE = 0x42,
|
||||
SPELL_FAILED_NOT_TRADING = 0x43,
|
||||
SPELL_FAILED_NOT_UNSHEATHED = 0x44,
|
||||
SPELL_FAILED_NOT_WHILE_GHOST = 0x45,
|
||||
SPELL_FAILED_NO_AMMO = 0x46,
|
||||
SPELL_FAILED_NO_CHARGES_REMAIN = 0x47,
|
||||
SPELL_FAILED_NO_CHAMPION = 0x48,
|
||||
SPELL_FAILED_NO_COMBO_POINTS = 0x49,
|
||||
SPELL_FAILED_NO_DUELING = 0x4A,
|
||||
SPELL_FAILED_NO_ENDURANCE = 0x4B,
|
||||
SPELL_FAILED_NO_FISH = 0x4C,
|
||||
SPELL_FAILED_NO_ITEMS_WHILE_SHAPESHIFTED = 0x4D,
|
||||
SPELL_FAILED_NO_MOUNTS_ALLOWED = 0x4E,
|
||||
SPELL_FAILED_NO_PET = 0x4F,
|
||||
SPELL_FAILED_NO_POWER = 0x50,
|
||||
SPELL_FAILED_NOTHING_TO_DISPEL = 0x51,
|
||||
SPELL_FAILED_NOTHING_TO_STEAL = 0x52,
|
||||
SPELL_FAILED_ONLY_ABOVEWATER = 0x53,
|
||||
SPELL_FAILED_ONLY_DAYTIME = 0x54,
|
||||
SPELL_FAILED_ONLY_INDOORS = 0x55,
|
||||
SPELL_FAILED_ONLY_MOUNTED = 0x56,
|
||||
SPELL_FAILED_ONLY_NIGHTTIME = 0x57,
|
||||
SPELL_FAILED_ONLY_OUTDOORS = 0x58,
|
||||
SPELL_FAILED_ONLY_SHAPESHIFT = 0x59,
|
||||
SPELL_FAILED_ONLY_STEALTHED = 0x5A,
|
||||
SPELL_FAILED_ONLY_UNDERWATER = 0x5B,
|
||||
SPELL_FAILED_OUT_OF_RANGE = 0x5C,
|
||||
SPELL_FAILED_PACIFIED = 0x5D,
|
||||
SPELL_FAILED_POSSESSED = 0x5E,
|
||||
SPELL_FAILED_REAGENTS = 0x5F,
|
||||
SPELL_FAILED_REQUIRES_AREA = 0x60,
|
||||
SPELL_FAILED_REQUIRES_SPELL_FOCUS = 0x61,
|
||||
SPELL_FAILED_ROOTED = 0x62,
|
||||
SPELL_FAILED_SILENCED = 0x63,
|
||||
SPELL_FAILED_SPELL_IN_PROGRESS = 0x64,
|
||||
SPELL_FAILED_SPELL_LEARNED = 0x65,
|
||||
SPELL_FAILED_SPELL_UNAVAILABLE = 0x66,
|
||||
SPELL_FAILED_STUNNED = 0x67,
|
||||
SPELL_FAILED_TARGETS_DEAD = 0x68,
|
||||
SPELL_FAILED_TARGET_AFFECTING_COMBAT = 0x69,
|
||||
SPELL_FAILED_TARGET_AURASTATE = 0x6A,
|
||||
SPELL_FAILED_TARGET_DUELING = 0x6B,
|
||||
SPELL_FAILED_TARGET_ENEMY = 0x6C,
|
||||
SPELL_FAILED_TARGET_ENRAGED = 0x6D,
|
||||
SPELL_FAILED_TARGET_FRIENDLY = 0x6E,
|
||||
SPELL_FAILED_TARGET_IN_COMBAT = 0x6F,
|
||||
SPELL_FAILED_TARGET_IS_PLAYER = 0x70,
|
||||
SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED = 0x71,
|
||||
SPELL_FAILED_TARGET_NOT_DEAD = 0x72,
|
||||
SPELL_FAILED_TARGET_NOT_IN_PARTY = 0x73,
|
||||
SPELL_FAILED_TARGET_NOT_LOOTED = 0x74,
|
||||
SPELL_FAILED_TARGET_NOT_PLAYER = 0x75,
|
||||
SPELL_FAILED_TARGET_NO_POCKETS = 0x76,
|
||||
SPELL_FAILED_TARGET_NO_WEAPONS = 0x77,
|
||||
SPELL_FAILED_TARGET_UNSKINNABLE = 0x78,
|
||||
SPELL_FAILED_THIRST_SATIATED = 0x79,
|
||||
SPELL_FAILED_TOO_CLOSE = 0x7A,
|
||||
SPELL_FAILED_TOO_MANY_OF_ITEM = 0x7B,
|
||||
SPELL_FAILED_TOTEM_CATEGORY = 0x7C,
|
||||
SPELL_FAILED_TOTEMS = 0x7D,
|
||||
SPELL_FAILED_TRAINING_POINTS = 0x7E,
|
||||
SPELL_FAILED_TRY_AGAIN = 0x7F,
|
||||
SPELL_FAILED_UNIT_NOT_BEHIND = 0x80,
|
||||
SPELL_FAILED_UNIT_NOT_INFRONT = 0x81,
|
||||
SPELL_FAILED_WRONG_PET_FOOD = 0x82,
|
||||
SPELL_FAILED_NOT_WHILE_FATIGUED = 0x83,
|
||||
SPELL_FAILED_TARGET_NOT_IN_INSTANCE = 0x84,
|
||||
SPELL_FAILED_NOT_WHILE_TRADING = 0x85,
|
||||
SPELL_FAILED_TARGET_NOT_IN_RAID = 0x86,
|
||||
SPELL_FAILED_DISENCHANT_WHILE_LOOTING = 0x87,
|
||||
SPELL_FAILED_PROSPECT_WHILE_LOOTING = 0x88,
|
||||
SPELL_FAILED_PROSPECT_NEED_MORE = 0x89,
|
||||
SPELL_FAILED_TARGET_FREEFORALL = 0x8A,
|
||||
SPELL_FAILED_NO_EDIBLE_CORPSES = 0x8B,
|
||||
SPELL_FAILED_ONLY_BATTLEGROUNDS = 0x8C,
|
||||
SPELL_FAILED_TARGET_NOT_GHOST = 0x8D,
|
||||
SPELL_FAILED_TOO_MANY_SKILLS = 0x8E,
|
||||
SPELL_FAILED_TRANSFORM_UNUSABLE = 0x8F,
|
||||
SPELL_FAILED_WRONG_WEATHER = 0x90,
|
||||
SPELL_FAILED_DAMAGE_IMMUNE = 0x91,
|
||||
SPELL_FAILED_PREVENTED_BY_MECHANIC = 0x92,
|
||||
SPELL_FAILED_PLAY_TIME = 0x93,
|
||||
SPELL_FAILED_REPUTATION = 0x94,
|
||||
SPELL_FAILED_MIN_SKILL = 0x95,
|
||||
SPELL_FAILED_NOT_IN_ARENA = 0x96,
|
||||
SPELL_FAILED_NOT_ON_SHAPESHIFT = 0x97,
|
||||
SPELL_FAILED_NOT_ON_STEALTHED = 0x98,
|
||||
SPELL_FAILED_NOT_ON_DAMAGE_IMMUNE = 0x99,
|
||||
SPELL_FAILED_NOT_ON_MOUNTED = 0x9A,
|
||||
SPELL_FAILED_TOO_SHALLOW = 0x9B,
|
||||
SPELL_FAILED_TARGET_NOT_IN_SANCTUARY = 0x9C,
|
||||
SPELL_FAILED_TARGET_IS_TRIVIAL = 0x9D,
|
||||
SPELL_FAILED_BM_OR_INVISGOD = 0x9E,
|
||||
SPELL_FAILED_EXPERT_RIDING_REQUIREMENT = 0x9F,
|
||||
SPELL_FAILED_ARTISAN_RIDING_REQUIREMENT = 0xA0,
|
||||
SPELL_FAILED_NOT_IDLE = 0xA1,
|
||||
SPELL_FAILED_NOT_INACTIVE = 0xA2,
|
||||
SPELL_FAILED_PARTIAL_PLAYTIME = 0xA3,
|
||||
SPELL_FAILED_NO_PLAYTIME = 0xA4,
|
||||
SPELL_FAILED_NOT_IN_BATTLEGROUND = 0xA5,
|
||||
SPELL_FAILED_ONLY_IN_ARENA = 0xA6,
|
||||
SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE = 0xA7,
|
||||
SPELL_FAILED_UNKNOWN = 0xA8,
|
||||
SPELL_FAILED_AFFECTING_COMBAT = 0,
|
||||
SPELL_FAILED_ALREADY_AT_FULL_HEALTH = 1,
|
||||
SPELL_FAILED_ALREADY_AT_FULL_MANA = 2,
|
||||
SPELL_FAILED_ALREADY_AT_FULL_POWER = 3,
|
||||
SPELL_FAILED_ALREADY_BEING_TAMED = 4,
|
||||
SPELL_FAILED_ALREADY_HAVE_CHARM = 5,
|
||||
SPELL_FAILED_ALREADY_HAVE_SUMMON = 6,
|
||||
SPELL_FAILED_ALREADY_OPEN = 7,
|
||||
SPELL_FAILED_AURA_BOUNCED = 8,
|
||||
SPELL_FAILED_AUTOTRACK_INTERRUPTED = 9,
|
||||
SPELL_FAILED_BAD_IMPLICIT_TARGETS = 10,
|
||||
SPELL_FAILED_BAD_TARGETS = 11,
|
||||
SPELL_FAILED_CANT_BE_CHARMED = 12,
|
||||
SPELL_FAILED_CANT_BE_DISENCHANTED = 13,
|
||||
SPELL_FAILED_CANT_BE_DISENCHANTED_SKILL = 14,
|
||||
SPELL_FAILED_CANT_BE_MILLED = 15,
|
||||
SPELL_FAILED_CANT_BE_PROSPECTED = 16,
|
||||
SPELL_FAILED_CANT_CAST_ON_TAPPED = 17,
|
||||
SPELL_FAILED_CANT_DUEL_WHILE_INVISIBLE = 18,
|
||||
SPELL_FAILED_CANT_DUEL_WHILE_STEALTHED = 19,
|
||||
SPELL_FAILED_CANT_STEALTH = 20,
|
||||
SPELL_FAILED_CASTER_AURASTATE = 21,
|
||||
SPELL_FAILED_CASTER_DEAD = 22,
|
||||
SPELL_FAILED_CHARMED = 23,
|
||||
SPELL_FAILED_CHEST_IN_USE = 24,
|
||||
SPELL_FAILED_CONFUSED = 25,
|
||||
SPELL_FAILED_DONT_REPORT = 26,
|
||||
SPELL_FAILED_EQUIPPED_ITEM = 27,
|
||||
SPELL_FAILED_EQUIPPED_ITEM_CLASS = 28,
|
||||
SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND = 29,
|
||||
SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND = 30,
|
||||
SPELL_FAILED_ERROR = 31,
|
||||
SPELL_FAILED_FIZZLE = 32,
|
||||
SPELL_FAILED_FLEEING = 33,
|
||||
SPELL_FAILED_FOOD_LOWLEVEL = 34,
|
||||
SPELL_FAILED_HIGHLEVEL = 35,
|
||||
SPELL_FAILED_HUNGER_SATIATED = 36,
|
||||
SPELL_FAILED_IMMUNE = 37,
|
||||
SPELL_FAILED_INCORRECT_AREA = 38,
|
||||
SPELL_FAILED_INTERRUPTED = 39,
|
||||
SPELL_FAILED_INTERRUPTED_COMBAT = 40,
|
||||
SPELL_FAILED_ITEM_ALREADY_ENCHANTED = 41,
|
||||
SPELL_FAILED_ITEM_GONE = 42,
|
||||
SPELL_FAILED_ITEM_NOT_FOUND = 43,
|
||||
SPELL_FAILED_ITEM_NOT_READY = 44,
|
||||
SPELL_FAILED_LEVEL_REQUIREMENT = 45,
|
||||
SPELL_FAILED_LINE_OF_SIGHT = 46,
|
||||
SPELL_FAILED_LOWLEVEL = 47,
|
||||
SPELL_FAILED_LOW_CASTLEVEL = 48,
|
||||
SPELL_FAILED_MAINHAND_EMPTY = 49,
|
||||
SPELL_FAILED_MOVING = 50,
|
||||
SPELL_FAILED_NEED_AMMO = 51,
|
||||
SPELL_FAILED_NEED_AMMO_POUCH = 52,
|
||||
SPELL_FAILED_NEED_EXOTIC_AMMO = 53,
|
||||
SPELL_FAILED_NEED_MORE_ITEMS = 54,
|
||||
SPELL_FAILED_NOPATH = 55,
|
||||
SPELL_FAILED_NOT_BEHIND = 56,
|
||||
SPELL_FAILED_NOT_FISHABLE = 57,
|
||||
SPELL_FAILED_NOT_FLYING = 58,
|
||||
SPELL_FAILED_NOT_HERE = 59,
|
||||
SPELL_FAILED_NOT_INFRONT = 60,
|
||||
SPELL_FAILED_NOT_IN_CONTROL = 61,
|
||||
SPELL_FAILED_NOT_KNOWN = 62,
|
||||
SPELL_FAILED_NOT_MOUNTED = 63,
|
||||
SPELL_FAILED_NOT_ON_TAXI = 64,
|
||||
SPELL_FAILED_NOT_ON_TRANSPORT = 65,
|
||||
SPELL_FAILED_NOT_READY = 66,
|
||||
SPELL_FAILED_NOT_SHAPESHIFT = 67,
|
||||
SPELL_FAILED_NOT_STANDING = 68,
|
||||
SPELL_FAILED_NOT_TRADEABLE = 69,
|
||||
SPELL_FAILED_NOT_TRADING = 70,
|
||||
SPELL_FAILED_NOT_UNSHEATHED = 71,
|
||||
SPELL_FAILED_NOT_WHILE_GHOST = 72,
|
||||
SPELL_FAILED_NOT_WHILE_LOOTING = 73,
|
||||
SPELL_FAILED_NO_AMMO = 74,
|
||||
SPELL_FAILED_NO_CHARGES_REMAIN = 75,
|
||||
SPELL_FAILED_NO_CHAMPION = 76,
|
||||
SPELL_FAILED_NO_COMBO_POINTS = 77,
|
||||
SPELL_FAILED_NO_DUELING = 78,
|
||||
SPELL_FAILED_NO_ENDURANCE = 79,
|
||||
SPELL_FAILED_NO_FISH = 80,
|
||||
SPELL_FAILED_NO_ITEMS_WHILE_SHAPESHIFTED = 81,
|
||||
SPELL_FAILED_NO_MOUNTS_ALLOWED = 82,
|
||||
SPELL_FAILED_NO_PET = 83,
|
||||
SPELL_FAILED_NO_POWER = 84,
|
||||
SPELL_FAILED_NOTHING_TO_DISPEL = 85,
|
||||
SPELL_FAILED_NOTHING_TO_STEAL = 86,
|
||||
SPELL_FAILED_ONLY_ABOVEWATER = 87,
|
||||
SPELL_FAILED_ONLY_DAYTIME = 88,
|
||||
SPELL_FAILED_ONLY_INDOORS = 89,
|
||||
SPELL_FAILED_ONLY_MOUNTED = 90,
|
||||
SPELL_FAILED_ONLY_NIGHTTIME = 91,
|
||||
SPELL_FAILED_ONLY_OUTDOORS = 92,
|
||||
SPELL_FAILED_ONLY_SHAPESHIFT = 93,
|
||||
SPELL_FAILED_ONLY_STEALTHED = 94,
|
||||
SPELL_FAILED_ONLY_UNDERWATER = 95,
|
||||
SPELL_FAILED_OUT_OF_RANGE = 96,
|
||||
SPELL_FAILED_PACIFIED = 97,
|
||||
SPELL_FAILED_POSSESSED = 98,
|
||||
SPELL_FAILED_REAGENTS = 99,
|
||||
SPELL_FAILED_REQUIRES_AREA = 100,
|
||||
SPELL_FAILED_REQUIRES_SPELL_FOCUS = 101,
|
||||
SPELL_FAILED_ROOTED = 102,
|
||||
SPELL_FAILED_SILENCED = 103,
|
||||
SPELL_FAILED_SPELL_IN_PROGRESS = 104,
|
||||
SPELL_FAILED_SPELL_LEARNED = 105,
|
||||
SPELL_FAILED_SPELL_UNAVAILABLE = 106,
|
||||
SPELL_FAILED_STUNNED = 107,
|
||||
SPELL_FAILED_TARGETS_DEAD = 108,
|
||||
SPELL_FAILED_TARGET_AFFECTING_COMBAT = 109,
|
||||
SPELL_FAILED_TARGET_AURASTATE = 110,
|
||||
SPELL_FAILED_TARGET_DUELING = 111,
|
||||
SPELL_FAILED_TARGET_ENEMY = 112,
|
||||
SPELL_FAILED_TARGET_ENRAGED = 113,
|
||||
SPELL_FAILED_TARGET_FRIENDLY = 114,
|
||||
SPELL_FAILED_TARGET_IN_COMBAT = 115,
|
||||
SPELL_FAILED_TARGET_IS_PLAYER = 116,
|
||||
SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED = 117,
|
||||
SPELL_FAILED_TARGET_NOT_DEAD = 118,
|
||||
SPELL_FAILED_TARGET_NOT_IN_PARTY = 119,
|
||||
SPELL_FAILED_TARGET_NOT_LOOTED = 120,
|
||||
SPELL_FAILED_TARGET_NOT_PLAYER = 121,
|
||||
SPELL_FAILED_TARGET_NO_POCKETS = 122,
|
||||
SPELL_FAILED_TARGET_NO_WEAPONS = 123,
|
||||
SPELL_FAILED_TARGET_NO_RANGED_WEAPONS = 124,
|
||||
SPELL_FAILED_TARGET_UNSKINNABLE = 125,
|
||||
SPELL_FAILED_THIRST_SATIATED = 126,
|
||||
SPELL_FAILED_TOO_CLOSE = 127,
|
||||
SPELL_FAILED_TOO_MANY_OF_ITEM = 128,
|
||||
SPELL_FAILED_TOTEM_CATEGORY = 129,
|
||||
SPELL_FAILED_TOTEMS = 130,
|
||||
SPELL_FAILED_TRY_AGAIN = 131,
|
||||
SPELL_FAILED_UNIT_NOT_BEHIND = 132,
|
||||
SPELL_FAILED_UNIT_NOT_INFRONT = 133,
|
||||
SPELL_FAILED_WRONG_PET_FOOD = 134,
|
||||
SPELL_FAILED_NOT_WHILE_FATIGUED = 135,
|
||||
SPELL_FAILED_TARGET_NOT_IN_INSTANCE = 136,
|
||||
SPELL_FAILED_NOT_WHILE_TRADING = 137,
|
||||
SPELL_FAILED_TARGET_NOT_IN_RAID = 138,
|
||||
SPELL_FAILED_TARGET_FREEFORALL = 139,
|
||||
SPELL_FAILED_NO_EDIBLE_CORPSES = 140,
|
||||
SPELL_FAILED_ONLY_BATTLEGROUNDS = 141,
|
||||
SPELL_FAILED_TARGET_NOT_GHOST = 142,
|
||||
SPELL_FAILED_TRANSFORM_UNUSABLE = 143,
|
||||
SPELL_FAILED_WRONG_WEATHER = 144,
|
||||
SPELL_FAILED_DAMAGE_IMMUNE = 145,
|
||||
SPELL_FAILED_PREVENTED_BY_MECHANIC = 146,
|
||||
SPELL_FAILED_PLAY_TIME = 147,
|
||||
SPELL_FAILED_REPUTATION = 148,
|
||||
SPELL_FAILED_MIN_SKILL = 149,
|
||||
SPELL_FAILED_NOT_IN_ARENA = 150,
|
||||
SPELL_FAILED_NOT_ON_SHAPESHIFT = 151,
|
||||
SPELL_FAILED_NOT_ON_STEALTHED = 152,
|
||||
SPELL_FAILED_NOT_ON_DAMAGE_IMMUNE = 153,
|
||||
SPELL_FAILED_NOT_ON_MOUNTED = 154,
|
||||
SPELL_FAILED_TOO_SHALLOW = 155,
|
||||
SPELL_FAILED_TARGET_NOT_IN_SANCTUARY = 156,
|
||||
SPELL_FAILED_TARGET_IS_TRIVIAL = 157,
|
||||
SPELL_FAILED_BM_OR_INVISGOD = 158,
|
||||
SPELL_FAILED_EXPERT_RIDING_REQUIREMENT = 159,
|
||||
SPELL_FAILED_ARTISAN_RIDING_REQUIREMENT = 160,
|
||||
SPELL_FAILED_NOT_IDLE = 161,
|
||||
SPELL_FAILED_NOT_INACTIVE = 162,
|
||||
SPELL_FAILED_PARTIAL_PLAYTIME = 163,
|
||||
SPELL_FAILED_NO_PLAYTIME = 164,
|
||||
SPELL_FAILED_NOT_IN_BATTLEGROUND = 165,
|
||||
SPELL_FAILED_NOT_IN_RAID_INSTANCE = 166,
|
||||
SPELL_FAILED_ONLY_IN_ARENA = 167,
|
||||
SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE = 168,
|
||||
SPELL_FAILED_ON_USE_ENCHANT = 169,
|
||||
SPELL_FAILED_NOT_ON_GROUND = 170,
|
||||
SPELL_FAILED_CUSTOM_ERROR = 171,
|
||||
SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW = 172,
|
||||
SPELL_FAILED_TOO_MANY_SOCKETS = 173,
|
||||
SPELL_FAILED_INVALID_GLYPH = 174,
|
||||
SPELL_FAILED_UNIQUE_GLYPH = 175,
|
||||
SPELL_FAILED_GLYPH_SOCKET_LOCKED = 176,
|
||||
SPELL_FAILED_NO_VALID_TARGETS = 177,
|
||||
SPELL_FAILED_ITEM_AT_MAX_CHARGES = 178,
|
||||
SPELL_FAILED_NOT_IN_BARBERSHOP = 179,
|
||||
SPELL_FAILED_FISHING_TOO_LOW = 180,
|
||||
SPELL_FAILED_UNKNOWN = 181
|
||||
};
|
||||
|
||||
enum SpellFamilyNames
|
||||
@@ -223,8 +239,12 @@ enum SpellFamilyNames
|
||||
SPELLFAMILY_HUNTER = 9,
|
||||
SPELLFAMILY_PALADIN = 10,
|
||||
SPELLFAMILY_SHAMAN = 11,
|
||||
SPELLFAMILY_UNK2 = 12,
|
||||
SPELLFAMILY_POTION = 13
|
||||
SPELLFAMILY_UNK2 = 12, // 2 spells (silence resistance)
|
||||
SPELLFAMILY_POTION = 13,
|
||||
// 14 - unused
|
||||
SPELLFAMILY_DEATHKNIGHT = 15,
|
||||
// 16 - unused
|
||||
SPELLFAMILY_PET = 17
|
||||
};
|
||||
|
||||
enum SpellDisableTypes
|
||||
@@ -397,6 +417,7 @@ inline bool IsAreaOfEffectSpell(SpellEntry const *spellInfo)
|
||||
inline bool IsAreaAuraEffect(uint32 effect)
|
||||
{
|
||||
if( effect == SPELL_EFFECT_APPLY_AREA_AURA_PARTY ||
|
||||
effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID ||
|
||||
effect == SPELL_EFFECT_APPLY_AREA_AURA_FRIEND ||
|
||||
effect == SPELL_EFFECT_APPLY_AREA_AURA_ENEMY ||
|
||||
effect == SPELL_EFFECT_APPLY_AREA_AURA_PET ||
|
||||
@@ -469,7 +490,11 @@ bool IsDiminishingReturnsGroupDurationLimited(DiminishingGroup group);
|
||||
DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group);
|
||||
|
||||
// Spell affects related declarations (accessed using SpellMgr functions)
|
||||
typedef std::map<uint32, uint64> SpellAffectMap;
|
||||
struct SpellAffectEntry
|
||||
{
|
||||
uint32 SpellClassMask[3];
|
||||
};
|
||||
typedef UNORDERED_MAP<uint32, SpellAffectEntry> SpellAffectMap;
|
||||
|
||||
// Spell proc event related declarations (accessed using SpellMgr functions)
|
||||
enum ProcFlags
|
||||
@@ -687,6 +712,9 @@ typedef std::multimap<uint32, SpellLearnSpellNode> SpellLearnSpellMap;
|
||||
|
||||
typedef std::multimap<uint32, SkillLineAbilityEntry const*> SkillLineAbilityMap;
|
||||
|
||||
typedef std::map<uint32, uint32> PetLevelupSpellSet;
|
||||
typedef std::map<uint32, PetLevelupSpellSet> PetLevelupSpellMap;
|
||||
|
||||
inline bool IsPrimaryProfessionSkill(uint32 skill)
|
||||
{
|
||||
SkillLineEntry const *pSkill = sSkillLineStore.LookupEntry(skill);
|
||||
@@ -727,15 +755,15 @@ class SpellMgr
|
||||
// Accessors (const or static functions)
|
||||
public:
|
||||
// Spell affects
|
||||
uint64 GetSpellAffectMask(uint16 spellId, uint8 effectId) const
|
||||
SpellAffectEntry const*GetSpellAffect(uint16 spellId, uint8 effectId) const
|
||||
{
|
||||
SpellAffectMap::const_iterator itr = mSpellAffectMap.find((spellId<<8) + effectId);
|
||||
if( itr != mSpellAffectMap.end( ) )
|
||||
return itr->second;
|
||||
return &itr->second;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool IsAffectedBySpell(SpellEntry const *spellInfo, uint32 spellId, uint8 effectId, uint64 familyFlags) const;
|
||||
bool IsAffectedByMod(SpellEntry const *spellInfo, SpellModifier *mod) const;
|
||||
|
||||
SpellElixirMap const& GetSpellElixirMap() const { return mSpellElixirs; }
|
||||
|
||||
@@ -938,11 +966,6 @@ class SpellMgr
|
||||
return 0;
|
||||
else
|
||||
return mSpellCustomAttr[spell_id];
|
||||
/*SpellCustomAttrMap::const_iterator itr = mSpellCustomAttrMap.find(spell_id);
|
||||
if(itr != mSpellCustomAttrMap.end())
|
||||
return itr->second;
|
||||
else
|
||||
return 0;*/
|
||||
}
|
||||
|
||||
const std::vector<int32> *GetSpellLinked(int32 spell_id) const
|
||||
@@ -954,6 +977,15 @@ class SpellMgr
|
||||
SpellEffectTargetTypes EffectTargetType[TOTAL_SPELL_EFFECTS];
|
||||
SpellSelectTargetTypes SpellTargetType[TOTAL_SPELL_TARGETS];
|
||||
|
||||
PetLevelupSpellSet const* GetPetLevelupSpellList(uint32 petFamily) const
|
||||
{
|
||||
PetLevelupSpellMap::const_iterator itr = mPetLevelupSpellMap.find(petFamily);
|
||||
if(itr != mPetLevelupSpellMap.end())
|
||||
return &itr->second;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Modifiers
|
||||
public:
|
||||
static SpellMgr& Instance();
|
||||
@@ -973,6 +1005,7 @@ class SpellMgr
|
||||
void LoadSpellPetAuras();
|
||||
void LoadSpellCustomAttr();
|
||||
void LoadSpellLinked();
|
||||
void LoadPetLevelupSpellMap();
|
||||
|
||||
private:
|
||||
SpellScriptTarget mSpellScriptTarget;
|
||||
@@ -989,6 +1022,7 @@ class SpellMgr
|
||||
SpellPetAuraMap mSpellPetAuraMap;
|
||||
SpellCustomAttribute mSpellCustomAttr;
|
||||
SpellLinkedMap mSpellLinkedMap;
|
||||
PetLevelupSpellMap mPetLevelupSpellMap;
|
||||
};
|
||||
|
||||
#define spellmgr SpellMgr::Instance()
|
||||
|
||||
+52
-14
@@ -51,24 +51,17 @@ bool Player::UpdateStats(Stats stat)
|
||||
switch(stat)
|
||||
{
|
||||
case STAT_STRENGTH:
|
||||
UpdateAttackPowerAndDamage();
|
||||
UpdateShieldBlockValue();
|
||||
break;
|
||||
case STAT_AGILITY:
|
||||
UpdateArmor();
|
||||
UpdateAttackPowerAndDamage(true);
|
||||
if(getClass() == CLASS_ROGUE || getClass() == CLASS_HUNTER || getClass() == CLASS_DRUID && m_form==FORM_CAT)
|
||||
UpdateAttackPowerAndDamage();
|
||||
|
||||
UpdateAllCritPercentages();
|
||||
UpdateDodgePercentage();
|
||||
break;
|
||||
|
||||
case STAT_STAMINA: UpdateMaxHealth(); break;
|
||||
case STAT_INTELLECT:
|
||||
UpdateMaxPower(POWER_MANA);
|
||||
UpdateAllSpellCritChances();
|
||||
UpdateAttackPowerAndDamage(true); //SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT, only intellect currently
|
||||
UpdateArmor(); //SPELL_AURA_MOD_RESISTANCE_OF_INTELLECT_PERCENT, only armor currently
|
||||
break;
|
||||
|
||||
@@ -78,8 +71,25 @@ bool Player::UpdateStats(Stats stat)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// Need update (exist AP from stat auras)
|
||||
UpdateAttackPowerAndDamage();
|
||||
UpdateAttackPowerAndDamage(true);
|
||||
|
||||
UpdateSpellDamageAndHealingBonus();
|
||||
UpdateManaRegen();
|
||||
|
||||
// Update ratings in exist SPELL_AURA_MOD_RATING_FROM_STAT and only depends from stat
|
||||
uint32 mask = 0;
|
||||
AuraList const& modRatingFromStat = GetAurasByType(SPELL_AURA_MOD_RATING_FROM_STAT);
|
||||
for(AuraList::const_iterator i = modRatingFromStat.begin();i != modRatingFromStat.end(); ++i)
|
||||
if (Stats((*i)->GetMiscBValue()) == stat)
|
||||
mask |= (*i)->GetMiscValue();
|
||||
if (mask)
|
||||
{
|
||||
for (uint32 rating = 0; rating < MAX_COMBAT_RATING; ++rating)
|
||||
if (mask & (1 << rating))
|
||||
ApplyRatingMod(CombatRating(rating), 0, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -255,6 +265,7 @@ void Player::UpdateAttackPowerAndDamage(bool ranged )
|
||||
{
|
||||
case CLASS_WARRIOR: val2 = level*3.0f + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break;
|
||||
case CLASS_PALADIN: val2 = level*3.0f + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break;
|
||||
case CLASS_DEATH_KNIGHT: val2 = level*3.0f + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break;
|
||||
case CLASS_ROGUE: val2 = level*2.0f + GetStat(STAT_STRENGTH) + GetStat(STAT_AGILITY) - 20.0f; break;
|
||||
case CLASS_HUNTER: val2 = level*2.0f + GetStat(STAT_STRENGTH) + GetStat(STAT_AGILITY) - 20.0f; break;
|
||||
case CLASS_SHAMAN: val2 = level*2.0f + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break;
|
||||
@@ -309,11 +320,20 @@ void Player::UpdateAttackPowerAndDamage(bool ranged )
|
||||
float attPowerMod = GetModifierValue(unitMod, TOTAL_VALUE);
|
||||
|
||||
//add dynamic flat mods
|
||||
if( ranged && (getClassMask() & CLASSMASK_WAND_USERS)==0)
|
||||
if ((getClassMask() & CLASSMASK_WAND_USERS)==0)
|
||||
{
|
||||
AuraList const& mRAPbyIntellect = GetAurasByType(SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT);
|
||||
for(AuraList::const_iterator i = mRAPbyIntellect.begin();i != mRAPbyIntellect.end(); ++i)
|
||||
attPowerMod += int32(GetStat(Stats((*i)->GetModifier()->m_miscvalue)) * (*i)->GetModifierValue() / 100.0f);
|
||||
if( ranged )
|
||||
{
|
||||
AuraList const& mRAPbyIntellect = GetAurasByType(SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT);
|
||||
for(AuraList::const_iterator i = mRAPbyIntellect.begin();i != mRAPbyIntellect.end(); ++i)
|
||||
attPowerMod += int32(GetStat(Stats((*i)->GetModifier()->m_miscvalue)) * (*i)->GetModifier()->m_amount / 100.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
AuraList const& mRAPbyIntellect = GetAurasByType(SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT);
|
||||
for(AuraList::const_iterator i = mRAPbyIntellect.begin();i != mRAPbyIntellect.end(); ++i)
|
||||
attPowerMod += int32(GetStat(Stats((*i)->GetModifier()->m_miscvalue)) * (*i)->GetModifier()->m_amount / 100.0f);
|
||||
}
|
||||
}
|
||||
|
||||
float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f;
|
||||
@@ -554,6 +574,24 @@ void Player::UpdateSpellCritChance(uint32 school)
|
||||
SetFloatValue(PLAYER_SPELL_CRIT_PERCENTAGE1 + school, crit);
|
||||
}
|
||||
|
||||
void Player::UpdateMeleeHitChances()
|
||||
{
|
||||
m_modMeleeHitChance = GetTotalAuraModifier(SPELL_AURA_MOD_HIT_CHANCE);
|
||||
m_modMeleeHitChance+= GetRatingBonusValue(CR_HIT_MELEE);
|
||||
}
|
||||
|
||||
void Player::UpdateRangedHitChances()
|
||||
{
|
||||
m_modRangedHitChance = GetTotalAuraModifier(SPELL_AURA_MOD_HIT_CHANCE);
|
||||
m_modRangedHitChance+= GetRatingBonusValue(CR_HIT_RANGED);
|
||||
}
|
||||
|
||||
void Player::UpdateSpellHitChances()
|
||||
{
|
||||
m_modSpellHitChance = GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE);
|
||||
m_modSpellHitChance+= GetRatingBonusValue(CR_HIT_SPELL);
|
||||
}
|
||||
|
||||
void Player::UpdateAllSpellCritChances()
|
||||
{
|
||||
for (int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; i++)
|
||||
@@ -624,9 +662,9 @@ void Player::UpdateManaRegen()
|
||||
int32 modManaRegenInterrupt = GetTotalAuraModifier(SPELL_AURA_MOD_MANA_REGEN_INTERRUPT);
|
||||
if (modManaRegenInterrupt > 100)
|
||||
modManaRegenInterrupt = 100;
|
||||
SetStatFloatValue(PLAYER_FIELD_MOD_MANA_REGEN_INTERRUPT, power_regen_mp5 + power_regen * modManaRegenInterrupt / 100.0f);
|
||||
SetStatFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER, power_regen_mp5 + power_regen * modManaRegenInterrupt / 100.0f);
|
||||
|
||||
SetStatFloatValue(PLAYER_FIELD_MOD_MANA_REGEN, power_regen_mp5 + power_regen);
|
||||
SetStatFloatValue(UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER, power_regen_mp5 + power_regen);
|
||||
}
|
||||
|
||||
void Player::_ApplyAllStatBonuses()
|
||||
@@ -923,7 +961,7 @@ void Pet::UpdateAttackPowerAndDamage(bool ranged)
|
||||
if(getPetType() == HUNTER_PET) //hunter pets benefit from owner's attack power
|
||||
{
|
||||
bonusAP = owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.22f;
|
||||
SetBonusDamage( int32(owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.125f));
|
||||
SetBonusDamage( int32(owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.1287f));
|
||||
}
|
||||
//demons benefit from warlocks shadow or fire damage
|
||||
else if(getPetType() == SUMMON_PET && owner->getClass() == CLASS_WARLOCK)
|
||||
|
||||
@@ -71,7 +71,7 @@ void WorldSession::SendTaxiStatus( uint64 guid )
|
||||
sLog.outDebug( "WORLD: Sent SMSG_TAXINODE_STATUS" );
|
||||
}
|
||||
|
||||
void WorldSession::HandleTaxiQueryAvailableNodesOpcode( WorldPacket & recv_data )
|
||||
void WorldSession::HandleTaxiQueryAvailableNodes( WorldPacket & recv_data )
|
||||
{
|
||||
CHECK_PACKET_SIZE(recv_data,8);
|
||||
|
||||
|
||||
@@ -137,7 +137,7 @@ void MapManager::LoadTransports()
|
||||
Transport::Transport() : GameObject()
|
||||
{
|
||||
// 2.3.2 - 0x5A
|
||||
m_updateFlag = (UPDATEFLAG_TRANSPORT | UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HASPOSITION);
|
||||
m_updateFlag = (UPDATEFLAG_TRANSPORT | UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION);
|
||||
}
|
||||
|
||||
bool Transport::Create(uint32 guidlow, uint32 mapid, float x, float y, float z, float ang, uint32 animprogress, uint32 dynflags)
|
||||
@@ -168,9 +168,10 @@ bool Transport::Create(uint32 guidlow, uint32 mapid, float x, float y, float z,
|
||||
SetFloatValue(OBJECT_FIELD_SCALE_X, goinfo->size);
|
||||
|
||||
SetUInt32Value(GAMEOBJECT_FACTION, goinfo->faction);
|
||||
SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags);
|
||||
|
||||
SetUInt32Value(OBJECT_FIELD_ENTRY, goinfo->id);
|
||||
//SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags);
|
||||
SetUInt32Value(GAMEOBJECT_FLAGS, MAKE_PAIR32(0x28, 0x64));
|
||||
SetUInt32Value(GAMEOBJECT_LEVEL, m_period);
|
||||
SetEntry(goinfo->id);
|
||||
|
||||
SetUInt32Value(GAMEOBJECT_DISPLAYID, goinfo->displayId);
|
||||
|
||||
@@ -179,7 +180,7 @@ bool Transport::Create(uint32 guidlow, uint32 mapid, float x, float y, float z,
|
||||
|
||||
SetGoAnimProgress(animprogress);
|
||||
if(dynflags)
|
||||
SetUInt32Value(GAMEOBJECT_DYN_FLAGS, dynflags);
|
||||
SetUInt32Value(GAMEOBJECT_DYNAMIC, MAKE_PAIR32(0, dynflags));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
+226
-105
@@ -60,6 +60,7 @@ float baseMoveSpeed[MAX_MOVE_TYPE] =
|
||||
3.141594f, // MOVE_TURN_RATE
|
||||
7.0f, // MOVE_FLIGHT
|
||||
4.5f, // MOVE_FLIGHT_BACK
|
||||
3.14f // MOVE_PITCH_RATE
|
||||
};
|
||||
|
||||
void InitTriggerAuraData();
|
||||
@@ -154,7 +155,7 @@ Unit::Unit()
|
||||
m_objectType |= TYPEMASK_UNIT;
|
||||
m_objectTypeId = TYPEID_UNIT;
|
||||
// 2.3.2 - 0x70
|
||||
m_updateFlag = (UPDATEFLAG_HIGHGUID | UPDATEFLAG_LIVING | UPDATEFLAG_HASPOSITION);
|
||||
m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_LIVING | UPDATEFLAG_HAS_POSITION);
|
||||
|
||||
m_attackTimer[BASE_ATTACK] = 0;
|
||||
m_attackTimer[OFF_ATTACK] = 0;
|
||||
@@ -1631,7 +1632,7 @@ void Unit::DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss)
|
||||
if( spellInfo->AttributesEx3 & 0x40000 && spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && ((*itr).second->GetCasterGUID() == GetGUID()))
|
||||
{
|
||||
(*itr).second->SetAuraDuration((*itr).second->GetAuraMaxDuration());
|
||||
(*itr).second->UpdateAuraDuration();
|
||||
(*itr).second->SendAuraUpdate(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1947,7 +1948,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo *damageInfo, bool durabilityLoss)
|
||||
if( spellInfo->AttributesEx3 & 0x40000 && spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && ((*itr).second->GetCasterGUID() == GetGUID()))
|
||||
{
|
||||
(*itr).second->SetAuraDuration((*itr).second->GetAuraMaxDuration());
|
||||
(*itr).second->UpdateAuraDuration();
|
||||
(*itr).second->SendAuraUpdate(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2342,9 +2343,7 @@ void Unit::DoAttackDamage (Unit *pVictim, uint32 *damage, CleanDamage *cleanDama
|
||||
case MELEE_HIT_BLOCK_CRIT:
|
||||
case MELEE_HIT_CRIT:
|
||||
{
|
||||
//*hitInfo = 0xEA;
|
||||
// 0xEA
|
||||
*hitInfo = HITINFO_CRITICALHIT | HITINFO_NORMALSWING2 | 0x8;
|
||||
*hitInfo = HITINFO_CRITICALHIT | HITINFO_NORMALSWING2 | HITINFO_UNK2;
|
||||
|
||||
// Crit bonus calc
|
||||
uint32 crit_bonus;
|
||||
@@ -2581,10 +2580,62 @@ void Unit::DoAttackDamage (Unit *pVictim, uint32 *damage, CleanDamage *cleanDama
|
||||
}
|
||||
case MELEE_HIT_GLANCING:
|
||||
{
|
||||
<<<<<<< HEAD:src/game/Unit.cpp
|
||||
int32 leveldif = int32(pVictim->getLevel()) - int32(getLevel());
|
||||
if (leveldif > 3) leveldif = 3;
|
||||
*damage *= (1 - leveldif * 0.1f);
|
||||
cleanDamage->damage = *damage;
|
||||
=======
|
||||
float reducePercent = 1.0f; //damage factor
|
||||
|
||||
// calculate base values and mods
|
||||
float baseLowEnd = 1.3;
|
||||
float baseHighEnd = 1.2;
|
||||
switch(getClass()) // lowering base values for casters
|
||||
{
|
||||
case CLASS_SHAMAN:
|
||||
case CLASS_PRIEST:
|
||||
case CLASS_MAGE:
|
||||
case CLASS_WARLOCK:
|
||||
case CLASS_DRUID:
|
||||
baseLowEnd -= 0.7;
|
||||
baseHighEnd -= 0.3;
|
||||
break;
|
||||
}
|
||||
|
||||
float maxLowEnd = 0.6;
|
||||
switch(getClass()) // upper for melee classes
|
||||
{
|
||||
case CLASS_WARRIOR:
|
||||
case CLASS_ROGUE:
|
||||
case CLASS_DEATH_KNIGHT:
|
||||
maxLowEnd = 0.91; //If the attacker is a melee class then instead the lower value of 0.91
|
||||
}
|
||||
|
||||
// calculate values
|
||||
int32 diff = int32(pVictim->GetDefenseSkillValue(this)) - int32(GetWeaponSkillValue(attType,pVictim));
|
||||
float lowEnd = baseLowEnd - ( 0.05f * diff );
|
||||
float highEnd = baseHighEnd - ( 0.03f * diff );
|
||||
|
||||
// apply max/min bounds
|
||||
if ( lowEnd < 0.01f ) //the low end must not go bellow 0.01f
|
||||
lowEnd = 0.01f;
|
||||
else if ( lowEnd > maxLowEnd ) //the smaller value of this and 0.6 is kept as the low end
|
||||
lowEnd = maxLowEnd;
|
||||
|
||||
if ( highEnd < 0.2f ) //high end limits
|
||||
highEnd = 0.2f;
|
||||
if ( highEnd > 0.99f )
|
||||
highEnd = 0.99f;
|
||||
|
||||
if(lowEnd > highEnd) // prevent negative range size
|
||||
lowEnd = highEnd;
|
||||
|
||||
reducePercent = lowEnd + rand_norm() * ( highEnd - lowEnd );
|
||||
|
||||
*damage = uint32(reducePercent * *damage);
|
||||
cleanDamage->damage += *damage;
|
||||
>>>>>>> upstream/master:src/game/Unit.cpp
|
||||
*hitInfo |= HITINFO_GLANCING;
|
||||
break;
|
||||
}
|
||||
@@ -2633,7 +2684,7 @@ void Unit::DoAttackDamage (Unit *pVictim, uint32 *damage, CleanDamage *cleanDama
|
||||
((*itr).second->GetCasterGUID() == GetGUID() && (!spellCasted || spellCasted->Id == 35395)) )
|
||||
{
|
||||
(*itr).second->SetAuraDuration((*itr).second->GetAuraMaxDuration());
|
||||
(*itr).second->UpdateAuraDuration();
|
||||
(*itr).second->SendAuraUpdate(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2758,21 +2809,20 @@ MeleeHitOutcome Unit::RollPhysicalOutcomeAgainst (Unit const *pVictim, WeaponAtt
|
||||
{
|
||||
// Increase from SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL aura
|
||||
crit_chance += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL, spellInfo->SchoolMask);
|
||||
|
||||
if( dodge_chance != 0.0f ) // if dodge chance is already 0, ignore talents for speed
|
||||
// Ignore combat result aura
|
||||
AuraList const& ignore = GetAurasByType(SPELL_AURA_IGNORE_COMBAT_RESULT);
|
||||
for(AuraList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
|
||||
{
|
||||
AuraList const& mCanNotBeDodge = GetAurasByType(SPELL_AURA_IGNORE_COMBAT_RESULT);
|
||||
for(AuraList::const_iterator i = mCanNotBeDodge.begin(); i != mCanNotBeDodge.end(); ++i)
|
||||
if (!(*i)->isAffectedOnSpell(spellInfo))
|
||||
continue;
|
||||
switch((*i)->GetModifier()->m_miscvalue)
|
||||
{
|
||||
// can't be dodged rogue finishing move
|
||||
if((*i)->GetModifier()->m_miscvalue == VICTIMSTATE_DODGE)
|
||||
{
|
||||
if(spellInfo->SpellFamilyName==SPELLFAMILY_ROGUE && (spellInfo->SpellFamilyFlags & SPELLFAMILYFLAG_ROGUE__FINISHING_MOVE))
|
||||
{
|
||||
dodge_chance = 0.0f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
case MELEE_HIT_DODGE: dodge_chance = 0.0f; break;
|
||||
case MELEE_HIT_BLOCK: block_chance = 0.0f; break;
|
||||
case MELEE_HIT_PARRY: parry_chance = 0.0f; break;
|
||||
default:
|
||||
DEBUG_LOG("Spell %u SPELL_AURA_IGNORE_COMBAT_RESULT have unhandled state %d", (*i)->GetId(), (*i)->GetModifier()->m_miscvalue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4738,7 +4788,7 @@ void Unit::DelayAura(uint32 spellId, uint32 effindex, int32 delaytime)
|
||||
iter->second->SetAuraDuration(0);
|
||||
else
|
||||
iter->second->SetAuraDuration(iter->second->GetAuraDuration() - delaytime);
|
||||
iter->second->UpdateAuraDuration();
|
||||
iter->second->SendAuraUpdate(false);
|
||||
sLog.outDebug("Aura %u partially interrupted on unit %u, new duration: %u ms",iter->second->GetModifier()->m_auraname, GetGUIDLow(), iter->second->GetAuraDuration());
|
||||
}
|
||||
}
|
||||
@@ -4930,6 +4980,7 @@ void Unit::SendSpellNonMeleeDamageLog(Unit *target,uint32 SpellID,uint32 Damage,
|
||||
data.append(GetPackGUID());
|
||||
data << uint32(SpellID);
|
||||
data << uint32(Damage-AbsorbedDamage-Resist-Blocked);
|
||||
data << uint32(0); // wotlk
|
||||
data << uint8(damageSchoolMask); // spell school
|
||||
data << uint32(AbsorbedDamage); // AbsorbedDamage
|
||||
data << uint32(Resist); // resist
|
||||
@@ -4994,31 +5045,66 @@ void Unit::SendAttackStateUpdate(uint32 HitInfo, Unit *target, uint8 SwingType,
|
||||
sLog.outDebug("WORLD: Sending SMSG_ATTACKERSTATEUPDATE");
|
||||
|
||||
WorldPacket data(SMSG_ATTACKERSTATEUPDATE, (16+45)); // we guess size
|
||||
data << (uint32)HitInfo;
|
||||
data << uint32(HitInfo); // flags
|
||||
data.append(GetPackGUID());
|
||||
data.append(target->GetPackGUID());
|
||||
data << (uint32)(Damage-AbsorbDamage-Resist-BlockedAmount);
|
||||
data << uint32(Damage-AbsorbDamage-Resist-BlockedAmount);// damage
|
||||
data << uint32(0); // overkill value
|
||||
|
||||
data << (uint8)SwingType; // count?
|
||||
|
||||
// for(i = 0; i < SwingType; ++i)
|
||||
data << (uint32)damageSchoolMask;
|
||||
data << (float)(Damage-AbsorbDamage-Resist-BlockedAmount);
|
||||
// still need to double check damage
|
||||
data << (uint32)(Damage-AbsorbDamage-Resist-BlockedAmount);
|
||||
data << (uint32)AbsorbDamage;
|
||||
data << (uint32)Resist;
|
||||
// end loop
|
||||
|
||||
data << (uint32)TargetState;
|
||||
if(HitInfo & (HITINFO_ABSORB | HITINFO_ABSORB2))
|
||||
{
|
||||
// for(i = 0; i < SwingType; ++i)
|
||||
data << uint32(AbsorbDamage);
|
||||
// end loop
|
||||
}
|
||||
|
||||
if( AbsorbDamage == 0 ) //also 0x3E8 = 0x3E8, check when that happens
|
||||
data << (uint32)0;
|
||||
else
|
||||
data << (uint32)-1;
|
||||
if(HitInfo & (HITINFO_RESIST | HITINFO_RESIST2))
|
||||
{
|
||||
// for(i = 0; i < SwingType; ++i)
|
||||
data << uint32(Resist);
|
||||
// end loop
|
||||
}
|
||||
|
||||
data << (uint8)TargetState;
|
||||
data << (uint32)0;
|
||||
data << (uint32)BlockedAmount;
|
||||
data << (uint32)0;
|
||||
|
||||
if(HitInfo & HITINFO_BLOCK)
|
||||
{
|
||||
data << uint32(BlockedAmount);
|
||||
}
|
||||
|
||||
if(HitInfo & HITINFO_UNK3)
|
||||
{
|
||||
data << uint32(0);
|
||||
}
|
||||
|
||||
if(HitInfo & HITINFO_UNK1)
|
||||
{
|
||||
data << uint32(0);
|
||||
data << float(0);
|
||||
data << float(0);
|
||||
data << float(0);
|
||||
data << float(0);
|
||||
data << float(0);
|
||||
data << float(0);
|
||||
data << float(0);
|
||||
data << float(0);
|
||||
for(uint8 i = 0; i < 5; ++i)
|
||||
{
|
||||
data << float(0);
|
||||
data << float(0);
|
||||
}
|
||||
data << uint32(0);
|
||||
}
|
||||
|
||||
SendMessageToSet( &data, true );
|
||||
}
|
||||
@@ -5239,7 +5325,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
|
||||
{
|
||||
switch (dummySpell->Id)
|
||||
{
|
||||
// Eye of Eye
|
||||
// Eye for an Eye
|
||||
case 9799:
|
||||
case 25988:
|
||||
{
|
||||
@@ -5856,7 +5942,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
|
||||
triggered_spell_id = 39373;
|
||||
break;
|
||||
}
|
||||
// Vestments of Faith (Priest Tier 3) - 4 pieces bonus
|
||||
// Greater Heal (Vestments of Faith (Priest Tier 3) - 4 pieces bonus)
|
||||
case 28809:
|
||||
{
|
||||
triggered_spell_id = 28810;
|
||||
@@ -5993,6 +6079,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
|
||||
}
|
||||
case SPELLFAMILY_PALADIN:
|
||||
{
|
||||
// TODO: spell list, formula change in 3.0.3
|
||||
// Seal of Righteousness - melee proc dummy
|
||||
if (dummySpell->SpellFamilyFlags&0x000000008000000LL && triggeredByAura->GetEffIndex()==0)
|
||||
{
|
||||
@@ -6089,7 +6176,8 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
|
||||
}
|
||||
break;
|
||||
}
|
||||
//Seal of Vengeance
|
||||
// TODO: fix basepoint calculation (changed in 3.0.3)
|
||||
// Seal of Vengeance
|
||||
case 31801:
|
||||
{
|
||||
if(effIndex != 0) // effect 1,2 used by seal unleashing code
|
||||
@@ -6098,7 +6186,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
|
||||
triggered_spell_id = 31803;
|
||||
break;
|
||||
}
|
||||
// Spiritual Att.
|
||||
// Spiritual Attunement
|
||||
case 31785:
|
||||
case 33776:
|
||||
{
|
||||
@@ -6282,7 +6370,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
|
||||
}
|
||||
|
||||
// Earth Shield
|
||||
if(dummySpell->SpellFamilyFlags==0x40000000000LL)
|
||||
if(dummySpell->SpellFamilyFlags & 0x0000040000000000LL)
|
||||
{
|
||||
if(GetTypeId() != TYPEID_PLAYER)
|
||||
return false;
|
||||
@@ -6320,6 +6408,8 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
|
||||
case 15208: spellId = 45294; break; // Rank 10
|
||||
case 25448: spellId = 45295; break; // Rank 11
|
||||
case 25449: spellId = 45296; break; // Rank 12
|
||||
case 49237: spellId = 49239; break; // Rank 13
|
||||
case 49238: spellId = 49240; break; // Rank 14
|
||||
// Chain Lightning
|
||||
case 421: spellId = 45297; break; // Rank 1
|
||||
case 930: spellId = 45298; break; // Rank 2
|
||||
@@ -6327,6 +6417,8 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
|
||||
case 10605: spellId = 45300; break; // Rank 4
|
||||
case 25439: spellId = 45301; break; // Rank 5
|
||||
case 25442: spellId = 45302; break; // Rank 6
|
||||
case 49268: spellId = 49270; break; // Rank 7
|
||||
case 49269: spellId = 49271; break; // Rank 8
|
||||
default:
|
||||
sLog.outError("Unit::HandleDummyAuraProc: non handled spell id: %u (LO)", procSpell->Id);
|
||||
return false;
|
||||
@@ -6337,21 +6429,14 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
|
||||
mod->value = -100;
|
||||
mod->type = SPELLMOD_PCT;
|
||||
mod->spellId = dummySpell->Id;
|
||||
mod->effectId = 0;
|
||||
mod->lastAffected = NULL;
|
||||
mod->mask = 0x0000000000000003LL;
|
||||
mod->charges = 0;
|
||||
mod->mask2= 0LL;
|
||||
((Player*)this)->AddSpellMod(mod, true);
|
||||
|
||||
// Remove cooldown (Chain Lightning - have Category Recovery time)
|
||||
if (procSpell->SpellFamilyFlags & 0x0000000000000002LL)
|
||||
((Player*)this)->RemoveSpellCooldown(spellId);
|
||||
|
||||
// Hmmm.. in most case spells already set half basepoints but...
|
||||
// Lightning Bolt (2-10 rank) have full basepoint and half bonus from level
|
||||
// As on wiki:
|
||||
// BUG: Rank 2 to 10 (and maybe 11) of Lightning Bolt will proc another Bolt with FULL damage (not halved). This bug is known and will probably be fixed soon.
|
||||
// So - no add changes :)
|
||||
CastSpell(pVictim, spellId, true, castItem, triggeredByAura);
|
||||
|
||||
((Player*)this)->AddSpellMod(mod, false);
|
||||
@@ -6624,7 +6709,7 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
|
||||
break;
|
||||
}
|
||||
// Shadowguard
|
||||
if((auraSpellInfo->SpellFamilyFlags & 0x80000000LL) && auraSpellInfo->SpellVisual==7958)
|
||||
if((auraSpellInfo->SpellFamilyFlags & 0x80000000LL) && auraSpellInfo->SpellVisual[0]==7958)
|
||||
{
|
||||
switch(triggeredByAura->GetSpellProto()->Id)
|
||||
{
|
||||
@@ -6979,14 +7064,14 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
|
||||
}
|
||||
|
||||
// Water Shield (we can't set cooldown for main spell - it's player casted spell
|
||||
if((auraSpellInfo->SpellFamilyFlags & 0x0000002000000000LL) && auraSpellInfo->SpellVisual==7358)
|
||||
if((auraSpellInfo->SpellFamilyFlags & 0x0000002000000000LL) && auraSpellInfo->SpellVisual[0]==7358)
|
||||
{
|
||||
target = this;
|
||||
break;
|
||||
}
|
||||
|
||||
// Lightning Shield
|
||||
if((auraSpellInfo->SpellFamilyFlags & 0x00000400) && auraSpellInfo->SpellVisual==37)
|
||||
if((auraSpellInfo->SpellFamilyFlags & 0x00000400) && auraSpellInfo->SpellVisual[0]==37)
|
||||
{
|
||||
// overwrite non existing triggered spell call in spell.dbc
|
||||
switch(triggeredByAura->GetSpellProto()->Id)
|
||||
@@ -7313,7 +7398,7 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
|
||||
if (auraSpellInfo->Id==37594)
|
||||
trigger_spell_id = 37595;
|
||||
// Shadowguard
|
||||
else if(auraSpellInfo->SpellFamilyFlags==0x100080000000LL && auraSpellInfo->SpellVisual==7958)
|
||||
else if(auraSpellInfo->SpellFamilyFlags==0x100080000000LL && auraSpellInfo->SpellVisual[0]==7958)
|
||||
{
|
||||
switch(auraSpellInfo->Id)
|
||||
{
|
||||
@@ -7508,7 +7593,7 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
|
||||
case SPELLFAMILY_SHAMAN:
|
||||
{
|
||||
//Lightning Shield (overwrite non existing triggered spell call in spell.dbc
|
||||
if(auraSpellInfo->SpellFamilyFlags==0x00000400 && auraSpellInfo->SpellVisual==37)
|
||||
if(auraSpellInfo->SpellFamilyFlags==0x00000400 && auraSpellInfo->SpellVisual[0]==37)
|
||||
{
|
||||
switch(auraSpellInfo->Id)
|
||||
{
|
||||
@@ -7720,21 +7805,21 @@ bool Unit::HandleOverrideClassScriptAuraProc(Unit *pVictim, Aura *triggeredByAur
|
||||
{
|
||||
case 836: // Improved Blizzard (Rank 1)
|
||||
{
|
||||
if (!procSpell || procSpell->SpellVisual!=9487)
|
||||
if (!procSpell || procSpell->SpellVisual[0]!=9487)
|
||||
return false;
|
||||
triggered_spell_id = 12484;
|
||||
break;
|
||||
}
|
||||
case 988: // Improved Blizzard (Rank 2)
|
||||
{
|
||||
if (!procSpell || procSpell->SpellVisual!=9487)
|
||||
if (!procSpell || procSpell->SpellVisual[0]!=9487)
|
||||
return false;
|
||||
triggered_spell_id = 12485;
|
||||
break;
|
||||
}
|
||||
case 989: // Improved Blizzard (Rank 3)
|
||||
{
|
||||
if (!procSpell || procSpell->SpellVisual!=9487)
|
||||
if (!procSpell || procSpell->SpellVisual[0]!=9487)
|
||||
return false;
|
||||
triggered_spell_id = 12486;
|
||||
break;
|
||||
@@ -8390,6 +8475,9 @@ void Unit::SetPet(Pet* pet)
|
||||
void Unit::SetCharm(Unit* pet)
|
||||
{
|
||||
SetUInt64Value(UNIT_FIELD_CHARM, pet ? pet->GetGUID() : 0);
|
||||
|
||||
if(GetTypeId() == TYPEID_PLAYER)
|
||||
((Player*)this)->m_mover = pet ? pet : this;
|
||||
}
|
||||
|
||||
void Unit::AddPlayerToVision(Player* plr)
|
||||
@@ -8468,6 +8556,7 @@ void Unit::SendHealSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, bool c
|
||||
data.append(GetPackGUID());
|
||||
data << uint32(SpellID);
|
||||
data << uint32(Damage);
|
||||
data << uint32(0); // over healing?
|
||||
data << uint8(critical ? 1 : 0);
|
||||
data << uint8(0); // unused in client?
|
||||
SendMessageToSet(&data, true);
|
||||
@@ -8648,7 +8737,7 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
|
||||
CastingTime = 0;
|
||||
}
|
||||
// Darkmoon Card: Vengeance - 0.1%
|
||||
else if (spellProto->SpellVisual == 9850 && spellProto->SpellIconID == 2230)
|
||||
else if (spellProto->SpellVisual[0] == 9850 && spellProto->SpellIconID == 2230)
|
||||
{
|
||||
CastingTime = 3.5;
|
||||
}
|
||||
@@ -8916,14 +9005,8 @@ int32 Unit::SpellBaseDamageBonus(SpellSchoolMask schoolMask)
|
||||
{
|
||||
if((*i)->GetModifier()->m_miscvalue & schoolMask)
|
||||
{
|
||||
SpellEntry const* iSpellProto = (*i)->GetSpellProto();
|
||||
uint8 eff = (*i)->GetEffIndex();
|
||||
|
||||
// stat used dependent from next effect aura SPELL_AURA_MOD_SPELL_HEALING presence and misc value (stat index)
|
||||
Stats usedStat = STAT_INTELLECT;
|
||||
if(eff < 2 && iSpellProto->EffectApplyAuraName[eff+1]==SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT)
|
||||
usedStat = Stats(iSpellProto->EffectMiscValue[eff+1]);
|
||||
|
||||
// stat used stored in miscValueB for this aura
|
||||
Stats usedStat = Stats((*i)->GetMiscBValue());
|
||||
DoneAdvertisedBenefit += int32(GetStat(usedStat) * (*i)->GetModifierValue() / 100.0f);
|
||||
}
|
||||
}
|
||||
@@ -9094,7 +9177,7 @@ uint32 Unit::SpellHealingBonus(SpellEntry const *spellProto, uint32 healamount,
|
||||
AuraList const& mDummyAuras = pVictim->GetAurasByType(SPELL_AURA_DUMMY);
|
||||
for(AuraList::const_iterator i = mDummyAuras.begin();i != mDummyAuras.end(); ++i)
|
||||
{
|
||||
if((*i)->GetSpellProto()->SpellVisual == 9180)
|
||||
if((*i)->GetSpellProto()->SpellVisual[0] == 9180)
|
||||
{
|
||||
// Flash of Light
|
||||
if ((spellProto->SpellFamilyFlags & 0x0000000040000000LL) && (*i)->GetEffIndex() == 1)
|
||||
@@ -10110,38 +10193,37 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)
|
||||
|
||||
propagateSpeedChange();
|
||||
|
||||
// Send speed change packet only for player
|
||||
if (GetTypeId()!=TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
WorldPacket data;
|
||||
if(!forced)
|
||||
{
|
||||
switch(mtype)
|
||||
{
|
||||
case MOVE_WALK:
|
||||
data.Initialize(MSG_MOVE_SET_WALK_SPEED, 8+4+1+4+4+4+4+4+4+4);
|
||||
data.Initialize(MSG_MOVE_SET_WALK_SPEED, 8+4+2+4+4+4+4+4+4+4);
|
||||
break;
|
||||
case MOVE_RUN:
|
||||
data.Initialize(MSG_MOVE_SET_RUN_SPEED, 8+4+1+4+4+4+4+4+4+4);
|
||||
data.Initialize(MSG_MOVE_SET_RUN_SPEED, 8+4+2+4+4+4+4+4+4+4);
|
||||
break;
|
||||
case MOVE_RUN_BACK:
|
||||
data.Initialize(MSG_MOVE_SET_RUN_BACK_SPEED, 8+4+1+4+4+4+4+4+4+4);
|
||||
data.Initialize(MSG_MOVE_SET_RUN_BACK_SPEED, 8+4+2+4+4+4+4+4+4+4);
|
||||
break;
|
||||
case MOVE_SWIM:
|
||||
data.Initialize(MSG_MOVE_SET_SWIM_SPEED, 8+4+1+4+4+4+4+4+4+4);
|
||||
data.Initialize(MSG_MOVE_SET_SWIM_SPEED, 8+4+2+4+4+4+4+4+4+4);
|
||||
break;
|
||||
case MOVE_SWIM_BACK:
|
||||
data.Initialize(MSG_MOVE_SET_SWIM_BACK_SPEED, 8+4+1+4+4+4+4+4+4+4);
|
||||
data.Initialize(MSG_MOVE_SET_SWIM_BACK_SPEED, 8+4+2+4+4+4+4+4+4+4);
|
||||
break;
|
||||
case MOVE_TURN_RATE:
|
||||
data.Initialize(MSG_MOVE_SET_TURN_RATE, 8+4+1+4+4+4+4+4+4+4);
|
||||
data.Initialize(MSG_MOVE_SET_TURN_RATE, 8+4+2+4+4+4+4+4+4+4);
|
||||
break;
|
||||
case MOVE_FLIGHT:
|
||||
data.Initialize(MSG_MOVE_SET_FLIGHT_SPEED, 8+4+1+4+4+4+4+4+4+4);
|
||||
data.Initialize(MSG_MOVE_SET_FLIGHT_SPEED, 8+4+2+4+4+4+4+4+4+4);
|
||||
break;
|
||||
case MOVE_FLIGHT_BACK:
|
||||
data.Initialize(MSG_MOVE_SET_FLIGHT_BACK_SPEED, 8+4+1+4+4+4+4+4+4+4);
|
||||
data.Initialize(MSG_MOVE_SET_FLIGHT_BACK_SPEED, 8+4+2+4+4+4+4+4+4+4);
|
||||
break;
|
||||
case MOVE_PITCH_RATE:
|
||||
data.Initialize(MSG_MOVE_SET_PITCH_RATE, 8+4+2+4+4+4+4+4+4+4);
|
||||
break;
|
||||
default:
|
||||
sLog.outError("Unit::SetSpeed: Unsupported move type (%d), data not sent to client.",mtype);
|
||||
@@ -10149,22 +10231,26 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)
|
||||
}
|
||||
|
||||
data.append(GetPackGUID());
|
||||
data << uint32(0); //movement flags
|
||||
data << uint8(0); //unk
|
||||
data << uint32(0); // movement flags
|
||||
data << uint16(0); // unk flags
|
||||
data << uint32(getMSTime());
|
||||
data << float(GetPositionX());
|
||||
data << float(GetPositionY());
|
||||
data << float(GetPositionZ());
|
||||
data << float(GetOrientation());
|
||||
data << uint32(0); //flag unk
|
||||
data << uint32(0); // fall time
|
||||
data << float(GetSpeed(mtype));
|
||||
SendMessageToSet( &data, true );
|
||||
}
|
||||
else
|
||||
{
|
||||
// register forced speed changes for WorldSession::HandleForceSpeedChangeAck
|
||||
// and do it only for real sent packets and use run for run/mounted as client expected
|
||||
++((Player*)this)->m_forced_speed_changes[mtype];
|
||||
if(GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
// register forced speed changes for WorldSession::HandleForceSpeedChangeAck
|
||||
// and do it only for real sent packets and use run for run/mounted as client expected
|
||||
++((Player*)this)->m_forced_speed_changes[mtype];
|
||||
}
|
||||
|
||||
switch(mtype)
|
||||
{
|
||||
case MOVE_WALK:
|
||||
@@ -10191,6 +10277,9 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)
|
||||
case MOVE_FLIGHT_BACK:
|
||||
data.Initialize(SMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE, 16);
|
||||
break;
|
||||
case MOVE_PITCH_RATE:
|
||||
data.Initialize(SMSG_FORCE_PITCH_RATE_CHANGE, 16);
|
||||
break;
|
||||
default:
|
||||
sLog.outError("Unit::SetSpeed: Unsupported move type (%d), data not sent to client.",mtype);
|
||||
return;
|
||||
@@ -10280,6 +10369,10 @@ bool Unit::CanHaveThreatList() const
|
||||
if( ((Creature*)this)->isTotem() )
|
||||
return false;
|
||||
|
||||
// vehicles can not have threat list
|
||||
if( ((Creature*)this)->isVehicle() )
|
||||
return false;
|
||||
|
||||
// pets can not have a threat list, unless they are controlled by a creature
|
||||
if( ((Creature*)this)->isPet() && IS_PLAYER_GUID(((Pet*)this)->GetOwnerGUID()) )
|
||||
return false;
|
||||
@@ -10528,6 +10621,8 @@ int32 Unit::CalculateSpellDuration(SpellEntry const* spellProto, uint8 effect_in
|
||||
int32 mechanic = GetEffectMechanic(spellProto, effect_index);
|
||||
// Find total mod value (negative bonus)
|
||||
int32 durationMod_always = target->GetTotalAuraModifierByMiscValue(SPELL_AURA_MECHANIC_DURATION_MOD, mechanic);
|
||||
// Modify from SPELL_AURA_MOD_DURATION_OF_EFFECTS_BY_DISPEL aura (stack always ?)
|
||||
durationMod_always+=target->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_DURATION_OF_EFFECTS_BY_DISPEL, spellProto->Dispel);
|
||||
// Find max mod (negative bonus)
|
||||
int32 durationMod_not_stack = target->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK, mechanic);
|
||||
|
||||
@@ -10729,7 +10824,9 @@ bool Unit::HandleStatModifier(UnitMods unitMod, UnitModifierType modifierType, f
|
||||
case UNIT_MOD_RAGE:
|
||||
case UNIT_MOD_FOCUS:
|
||||
case UNIT_MOD_ENERGY:
|
||||
case UNIT_MOD_HAPPINESS: UpdateMaxPower(GetPowerTypeByAuraGroup(unitMod)); break;
|
||||
case UNIT_MOD_HAPPINESS:
|
||||
case UNIT_MOD_RUNE:
|
||||
case UNIT_MOD_RUNIC_POWER: UpdateMaxPower(GetPowerTypeByAuraGroup(unitMod)); break;
|
||||
|
||||
case UNIT_MOD_RESISTANCE_HOLY:
|
||||
case UNIT_MOD_RESISTANCE_FIRE:
|
||||
@@ -10842,21 +10939,18 @@ Stats Unit::GetStatByAuraGroup(UnitMods unitMod) const
|
||||
|
||||
Powers Unit::GetPowerTypeByAuraGroup(UnitMods unitMod) const
|
||||
{
|
||||
Powers power = POWER_MANA;
|
||||
|
||||
switch(unitMod)
|
||||
{
|
||||
case UNIT_MOD_MANA: power = POWER_MANA; break;
|
||||
case UNIT_MOD_RAGE: power = POWER_RAGE; break;
|
||||
case UNIT_MOD_FOCUS: power = POWER_FOCUS; break;
|
||||
case UNIT_MOD_ENERGY: power = POWER_ENERGY; break;
|
||||
case UNIT_MOD_HAPPINESS: power = POWER_HAPPINESS; break;
|
||||
|
||||
default:
|
||||
break;
|
||||
case UNIT_MOD_MANA: return POWER_MANA;
|
||||
case UNIT_MOD_RAGE: return POWER_RAGE;
|
||||
case UNIT_MOD_FOCUS: return POWER_FOCUS;
|
||||
case UNIT_MOD_ENERGY: return POWER_ENERGY;
|
||||
case UNIT_MOD_HAPPINESS: return POWER_HAPPINESS;
|
||||
case UNIT_MOD_RUNE: return POWER_RUNE;
|
||||
case UNIT_MOD_RUNIC_POWER:return POWER_RUNIC_POWER;
|
||||
}
|
||||
|
||||
return power;
|
||||
return POWER_MANA;
|
||||
}
|
||||
|
||||
float Unit::GetTotalAttackPowerValue(WeaponAttackType attType) const
|
||||
@@ -10955,6 +11049,12 @@ void Unit::SetPower(Powers power, uint32 val)
|
||||
|
||||
SetStatInt32Value(UNIT_FIELD_POWER1 + power, val);
|
||||
|
||||
WorldPacket data(SMSG_POWER_UPDATE);
|
||||
data.append(GetPackGUID());
|
||||
data << uint8(power);
|
||||
data << uint32(val);
|
||||
SendMessageToSet(&data, GetTypeId() == TYPEID_PLAYER ? true : false);
|
||||
|
||||
// group update
|
||||
if(GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
@@ -11068,6 +11168,7 @@ uint32 Unit::GetCreatePowers( Powers power ) const
|
||||
case POWER_FOCUS: return (GetTypeId()==TYPEID_PLAYER || !((Creature const*)this)->isPet() || ((Pet const*)this)->getPetType()!=HUNTER_PET ? 0 : 100);
|
||||
case POWER_ENERGY: return 100;
|
||||
case POWER_HAPPINESS: return (GetTypeId()==TYPEID_PLAYER || !((Creature const*)this)->isPet() || ((Pet const*)this)->getPetType()!=HUNTER_PET ? 0 : 1050000);
|
||||
case POWER_RUNIC_POWER: return 1000;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -11155,7 +11256,7 @@ void CharmInfo::InitEmptyActionBar(bool withAttack)
|
||||
|
||||
for(uint32 x = 0; x < 10; ++x)
|
||||
{
|
||||
PetActionBar[x].Type = ACT_CAST;
|
||||
PetActionBar[x].Type = ACT_PASSIVE;
|
||||
PetActionBar[x].SpellOrAction = 0;
|
||||
}
|
||||
if (withAttack)
|
||||
@@ -11171,13 +11272,20 @@ void CharmInfo::InitPossessCreateSpells()
|
||||
InitEmptyActionBar();
|
||||
if(m_unit->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
for(uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i)
|
||||
/*for(uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i)
|
||||
{
|
||||
uint32 spellid = ((Creature*)m_unit)->m_spells[i];
|
||||
if(IsPassiveSpell(spellid))
|
||||
m_unit->CastSpell(m_unit, spellid, true);
|
||||
else
|
||||
AddSpellToAB(0, spellid, ACT_CAST);
|
||||
}*/
|
||||
for(uint32 x = 0; x < CREATURE_MAX_SPELLS; ++x)
|
||||
{
|
||||
if (IsPassiveSpell(((Creature*)m_unit)->m_spells[x]))
|
||||
m_unit->CastSpell(m_unit, ((Creature*)m_unit)->m_spells[x], true);
|
||||
else
|
||||
AddSpellToAB(0, ((Creature*)m_unit)->m_spells[x], ACT_PASSIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11221,7 +11329,7 @@ void CharmInfo::InitCharmCreateSpells()
|
||||
if(onlyselfcast || !IsPositiveSpell(spellId)) //only self cast and spells versus enemies are autocastable
|
||||
newstate = ACT_DISABLED;
|
||||
else
|
||||
newstate = ACT_CAST;
|
||||
newstate = ACT_PASSIVE;
|
||||
|
||||
AddSpellToAB(0, spellId, newstate);
|
||||
}
|
||||
@@ -11232,7 +11340,7 @@ bool CharmInfo::AddSpellToAB(uint32 oldid, uint32 newid, ActiveStates newstate)
|
||||
{
|
||||
for(uint8 i = 0; i < 10; i++)
|
||||
{
|
||||
if((PetActionBar[i].Type == ACT_DISABLED || PetActionBar[i].Type == ACT_ENABLED || PetActionBar[i].Type == ACT_CAST) && PetActionBar[i].SpellOrAction == oldid)
|
||||
if((PetActionBar[i].Type == ACT_DISABLED || PetActionBar[i].Type == ACT_ENABLED || PetActionBar[i].Type == ACT_PASSIVE) && PetActionBar[i].SpellOrAction == oldid)
|
||||
{
|
||||
PetActionBar[i].SpellOrAction = newid;
|
||||
if(!oldid)
|
||||
@@ -11847,8 +11955,11 @@ void Unit::SendPetCastFail(uint32 spellid, uint8 msg)
|
||||
return;
|
||||
|
||||
WorldPacket data(SMSG_PET_CAST_FAILED, (4+1));
|
||||
data << uint8(0); // cast count?
|
||||
data << uint32(spellid);
|
||||
data << uint8(msg);
|
||||
// uint32 for some reason
|
||||
// uint32 for some reason
|
||||
((Player*)owner)->GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
||||
@@ -12402,7 +12513,10 @@ Pet* Unit::CreateTamedPetFrom(Creature* creatureTarget,uint32 spell_id)
|
||||
pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, getFaction());
|
||||
pet->SetUInt32Value(UNIT_CREATED_BY_SPELL, spell_id);
|
||||
|
||||
if(!pet->InitStatsForLevel(creatureTarget->getLevel()))
|
||||
uint32 level = (creatureTarget->getLevel() < (getLevel() - 5)) ? (getLevel() - 5) : creatureTarget->getLevel();
|
||||
pet->SetFreeTalentPoints(pet->GetMaxTalentPointsForLevel(level));
|
||||
|
||||
if(!pet->InitStatsForLevel(level))
|
||||
{
|
||||
sLog.outError("ERROR: Pet::InitStatsForLevel() failed for creature (Entry: %u)!",creatureTarget->GetEntry());
|
||||
delete pet;
|
||||
@@ -12533,10 +12647,8 @@ bool Unit::HandleMeandingAuraProc( Aura* triggeredByAura )
|
||||
mod->value = jumps-5; // negative
|
||||
mod->type = SPELLMOD_FLAT;
|
||||
mod->spellId = spellProto->Id;
|
||||
mod->effectId = effIdx;
|
||||
mod->lastAffected = NULL;
|
||||
mod->mask = spellProto->SpellFamilyFlags;
|
||||
mod->charges = 0;
|
||||
mod->mask = spellProto->SpellFamilyFlags;
|
||||
mod->mask2 = spellProto->SpellFamilyFlags2;
|
||||
|
||||
caster->AddSpellMod(mod, true);
|
||||
CastCustomSpell(target,spellProto->Id,&heal,NULL,NULL,true,NULL,triggeredByAura,caster->GetGUID());
|
||||
@@ -12724,6 +12836,15 @@ void Unit::Kill(Unit *pVictim, bool durabilityLoss)
|
||||
bg->HandleKillUnit((Creature*)pVictim, player);
|
||||
}
|
||||
}
|
||||
|
||||
// achievement stuff
|
||||
if ( pVictim->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
if(GetTypeId() == TYPEID_UNIT)
|
||||
((Player*)pVictim)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE, GetEntry());
|
||||
else if(GetTypeId() == TYPEID_PLAYER)
|
||||
((Player*)pVictim)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::SetControlled(bool apply, UnitState state)
|
||||
@@ -12793,7 +12914,7 @@ void Unit::SetStunned(bool apply)
|
||||
if(apply)
|
||||
{
|
||||
SetUInt64Value(UNIT_FIELD_TARGET, 0);
|
||||
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE);
|
||||
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
|
||||
CastStop();
|
||||
|
||||
// Creature specific
|
||||
@@ -12811,7 +12932,7 @@ void Unit::SetStunned(bool apply)
|
||||
{
|
||||
if(isAlive() && getVictim())
|
||||
SetUInt64Value(UNIT_FIELD_TARGET, getVictim()->GetGUID());
|
||||
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE);
|
||||
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
|
||||
|
||||
if(!hasUnitState(UNIT_STAT_ROOT)) // prevent allow move if have also root effect
|
||||
{
|
||||
@@ -13009,4 +13130,4 @@ void Unit::AddAura(uint32 spellId, Unit* target)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+100
-41
@@ -149,6 +149,7 @@ enum ShapeshiftForm
|
||||
FORM_BERSERKERSTANCE = 0x13,
|
||||
FORM_TEST = 0x14,
|
||||
FORM_ZOMBIE = 0x15,
|
||||
FORM_METAMORPHOSIS = 0x16,
|
||||
FORM_FLIGHT_EPIC = 0x1B,
|
||||
FORM_SHADOW = 0x1C,
|
||||
FORM_FLIGHT = 0x1D,
|
||||
@@ -168,14 +169,14 @@ enum SheathState
|
||||
// byte (1 from 0..3) of UNIT_FIELD_BYTES_2
|
||||
enum UnitBytes2_Flags
|
||||
{
|
||||
UNIT_BYTE2_FLAG_UNK0 = 0x01,
|
||||
UNIT_BYTE2_FLAG_UNK1 = 0x02,
|
||||
UNIT_BYTE2_FLAG_UNK2 = 0x04,
|
||||
UNIT_BYTE2_FLAG_UNK3 = 0x08,
|
||||
UNIT_BYTE2_FLAG_AURAS = 0x10, // show possitive auras as positive, and allow its dispel
|
||||
UNIT_BYTE2_FLAG_UNK5 = 0x20,
|
||||
UNIT_BYTE2_FLAG_UNK6 = 0x40,
|
||||
UNIT_BYTE2_FLAG_UNK7 = 0x80
|
||||
UNIT_BYTE2_FLAG_PVP = 0x01,
|
||||
UNIT_BYTE2_FLAG_UNK1 = 0x02,
|
||||
UNIT_BYTE2_FLAG_FFA_PVP = 0x04,
|
||||
UNIT_BYTE2_FLAG_SANCTUARY = 0x08,
|
||||
UNIT_BYTE2_FLAG_UNK4 = 0x10,
|
||||
UNIT_BYTE2_FLAG_UNK5 = 0x20,
|
||||
UNIT_BYTE2_FLAG_UNK6 = 0x40,
|
||||
UNIT_BYTE2_FLAG_UNK7 = 0x80
|
||||
};
|
||||
|
||||
// byte (2 from 0..3) of UNIT_FIELD_BYTES_2
|
||||
@@ -213,16 +214,27 @@ enum HitInfo
|
||||
HITINFO_UNK1 = 0x00000001, // req correct packet structure
|
||||
HITINFO_NORMALSWING2 = 0x00000002,
|
||||
HITINFO_LEFTSWING = 0x00000004,
|
||||
HITINFO_UNK2 = 0x00000008,
|
||||
HITINFO_MISS = 0x00000010,
|
||||
HITINFO_ABSORB = 0x00000020, // plays absorb sound
|
||||
HITINFO_RESIST = 0x00000040, // resisted at least some damage
|
||||
HITINFO_CRITICALHIT = 0x00000080,
|
||||
HITINFO_UNK2 = 0x00000100, // wotlk?
|
||||
HITINFO_UNK3 = 0x00002000, // wotlk?
|
||||
HITINFO_GLANCING = 0x00004000,
|
||||
HITINFO_CRUSHING = 0x00008000,
|
||||
HITINFO_NOACTION = 0x00010000,
|
||||
HITINFO_SWINGNOHITSOUND = 0x00080000
|
||||
HITINFO_ABSORB = 0x00000020, // absorbed damage
|
||||
HITINFO_ABSORB2 = 0x00000040, // absorbed damage
|
||||
HITINFO_RESIST = 0x00000080, // resisted atleast some damage
|
||||
HITINFO_RESIST2 = 0x00000100, // resisted atleast some damage
|
||||
HITINFO_CRITICALHIT = 0x00000200, // critical hit
|
||||
// 0x00000400
|
||||
// 0x00000800
|
||||
// 0x00001000
|
||||
HITINFO_BLOCK = 0x00002000, // blocked damage
|
||||
// 0x00004000
|
||||
// 0x00008000
|
||||
HITINFO_GLANCING = 0x00010000,
|
||||
HITINFO_CRUSHING = 0x00020000,
|
||||
HITINFO_NOACTION = 0x00040000, // guessed
|
||||
// 0x00080000
|
||||
// 0x00100000
|
||||
HITINFO_SWINGNOHITSOUND = 0x00200000, // guessed
|
||||
// 0x00400000
|
||||
HITINFO_UNK3 = 0x00800000
|
||||
};
|
||||
|
||||
//i would like to remove this: (it is defined in item.h
|
||||
@@ -294,11 +306,13 @@ enum UnitMods
|
||||
UNIT_MOD_STAT_INTELLECT,
|
||||
UNIT_MOD_STAT_SPIRIT,
|
||||
UNIT_MOD_HEALTH,
|
||||
UNIT_MOD_MANA, // UNIT_MOD_MANA..UNIT_MOD_HAPPINESS must be in existed order, it's accessed by index values of Powers enum.
|
||||
UNIT_MOD_MANA, // UNIT_MOD_MANA..UNIT_MOD_RUNIC_POWER must be in existed order, it's accessed by index values of Powers enum.
|
||||
UNIT_MOD_RAGE,
|
||||
UNIT_MOD_FOCUS,
|
||||
UNIT_MOD_ENERGY,
|
||||
UNIT_MOD_HAPPINESS,
|
||||
UNIT_MOD_RUNE,
|
||||
UNIT_MOD_RUNIC_POWER,
|
||||
UNIT_MOD_ARMOR, // UNIT_MOD_ARMOR..UNIT_MOD_RESISTANCE_ARCANE must be in existed order, it's accessed by index values of SpellSchools enum.
|
||||
UNIT_MOD_RESISTANCE_HOLY,
|
||||
UNIT_MOD_RESISTANCE_FIRE,
|
||||
@@ -318,7 +332,7 @@ enum UnitMods
|
||||
UNIT_MOD_RESISTANCE_START = UNIT_MOD_ARMOR,
|
||||
UNIT_MOD_RESISTANCE_END = UNIT_MOD_RESISTANCE_ARCANE + 1,
|
||||
UNIT_MOD_POWER_START = UNIT_MOD_MANA,
|
||||
UNIT_MOD_POWER_END = UNIT_MOD_HAPPINESS + 1
|
||||
UNIT_MOD_POWER_END = UNIT_MOD_RUNIC_POWER + 1
|
||||
};
|
||||
|
||||
enum BaseModGroup
|
||||
@@ -383,9 +397,10 @@ enum UnitMoveType
|
||||
MOVE_TURN_RATE = 5,
|
||||
MOVE_FLIGHT = 6,
|
||||
MOVE_FLIGHT_BACK = 7,
|
||||
MOVE_PITCH_RATE = 8
|
||||
};
|
||||
|
||||
#define MAX_MOVE_TYPE 8
|
||||
#define MAX_MOVE_TYPE 9
|
||||
|
||||
extern float baseMoveSpeed[MAX_MOVE_TYPE];
|
||||
|
||||
@@ -423,10 +438,11 @@ enum CombatRating
|
||||
CR_WEAPON_SKILL_MAINHAND = 20,
|
||||
CR_WEAPON_SKILL_OFFHAND = 21,
|
||||
CR_WEAPON_SKILL_RANGED = 22,
|
||||
CR_EXPERTISE = 23
|
||||
CR_EXPERTISE = 23,
|
||||
CR_ARMOR_PENETRATION = 24
|
||||
};
|
||||
|
||||
#define MAX_COMBAT_RATING 24
|
||||
#define MAX_COMBAT_RATING 25
|
||||
|
||||
enum DamageEffectType
|
||||
{
|
||||
@@ -460,19 +476,19 @@ enum UnitFlags
|
||||
UNIT_FLAG_UNKNOWN9 = 0x00000040,
|
||||
UNIT_FLAG_NOT_ATTACKABLE_1 = 0x00000080, // ?? (UNIT_FLAG_PVP_ATTACKABLE | UNIT_FLAG_NOT_ATTACKABLE_1) is NON_PVP_ATTACKABLE
|
||||
UNIT_FLAG_NOT_ATTACKABLE_2 = 0x00000100, // 2.0.8
|
||||
UNIT_FLAG_UNKNOWN11 = 0x00000200,
|
||||
UNIT_FLAG_UNKNOWN11 = 0x00000200, // 3.0.3 - makes you unable to attack everything
|
||||
UNIT_FLAG_LOOTING = 0x00000400, // loot animation
|
||||
UNIT_FLAG_PET_IN_COMBAT = 0x00000800, // in combat?, 2.0.8
|
||||
UNIT_FLAG_PVP = 0x00001000,
|
||||
UNIT_FLAG_PVP = 0x00001000, // changed in 3.0.3
|
||||
UNIT_FLAG_SILENCED = 0x00002000, // silenced, 2.1.1
|
||||
UNIT_FLAG_UNKNOWN4 = 0x00004000, // 2.0.8
|
||||
UNIT_FLAG_UNKNOWN13 = 0x00008000,
|
||||
UNIT_FLAG_UNKNOWN14 = 0x00010000,
|
||||
UNIT_FLAG_PACIFIED = 0x00020000,
|
||||
UNIT_FLAG_DISABLE_ROTATE = 0x00040000, // stunned, 2.1.1
|
||||
UNIT_FLAG_PACIFIED = 0x00020000, // 3.0.3 ok
|
||||
UNIT_FLAG_STUNNED = 0x00040000, // 3.0.3 ok
|
||||
UNIT_FLAG_IN_COMBAT = 0x00080000,
|
||||
UNIT_FLAG_TAXI_FLIGHT = 0x00100000, // disable casting at client side spell not allowed by taxi flight (mounted?), probably used with 0x4 flag
|
||||
UNIT_FLAG_DISARMED = 0x00200000, // disable melee spells casting..., "Required melee weapon" added to melee spells tooltip.
|
||||
UNIT_FLAG_DISARMED = 0x00200000, // 3.0.3, disable melee spells casting..., "Required melee weapon" added to melee spells tooltip.
|
||||
UNIT_FLAG_CONFUSED = 0x00400000,
|
||||
UNIT_FLAG_FLEEING = 0x00800000,
|
||||
UNIT_FLAG_UNKNOWN5 = 0x01000000, // used in spell Eyes of the Beast for pet...
|
||||
@@ -487,9 +503,10 @@ enum UnitFlags
|
||||
// Value masks for UNIT_FIELD_FLAGS_2
|
||||
enum UnitFlags2
|
||||
{
|
||||
UNIT_FLAG2_FEIGN_DEATH = 0x00000001,
|
||||
UNIT_FLAG2_COMPREHEND_LANG= 0x00000008,
|
||||
UNIT_FLAG2_FORCE_MOVE = 0x00000040
|
||||
UNIT_FLAG2_FEIGN_DEATH = 0x00000001,
|
||||
UNIT_FLAG2_COMPREHEND_LANG = 0x00000008,
|
||||
UNIT_FLAG2_FORCE_MOVE = 0x00000040,
|
||||
UNIT_FLAG2_REGENERATE_POWER = 0x00000800
|
||||
};
|
||||
|
||||
/// Non Player Character flags
|
||||
@@ -635,8 +652,18 @@ uint32 createProcExtendMask(SpellNonMeleeDamage *damageInfo, SpellMissInfo missC
|
||||
|
||||
struct UnitActionBarEntry
|
||||
{
|
||||
uint32 Type;
|
||||
uint32 SpellOrAction;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint16 SpellOrAction;
|
||||
uint16 Type;
|
||||
};
|
||||
struct
|
||||
{
|
||||
uint32 Raw;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
#define MAX_DECLINED_NAME_CASES 5
|
||||
@@ -658,13 +685,12 @@ enum CurrentSpellTypes
|
||||
|
||||
enum ActiveStates
|
||||
{
|
||||
ACT_ENABLED = 0xC100,
|
||||
ACT_DISABLED = 0x8100,
|
||||
ACT_COMMAND = 0x0700,
|
||||
ACT_REACTION = 0x0600,
|
||||
ACT_CAST = 0x0100,
|
||||
ACT_PASSIVE = 0x0000,
|
||||
ACT_DECIDE = 0x0001
|
||||
ACT_PASSIVE = 0x0100, // 0x0100 - passive
|
||||
ACT_DISABLED = 0x8100, // 0x8000 - castable
|
||||
ACT_ENABLED = 0xC100, // 0x4000 | 0x8000 - auto cast + castable
|
||||
ACT_COMMAND = 0x0700, // 0x0100 | 0x0200 | 0x0400
|
||||
ACT_REACTION = 0x0600, // 0x0200 | 0x0400
|
||||
ACT_DECIDE = 0x0001 // what is it?
|
||||
};
|
||||
|
||||
enum ReactStates
|
||||
@@ -754,6 +780,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
|
||||
typedef std::list<DiminishingReturn> Diminishing;
|
||||
typedef std::set<AuraType> AuraTypeSet;
|
||||
typedef std::set<uint32> ComboPointHolderSet;
|
||||
typedef std::map<uint8, uint32> VisibleAuraMap;
|
||||
|
||||
virtual ~Unit ( );
|
||||
|
||||
@@ -884,8 +911,14 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
|
||||
|
||||
return false;
|
||||
}
|
||||
bool IsPvP() const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP); }
|
||||
void SetPvP(bool state) { if(state) SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP); else RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP); }
|
||||
bool IsPvP() const { return HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP); }
|
||||
void SetPvP(bool state)
|
||||
{
|
||||
if(state)
|
||||
SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP);
|
||||
else
|
||||
RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP);
|
||||
}
|
||||
uint32 GetCreatureType() const;
|
||||
uint32 GetCreatureTypeMask() const
|
||||
{
|
||||
@@ -1255,6 +1288,30 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
|
||||
void removeHatedBy(HostilReference* /*pHostilReference*/ ) { /* nothing to do yet */ }
|
||||
HostilRefManager& getHostilRefManager() { return m_HostilRefManager; }
|
||||
|
||||
uint32 GetVisibleAura(uint8 slot)
|
||||
{
|
||||
VisibleAuraMap::iterator itr = m_visibleAuras.find(slot);
|
||||
if(itr != m_visibleAuras.end())
|
||||
return itr->second;
|
||||
return 0;
|
||||
}
|
||||
void SetVisibleAura(uint8 slot, uint32 spellid)
|
||||
{
|
||||
if(spellid == 0)
|
||||
{
|
||||
VisibleAuraMap::iterator itr = m_visibleAuras.find(slot);
|
||||
if(itr != m_visibleAuras.end())
|
||||
{
|
||||
m_visibleAuras.erase(itr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_visibleAuras[slot] = spellid;
|
||||
}
|
||||
VisibleAuraMap const *GetVisibleAuras() { return &m_visibleAuras; }
|
||||
uint8 GetVisibleAurasCount() { return m_visibleAuras.size(); }
|
||||
|
||||
Aura* GetAura(uint32 spellId, uint32 effindex);
|
||||
AuraMap & GetAuras() { return m_Auras; }
|
||||
AuraMap const& GetAuras() const { return m_Auras; }
|
||||
@@ -1446,6 +1503,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
|
||||
float m_weaponDamage[MAX_ATTACK][2];
|
||||
bool m_canModifyStats;
|
||||
//std::list< spellEffectPair > AuraSpells[TOTAL_AURAS]; // TODO: use this if ok for mem
|
||||
VisibleAuraMap m_visibleAuras;
|
||||
|
||||
float m_speed_rate[MAX_MOVE_TYPE];
|
||||
|
||||
@@ -1459,6 +1517,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
|
||||
uint32 m_unit_movement_flags;
|
||||
|
||||
uint32 m_reactiveTimer[MAX_REACTIVE];
|
||||
uint32 m_regenTimer;
|
||||
|
||||
private:
|
||||
void SendAttackStop(Unit* victim); // only from AttackStop(Unit*)
|
||||
|
||||
@@ -108,7 +108,7 @@ bool UpdateData::BuildPacket(WorldPacket *packet, bool hasTransport)
|
||||
ByteBuffer buf(m_data.size() + 10 + m_outOfRangeGUIDs.size()*8);
|
||||
|
||||
buf << (uint32) (!m_outOfRangeGUIDs.empty() ? m_blockCount + 1 : m_blockCount);
|
||||
buf << (uint8) (hasTransport ? 1 : 0);
|
||||
//buf << (uint8) (hasTransport ? 1 : 0);
|
||||
|
||||
if(!m_outOfRangeGUIDs.empty())
|
||||
{
|
||||
|
||||
@@ -38,11 +38,12 @@ enum OBJECT_UPDATE_FLAGS
|
||||
UPDATEFLAG_NONE = 0x00,
|
||||
UPDATEFLAG_SELF = 0x01,
|
||||
UPDATEFLAG_TRANSPORT = 0x02,
|
||||
UPDATEFLAG_FULLGUID = 0x04,
|
||||
UPDATEFLAG_HAS_TARGET = 0x04,
|
||||
UPDATEFLAG_LOWGUID = 0x08,
|
||||
UPDATEFLAG_HIGHGUID = 0x10,
|
||||
UPDATEFLAG_LIVING = 0x20,
|
||||
UPDATEFLAG_HASPOSITION = 0x40
|
||||
UPDATEFLAG_HAS_POSITION = 0x40,
|
||||
UPDATEFLAG_VEHICLE = 0x80
|
||||
};
|
||||
|
||||
class UpdateData
|
||||
|
||||
+290
-241
@@ -21,7 +21,7 @@
|
||||
#ifndef _UPDATEFIELDS_AUTO_H
|
||||
#define _UPDATEFIELDS_AUTO_H
|
||||
|
||||
// Auto generated for version 2, 4, 3, 8606
|
||||
// Auto generated for version 3, 0, 3, 9183
|
||||
|
||||
enum EObjectFields
|
||||
{
|
||||
@@ -43,13 +43,37 @@ enum EItemFields
|
||||
ITEM_FIELD_DURATION = OBJECT_END + 0x0009, // Size: 1, Type: INT, Flags: OWNER_ONLY, UNK2
|
||||
ITEM_FIELD_SPELL_CHARGES = OBJECT_END + 0x000A, // Size: 5, Type: INT, Flags: OWNER_ONLY, UNK2
|
||||
ITEM_FIELD_FLAGS = OBJECT_END + 0x000F, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT = OBJECT_END + 0x0010, // Size: 33, Type: INT, Flags: PUBLIC
|
||||
ITEM_FIELD_PROPERTY_SEED = OBJECT_END + 0x0031, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
ITEM_FIELD_RANDOM_PROPERTIES_ID = OBJECT_END + 0x0032, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
ITEM_FIELD_ITEM_TEXT_ID = OBJECT_END + 0x0033, // Size: 1, Type: INT, Flags: OWNER_ONLY
|
||||
ITEM_FIELD_DURABILITY = OBJECT_END + 0x0034, // Size: 1, Type: INT, Flags: OWNER_ONLY, UNK2
|
||||
ITEM_FIELD_MAXDURABILITY = OBJECT_END + 0x0035, // Size: 1, Type: INT, Flags: OWNER_ONLY, UNK2
|
||||
ITEM_END = OBJECT_END + 0x0036,
|
||||
ITEM_FIELD_ENCHANTMENT_1_1 = OBJECT_END + 0x0010, // Size: 2, Type: INT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_1_3 = OBJECT_END + 0x0012, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_2_1 = OBJECT_END + 0x0013, // Size: 2, Type: INT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_2_3 = OBJECT_END + 0x0015, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_3_1 = OBJECT_END + 0x0016, // Size: 2, Type: INT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_3_3 = OBJECT_END + 0x0018, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_4_1 = OBJECT_END + 0x0019, // Size: 2, Type: INT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_4_3 = OBJECT_END + 0x001B, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_5_1 = OBJECT_END + 0x001C, // Size: 2, Type: INT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_5_3 = OBJECT_END + 0x001E, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_6_1 = OBJECT_END + 0x001F, // Size: 2, Type: INT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_6_3 = OBJECT_END + 0x0021, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_7_1 = OBJECT_END + 0x0022, // Size: 2, Type: INT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_7_3 = OBJECT_END + 0x0024, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_8_1 = OBJECT_END + 0x0025, // Size: 2, Type: INT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_8_3 = OBJECT_END + 0x0027, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_9_1 = OBJECT_END + 0x0028, // Size: 2, Type: INT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_9_3 = OBJECT_END + 0x002A, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_10_1 = OBJECT_END + 0x002B, // Size: 2, Type: INT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_10_3 = OBJECT_END + 0x002D, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_11_1 = OBJECT_END + 0x002E, // Size: 2, Type: INT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_11_3 = OBJECT_END + 0x0030, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_12_1 = OBJECT_END + 0x0031, // Size: 2, Type: INT, Flags: PUBLIC
|
||||
ITEM_FIELD_ENCHANTMENT_12_3 = OBJECT_END + 0x0033, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
ITEM_FIELD_PROPERTY_SEED = OBJECT_END + 0x0034, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
ITEM_FIELD_RANDOM_PROPERTIES_ID = OBJECT_END + 0x0035, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
ITEM_FIELD_ITEM_TEXT_ID = OBJECT_END + 0x0036, // Size: 1, Type: INT, Flags: OWNER_ONLY
|
||||
ITEM_FIELD_DURABILITY = OBJECT_END + 0x0037, // Size: 1, Type: INT, Flags: OWNER_ONLY, UNK2
|
||||
ITEM_FIELD_MAXDURABILITY = OBJECT_END + 0x0038, // Size: 1, Type: INT, Flags: OWNER_ONLY, UNK2
|
||||
ITEM_FIELD_PAD = OBJECT_END + 0x0039, // Size: 1, Type: INT, Flags: NONE
|
||||
ITEM_END = OBJECT_END + 0x003A,
|
||||
};
|
||||
|
||||
enum EContainerFields
|
||||
@@ -64,93 +88,94 @@ enum EUnitFields
|
||||
{
|
||||
UNIT_FIELD_CHARM = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
UNIT_FIELD_SUMMON = OBJECT_END + 0x0002, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
UNIT_FIELD_CHARMEDBY = OBJECT_END + 0x0004, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
UNIT_FIELD_SUMMONEDBY = OBJECT_END + 0x0006, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
UNIT_FIELD_CREATEDBY = OBJECT_END + 0x0008, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
UNIT_FIELD_TARGET = OBJECT_END + 0x000A, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
UNIT_FIELD_PERSUADED = OBJECT_END + 0x000C, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
UNIT_FIELD_CRITTER = OBJECT_END + 0x0004, // Size: 2, Type: LONG, Flags: PRIVATE
|
||||
UNIT_FIELD_CHARMEDBY = OBJECT_END + 0x0006, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
UNIT_FIELD_SUMMONEDBY = OBJECT_END + 0x0008, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
UNIT_FIELD_CREATEDBY = OBJECT_END + 0x000A, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
UNIT_FIELD_TARGET = OBJECT_END + 0x000C, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
UNIT_FIELD_CHANNEL_OBJECT = OBJECT_END + 0x000E, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
UNIT_FIELD_HEALTH = OBJECT_END + 0x0010, // Size: 1, Type: INT, Flags: DYNAMIC
|
||||
UNIT_FIELD_POWER1 = OBJECT_END + 0x0011, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_POWER2 = OBJECT_END + 0x0012, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_POWER3 = OBJECT_END + 0x0013, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_POWER4 = OBJECT_END + 0x0014, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_POWER5 = OBJECT_END + 0x0015, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_MAXHEALTH = OBJECT_END + 0x0016, // Size: 1, Type: INT, Flags: DYNAMIC
|
||||
UNIT_FIELD_MAXPOWER1 = OBJECT_END + 0x0017, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_MAXPOWER2 = OBJECT_END + 0x0018, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_MAXPOWER3 = OBJECT_END + 0x0019, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_MAXPOWER4 = OBJECT_END + 0x001A, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_MAXPOWER5 = OBJECT_END + 0x001B, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_LEVEL = OBJECT_END + 0x001C, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_FACTIONTEMPLATE = OBJECT_END + 0x001D, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_BYTES_0 = OBJECT_END + 0x001E, // Size: 1, Type: BYTES, Flags: PUBLIC
|
||||
UNIT_VIRTUAL_ITEM_SLOT_DISPLAY = OBJECT_END + 0x001F, // Size: 3, Type: INT, Flags: PUBLIC
|
||||
UNIT_VIRTUAL_ITEM_INFO = OBJECT_END + 0x0022, // Size: 6, Type: BYTES, Flags: PUBLIC
|
||||
UNIT_FIELD_FLAGS = OBJECT_END + 0x0028, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_FLAGS_2 = OBJECT_END + 0x0029, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_AURA = OBJECT_END + 0x002A, // Size: 56, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_AURAFLAGS = OBJECT_END + 0x0062, // Size: 14, Type: BYTES, Flags: PUBLIC
|
||||
UNIT_FIELD_AURALEVELS = OBJECT_END + 0x0070, // Size: 14, Type: BYTES, Flags: PUBLIC
|
||||
UNIT_FIELD_AURAAPPLICATIONS = OBJECT_END + 0x007E, // Size: 14, Type: BYTES, Flags: PUBLIC
|
||||
UNIT_FIELD_AURASTATE = OBJECT_END + 0x008C, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_BASEATTACKTIME = OBJECT_END + 0x008D, // Size: 2, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_RANGEDATTACKTIME = OBJECT_END + 0x008F, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
UNIT_FIELD_BOUNDINGRADIUS = OBJECT_END + 0x0090, // Size: 1, Type: FLOAT, Flags: PUBLIC
|
||||
UNIT_FIELD_COMBATREACH = OBJECT_END + 0x0091, // Size: 1, Type: FLOAT, Flags: PUBLIC
|
||||
UNIT_FIELD_DISPLAYID = OBJECT_END + 0x0092, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_NATIVEDISPLAYID = OBJECT_END + 0x0093, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_MOUNTDISPLAYID = OBJECT_END + 0x0094, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_MINDAMAGE = OBJECT_END + 0x0095, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3
|
||||
UNIT_FIELD_MAXDAMAGE = OBJECT_END + 0x0096, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3
|
||||
UNIT_FIELD_MINOFFHANDDAMAGE = OBJECT_END + 0x0097, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3
|
||||
UNIT_FIELD_MAXOFFHANDDAMAGE = OBJECT_END + 0x0098, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3
|
||||
UNIT_FIELD_BYTES_1 = OBJECT_END + 0x0099, // Size: 1, Type: BYTES, Flags: PUBLIC
|
||||
UNIT_FIELD_PETNUMBER = OBJECT_END + 0x009A, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_PET_NAME_TIMESTAMP = OBJECT_END + 0x009B, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_PETEXPERIENCE = OBJECT_END + 0x009C, // Size: 1, Type: INT, Flags: OWNER_ONLY
|
||||
UNIT_FIELD_PETNEXTLEVELEXP = OBJECT_END + 0x009D, // Size: 1, Type: INT, Flags: OWNER_ONLY
|
||||
UNIT_DYNAMIC_FLAGS = OBJECT_END + 0x009E, // Size: 1, Type: INT, Flags: DYNAMIC
|
||||
UNIT_CHANNEL_SPELL = OBJECT_END + 0x009F, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_MOD_CAST_SPEED = OBJECT_END + 0x00A0, // Size: 1, Type: FLOAT, Flags: PUBLIC
|
||||
UNIT_CREATED_BY_SPELL = OBJECT_END + 0x00A1, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_NPC_FLAGS = OBJECT_END + 0x00A2, // Size: 1, Type: INT, Flags: DYNAMIC
|
||||
UNIT_NPC_EMOTESTATE = OBJECT_END + 0x00A3, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_TRAINING_POINTS = OBJECT_END + 0x00A4, // Size: 1, Type: TWO_SHORT, Flags: OWNER_ONLY
|
||||
UNIT_FIELD_STAT0 = OBJECT_END + 0x00A5, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_STAT1 = OBJECT_END + 0x00A6, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_STAT2 = OBJECT_END + 0x00A7, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_STAT3 = OBJECT_END + 0x00A8, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_STAT4 = OBJECT_END + 0x00A9, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_POSSTAT0 = OBJECT_END + 0x00AA, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_POSSTAT1 = OBJECT_END + 0x00AB, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_POSSTAT2 = OBJECT_END + 0x00AC, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_POSSTAT3 = OBJECT_END + 0x00AD, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_POSSTAT4 = OBJECT_END + 0x00AE, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_NEGSTAT0 = OBJECT_END + 0x00AF, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_NEGSTAT1 = OBJECT_END + 0x00B0, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_NEGSTAT2 = OBJECT_END + 0x00B1, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_NEGSTAT3 = OBJECT_END + 0x00B2, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_NEGSTAT4 = OBJECT_END + 0x00B3, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_RESISTANCES = OBJECT_END + 0x00B4, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY, UNK3
|
||||
UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE = OBJECT_END + 0x00BB, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE = OBJECT_END + 0x00C2, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_BASE_MANA = OBJECT_END + 0x00C9, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_BASE_HEALTH = OBJECT_END + 0x00CA, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_BYTES_2 = OBJECT_END + 0x00CB, // Size: 1, Type: BYTES, Flags: PUBLIC
|
||||
UNIT_FIELD_ATTACK_POWER = OBJECT_END + 0x00CC, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_ATTACK_POWER_MODS = OBJECT_END + 0x00CD, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x00CE, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_RANGED_ATTACK_POWER = OBJECT_END + 0x00CF, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_RANGED_ATTACK_POWER_MODS = OBJECT_END + 0x00D0, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x00D1, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_MINRANGEDDAMAGE = OBJECT_END + 0x00D2, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_MAXRANGEDDAMAGE = OBJECT_END + 0x00D3, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_POWER_COST_MODIFIER = OBJECT_END + 0x00D4, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_POWER_COST_MULTIPLIER = OBJECT_END + 0x00DB, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_MAXHEALTHMODIFIER = OBJECT_END + 0x00E2, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_PADDING = OBJECT_END + 0x00E3, // Size: 1, Type: INT, Flags: NONE
|
||||
UNIT_END = OBJECT_END + 0x00E4,
|
||||
UNIT_FIELD_BYTES_0 = OBJECT_END + 0x0010, // Size: 1, Type: BYTES, Flags: PUBLIC
|
||||
UNIT_FIELD_HEALTH = OBJECT_END + 0x0011, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_POWER1 = OBJECT_END + 0x0012, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_POWER2 = OBJECT_END + 0x0013, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_POWER3 = OBJECT_END + 0x0014, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_POWER4 = OBJECT_END + 0x0015, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_POWER5 = OBJECT_END + 0x0016, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_POWER6 = OBJECT_END + 0x0017, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_POWER7 = OBJECT_END + 0x0018, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_MAXHEALTH = OBJECT_END + 0x0019, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_MAXPOWER1 = OBJECT_END + 0x001A, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_MAXPOWER2 = OBJECT_END + 0x001B, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_MAXPOWER3 = OBJECT_END + 0x001C, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_MAXPOWER4 = OBJECT_END + 0x001D, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_MAXPOWER5 = OBJECT_END + 0x001E, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_MAXPOWER6 = OBJECT_END + 0x001F, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_MAXPOWER7 = OBJECT_END + 0x0020, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER = OBJECT_END + 0x0021, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER = OBJECT_END + 0x0028, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_LEVEL = OBJECT_END + 0x002F, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_FACTIONTEMPLATE = OBJECT_END + 0x0030, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_VIRTUAL_ITEM_SLOT_ID = OBJECT_END + 0x0031, // Size: 3, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_FLAGS = OBJECT_END + 0x0034, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_FLAGS_2 = OBJECT_END + 0x0035, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_AURASTATE = OBJECT_END + 0x0036, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_BASEATTACKTIME = OBJECT_END + 0x0037, // Size: 2, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_RANGEDATTACKTIME = OBJECT_END + 0x0039, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
UNIT_FIELD_BOUNDINGRADIUS = OBJECT_END + 0x003A, // Size: 1, Type: FLOAT, Flags: PUBLIC
|
||||
UNIT_FIELD_COMBATREACH = OBJECT_END + 0x003B, // Size: 1, Type: FLOAT, Flags: PUBLIC
|
||||
UNIT_FIELD_DISPLAYID = OBJECT_END + 0x003C, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_NATIVEDISPLAYID = OBJECT_END + 0x003D, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_MOUNTDISPLAYID = OBJECT_END + 0x003E, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_MINDAMAGE = OBJECT_END + 0x003F, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3
|
||||
UNIT_FIELD_MAXDAMAGE = OBJECT_END + 0x0040, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3
|
||||
UNIT_FIELD_MINOFFHANDDAMAGE = OBJECT_END + 0x0041, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3
|
||||
UNIT_FIELD_MAXOFFHANDDAMAGE = OBJECT_END + 0x0042, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3
|
||||
UNIT_FIELD_BYTES_1 = OBJECT_END + 0x0043, // Size: 1, Type: BYTES, Flags: PUBLIC
|
||||
UNIT_FIELD_PETNUMBER = OBJECT_END + 0x0044, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_PET_NAME_TIMESTAMP = OBJECT_END + 0x0045, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_PETEXPERIENCE = OBJECT_END + 0x0046, // Size: 1, Type: INT, Flags: OWNER_ONLY
|
||||
UNIT_FIELD_PETNEXTLEVELEXP = OBJECT_END + 0x0047, // Size: 1, Type: INT, Flags: OWNER_ONLY
|
||||
UNIT_DYNAMIC_FLAGS = OBJECT_END + 0x0048, // Size: 1, Type: INT, Flags: DYNAMIC
|
||||
UNIT_CHANNEL_SPELL = OBJECT_END + 0x0049, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_MOD_CAST_SPEED = OBJECT_END + 0x004A, // Size: 1, Type: FLOAT, Flags: PUBLIC
|
||||
UNIT_CREATED_BY_SPELL = OBJECT_END + 0x004B, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_NPC_FLAGS = OBJECT_END + 0x004C, // Size: 1, Type: INT, Flags: DYNAMIC
|
||||
UNIT_NPC_EMOTESTATE = OBJECT_END + 0x004D, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_STAT0 = OBJECT_END + 0x004E, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_STAT1 = OBJECT_END + 0x004F, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_STAT2 = OBJECT_END + 0x0050, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_STAT3 = OBJECT_END + 0x0051, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_STAT4 = OBJECT_END + 0x0052, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_POSSTAT0 = OBJECT_END + 0x0053, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_POSSTAT1 = OBJECT_END + 0x0054, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_POSSTAT2 = OBJECT_END + 0x0055, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_POSSTAT3 = OBJECT_END + 0x0056, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_POSSTAT4 = OBJECT_END + 0x0057, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_NEGSTAT0 = OBJECT_END + 0x0058, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_NEGSTAT1 = OBJECT_END + 0x0059, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_NEGSTAT2 = OBJECT_END + 0x005A, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_NEGSTAT3 = OBJECT_END + 0x005B, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_NEGSTAT4 = OBJECT_END + 0x005C, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_RESISTANCES = OBJECT_END + 0x005D, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY, UNK3
|
||||
UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE = OBJECT_END + 0x0064, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE = OBJECT_END + 0x006B, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_BASE_MANA = OBJECT_END + 0x0072, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
UNIT_FIELD_BASE_HEALTH = OBJECT_END + 0x0073, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_BYTES_2 = OBJECT_END + 0x0074, // Size: 1, Type: BYTES, Flags: PUBLIC
|
||||
UNIT_FIELD_ATTACK_POWER = OBJECT_END + 0x0075, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_ATTACK_POWER_MODS = OBJECT_END + 0x0076, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x0077, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_RANGED_ATTACK_POWER = OBJECT_END + 0x0078, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_RANGED_ATTACK_POWER_MODS = OBJECT_END + 0x0079, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x007A, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_MINRANGEDDAMAGE = OBJECT_END + 0x007B, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_MAXRANGEDDAMAGE = OBJECT_END + 0x007C, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_POWER_COST_MODIFIER = OBJECT_END + 0x007D, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_POWER_COST_MULTIPLIER = OBJECT_END + 0x0084, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_MAXHEALTHMODIFIER = OBJECT_END + 0x008B, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY
|
||||
UNIT_FIELD_HOVERHEIGHT = OBJECT_END + 0x008C, // Size: 1, Type: FLOAT, Flags: PUBLIC
|
||||
UNIT_FIELD_PADDING = OBJECT_END + 0x008D, // Size: 1, Type: INT, Flags: NONE
|
||||
UNIT_END = OBJECT_END + 0x008E,
|
||||
|
||||
PLAYER_DUEL_ARBITER = UNIT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_FLAGS = UNIT_END + 0x0002, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
@@ -262,160 +287,184 @@ enum EUnitFields
|
||||
PLAYER_QUEST_LOG_25_3 = UNIT_END + 0x006C, // Size: 1, Type: BYTES, Flags: PRIVATE
|
||||
PLAYER_QUEST_LOG_25_4 = UNIT_END + 0x006D, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_VISIBLE_ITEM_1_CREATOR = UNIT_END + 0x006E, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_1_0 = UNIT_END + 0x0070, // Size: 12, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_1_PROPERTIES = UNIT_END + 0x007C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_1_PAD = UNIT_END + 0x007D, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_2_CREATOR = UNIT_END + 0x007E, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_2_0 = UNIT_END + 0x0080, // Size: 12, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_2_PROPERTIES = UNIT_END + 0x008C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_2_PAD = UNIT_END + 0x008D, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_3_CREATOR = UNIT_END + 0x008E, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_3_0 = UNIT_END + 0x0090, // Size: 12, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_3_PROPERTIES = UNIT_END + 0x009C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_3_PAD = UNIT_END + 0x009D, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_4_CREATOR = UNIT_END + 0x009E, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_4_0 = UNIT_END + 0x00A0, // Size: 12, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_4_PROPERTIES = UNIT_END + 0x00AC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_4_PAD = UNIT_END + 0x00AD, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_5_CREATOR = UNIT_END + 0x00AE, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_5_0 = UNIT_END + 0x00B0, // Size: 12, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_5_PROPERTIES = UNIT_END + 0x00BC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_5_PAD = UNIT_END + 0x00BD, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_6_CREATOR = UNIT_END + 0x00BE, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_6_0 = UNIT_END + 0x00C0, // Size: 12, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_6_PROPERTIES = UNIT_END + 0x00CC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_6_PAD = UNIT_END + 0x00CD, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_7_CREATOR = UNIT_END + 0x00CE, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_7_0 = UNIT_END + 0x00D0, // Size: 12, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_7_PROPERTIES = UNIT_END + 0x00DC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_7_PAD = UNIT_END + 0x00DD, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_8_CREATOR = UNIT_END + 0x00DE, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_8_0 = UNIT_END + 0x00E0, // Size: 12, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_8_PROPERTIES = UNIT_END + 0x00EC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_8_PAD = UNIT_END + 0x00ED, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_9_CREATOR = UNIT_END + 0x00EE, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_9_0 = UNIT_END + 0x00F0, // Size: 12, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_9_PROPERTIES = UNIT_END + 0x00FC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_9_PAD = UNIT_END + 0x00FD, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_10_CREATOR = UNIT_END + 0x00FE, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_10_0 = UNIT_END + 0x0100, // Size: 12, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_10_PROPERTIES = UNIT_END + 0x010C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_10_PAD = UNIT_END + 0x010D, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_11_CREATOR = UNIT_END + 0x010E, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_11_0 = UNIT_END + 0x0110, // Size: 12, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_11_PROPERTIES = UNIT_END + 0x011C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_11_PAD = UNIT_END + 0x011D, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_12_CREATOR = UNIT_END + 0x011E, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_12_0 = UNIT_END + 0x0120, // Size: 12, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_12_PROPERTIES = UNIT_END + 0x012C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_12_PAD = UNIT_END + 0x012D, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_13_CREATOR = UNIT_END + 0x012E, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_13_0 = UNIT_END + 0x0130, // Size: 12, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_13_PROPERTIES = UNIT_END + 0x013C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_13_PAD = UNIT_END + 0x013D, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_14_CREATOR = UNIT_END + 0x013E, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_14_0 = UNIT_END + 0x0140, // Size: 12, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_14_PROPERTIES = UNIT_END + 0x014C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_14_PAD = UNIT_END + 0x014D, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_15_CREATOR = UNIT_END + 0x014E, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_15_0 = UNIT_END + 0x0150, // Size: 12, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_15_PROPERTIES = UNIT_END + 0x015C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_15_PAD = UNIT_END + 0x015D, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_16_CREATOR = UNIT_END + 0x015E, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_16_0 = UNIT_END + 0x0160, // Size: 12, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_16_PROPERTIES = UNIT_END + 0x016C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_16_PAD = UNIT_END + 0x016D, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_17_CREATOR = UNIT_END + 0x016E, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_17_0 = UNIT_END + 0x0170, // Size: 12, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_17_PROPERTIES = UNIT_END + 0x017C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_17_PAD = UNIT_END + 0x017D, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_18_CREATOR = UNIT_END + 0x017E, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_18_0 = UNIT_END + 0x0180, // Size: 12, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_18_PROPERTIES = UNIT_END + 0x018C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_18_PAD = UNIT_END + 0x018D, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_19_CREATOR = UNIT_END + 0x018E, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_19_0 = UNIT_END + 0x0190, // Size: 12, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_19_PROPERTIES = UNIT_END + 0x019C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_19_PAD = UNIT_END + 0x019D, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_CHOSEN_TITLE = UNIT_END + 0x019E, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_FIELD_PAD_0 = UNIT_END + 0x019F, // Size: 1, Type: INT, Flags: NONE
|
||||
PLAYER_FIELD_INV_SLOT_HEAD = UNIT_END + 0x01A0, // Size: 46, Type: LONG, Flags: PRIVATE
|
||||
PLAYER_FIELD_PACK_SLOT_1 = UNIT_END + 0x01CE, // Size: 32, Type: LONG, Flags: PRIVATE
|
||||
PLAYER_FIELD_BANK_SLOT_1 = UNIT_END + 0x01EE, // Size: 56, Type: LONG, Flags: PRIVATE
|
||||
PLAYER_FIELD_BANKBAG_SLOT_1 = UNIT_END + 0x0226, // Size: 14, Type: LONG, Flags: PRIVATE
|
||||
PLAYER_FIELD_VENDORBUYBACK_SLOT_1 = UNIT_END + 0x0234, // Size: 24, Type: LONG, Flags: PRIVATE
|
||||
PLAYER_FIELD_KEYRING_SLOT_1 = UNIT_END + 0x024C, // Size: 64, Type: LONG, Flags: PRIVATE
|
||||
PLAYER_FIELD_VANITYPET_SLOT_1 = UNIT_END + 0x028C, // Size: 36, Type: LONG, Flags: PRIVATE
|
||||
PLAYER_FARSIGHT = UNIT_END + 0x02B0, // Size: 2, Type: LONG, Flags: PRIVATE
|
||||
PLAYER__FIELD_KNOWN_TITLES = UNIT_END + 0x02B2, // Size: 2, Type: LONG, Flags: PRIVATE
|
||||
PLAYER_XP = UNIT_END + 0x02B4, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_NEXT_LEVEL_XP = UNIT_END + 0x02B5, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_SKILL_INFO_1_1 = UNIT_END + 0x02B6, // Size: 384, Type: TWO_SHORT, Flags: PRIVATE
|
||||
PLAYER_CHARACTER_POINTS1 = UNIT_END + 0x0436, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_CHARACTER_POINTS2 = UNIT_END + 0x0437, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_TRACK_CREATURES = UNIT_END + 0x0438, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_TRACK_RESOURCES = UNIT_END + 0x0439, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_BLOCK_PERCENTAGE = UNIT_END + 0x043A, // Size: 1, Type: FLOAT, Flags: PRIVATE
|
||||
PLAYER_DODGE_PERCENTAGE = UNIT_END + 0x043B, // Size: 1, Type: FLOAT, Flags: PRIVATE
|
||||
PLAYER_PARRY_PERCENTAGE = UNIT_END + 0x043C, // Size: 1, Type: FLOAT, Flags: PRIVATE
|
||||
PLAYER_EXPERTISE = UNIT_END + 0x043D, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_OFFHAND_EXPERTISE = UNIT_END + 0x043E, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_CRIT_PERCENTAGE = UNIT_END + 0x043F, // Size: 1, Type: FLOAT, Flags: PRIVATE
|
||||
PLAYER_RANGED_CRIT_PERCENTAGE = UNIT_END + 0x0440, // Size: 1, Type: FLOAT, Flags: PRIVATE
|
||||
PLAYER_OFFHAND_CRIT_PERCENTAGE = UNIT_END + 0x0441, // Size: 1, Type: FLOAT, Flags: PRIVATE
|
||||
PLAYER_SPELL_CRIT_PERCENTAGE1 = UNIT_END + 0x0442, // Size: 7, Type: FLOAT, Flags: PRIVATE
|
||||
PLAYER_SHIELD_BLOCK = UNIT_END + 0x0449, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_EXPLORED_ZONES_1 = UNIT_END + 0x044A, // Size: 128, Type: BYTES, Flags: PRIVATE
|
||||
PLAYER_REST_STATE_EXPERIENCE = UNIT_END + 0x04CA, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_COINAGE = UNIT_END + 0x04CB, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_MOD_DAMAGE_DONE_POS = UNIT_END + 0x04CC, // Size: 7, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_MOD_DAMAGE_DONE_NEG = UNIT_END + 0x04D3, // Size: 7, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_MOD_DAMAGE_DONE_PCT = UNIT_END + 0x04DA, // Size: 7, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_MOD_HEALING_DONE_POS = UNIT_END + 0x04E1, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_MOD_TARGET_RESISTANCE = UNIT_END + 0x04E2, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE = UNIT_END + 0x04E3, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_BYTES = UNIT_END + 0x04E4, // Size: 1, Type: BYTES, Flags: PRIVATE
|
||||
PLAYER_AMMO_ID = UNIT_END + 0x04E5, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_SELF_RES_SPELL = UNIT_END + 0x04E6, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_PVP_MEDALS = UNIT_END + 0x04E7, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_BUYBACK_PRICE_1 = UNIT_END + 0x04E8, // Size: 12, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_BUYBACK_TIMESTAMP_1 = UNIT_END + 0x04F4, // Size: 12, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_KILLS = UNIT_END + 0x0500, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE
|
||||
PLAYER_FIELD_TODAY_CONTRIBUTION = UNIT_END + 0x0501, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_YESTERDAY_CONTRIBUTION = UNIT_END + 0x0502, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_LIFETIME_HONORBALE_KILLS = UNIT_END + 0x0503, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_BYTES2 = UNIT_END + 0x0504, // Size: 1, Type: BYTES, Flags: PRIVATE
|
||||
PLAYER_FIELD_WATCHED_FACTION_INDEX = UNIT_END + 0x0505, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_COMBAT_RATING_1 = UNIT_END + 0x0506, // Size: 24, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_ARENA_TEAM_INFO_1_1 = UNIT_END + 0x051E, // Size: 18, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_HONOR_CURRENCY = UNIT_END + 0x0530, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_ARENA_CURRENCY = UNIT_END + 0x0531, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_MOD_MANA_REGEN = UNIT_END + 0x0532, // Size: 1, Type: FLOAT, Flags: PRIVATE
|
||||
PLAYER_FIELD_MOD_MANA_REGEN_INTERRUPT = UNIT_END + 0x0533, // Size: 1, Type: FLOAT, Flags: PRIVATE
|
||||
PLAYER_FIELD_MAX_LEVEL = UNIT_END + 0x0534, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_DAILY_QUESTS_1 = UNIT_END + 0x0535, // Size: 25, Type: INT, Flags: PRIVATE
|
||||
PLAYER_END = UNIT_END + 0x054E,
|
||||
PLAYER_VISIBLE_ITEM_1_0 = UNIT_END + 0x0070, // Size: 13, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_1_PROPERTIES = UNIT_END + 0x007D, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_1_SEED = UNIT_END + 0x007E, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_1_PAD = UNIT_END + 0x007F, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_2_CREATOR = UNIT_END + 0x0080, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_2_0 = UNIT_END + 0x0082, // Size: 13, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_2_PROPERTIES = UNIT_END + 0x008F, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_2_SEED = UNIT_END + 0x0090, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_2_PAD = UNIT_END + 0x0091, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_3_CREATOR = UNIT_END + 0x0092, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_3_0 = UNIT_END + 0x0094, // Size: 13, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_3_PROPERTIES = UNIT_END + 0x00A1, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_3_SEED = UNIT_END + 0x00A2, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_3_PAD = UNIT_END + 0x00A3, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_4_CREATOR = UNIT_END + 0x00A4, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_4_0 = UNIT_END + 0x00A6, // Size: 13, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_4_PROPERTIES = UNIT_END + 0x00B3, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_4_SEED = UNIT_END + 0x00B4, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_4_PAD = UNIT_END + 0x00B5, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_5_CREATOR = UNIT_END + 0x00B6, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_5_0 = UNIT_END + 0x00B8, // Size: 13, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_5_PROPERTIES = UNIT_END + 0x00C5, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_5_SEED = UNIT_END + 0x00C6, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_5_PAD = UNIT_END + 0x00C7, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_6_CREATOR = UNIT_END + 0x00C8, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_6_0 = UNIT_END + 0x00CA, // Size: 13, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_6_PROPERTIES = UNIT_END + 0x00D7, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_6_SEED = UNIT_END + 0x00D8, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_6_PAD = UNIT_END + 0x00D9, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_7_CREATOR = UNIT_END + 0x00DA, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_7_0 = UNIT_END + 0x00DC, // Size: 13, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_7_PROPERTIES = UNIT_END + 0x00E9, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_7_SEED = UNIT_END + 0x00EA, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_7_PAD = UNIT_END + 0x00EB, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_8_CREATOR = UNIT_END + 0x00EC, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_8_0 = UNIT_END + 0x00EE, // Size: 13, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_8_PROPERTIES = UNIT_END + 0x00FB, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_8_SEED = UNIT_END + 0x00FC, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_8_PAD = UNIT_END + 0x00FD, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_9_CREATOR = UNIT_END + 0x00FE, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_9_0 = UNIT_END + 0x0100, // Size: 13, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_9_PROPERTIES = UNIT_END + 0x010D, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_9_SEED = UNIT_END + 0x010E, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_9_PAD = UNIT_END + 0x010F, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_10_CREATOR = UNIT_END + 0x0110, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_10_0 = UNIT_END + 0x0112, // Size: 13, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_10_PROPERTIES = UNIT_END + 0x011F, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_10_SEED = UNIT_END + 0x0120, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_10_PAD = UNIT_END + 0x0121, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_11_CREATOR = UNIT_END + 0x0122, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_11_0 = UNIT_END + 0x0124, // Size: 13, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_11_PROPERTIES = UNIT_END + 0x0131, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_11_SEED = UNIT_END + 0x0132, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_11_PAD = UNIT_END + 0x0133, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_12_CREATOR = UNIT_END + 0x0134, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_12_0 = UNIT_END + 0x0136, // Size: 13, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_12_PROPERTIES = UNIT_END + 0x0143, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_12_SEED = UNIT_END + 0x0144, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_12_PAD = UNIT_END + 0x0145, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_13_CREATOR = UNIT_END + 0x0146, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_13_0 = UNIT_END + 0x0148, // Size: 13, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_13_PROPERTIES = UNIT_END + 0x0155, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_13_SEED = UNIT_END + 0x0156, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_13_PAD = UNIT_END + 0x0157, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_14_CREATOR = UNIT_END + 0x0158, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_14_0 = UNIT_END + 0x015A, // Size: 13, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_14_PROPERTIES = UNIT_END + 0x0167, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_14_SEED = UNIT_END + 0x0168, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_14_PAD = UNIT_END + 0x0169, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_15_CREATOR = UNIT_END + 0x016A, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_15_0 = UNIT_END + 0x016C, // Size: 13, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_15_PROPERTIES = UNIT_END + 0x0179, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_15_SEED = UNIT_END + 0x017A, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_15_PAD = UNIT_END + 0x017B, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_16_CREATOR = UNIT_END + 0x017C, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_16_0 = UNIT_END + 0x017E, // Size: 13, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_16_PROPERTIES = UNIT_END + 0x018B, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_16_SEED = UNIT_END + 0x018C, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_16_PAD = UNIT_END + 0x018D, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_17_CREATOR = UNIT_END + 0x018E, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_17_0 = UNIT_END + 0x0190, // Size: 13, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_17_PROPERTIES = UNIT_END + 0x019D, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_17_SEED = UNIT_END + 0x019E, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_17_PAD = UNIT_END + 0x019F, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_18_CREATOR = UNIT_END + 0x01A0, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_18_0 = UNIT_END + 0x01A2, // Size: 13, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_18_PROPERTIES = UNIT_END + 0x01AF, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_18_SEED = UNIT_END + 0x01B0, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_18_PAD = UNIT_END + 0x01B1, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_19_CREATOR = UNIT_END + 0x01B2, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_19_0 = UNIT_END + 0x01B4, // Size: 13, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_19_PROPERTIES = UNIT_END + 0x01C1, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_19_SEED = UNIT_END + 0x01C2, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_VISIBLE_ITEM_19_PAD = UNIT_END + 0x01C3, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_CHOSEN_TITLE = UNIT_END + 0x01C4, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
PLAYER_FIELD_PAD_0 = UNIT_END + 0x01C5, // Size: 1, Type: INT, Flags: NONE
|
||||
PLAYER_FIELD_INV_SLOT_HEAD = UNIT_END + 0x01C6, // Size: 46, Type: LONG, Flags: PRIVATE
|
||||
PLAYER_FIELD_PACK_SLOT_1 = UNIT_END + 0x01F4, // Size: 32, Type: LONG, Flags: PRIVATE
|
||||
PLAYER_FIELD_BANK_SLOT_1 = UNIT_END + 0x0214, // Size: 56, Type: LONG, Flags: PRIVATE
|
||||
PLAYER_FIELD_BANKBAG_SLOT_1 = UNIT_END + 0x024C, // Size: 14, Type: LONG, Flags: PRIVATE
|
||||
PLAYER_FIELD_VENDORBUYBACK_SLOT_1 = UNIT_END + 0x025A, // Size: 24, Type: LONG, Flags: PRIVATE
|
||||
PLAYER_FIELD_KEYRING_SLOT_1 = UNIT_END + 0x0272, // Size: 64, Type: LONG, Flags: PRIVATE
|
||||
PLAYER_FIELD_VANITYPET_SLOT_1 = UNIT_END + 0x02B2, // Size: 36, Type: LONG, Flags: PRIVATE
|
||||
PLAYER_FIELD_CURRENCYTOKEN_SLOT_1 = UNIT_END + 0x02D6, // Size: 64, Type: LONG, Flags: PRIVATE
|
||||
PLAYER_FIELD_QUESTBAG_SLOT_1 = UNIT_END + 0x0316, // Size: 64, Type: LONG, Flags: PRIVATE
|
||||
PLAYER_FARSIGHT = UNIT_END + 0x0356, // Size: 2, Type: LONG, Flags: PRIVATE
|
||||
PLAYER__FIELD_KNOWN_TITLES = UNIT_END + 0x0358, // Size: 2, Type: LONG, Flags: PRIVATE
|
||||
PLAYER__FIELD_KNOWN_TITLES1 = UNIT_END + 0x035A, // Size: 2, Type: LONG, Flags: PRIVATE
|
||||
PLAYER_FIELD_KNOWN_CURRENCIES = UNIT_END + 0x035C, // Size: 2, Type: LONG, Flags: PRIVATE
|
||||
PLAYER_XP = UNIT_END + 0x035E, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_NEXT_LEVEL_XP = UNIT_END + 0x035F, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_SKILL_INFO_1_1 = UNIT_END + 0x0360, // Size: 384, Type: TWO_SHORT, Flags: PRIVATE
|
||||
PLAYER_CHARACTER_POINTS1 = UNIT_END + 0x04E0, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_CHARACTER_POINTS2 = UNIT_END + 0x04E1, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_TRACK_CREATURES = UNIT_END + 0x04E2, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_TRACK_RESOURCES = UNIT_END + 0x04E3, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_BLOCK_PERCENTAGE = UNIT_END + 0x04E4, // Size: 1, Type: FLOAT, Flags: PRIVATE
|
||||
PLAYER_DODGE_PERCENTAGE = UNIT_END + 0x04E5, // Size: 1, Type: FLOAT, Flags: PRIVATE
|
||||
PLAYER_PARRY_PERCENTAGE = UNIT_END + 0x04E6, // Size: 1, Type: FLOAT, Flags: PRIVATE
|
||||
PLAYER_EXPERTISE = UNIT_END + 0x04E7, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_OFFHAND_EXPERTISE = UNIT_END + 0x04E8, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_CRIT_PERCENTAGE = UNIT_END + 0x04E9, // Size: 1, Type: FLOAT, Flags: PRIVATE
|
||||
PLAYER_RANGED_CRIT_PERCENTAGE = UNIT_END + 0x04EA, // Size: 1, Type: FLOAT, Flags: PRIVATE
|
||||
PLAYER_OFFHAND_CRIT_PERCENTAGE = UNIT_END + 0x04EB, // Size: 1, Type: FLOAT, Flags: PRIVATE
|
||||
PLAYER_SPELL_CRIT_PERCENTAGE1 = UNIT_END + 0x04EC, // Size: 7, Type: FLOAT, Flags: PRIVATE
|
||||
PLAYER_SHIELD_BLOCK = UNIT_END + 0x04F3, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_SHIELD_BLOCK_CRIT_PERCENTAGE = UNIT_END + 0x04F4, // Size: 1, Type: FLOAT, Flags: PRIVATE
|
||||
PLAYER_EXPLORED_ZONES_1 = UNIT_END + 0x04F5, // Size: 128, Type: BYTES, Flags: PRIVATE
|
||||
PLAYER_REST_STATE_EXPERIENCE = UNIT_END + 0x0575, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_COINAGE = UNIT_END + 0x0576, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_MOD_DAMAGE_DONE_POS = UNIT_END + 0x0577, // Size: 7, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_MOD_DAMAGE_DONE_NEG = UNIT_END + 0x057E, // Size: 7, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_MOD_DAMAGE_DONE_PCT = UNIT_END + 0x0585, // Size: 7, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_MOD_HEALING_DONE_POS = UNIT_END + 0x058C, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_MOD_TARGET_RESISTANCE = UNIT_END + 0x058D, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE = UNIT_END + 0x058E, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_BYTES = UNIT_END + 0x058F, // Size: 1, Type: BYTES, Flags: PRIVATE
|
||||
PLAYER_AMMO_ID = UNIT_END + 0x0590, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_SELF_RES_SPELL = UNIT_END + 0x0591, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_PVP_MEDALS = UNIT_END + 0x0592, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_BUYBACK_PRICE_1 = UNIT_END + 0x0593, // Size: 12, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_BUYBACK_TIMESTAMP_1 = UNIT_END + 0x059F, // Size: 12, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_KILLS = UNIT_END + 0x05AB, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE
|
||||
PLAYER_FIELD_TODAY_CONTRIBUTION = UNIT_END + 0x05AC, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_YESTERDAY_CONTRIBUTION = UNIT_END + 0x05AD, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_LIFETIME_HONORBALE_KILLS = UNIT_END + 0x05AE, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_BYTES2 = UNIT_END + 0x05AF, // Size: 1, Type: BYTES, Flags: PRIVATE
|
||||
PLAYER_FIELD_WATCHED_FACTION_INDEX = UNIT_END + 0x05B0, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_COMBAT_RATING_1 = UNIT_END + 0x05B1, // Size: 25, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_ARENA_TEAM_INFO_1_1 = UNIT_END + 0x05CA, // Size: 18, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_HONOR_CURRENCY = UNIT_END + 0x05DC, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_ARENA_CURRENCY = UNIT_END + 0x05DD, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_MAX_LEVEL = UNIT_END + 0x05DE, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_DAILY_QUESTS_1 = UNIT_END + 0x05DF, // Size: 25, Type: INT, Flags: PRIVATE
|
||||
PLAYER_RUNE_REGEN_1 = UNIT_END + 0x05F8, // Size: 4, Type: FLOAT, Flags: PRIVATE
|
||||
PLAYER_NO_REAGENT_COST_1 = UNIT_END + 0x05FC, // Size: 3, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_GLYPH_SLOTS_1 = UNIT_END + 0x05FF, // Size: 8, Type: INT, Flags: PRIVATE
|
||||
PLAYER_FIELD_GLYPHS_1 = UNIT_END + 0x0607, // Size: 8, Type: INT, Flags: PRIVATE
|
||||
PLAYER_GLYPHS_ENABLED = UNIT_END + 0x060F, // Size: 1, Type: INT, Flags: PRIVATE
|
||||
PLAYER_END = UNIT_END + 0x0610,
|
||||
};
|
||||
|
||||
enum EGameObjectFields
|
||||
{
|
||||
OBJECT_FIELD_CREATED_BY = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
GAMEOBJECT_DISPLAYID = OBJECT_END + 0x0002, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
GAMEOBJECT_FLAGS = OBJECT_END + 0x0003, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
GAMEOBJECT_ROTATION = OBJECT_END + 0x0004, // Size: 4, Type: FLOAT, Flags: PUBLIC
|
||||
GAMEOBJECT_STATE = OBJECT_END + 0x0008, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
GAMEOBJECT_POS_X = OBJECT_END + 0x0009, // Size: 1, Type: FLOAT, Flags: PUBLIC
|
||||
GAMEOBJECT_POS_Y = OBJECT_END + 0x000A, // Size: 1, Type: FLOAT, Flags: PUBLIC
|
||||
GAMEOBJECT_POS_Z = OBJECT_END + 0x000B, // Size: 1, Type: FLOAT, Flags: PUBLIC
|
||||
GAMEOBJECT_FACING = OBJECT_END + 0x000C, // Size: 1, Type: FLOAT, Flags: PUBLIC
|
||||
GAMEOBJECT_DYN_FLAGS = OBJECT_END + 0x000D, // Size: 1, Type: INT, Flags: DYNAMIC
|
||||
GAMEOBJECT_FACTION = OBJECT_END + 0x000E, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
GAMEOBJECT_TYPE_ID = OBJECT_END + 0x000F, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
GAMEOBJECT_FLAGS = OBJECT_END + 0x0003, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
|
||||
GAMEOBJECT_ROTATION = OBJECT_END + 0x0004, // Size: 2, Type: LONG, Flags: PUBLIC
|
||||
GAMEOBJECT_PARENTROTATION = OBJECT_END + 0x0006, // Size: 4, Type: FLOAT, Flags: PUBLIC
|
||||
GAMEOBJECT_POS_X = OBJECT_END + 0x000A, // Size: 1, Type: FLOAT, Flags: PUBLIC
|
||||
GAMEOBJECT_POS_Y = OBJECT_END + 0x000B, // Size: 1, Type: FLOAT, Flags: PUBLIC
|
||||
GAMEOBJECT_POS_Z = OBJECT_END + 0x000C, // Size: 1, Type: FLOAT, Flags: PUBLIC
|
||||
GAMEOBJECT_FACING = OBJECT_END + 0x000D, // Size: 1, Type: FLOAT, Flags: PUBLIC
|
||||
GAMEOBJECT_DYNAMIC = OBJECT_END + 0x000E, // Size: 1, Type: TWO_SHORT, Flags: DYNAMIC
|
||||
GAMEOBJECT_FACTION = OBJECT_END + 0x000F, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
GAMEOBJECT_LEVEL = OBJECT_END + 0x0010, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
GAMEOBJECT_ARTKIT = OBJECT_END + 0x0011, // Size: 1, Type: INT, Flags: PUBLIC
|
||||
GAMEOBJECT_ANIMPROGRESS = OBJECT_END + 0x0012, // Size: 1, Type: INT, Flags: DYNAMIC
|
||||
GAMEOBJECT_PADDING = OBJECT_END + 0x0013, // Size: 1, Type: INT, Flags: NONE
|
||||
GAMEOBJECT_END = OBJECT_END + 0x0014,
|
||||
GAMEOBJECT_BYTES_1 = OBJECT_END + 0x0011, // Size: 1, Type: BYTES, Flags: PUBLIC
|
||||
GAMEOBJECT_END = OBJECT_END + 0x0012,
|
||||
};
|
||||
|
||||
enum EDynamicObjectFields
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Common.h"
|
||||
#include "Log.h"
|
||||
#include "WorldSession.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "Vehicle.h"
|
||||
#include "MapManager.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "Unit.h"
|
||||
#include "Util.h"
|
||||
|
||||
Vehicle::Vehicle() : Creature(), m_vehicleId(0)
|
||||
{
|
||||
m_isVehicle = true;
|
||||
m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_LIVING | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_VEHICLE);
|
||||
}
|
||||
|
||||
Vehicle::~Vehicle()
|
||||
{
|
||||
if(m_uint32Values) // only for fully created Object
|
||||
ObjectAccessor::Instance().RemoveObject(this);
|
||||
}
|
||||
|
||||
void Vehicle::AddToWorld()
|
||||
{
|
||||
///- Register the vehicle for guid lookup
|
||||
if(!IsInWorld()) ObjectAccessor::Instance().AddObject(this);
|
||||
Unit::AddToWorld();
|
||||
}
|
||||
|
||||
void Vehicle::RemoveFromWorld()
|
||||
{
|
||||
///- Remove the vehicle from the accessor
|
||||
if(IsInWorld()) ObjectAccessor::Instance().RemoveObject(this);
|
||||
///- Don't call the function for Creature, normal mobs + totems go in a different storage
|
||||
Unit::RemoveFromWorld();
|
||||
}
|
||||
|
||||
void Vehicle::setDeathState(DeathState s) // overwrite virtual Creature::setDeathState and Unit::setDeathState
|
||||
{
|
||||
Creature::setDeathState(s);
|
||||
}
|
||||
|
||||
void Vehicle::Update(uint32 diff)
|
||||
{
|
||||
Creature::Update(diff);
|
||||
}
|
||||
|
||||
bool Vehicle::Create(uint32 guidlow, Map *map, uint32 Entry, uint32 vehicleId, uint32 team)
|
||||
{
|
||||
SetMapId(map->GetId());
|
||||
SetInstanceId(map->GetInstanceId());
|
||||
|
||||
Object::_Create(guidlow, Entry, HIGHGUID_VEHICLE);
|
||||
|
||||
if(!InitEntry(Entry, team))
|
||||
return false;
|
||||
|
||||
m_defaultMovementType = IDLE_MOTION_TYPE;
|
||||
|
||||
AIM_Initialize();
|
||||
|
||||
SetVehicleId(vehicleId);
|
||||
|
||||
SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
|
||||
SetFloatValue(UNIT_FIELD_HOVERHEIGHT, 1.0f);
|
||||
|
||||
CreatureInfo const *ci = GetCreatureInfo();
|
||||
setFaction(team == ALLIANCE ? ci->faction_A : ci->faction_H);
|
||||
SetMaxHealth(ci->maxhealth);
|
||||
SelectLevel(ci);
|
||||
SetHealth(GetMaxHealth());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Vehicle::Dismiss()
|
||||
{
|
||||
SendObjectDeSpawnAnim(GetGUID());
|
||||
CombatStop();
|
||||
CleanupsBeforeDelete();
|
||||
AddObjectToRemoveList();
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef MANGOSSERVER_VEHICLE_H
|
||||
#define MANGOSSERVER_VEHICLE_H
|
||||
|
||||
#include "ObjectDefines.h"
|
||||
#include "Creature.h"
|
||||
#include "Unit.h"
|
||||
|
||||
class Vehicle : public Creature
|
||||
{
|
||||
public:
|
||||
explicit Vehicle();
|
||||
virtual ~Vehicle();
|
||||
|
||||
void AddToWorld();
|
||||
void RemoveFromWorld();
|
||||
|
||||
bool Create (uint32 guidlow, Map *map, uint32 Entry, uint32 vehicleId, uint32 team);
|
||||
|
||||
void setDeathState(DeathState s); // overwrite virtual Creature::setDeathState and Unit::setDeathState
|
||||
void Update(uint32 diff); // overwrite virtual Creature::Update and Unit::Update
|
||||
|
||||
uint32 GetVehicleId() { return m_vehicleId; }
|
||||
void SetVehicleId(uint32 vehicleid) { m_vehicleId = vehicleid; }
|
||||
|
||||
void Dismiss();
|
||||
|
||||
protected:
|
||||
uint32 m_vehicleId;
|
||||
|
||||
private:
|
||||
void SaveToDB(uint32, uint8) // overwrited of Creature::SaveToDB - don't must be called
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
void DeleteFromDB() // overwrited of Creature::DeleteFromDB - don't must be called
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
+67
-22
@@ -232,7 +232,7 @@ World::AddSession_ (WorldSession* s)
|
||||
|
||||
uint32 Sessions = GetActiveAndQueuedSessionCount ();
|
||||
uint32 pLimit = GetPlayerAmountLimit ();
|
||||
uint32 QueueSize = GetQueueSize (); //number of players in the queue
|
||||
uint32 QueueSize = GetQueueSize (); //number of players in the queue
|
||||
|
||||
//so we don't count the user trying to
|
||||
//login as a session and queue the socket that we are using
|
||||
@@ -249,10 +249,10 @@ World::AddSession_ (WorldSession* s)
|
||||
|
||||
WorldPacket packet(SMSG_AUTH_RESPONSE, 1 + 4 + 1 + 4 + 1);
|
||||
packet << uint8 (AUTH_OK);
|
||||
packet << uint32 (0); // unknown random value...
|
||||
packet << uint8 (0);
|
||||
packet << uint32 (0);
|
||||
packet << uint8 (s->Expansion()); // 0 - normal, 1 - TBC, must be set in database manually for each account
|
||||
packet << uint32 (0); // BillingTimeRemaining
|
||||
packet << uint8 (0); // BillingPlanFlags
|
||||
packet << uint32 (0); // BillingTimeRested
|
||||
packet << uint8 (s->Expansion()); // 0 - normal, 1 - TBC, must be set in database manually for each account
|
||||
s->SendPacket (&packet);
|
||||
|
||||
UpdateMaxSessionCounters ();
|
||||
@@ -260,7 +260,7 @@ World::AddSession_ (WorldSession* s)
|
||||
// Updates the population
|
||||
if (pLimit > 0)
|
||||
{
|
||||
float popu = GetActiveSessionCount (); //updated number of users on the server
|
||||
float popu = GetActiveSessionCount (); //updated number of users on the server
|
||||
popu /= pLimit;
|
||||
popu *= 2;
|
||||
loginDatabase.PExecute ("UPDATE realmlist SET population = '%f' WHERE id = '%d'", popu, realmID);
|
||||
@@ -287,10 +287,10 @@ void World::AddQueuedPlayer(WorldSession* sess)
|
||||
// The 1st SMSG_AUTH_RESPONSE needs to contain other info too.
|
||||
WorldPacket packet (SMSG_AUTH_RESPONSE, 1 + 4 + 1 + 4 + 1);
|
||||
packet << uint8 (AUTH_WAIT_QUEUE);
|
||||
packet << uint32 (0); // unknown random value...
|
||||
packet << uint8 (0);
|
||||
packet << uint32 (0);
|
||||
packet << uint8 (sess->Expansion () ? 1 : 0); // 0 - normal, 1 - TBC, must be set in database manually for each account
|
||||
packet << uint32 (0); // BillingTimeRemaining
|
||||
packet << uint8 (0); // BillingPlanFlags
|
||||
packet << uint32 (0); // BillingTimeRested
|
||||
packet << uint8 (sess->Expansion () ? 1 : 0); // 0 - normal, 1 - TBC, must be set in database manually for each account
|
||||
packet << uint32(GetQueuePos (sess));
|
||||
sess->SendPacket (&packet);
|
||||
|
||||
@@ -408,24 +408,30 @@ void World::LoadConfigSettings(bool reload)
|
||||
rate_values[RATE_HEALTH] = sConfig.GetFloatDefault("Rate.Health", 1);
|
||||
if(rate_values[RATE_HEALTH] < 0)
|
||||
{
|
||||
sLog.outError("Rate.Health (%f) mustbe > 0. Using 1 instead.",rate_values[RATE_HEALTH]);
|
||||
sLog.outError("Rate.Health (%f) must be > 0. Using 1 instead.",rate_values[RATE_HEALTH]);
|
||||
rate_values[RATE_HEALTH] = 1;
|
||||
}
|
||||
rate_values[RATE_POWER_MANA] = sConfig.GetFloatDefault("Rate.Mana", 1);
|
||||
if(rate_values[RATE_POWER_MANA] < 0)
|
||||
{
|
||||
sLog.outError("Rate.Mana (%f) mustbe > 0. Using 1 instead.",rate_values[RATE_POWER_MANA]);
|
||||
sLog.outError("Rate.Mana (%f) must be > 0. Using 1 instead.",rate_values[RATE_POWER_MANA]);
|
||||
rate_values[RATE_POWER_MANA] = 1;
|
||||
}
|
||||
rate_values[RATE_POWER_RAGE_INCOME] = sConfig.GetFloatDefault("Rate.Rage.Income", 1);
|
||||
rate_values[RATE_POWER_RAGE_LOSS] = sConfig.GetFloatDefault("Rate.Rage.Loss", 1);
|
||||
if(rate_values[RATE_POWER_RAGE_LOSS] < 0)
|
||||
{
|
||||
sLog.outError("Rate.Rage.Loss (%f) mustbe > 0. Using 1 instead.",rate_values[RATE_POWER_RAGE_LOSS]);
|
||||
sLog.outError("Rate.Rage.Loss (%f) must be > 0. Using 1 instead.",rate_values[RATE_POWER_RAGE_LOSS]);
|
||||
rate_values[RATE_POWER_RAGE_LOSS] = 1;
|
||||
}
|
||||
rate_values[RATE_POWER_RUNICPOWER_INCOME] = sConfig.GetFloatDefault("Rate.RunicPower.Income", 1);
|
||||
rate_values[RATE_POWER_RUNICPOWER_LOSS] = sConfig.GetFloatDefault("Rate.RunicPower.Loss", 1);
|
||||
if(rate_values[RATE_POWER_RUNICPOWER_LOSS] < 0)
|
||||
{
|
||||
sLog.outError("Rate.RunicPower.Loss (%f) must be > 0. Using 1 instead.",rate_values[RATE_POWER_RUNICPOWER_LOSS]);
|
||||
rate_values[RATE_POWER_RUNICPOWER_LOSS] = 1;
|
||||
}
|
||||
rate_values[RATE_POWER_FOCUS] = sConfig.GetFloatDefault("Rate.Focus", 1.0f);
|
||||
rate_values[RATE_LOYALTY] = sConfig.GetFloatDefault("Rate.Loyalty", 1.0f);
|
||||
rate_values[RATE_SKILL_DISCOVERY] = sConfig.GetFloatDefault("Rate.Skill.Discovery", 1.0f);
|
||||
rate_values[RATE_DROP_ITEM_POOR] = sConfig.GetFloatDefault("Rate.Drop.Item.Poor", 1.0f);
|
||||
rate_values[RATE_DROP_ITEM_NORMAL] = sConfig.GetFloatDefault("Rate.Drop.Item.Normal", 1.0f);
|
||||
@@ -617,6 +623,15 @@ void World::LoadConfigSettings(bool reload)
|
||||
m_configs[CONFIG_CHARACTERS_PER_ACCOUNT] = m_configs[CONFIG_CHARACTERS_PER_REALM];
|
||||
}
|
||||
|
||||
m_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM] = sConfig.GetIntDefault("HeroicCharactersPerRealm", 1);
|
||||
if(m_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM] < 0 || m_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM] > 10)
|
||||
{
|
||||
sLog.outError("HeroicCharactersPerRealm (%i) must be in range 0..10. Set to 1.",m_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM]);
|
||||
m_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM] = 1;
|
||||
}
|
||||
|
||||
m_configs[CONFIG_MIN_LEVEL_FOR_HEROIC_CHARACTER_CREATING] = sConfig.GetIntDefault("MinLevelForHeroicCharacterCreating", 55);
|
||||
|
||||
m_configs[CONFIG_SKIP_CINEMATICS] = sConfig.GetIntDefault("SkipCinematics", 0);
|
||||
if(m_configs[CONFIG_SKIP_CINEMATICS] < 0 || m_configs[CONFIG_SKIP_CINEMATICS] > 2)
|
||||
{
|
||||
@@ -651,6 +666,20 @@ void World::LoadConfigSettings(bool reload)
|
||||
m_configs[CONFIG_START_PLAYER_LEVEL] = m_configs[CONFIG_MAX_PLAYER_LEVEL];
|
||||
}
|
||||
|
||||
m_configs[CONFIG_START_HEROIC_PLAYER_LEVEL] = sConfig.GetIntDefault("StartHeroicPlayerLevel", 55);
|
||||
if(m_configs[CONFIG_START_HEROIC_PLAYER_LEVEL] < 1)
|
||||
{
|
||||
sLog.outError("StartHeroicPlayerLevel (%i) must be in range 1..MaxPlayerLevel(%u). Set to 55.",
|
||||
m_configs[CONFIG_START_HEROIC_PLAYER_LEVEL],m_configs[CONFIG_MAX_PLAYER_LEVEL]);
|
||||
m_configs[CONFIG_START_HEROIC_PLAYER_LEVEL] = 55;
|
||||
}
|
||||
else if(m_configs[CONFIG_START_HEROIC_PLAYER_LEVEL] > m_configs[CONFIG_MAX_PLAYER_LEVEL])
|
||||
{
|
||||
sLog.outError("StartHeroicPlayerLevel (%i) must be in range 1..MaxPlayerLevel(%u). Set to %u.",
|
||||
m_configs[CONFIG_START_HEROIC_PLAYER_LEVEL],m_configs[CONFIG_MAX_PLAYER_LEVEL],m_configs[CONFIG_MAX_PLAYER_LEVEL]);
|
||||
m_configs[CONFIG_START_HEROIC_PLAYER_LEVEL] = m_configs[CONFIG_MAX_PLAYER_LEVEL];
|
||||
}
|
||||
|
||||
m_configs[CONFIG_START_PLAYER_MONEY] = sConfig.GetIntDefault("StartPlayerMoney", 0);
|
||||
if(m_configs[CONFIG_START_PLAYER_MONEY] < 0)
|
||||
{
|
||||
@@ -723,17 +752,17 @@ void World::LoadConfigSettings(bool reload)
|
||||
m_configs[CONFIG_MIN_PETITION_SIGNS] = sConfig.GetIntDefault("MinPetitionSigns", 9);
|
||||
if(m_configs[CONFIG_MIN_PETITION_SIGNS] > 9)
|
||||
{
|
||||
sLog.outError("MinPetitionSigns (%i) must be in range 0..9. Set to 9.",m_configs[CONFIG_MIN_PETITION_SIGNS]);
|
||||
sLog.outError("MinPetitionSigns (%i) must be in range 0..9. Set to 9.", m_configs[CONFIG_MIN_PETITION_SIGNS]);
|
||||
m_configs[CONFIG_MIN_PETITION_SIGNS] = 9;
|
||||
}
|
||||
|
||||
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_CHAT] = sConfig.GetIntDefault("GM.Chat",2);
|
||||
m_configs[CONFIG_GM_WISPERING_TO] = sConfig.GetIntDefault("GM.WhisperingTo",2);
|
||||
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_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);
|
||||
m_configs[CONFIG_GM_IN_WHO_LIST] = sConfig.GetBoolDefault("GM.InWhoList",false);
|
||||
m_configs[CONFIG_GM_IN_GM_LIST] = sConfig.GetBoolDefault("GM.InGMList", false);
|
||||
m_configs[CONFIG_GM_IN_WHO_LIST] = sConfig.GetBoolDefault("GM.InWhoList", false);
|
||||
m_configs[CONFIG_GM_LOG_TRADE] = sConfig.GetBoolDefault("GM.LogTrade", false);
|
||||
|
||||
m_configs[CONFIG_START_GM_LEVEL] = sConfig.GetIntDefault("GM.StartLevel", 1);
|
||||
@@ -774,6 +803,7 @@ void World::LoadConfigSettings(bool reload)
|
||||
m_configs[CONFIG_SKILL_CHANCE_SKINNING_STEPS] = sConfig.GetIntDefault("SkillChance.SkinningSteps",75);
|
||||
|
||||
m_configs[CONFIG_SKILL_PROSPECTING] = sConfig.GetBoolDefault("SkillChance.Prospecting",false);
|
||||
m_configs[CONFIG_SKILL_MILLING] = sConfig.GetBoolDefault("SkillChance.Milling",false);
|
||||
|
||||
m_configs[CONFIG_SKILL_GAIN_CRAFTING] = sConfig.GetIntDefault("SkillGain.Crafting", 1);
|
||||
if(m_configs[CONFIG_SKILL_GAIN_CRAFTING] < 0)
|
||||
@@ -1059,12 +1089,18 @@ void World::SetInitialWorldSettings()
|
||||
sLog.outString( "Loading InstanceTemplate" );
|
||||
objmgr.LoadInstanceTemplate();
|
||||
|
||||
sLog.outString( "Loading AchievementCriteriaList..." );
|
||||
objmgr.LoadAchievementCriteriaList();
|
||||
|
||||
sLog.outString( "Loading completed achievements..." );
|
||||
objmgr.LoadCompletedAchievements();
|
||||
|
||||
sLog.outString( "Loading SkillLineAbilityMultiMap Data..." );
|
||||
spellmgr.LoadSkillLineAbilityMap();
|
||||
|
||||
///- Clean up and pack instances
|
||||
sLog.outString( "Cleaning up instances..." );
|
||||
sInstanceSaveManager.CleanupInstances(); // must be called before `creature_respawn`/`gameobject_respawn` tables
|
||||
sInstanceSaveManager.CleanupInstances(); // must be called before `creature_respawn`/`gameobject_respawn` tables
|
||||
|
||||
sLog.outString( "Packing instances..." );
|
||||
sInstanceSaveManager.PackInstances();
|
||||
@@ -1190,6 +1226,9 @@ void World::SetInitialWorldSettings()
|
||||
sLog.outString( "Loading spell pet auras..." );
|
||||
spellmgr.LoadSpellPetAuras();
|
||||
|
||||
sLog.outString( "Loading pet levelup spells..." );
|
||||
spellmgr.LoadPetLevelupSpellMap();
|
||||
|
||||
sLog.outString( "Loading spell extra attributes...(TODO)" );
|
||||
spellmgr.LoadSpellCustomAttr();
|
||||
|
||||
@@ -1669,6 +1708,9 @@ void World::ScriptsProcess()
|
||||
case HIGHGUID_PET:
|
||||
source = HashMapHolder<Pet>::Find(step.sourceGUID);
|
||||
break;
|
||||
case HIGHGUID_VEHICLE:
|
||||
source = HashMapHolder<Vehicle>::Find(step.sourceGUID);
|
||||
break;
|
||||
case HIGHGUID_PLAYER:
|
||||
source = HashMapHolder<Player>::Find(step.sourceGUID);
|
||||
break;
|
||||
@@ -1698,6 +1740,9 @@ void World::ScriptsProcess()
|
||||
case HIGHGUID_PET:
|
||||
target = HashMapHolder<Pet>::Find(step.targetGUID);
|
||||
break;
|
||||
case HIGHGUID_VEHICLE:
|
||||
target = HashMapHolder<Vehicle>::Find(step.targetGUID);
|
||||
break;
|
||||
case HIGHGUID_PLAYER: // empty GUID case also
|
||||
target = HashMapHolder<Player>::Find(step.targetGUID);
|
||||
break;
|
||||
|
||||
+6
-1
@@ -102,9 +102,12 @@ enum WorldConfigs
|
||||
CONFIG_CHARACTERS_CREATING_DISABLED,
|
||||
CONFIG_CHARACTERS_PER_ACCOUNT,
|
||||
CONFIG_CHARACTERS_PER_REALM,
|
||||
CONFIG_HEROIC_CHARACTERS_PER_REALM,
|
||||
CONFIG_MIN_LEVEL_FOR_HEROIC_CHARACTER_CREATING,
|
||||
CONFIG_SKIP_CINEMATICS,
|
||||
CONFIG_MAX_PLAYER_LEVEL,
|
||||
CONFIG_START_PLAYER_LEVEL,
|
||||
CONFIG_START_HEROIC_PLAYER_LEVEL,
|
||||
CONFIG_START_PLAYER_MONEY,
|
||||
CONFIG_MAX_HONOR_POINTS,
|
||||
CONFIG_START_HONOR_POINTS,
|
||||
@@ -183,6 +186,7 @@ enum WorldConfigs
|
||||
CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS,
|
||||
CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS,
|
||||
CONFIG_BATTLEGROUND_PREMATURE_FINISH_TIMER,
|
||||
CONFIG_SKILL_MILLING,
|
||||
|
||||
CONFIG_MAX_WHO,
|
||||
CONFIG_BG_START_MUSIC,
|
||||
@@ -207,6 +211,8 @@ enum Rates
|
||||
RATE_POWER_MANA,
|
||||
RATE_POWER_RAGE_INCOME,
|
||||
RATE_POWER_RAGE_LOSS,
|
||||
RATE_POWER_RUNICPOWER_INCOME,
|
||||
RATE_POWER_RUNICPOWER_LOSS,
|
||||
RATE_POWER_FOCUS,
|
||||
RATE_SKILL_DISCOVERY,
|
||||
RATE_DROP_ITEM_POOR,
|
||||
@@ -250,7 +256,6 @@ enum Rates
|
||||
RATE_MINING_AMOUNT,
|
||||
RATE_MINING_NEXT,
|
||||
RATE_TALENT,
|
||||
RATE_LOYALTY,
|
||||
RATE_CORPSE_DECAY_LOOTED,
|
||||
RATE_INSTANCE_RESET_TIME,
|
||||
RATE_TARGET_POS_RECALCULATION_RANGE,
|
||||
|
||||
@@ -525,3 +525,90 @@ void WorldSession::SendAuthWaitQue(uint32 position)
|
||||
SendPacket(&packet);
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::LoadAccountData()
|
||||
{
|
||||
for (uint32 i = 0; i < NUM_ACCOUNT_DATA_TYPES; ++i)
|
||||
{
|
||||
AccountData data;
|
||||
m_accountData[i] = data;
|
||||
}
|
||||
|
||||
QueryResult *result = CharacterDatabase.PQuery("SELECT type, time, data FROM account_data WHERE account='%u'", GetAccountId());
|
||||
|
||||
if(!result)
|
||||
return;
|
||||
|
||||
do
|
||||
{
|
||||
Field *fields = result->Fetch();
|
||||
|
||||
uint32 type = fields[0].GetUInt32();
|
||||
if(type < NUM_ACCOUNT_DATA_TYPES)
|
||||
{
|
||||
m_accountData[type].Time = fields[1].GetUInt32();
|
||||
m_accountData[type].Data = fields[2].GetCppString();
|
||||
}
|
||||
} while (result->NextRow());
|
||||
|
||||
delete result;
|
||||
}
|
||||
|
||||
void WorldSession::SetAccountData(uint32 type, time_t time_, std::string data)
|
||||
{
|
||||
m_accountData[type].Time = time_;
|
||||
m_accountData[type].Data = data;
|
||||
|
||||
uint32 acc = GetAccountId();
|
||||
CharacterDatabase.PExecute("DELETE FROM account_data WHERE account='%u' AND type='%u'", acc, type);
|
||||
CharacterDatabase.escape_string(data);
|
||||
CharacterDatabase.PExecute("INSERT INTO account_data VALUES ('%u','%u','%u','%s')", acc, type, (uint32)time_, data.c_str());
|
||||
}
|
||||
|
||||
void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo *mi)
|
||||
{
|
||||
CHECK_PACKET_SIZE(data, data.rpos()+4+2+4+4+4+4+4);
|
||||
data >> mi->flags;
|
||||
data >> mi->unk1;
|
||||
data >> mi->time;
|
||||
data >> mi->x;
|
||||
data >> mi->y;
|
||||
data >> mi->z;
|
||||
data >> mi->o;
|
||||
|
||||
if(mi->flags & MOVEMENTFLAG_ONTRANSPORT)
|
||||
{
|
||||
CHECK_PACKET_SIZE(data, data.rpos()+8+4+4+4+4+4+1);
|
||||
data >> mi->t_guid;
|
||||
data >> mi->t_x;
|
||||
data >> mi->t_y;
|
||||
data >> mi->t_z;
|
||||
data >> mi->t_o;
|
||||
data >> mi->t_time;
|
||||
data >> mi->t_seat;
|
||||
}
|
||||
|
||||
if((mi->flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2)) || (mi->unk1 & 0x20))
|
||||
{
|
||||
CHECK_PACKET_SIZE(data, data.rpos()+4);
|
||||
data >> mi->s_pitch;
|
||||
}
|
||||
|
||||
CHECK_PACKET_SIZE(data, data.rpos()+4);
|
||||
data >> mi->fallTime;
|
||||
|
||||
if(mi->flags & MOVEMENTFLAG_JUMPING)
|
||||
{
|
||||
CHECK_PACKET_SIZE(data, data.rpos()+4+4+4+4);
|
||||
data >> mi->j_unk;
|
||||
data >> mi->j_sinAngle;
|
||||
data >> mi->j_cosAngle;
|
||||
data >> mi->j_xyspeed;
|
||||
}
|
||||
|
||||
if(mi->flags & MOVEMENTFLAG_SPLINE)
|
||||
{
|
||||
CHECK_PACKET_SIZE(data, data.rpos()+4);
|
||||
data >> mi->u_unk1;
|
||||
}
|
||||
}
|
||||
|
||||
+47
-4
@@ -47,6 +47,16 @@ class CharacterHandler;
|
||||
|
||||
#define CHECK_PACKET_SIZE(P,S) if((P).size() < (S)) return SizeError((P),(S));
|
||||
|
||||
#define NUM_ACCOUNT_DATA_TYPES 8
|
||||
|
||||
struct AccountData
|
||||
{
|
||||
AccountData() : Time(NULL), Data("") {}
|
||||
|
||||
time_t Time;
|
||||
std::string Data;
|
||||
};
|
||||
|
||||
enum PartyOperation
|
||||
{
|
||||
PARTY_OP_INVITE = 0,
|
||||
@@ -81,6 +91,8 @@ class TRINITY_DLL_SPEC WorldSession
|
||||
|
||||
void SizeError(WorldPacket const& packet, uint32 size) const;
|
||||
|
||||
void ReadMovementInfo(WorldPacket &data, MovementInfo *mi);
|
||||
|
||||
void SendPacket(WorldPacket const* packet);
|
||||
void SendNotification(const char *format,...) ATTR_PRINTF(2,3);
|
||||
void SendNotification(int32 string_id,...);
|
||||
@@ -153,6 +165,11 @@ class TRINITY_DLL_SPEC WorldSession
|
||||
//pet
|
||||
void SendPetNameQuery(uint64 guid, uint32 petnumber);
|
||||
|
||||
// Account Data
|
||||
AccountData *GetAccountData(uint32 type) { return &m_accountData[type]; }
|
||||
void SetAccountData(uint32 type, time_t time_, std::string data);
|
||||
void LoadAccountData();
|
||||
|
||||
//mail
|
||||
//used with item_page table
|
||||
bool SendItemInfo( uint32 itemid, WorldPacket data );
|
||||
@@ -324,7 +341,8 @@ class TRINITY_DLL_SPEC WorldSession
|
||||
void HandleMovementOpcodes(WorldPacket& recvPacket);
|
||||
void HandlePossessedMovement(WorldPacket& recv_data, MovementInfo& movementInfo, uint32& MovementFlags);
|
||||
void HandleSetActiveMoverOpcode(WorldPacket &recv_data);
|
||||
void HandleNotActiveMoverOpcode(WorldPacket &recv_data);
|
||||
void HandleMoveNotActiveMover(WorldPacket &recv_data);
|
||||
void HandleDismissControlledVehicle(WorldPacket &recv_data);
|
||||
void HandleMoveTimeSkippedOpcode(WorldPacket &recv_data);
|
||||
|
||||
void HandleRequestRaidInfoOpcode( WorldPacket & recv_data );
|
||||
@@ -385,7 +403,7 @@ class TRINITY_DLL_SPEC WorldSession
|
||||
void HandleGuildSaveEmblemOpcode(WorldPacket& recvPacket);
|
||||
|
||||
void HandleTaxiNodeStatusQueryOpcode(WorldPacket& recvPacket);
|
||||
void HandleTaxiQueryAvailableNodesOpcode(WorldPacket& recvPacket);
|
||||
void HandleTaxiQueryAvailableNodes(WorldPacket& recvPacket);
|
||||
void HandleActivateTaxiOpcode(WorldPacket& recvPacket);
|
||||
void HandleActivateTaxiFarOpcode(WorldPacket& recvPacket);
|
||||
void HandleTaxiNextDestinationOpcode(WorldPacket& recvPacket);
|
||||
@@ -429,6 +447,7 @@ class TRINITY_DLL_SPEC WorldSession
|
||||
void HandleAuctionRemoveItem( WorldPacket & recv_data );
|
||||
void HandleAuctionListOwnerItems( WorldPacket & recv_data );
|
||||
void HandleAuctionPlaceBid( WorldPacket & recv_data );
|
||||
void HandleAuctionListPendingSales( WorldPacket & recv_data );
|
||||
|
||||
void HandleGetMail( WorldPacket & recv_data );
|
||||
void HandleSendMail( WorldPacket & recv_data );
|
||||
@@ -543,6 +562,7 @@ class TRINITY_DLL_SPEC WorldSession
|
||||
void HandlePetUnlearnOpcode( WorldPacket& recvPacket );
|
||||
void HandlePetSpellAutocastOpcode( WorldPacket& recvPacket );
|
||||
void HandlePetCastSpellOpcode( WorldPacket& recvPacket );
|
||||
void HandlePetLearnTalent( WorldPacket& recvPacket );
|
||||
|
||||
void HandleSetActionBar(WorldPacket& recv_data);
|
||||
|
||||
@@ -579,10 +599,9 @@ class TRINITY_DLL_SPEC WorldSession
|
||||
void HandleLfmSetNoneOpcode(WorldPacket& recv_data);
|
||||
void HandleLfmSetOpcode(WorldPacket& recv_data);
|
||||
void HandleLfgSetCommentOpcode(WorldPacket& recv_data);
|
||||
void HandleNewUnknownOpcode(WorldPacket& recv_data);
|
||||
void HandleChooseTitleOpcode(WorldPacket& recv_data);
|
||||
void HandleRealmStateRequestOpcode(WorldPacket& recv_data);
|
||||
void HandleAllowMoveAckOpcode(WorldPacket& recv_data);
|
||||
void HandleTimeSyncResp(WorldPacket& recv_data);
|
||||
void HandleWhoisOpcode(WorldPacket& recv_data);
|
||||
void HandleResetInstancesOpcode(WorldPacket& recv_data);
|
||||
|
||||
@@ -628,6 +647,29 @@ class TRINITY_DLL_SPEC WorldSession
|
||||
void HandleGuildBankBuyTab(WorldPacket& recv_data);
|
||||
void HandleGuildBankTabText(WorldPacket& recv_data);
|
||||
void HandleGuildBankSetTabText(WorldPacket& recv_data);
|
||||
|
||||
// Calendar
|
||||
void HandleCalendarGetCalendar(WorldPacket& recv_data);
|
||||
void HandleCalendarGetEvent(WorldPacket& recv_data);
|
||||
void HandleCalendarGuildFilter(WorldPacket& recv_data);
|
||||
void HandleCalendarArenaTeam(WorldPacket& recv_data);
|
||||
void HandleCalendarAddEvent(WorldPacket& recv_data);
|
||||
void HandleCalendarUpdateEvent(WorldPacket& recv_data);
|
||||
void HandleCalendarRemoveEvent(WorldPacket& recv_data);
|
||||
void HandleCalendarCopyEvent(WorldPacket& recv_data);
|
||||
void HandleCalendarEventInvite(WorldPacket& recv_data);
|
||||
void HandleCalendarEventRsvp(WorldPacket& recv_data);
|
||||
void HandleCalendarEventRemoveInvite(WorldPacket& recv_data);
|
||||
void HandleCalendarEventStatus(WorldPacket& recv_data);
|
||||
void HandleCalendarEventModeratorStatus(WorldPacket& recv_data);
|
||||
void HandleCalendarComplain(WorldPacket& recv_data);
|
||||
void HandleCalendarGetNumPending(WorldPacket& recv_data);
|
||||
|
||||
void HandleSpellClick(WorldPacket& recv_data);
|
||||
void HandleAlterAppearance(WorldPacket& recv_data);
|
||||
void HandleRemoveGlyph(WorldPacket& recv_data);
|
||||
void HandleCharCustomize(WorldPacket& recv_data);
|
||||
void HandleInspectAchievements(WorldPacket& recv_data);
|
||||
private:
|
||||
// private trade methods
|
||||
void moveItems(Item* myItems[], Item* hisItems[]);
|
||||
@@ -650,6 +692,7 @@ class TRINITY_DLL_SPEC WorldSession
|
||||
LocaleConstant m_sessionDbcLocale;
|
||||
int m_sessionDbLocaleIndex;
|
||||
uint32 m_latency;
|
||||
AccountData m_accountData[NUM_ACCOUNT_DATA_TYPES];
|
||||
|
||||
ZThread::LockedQueue<WorldPacket*,ZThread::FastMutex> _recvQueue;
|
||||
};
|
||||
|
||||
+50
-13
@@ -54,8 +54,48 @@
|
||||
|
||||
struct ServerPktHeader
|
||||
{
|
||||
uint16 size;
|
||||
uint16 cmd;
|
||||
/**
|
||||
* size is the length of the payload _plus_ the length of the opcode
|
||||
*/
|
||||
ServerPktHeader(uint32 size, uint16 cmd) : size(size)
|
||||
{
|
||||
uint8 headerIndex=0;
|
||||
if(isLargePacket())
|
||||
{
|
||||
sLog.outDebug("initializing large server to client packet. Size: %u, cmd: %u", size, cmd);
|
||||
header= new uint8[5];
|
||||
header[headerIndex++] = 0x80|(0xFF &(size>>16));
|
||||
}
|
||||
else
|
||||
{
|
||||
header= new uint8[4];
|
||||
}
|
||||
|
||||
header[headerIndex++] = 0xFF &(size>>8);
|
||||
header[headerIndex++] = 0xFF &size;
|
||||
|
||||
header[headerIndex++] = 0xFF & cmd;
|
||||
header[headerIndex++] = 0xFF & (cmd>>8);
|
||||
}
|
||||
|
||||
~ServerPktHeader()
|
||||
{
|
||||
delete[] header;
|
||||
}
|
||||
|
||||
uint8 getHeaderLength()
|
||||
{
|
||||
// cmd = 2 bytes, size= 2||3bytes
|
||||
return 2+(isLargePacket()?3:2);
|
||||
}
|
||||
|
||||
bool isLargePacket()
|
||||
{
|
||||
return size > 0x7FFF;
|
||||
}
|
||||
|
||||
const uint32 size;
|
||||
uint8 *header;
|
||||
};
|
||||
|
||||
struct ClientPktHeader
|
||||
@@ -639,7 +679,7 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
|
||||
// NOTE: ATM the socket is singlethread, have this in mind ...
|
||||
uint8 digest[20];
|
||||
uint32 clientSeed;
|
||||
uint32 unk2;
|
||||
uint32 unk2, unk3;
|
||||
uint32 BuiltNumberClient;
|
||||
uint32 id, security;
|
||||
//uint8 expansion = 0;
|
||||
@@ -661,6 +701,7 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
|
||||
recvPacket >> BuiltNumberClient; // for now no use
|
||||
recvPacket >> unk2;
|
||||
recvPacket >> account;
|
||||
recvPacket >> unk3;
|
||||
|
||||
if (recvPacket.size () < (4 + 4 + (account.size () + 1) + 4 + 20))
|
||||
{
|
||||
@@ -880,6 +921,8 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
|
||||
m_Crypt.SetKey (&K);
|
||||
m_Crypt.Init ();
|
||||
|
||||
m_Session->LoadAccountData();
|
||||
|
||||
// In case needed sometime the second arg is in microseconds 1 000 000 = 1 sec
|
||||
ACE_OS::sleep (ACE_Time_Value (0, 10000));
|
||||
|
||||
@@ -963,23 +1006,17 @@ int WorldSocket::HandlePing (WorldPacket& recvPacket)
|
||||
|
||||
int WorldSocket::iSendPacket (const WorldPacket& pct)
|
||||
{
|
||||
if (m_OutBuffer->space () < pct.size () + sizeof (ServerPktHeader))
|
||||
ServerPktHeader header(pct.size()+2, pct.GetOpcode());
|
||||
if (m_OutBuffer->space () < pct.size () + header.getHeaderLength())
|
||||
{
|
||||
errno = ENOBUFS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ServerPktHeader header;
|
||||
|
||||
header.cmd = pct.GetOpcode ();
|
||||
EndianConvert(header.cmd);
|
||||
m_Crypt.EncryptSend ( header.header, header.getHeaderLength());
|
||||
|
||||
header.size = (uint16) pct.size () + 2;
|
||||
EndianConvertReverse(header.size);
|
||||
|
||||
m_Crypt.EncryptSend ((uint8*) & header, sizeof (header));
|
||||
|
||||
if (m_OutBuffer->copy ((char*) & header, sizeof (header)) == -1)
|
||||
if (m_OutBuffer->copy ((char*) header.header, header.getHeaderLength()) == -1)
|
||||
ACE_ASSERT (false);
|
||||
|
||||
if (!pct.empty ())
|
||||
|
||||
@@ -63,6 +63,7 @@ bool ChatHandler::HandleDebugSpellFailCommand(const char* args)
|
||||
uint8 failnum = (uint8)atoi(px);
|
||||
|
||||
WorldPacket data(SMSG_CAST_FAILED, 5);
|
||||
data << uint8(0);
|
||||
data << uint32(133);
|
||||
data << uint8(failnum);
|
||||
m_session->SendPacket(&data);
|
||||
@@ -568,5 +569,55 @@ bool ChatHandler::HandleDebugHostilRefList(const char * /*args*/)
|
||||
ref = ref->next();
|
||||
}
|
||||
SendSysMessage("End of hostil reference list.");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChatHandler::HandleSpawnVehicle(const char* args)
|
||||
{
|
||||
if(!args)
|
||||
return false;
|
||||
|
||||
char* e = strtok((char*)args, " ");
|
||||
char* i = strtok(NULL, " ");
|
||||
|
||||
if (!e || !i)
|
||||
return false;
|
||||
|
||||
uint32 entry = (uint32)atoi(e);
|
||||
uint32 id = (uint32)atoi(i);
|
||||
|
||||
CreatureInfo const *ci = objmgr.GetCreatureTemplate(entry);
|
||||
|
||||
if(!ci)
|
||||
return false;
|
||||
|
||||
VehicleEntry const *ve = sVehicleStore.LookupEntry(id);
|
||||
|
||||
if(!ve)
|
||||
return false;
|
||||
|
||||
Vehicle *v = new Vehicle;
|
||||
Map *map = m_session->GetPlayer()->GetMap();
|
||||
if(!v->Create(objmgr.GenerateLowGuid(HIGHGUID_VEHICLE), map, entry, id, m_session->GetPlayer()->GetTeam()))
|
||||
{
|
||||
delete v;
|
||||
return false;
|
||||
}
|
||||
|
||||
float px, py, pz;
|
||||
m_session->GetPlayer()->GetClosePoint(px, py, pz, m_session->GetPlayer()->GetObjectSize());
|
||||
|
||||
v->Relocate(px, py, pz, m_session->GetPlayer()->GetOrientation());
|
||||
|
||||
if(!v->IsPositionValid())
|
||||
{
|
||||
sLog.outError("ERROR: Vehicle (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",
|
||||
v->GetGUIDLow(), v->GetEntry(), v->GetPositionX(), v->GetPositionY());
|
||||
delete v;
|
||||
return false;
|
||||
}
|
||||
|
||||
map->Add((Creature*)v);
|
||||
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user