mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 13:37:05 +00:00
Merge branch 'master' into 310
Conflicts: src/game/Unit.cpp
This commit is contained in:
commit
17d86309fa
22 changed files with 373 additions and 190 deletions
Binary file not shown.
|
|
@ -315,7 +315,11 @@ int WMOGroup::ConvertToVMAPGroupWmo(FILE *output, bool pPreciseVectorData)
|
|||
IndexExTr = new int[mopy_size];
|
||||
for (int i=0; i<mopy_size; i+=2)
|
||||
{
|
||||
if ((int)MOPY[i]==0x00000008 ||(int)MOPY[i]==0x00000009 ||(int)MOPY[i]==0x00000020 ||(int)MOPY[i]==0x00000021 ||(int)MOPY[i]==0x00000022 ||(int)MOPY[i]==0x00000048 ||(int)MOPY[i]==0x00000049 ||(int)MOPY[i]==0x00000060 ||(int)MOPY[i]==0x00000061 ||(int)MOPY[i]==0x00000062 ||(int)MOPY[i]==0x0000000A ||(int)MOPY[i]==0x0000004A)
|
||||
// Skip no collision triangles
|
||||
if ((int)MOPY[i]&WMO_MATERIAL_NO_COLLISION)
|
||||
continue;
|
||||
// Use only this triangles
|
||||
if ((int)MOPY[i]&(WMO_MATERIAL_HINT|WMO_MATERIAL_COLLIDE_HIT))
|
||||
{
|
||||
MopyEx[n] = MOPY[i];
|
||||
MopyEx[(n+1)] = MOPY[(i+1)];
|
||||
|
|
|
|||
|
|
@ -10,6 +10,14 @@
|
|||
#include <set>
|
||||
#include "mpq.h"
|
||||
|
||||
// MOPY flags
|
||||
#define WMO_MATERIAL_NOCAMCOLLIDE 0x01
|
||||
#define WMO_MATERIAL_DETAIL 0x02
|
||||
#define WMO_MATERIAL_NO_COLLISION 0x04
|
||||
#define WMO_MATERIAL_HINT 0x08
|
||||
#define WMO_MATERIAL_RENDER 0x10
|
||||
#define WMO_MATERIAL_COLLIDE_HIT 0x20
|
||||
#define WMO_MATERIAL_WALL_SURFACE 0x40
|
||||
|
||||
class WMOInstance;
|
||||
class WMOManager;
|
||||
|
|
|
|||
|
|
@ -407,21 +407,21 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
|
|||
{
|
||||
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())
|
||||
if (achievementCriteria->groupFlag & ACHIEVEMENT_CRITERIA_GROUP_NOT_IN_GROUP && GetPlayer()->GetGroup())
|
||||
continue;
|
||||
|
||||
AchievementEntry const *achievement = sAchievementStore.LookupEntry(achievementCriteria->referredAchievement);
|
||||
if(!achievement)
|
||||
if (!achievement)
|
||||
continue;
|
||||
|
||||
if ((achievement->factionFlag == ACHIEVEMENT_FACTION_FLAG_HORDE && GetPlayer()->GetTeam() != HORDE) ||
|
||||
(achievement->factionFlag == ACHIEVEMENT_FACTION_FLAG_ALLIANCE && GetPlayer()->GetTeam() != ALLIANCE))
|
||||
continue;
|
||||
|
||||
// don't update already completed criteria
|
||||
if (IsCompletedCriteria(achievementCriteria,achievement))
|
||||
continue;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
// std. case: increment at 1
|
||||
|
|
@ -834,6 +834,15 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
|
|||
if(miscvalue1 != achievementCriteria->equip_item.itemID)
|
||||
continue;
|
||||
|
||||
SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
|
||||
break;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT:
|
||||
// miscvalue1 = go entry
|
||||
if(!miscvalue1)
|
||||
continue;
|
||||
if(miscvalue1 != achievementCriteria->use_gameobject.goEntry)
|
||||
continue;
|
||||
|
||||
SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
|
||||
break;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS:
|
||||
|
|
@ -926,7 +935,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
|
|||
case ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_NUMBER_OF_TALENT_RESETS:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_EARNED_PVP_TITLE:
|
||||
|
|
@ -955,20 +963,24 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
|
|||
case ACHIEVEMENT_CRITERIA_TYPE_TOTAL:
|
||||
break; // Not implemented yet :(
|
||||
}
|
||||
if(IsCompletedCriteria(achievementCriteria))
|
||||
CompletedCriteria(achievementCriteria);
|
||||
if(IsCompletedCriteria(achievementCriteria,achievement))
|
||||
CompletedCriteria(achievementCriteria,achievement);
|
||||
|
||||
|
||||
if(AchievementEntryList const* achRefList = achievementmgr.GetAchievementByReferencedId(achievement->ID))
|
||||
{
|
||||
for(AchievementEntryList::const_iterator itr = achRefList->begin(); itr != achRefList->end(); ++itr)
|
||||
if(IsCompletedAchievement(*itr))
|
||||
CompletedAchievement(*itr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const uint32 achievIdByClass[MAX_CLASSES] = { 0, 459, 465 , 462, 458, 464, 461, 467, 460, 463, 0, 466 };
|
||||
static const uint32 achievIdByRace[MAX_RACES] = { 0, 1408, 1410, 1407, 1409, 1413, 1411, 1404, 1412, 0, 1405, 1406 };
|
||||
|
||||
bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achievementCriteria)
|
||||
bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achievementCriteria, AchievementEntry const* achievement)
|
||||
{
|
||||
AchievementEntry const* achievement = sAchievementStore.LookupEntry(achievementCriteria->referredAchievement);
|
||||
if(!achievement)
|
||||
return false;
|
||||
|
||||
// counter can never complete
|
||||
if(achievement->flags & ACHIEVEMENT_FLAG_COUNTER)
|
||||
return false;
|
||||
|
|
@ -1056,6 +1068,8 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve
|
|||
return progress->counter >= achievementCriteria->quest_reward_money.goldInCopper;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY:
|
||||
return progress->counter >= achievementCriteria->loot_money.goldInCopper;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT:
|
||||
return progress->counter >= achievementCriteria->use_gameobject.useCount;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS:
|
||||
return progress->counter >= achievementCriteria->learn_skilline_spell.spellCount;
|
||||
|
||||
|
|
@ -1083,45 +1097,64 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve
|
|||
return false;
|
||||
}
|
||||
|
||||
void AchievementMgr::CompletedCriteria(AchievementCriteriaEntry const* criteria)
|
||||
void AchievementMgr::CompletedCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement)
|
||||
{
|
||||
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)
|
||||
{
|
||||
// already completed and stored
|
||||
if (m_completedAchievements.find(achievement->ID)!=m_completedAchievements.end())
|
||||
return;
|
||||
|
||||
if ((criteria->referredAchievement==achievement->ID && (criteria->completionFlag & ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL)) ||
|
||||
IsCompletedAchievement(achievement))
|
||||
CompletedAchievement(achievement);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: achievement 705 requires 4 criteria to be fulfilled
|
||||
AchievementCompletionState AchievementMgr::GetAchievementCompletionState(AchievementEntry const* entry)
|
||||
bool AchievementMgr::IsCompletedAchievement(AchievementEntry const* entry)
|
||||
{
|
||||
if(m_completedAchievements.find(entry->ID)!=m_completedAchievements.end())
|
||||
return ACHIEVEMENT_COMPLETED_COMPLETED_STORED;
|
||||
// for achievement with referenced achievement criterias get from referenced and counter from self
|
||||
uint32 achievmentForTestId = entry->refAchievement ? entry->refAchievement : entry->ID;
|
||||
uint32 achievmentForTestCount = entry->count;
|
||||
|
||||
bool foundOutstanding = false;
|
||||
for (uint32 entryId = 0; entryId<sAchievementCriteriaStore.GetNumRows(); entryId++)
|
||||
AchievementCriteriaEntryList const* cList = achievementmgr.GetAchievementCriteriaByAchievement(achievmentForTestId);
|
||||
if(!cList)
|
||||
return false;
|
||||
|
||||
uint32 count = 0;
|
||||
bool completed_all = true;
|
||||
|
||||
for(AchievementCriteriaEntryList::const_iterator itr = cList->begin(); itr != cList->end(); ++itr)
|
||||
{
|
||||
AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(entryId);
|
||||
if(!criteria || criteria->referredAchievement!= entry->ID)
|
||||
continue;
|
||||
AchievementCriteriaEntry const* criteria = *itr;
|
||||
|
||||
if(IsCompletedCriteria(criteria) && criteria->completionFlag & ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL)
|
||||
return ACHIEVEMENT_COMPLETED_COMPLETED_NOT_STORED;
|
||||
bool completed = IsCompletedCriteria(criteria,entry);
|
||||
|
||||
// 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;
|
||||
// found an uncompleted criteria, but DONT return false yet - there might be a completed criteria with ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL
|
||||
if(completed)
|
||||
++count;
|
||||
else
|
||||
completed_all = false;
|
||||
|
||||
if(achievmentForTestId == entry->ID) // not referenced achievement
|
||||
{
|
||||
// completed as single req. criteria
|
||||
if(completed && criteria->completionFlag & ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL)
|
||||
return true;
|
||||
}
|
||||
|
||||
// completed as have req. count of completed criterias
|
||||
if(achievmentForTestCount > 0 && achievmentForTestCount <= count)
|
||||
return true;
|
||||
}
|
||||
if(foundOutstanding)
|
||||
return ACHIEVEMENT_COMPLETED_NONE;
|
||||
else
|
||||
return ACHIEVEMENT_COMPLETED_COMPLETED_NOT_STORED;
|
||||
|
||||
// all criterias completed requirement
|
||||
if(completed_all && achievmentForTestCount==0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 changeValue, ProgressType ptype)
|
||||
|
|
@ -1317,7 +1350,7 @@ void AchievementGlobalMgr::LoadAchievementCriteriaList()
|
|||
}
|
||||
|
||||
barGoLink bar( sAchievementCriteriaStore.GetNumRows() );
|
||||
for (uint32 entryId = 0; entryId<sAchievementCriteriaStore.GetNumRows(); entryId++)
|
||||
for (uint32 entryId = 0; entryId < sAchievementCriteriaStore.GetNumRows(); ++entryId)
|
||||
{
|
||||
bar.step();
|
||||
|
||||
|
|
@ -1326,12 +1359,42 @@ void AchievementGlobalMgr::LoadAchievementCriteriaList()
|
|||
continue;
|
||||
|
||||
m_AchievementCriteriasByType[criteria->requiredType].push_back(criteria);
|
||||
m_AchievementCriteriaListByAchievement[criteria->referredAchievement].push_back(criteria);
|
||||
}
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString(">> Loaded %lu achievement criteria.",(unsigned long)m_AchievementCriteriasByType->size());
|
||||
}
|
||||
|
||||
void AchievementGlobalMgr::LoadAchievementReferenceList()
|
||||
{
|
||||
if(sAchievementStore.GetNumRows()==0)
|
||||
{
|
||||
barGoLink bar(1);
|
||||
bar.step();
|
||||
|
||||
sLog.outString();
|
||||
sLog.outErrorDb(">> Loaded 0 achievement references.");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 count = 0;
|
||||
barGoLink bar( sAchievementStore.GetNumRows() );
|
||||
for (uint32 entryId = 0; entryId < sAchievementStore.GetNumRows(); ++entryId)
|
||||
{
|
||||
bar.step();
|
||||
|
||||
AchievementEntry const* achievement = sAchievementStore.LookupEntry(entryId);
|
||||
if(!achievement || !achievement->refAchievement)
|
||||
continue;
|
||||
|
||||
m_AchievementListByReferencedId[achievement->refAchievement].push_back(achievement);
|
||||
++count;
|
||||
}
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString(">> Loaded %u achievement references.",count);
|
||||
}
|
||||
|
||||
void AchievementGlobalMgr::LoadCompletedAchievements()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -30,7 +30,11 @@
|
|||
#define CRITERIA_CAST_SPELL_REQ_COUNT 46
|
||||
#define ACHIEVEMENT_REWARD_COUNT 57
|
||||
|
||||
typedef std::list<const AchievementCriteriaEntry*> AchievementCriteriaEntryList;
|
||||
typedef std::list<AchievementCriteriaEntry const*> AchievementCriteriaEntryList;
|
||||
typedef std::list<AchievementEntry const*> AchievementEntryList;
|
||||
|
||||
typedef std::map<uint32,AchievementCriteriaEntryList> AchievementCriteriaListByAchievement;
|
||||
typedef std::map<uint32,AchievementEntryList> AchievementListByReferencedId;
|
||||
|
||||
struct CriteriaProgress
|
||||
{
|
||||
|
|
@ -80,13 +84,6 @@ class Unit;
|
|||
class Player;
|
||||
class WorldPacket;
|
||||
|
||||
enum AchievementCompletionState
|
||||
{
|
||||
ACHIEVEMENT_COMPLETED_NONE,
|
||||
ACHIEVEMENT_COMPLETED_COMPLETED_NOT_STORED,
|
||||
ACHIEVEMENT_COMPLETED_COMPLETED_STORED,
|
||||
};
|
||||
|
||||
class AchievementMgr
|
||||
{
|
||||
public:
|
||||
|
|
@ -108,10 +105,11 @@ class AchievementMgr
|
|||
void SendAchievementEarned(AchievementEntry const* achievement);
|
||||
void SendCriteriaUpdate(uint32 id, CriteriaProgress const* progress);
|
||||
void SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 changeValue, ProgressType ptype = PROGRESS_SET);
|
||||
void CompletedCriteria(AchievementCriteriaEntry const* entry);
|
||||
void CompletedCriteria(AchievementCriteriaEntry const* entry, AchievementEntry const* achievement);
|
||||
void CompletedAchievement(AchievementEntry const* entry);
|
||||
bool IsCompletedCriteria(AchievementCriteriaEntry const* entry);
|
||||
AchievementCompletionState GetAchievementCompletionState(AchievementEntry const* entry);
|
||||
bool IsCompletedCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement);
|
||||
bool IsCompletedAchievement(AchievementEntry const* entry);
|
||||
void CompleteAchievementsWithRefs(AchievementEntry const* entry);
|
||||
void BuildAllDataPacket(WorldPacket *data);
|
||||
|
||||
Player* m_player;
|
||||
|
|
@ -123,6 +121,17 @@ class AchievementGlobalMgr
|
|||
{
|
||||
public:
|
||||
AchievementCriteriaEntryList const& GetAchievementCriteriaByType(AchievementCriteriaTypes type);
|
||||
AchievementCriteriaEntryList const* GetAchievementCriteriaByAchievement(uint32 id)
|
||||
{
|
||||
AchievementCriteriaListByAchievement::const_iterator itr = m_AchievementCriteriaListByAchievement.find(id);
|
||||
return itr != m_AchievementCriteriaListByAchievement.end() ? &itr->second : NULL;
|
||||
}
|
||||
|
||||
AchievementEntryList const* GetAchievementByReferencedId(uint32 id) const
|
||||
{
|
||||
AchievementListByReferencedId::const_iterator itr = m_AchievementListByReferencedId.find(id);
|
||||
return itr != m_AchievementListByReferencedId.end() ? &itr->second : NULL;
|
||||
}
|
||||
|
||||
AchievementReward const* GetAchievementReward(AchievementEntry const* achievement) const
|
||||
{
|
||||
|
|
@ -156,6 +165,7 @@ class AchievementGlobalMgr
|
|||
}
|
||||
|
||||
void LoadAchievementCriteriaList();
|
||||
void LoadAchievementReferenceList();
|
||||
void LoadCompletedAchievements();
|
||||
void LoadRewards();
|
||||
void LoadRewardLocales();
|
||||
|
|
@ -164,6 +174,10 @@ class AchievementGlobalMgr
|
|||
|
||||
// store achievement criterias by type to speed up lookup
|
||||
AchievementCriteriaEntryList m_AchievementCriteriasByType[ACHIEVEMENT_CRITERIA_TYPE_TOTAL];
|
||||
// store achievement criterias by achievement to speed up lookup
|
||||
AchievementCriteriaListByAchievement m_AchievementCriteriaListByAchievement;
|
||||
// store achievements by referenced achievement id to speed up lookup
|
||||
AchievementListByReferencedId m_AchievementListByReferencedId;
|
||||
|
||||
typedef std::set<uint32> AllCompletedAchievements;
|
||||
AllCompletedAchievements m_allCompletedAchievements;
|
||||
|
|
|
|||
|
|
@ -52,8 +52,8 @@ struct AchievementEntry
|
|||
//uint32 icon; // 42 icon (from SpellIcon.dbc)
|
||||
//char *titleReward[16]; // 43-58
|
||||
//uint32 titleReward_flags; // 59
|
||||
//uint32 count; // 60 - need this count Criteria for complete
|
||||
uint32 refAchievement; // 61 - related achievement?
|
||||
uint32 count; // 60 - need this count of completed criterias (own or referenced achievement criterias)
|
||||
uint32 refAchievement; // 61 - referenced achievement (counting of all completed criterias)
|
||||
};
|
||||
|
||||
struct AchievementCategoryEntry
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
#ifndef MANGOS_DBCSFRM_H
|
||||
#define MANGOS_DBCSFRM_H
|
||||
|
||||
const char Achievementfmt[]="niixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiixixxxxxxxxxxxxxxxxxxxi";
|
||||
const char Achievementfmt[]="niixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiixixxxxxxxxxxxxxxxxxxii";
|
||||
const char AchievementCriteriafmt[]="niiiiiiiixxxxxxxxxxxxxxxxxiixix";
|
||||
const char AreaTableEntryfmt[]="iiinixxxxxissssssssssssssssxixxxxxxx";
|
||||
const char AreaGroupEntryfmt[]="niiiiiii";
|
||||
|
|
|
|||
116
src/game/Map.cpp
116
src/game/Map.cpp
|
|
@ -48,11 +48,11 @@ Map::~Map()
|
|||
UnloadAll(true);
|
||||
}
|
||||
|
||||
bool Map::ExistMap(uint32 mapid,int x,int y)
|
||||
bool Map::ExistMap(uint32 mapid,int gx,int gy)
|
||||
{
|
||||
int len = sWorld.GetDataPath().length()+strlen("maps/%03u%02u%02u.map")+1;
|
||||
char* tmp = new char[len];
|
||||
snprintf(tmp, len, (char *)(sWorld.GetDataPath()+"maps/%03u%02u%02u.map").c_str(),mapid,x,y);
|
||||
snprintf(tmp, len, (char *)(sWorld.GetDataPath()+"maps/%03u%02u%02u.map").c_str(),mapid,gx,gy);
|
||||
|
||||
FILE *pf=fopen(tmp,"rb");
|
||||
|
||||
|
|
@ -79,17 +79,17 @@ bool Map::ExistMap(uint32 mapid,int x,int y)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Map::ExistVMap(uint32 mapid,int x,int y)
|
||||
bool Map::ExistVMap(uint32 mapid,int gx,int gy)
|
||||
{
|
||||
if(VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager())
|
||||
{
|
||||
if(vmgr->isMapLoadingEnabled())
|
||||
{
|
||||
// x and y are swapped !! => fixed now
|
||||
bool exists = vmgr->existsMap((sWorld.GetDataPath()+ "vmaps").c_str(), mapid, x,y);
|
||||
bool exists = vmgr->existsMap((sWorld.GetDataPath()+ "vmaps").c_str(), mapid, gx,gy);
|
||||
if(!exists)
|
||||
{
|
||||
std::string name = vmgr->getDirFileName(mapid,x,y);
|
||||
std::string name = vmgr->getDirFileName(mapid,gx,gy);
|
||||
sLog.outError("VMap file '%s' is missing or point to wrong version vmap file, redo vmaps with latest vmap_assembler.exe program", (sWorld.GetDataPath()+"vmaps/"+name).c_str());
|
||||
return false;
|
||||
}
|
||||
|
|
@ -99,75 +99,70 @@ bool Map::ExistVMap(uint32 mapid,int x,int y)
|
|||
return true;
|
||||
}
|
||||
|
||||
void Map::LoadVMap(int x,int y)
|
||||
void Map::LoadVMap(int gx,int gy)
|
||||
{
|
||||
// x and y are swapped !!
|
||||
int vmapLoadResult = VMAP::VMapFactory::createOrGetVMapManager()->loadMap((sWorld.GetDataPath()+ "vmaps").c_str(), GetId(), x,y);
|
||||
int vmapLoadResult = VMAP::VMapFactory::createOrGetVMapManager()->loadMap((sWorld.GetDataPath()+ "vmaps").c_str(), GetId(), gx,gy);
|
||||
switch(vmapLoadResult)
|
||||
{
|
||||
case VMAP::VMAP_LOAD_RESULT_OK:
|
||||
sLog.outDetail("VMAP loaded name:%s, id:%d, x:%d, y:%d (vmap rep.: x:%d, y:%d)", GetMapName(), GetId(), x,y, x,y);
|
||||
sLog.outDetail("VMAP loaded name:%s, id:%d, x:%d, y:%d (vmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx,gy,gx,gy);
|
||||
break;
|
||||
case VMAP::VMAP_LOAD_RESULT_ERROR:
|
||||
sLog.outDetail("Could not load VMAP name:%s, id:%d, x:%d, y:%d (vmap rep.: x:%d, y:%d)", GetMapName(), GetId(), x,y, x,y);
|
||||
sLog.outDetail("Could not load VMAP name:%s, id:%d, x:%d, y:%d (vmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx,gy,gx,gy);
|
||||
break;
|
||||
case VMAP::VMAP_LOAD_RESULT_IGNORED:
|
||||
DEBUG_LOG("Ignored VMAP name:%s, id:%d, x:%d, y:%d (vmap rep.: x:%d, y:%d)", GetMapName(), GetId(), x,y, x,y);
|
||||
DEBUG_LOG("Ignored VMAP name:%s, id:%d, x:%d, y:%d (vmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx,gy,gx,gy);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Map::LoadMap(uint32 mapid, uint32 instanceid, int x,int y)
|
||||
void Map::LoadMap(int gx,int gy)
|
||||
{
|
||||
if( instanceid != 0 )
|
||||
if( i_InstanceId != 0 )
|
||||
{
|
||||
if(GridMaps[x][y])
|
||||
if(GridMaps[gx][gy])
|
||||
return;
|
||||
|
||||
Map* baseMap = const_cast<Map*>(MapManager::Instance().GetBaseMap(mapid));
|
||||
Map* baseMap = const_cast<Map*>(MapManager::Instance().GetBaseMap(i_id));
|
||||
|
||||
// load gridmap for base map
|
||||
if (!baseMap->GridMaps[x][y])
|
||||
baseMap->EnsureGridCreated(GridPair(63-x,63-y));
|
||||
// load grid map for base map
|
||||
if (!baseMap->GridMaps[gx][gy])
|
||||
baseMap->EnsureGridCreated(GridPair(63-gx,63-gy));
|
||||
|
||||
//+++ if (!baseMap->GridMaps[x][y]) don't check for GridMaps[gx][gy], we need the management for vmaps
|
||||
// return;
|
||||
|
||||
((MapInstanced*)(baseMap))->AddGridMapReference(GridPair(x,y));
|
||||
GridMaps[x][y] = baseMap->GridMaps[x][y];
|
||||
((MapInstanced*)(baseMap))->AddGridMapReference(GridPair(gx,gy));
|
||||
GridMaps[gx][gy] = baseMap->GridMaps[gx][gy];
|
||||
return;
|
||||
}
|
||||
|
||||
//map already load, delete it before reloading (Is it necessary? Do we really need the ability the reload maps during runtime?)
|
||||
if(GridMaps[x][y])
|
||||
if(GridMaps[gx][gy])
|
||||
{
|
||||
sLog.outDetail("Unloading already loaded map %u before reloading.",mapid);
|
||||
delete (GridMaps[x][y]);
|
||||
GridMaps[x][y]=NULL;
|
||||
sLog.outDetail("Unloading already loaded map %u before reloading.",i_id);
|
||||
delete (GridMaps[gx][gy]);
|
||||
GridMaps[gx][gy]=NULL;
|
||||
}
|
||||
|
||||
// map file name
|
||||
char *tmp=NULL;
|
||||
// Pihhan: dataPath length + "maps/" + 3+2+2+ ".map" length may be > 32 !
|
||||
int len = sWorld.GetDataPath().length()+strlen("maps/%03u%02u%02u.map")+1;
|
||||
tmp = new char[len];
|
||||
snprintf(tmp, len, (char *)(sWorld.GetDataPath()+"maps/%03u%02u%02u.map").c_str(),mapid,x,y);
|
||||
snprintf(tmp, len, (char *)(sWorld.GetDataPath()+"maps/%03u%02u%02u.map").c_str(),i_id,gx,gy);
|
||||
sLog.outDetail("Loading map %s",tmp);
|
||||
// loading data
|
||||
GridMaps[x][y] = new GridMap();
|
||||
if (!GridMaps[x][y]->loadData(tmp))
|
||||
GridMaps[gx][gy] = new GridMap();
|
||||
if (!GridMaps[gx][gy]->loadData(tmp))
|
||||
{
|
||||
sLog.outError("Error load map file: \n %s\n", tmp);
|
||||
}
|
||||
delete [] tmp;
|
||||
return;
|
||||
}
|
||||
|
||||
void Map::LoadMapAndVMap(uint32 mapid, uint32 instanceid, int x,int y)
|
||||
void Map::LoadMapAndVMap(int gx,int gy)
|
||||
{
|
||||
LoadMap(mapid,instanceid,x,y);
|
||||
if(instanceid == 0)
|
||||
LoadVMap(x, y); // Only load the data for the base map
|
||||
LoadMap(gx,gy);
|
||||
if(i_InstanceId == 0)
|
||||
LoadVMap(gx, gy); // Only load the data for the base map
|
||||
}
|
||||
|
||||
void Map::InitStateMachine()
|
||||
|
|
@ -334,20 +329,20 @@ Map::EnsureGridCreated(const GridPair &p)
|
|||
int gy=63-p.y_coord;
|
||||
|
||||
if(!GridMaps[gx][gy])
|
||||
Map::LoadMapAndVMap(i_id,i_InstanceId,gx,gy);
|
||||
LoadMapAndVMap(gx,gy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Map::EnsureGridLoaded(const Cell &cell, Player *player)
|
||||
Map::EnsureGridLoadedAtEnter(const Cell &cell, Player *player)
|
||||
{
|
||||
EnsureGridCreated(GridPair(cell.GridX(), cell.GridY()));
|
||||
NGridType *grid = getNGrid(cell.GridX(), cell.GridY());
|
||||
NGridType *grid;
|
||||
|
||||
assert(grid != NULL);
|
||||
if (!isGridObjectDataLoaded(cell.GridX(), cell.GridY()))
|
||||
if(EnsureGridLoaded(cell))
|
||||
{
|
||||
grid = getNGrid(cell.GridX(), cell.GridY());
|
||||
|
||||
if (player)
|
||||
{
|
||||
player->SendDelayResponse(MAX_GRID_LOAD_TIME);
|
||||
|
|
@ -358,23 +353,17 @@ Map::EnsureGridLoaded(const Cell &cell, Player *player)
|
|||
DEBUG_LOG("Active object nearby triggers of loading grid [%u,%u] on map %u", cell.GridX(), cell.GridY(), i_id);
|
||||
}
|
||||
|
||||
ObjectGridLoader loader(*grid, this, cell);
|
||||
loader.LoadN();
|
||||
setGridObjectDataLoaded(true, cell.GridX(), cell.GridY());
|
||||
|
||||
// Add resurrectable corpses to world object list in grid
|
||||
ObjectAccessor::Instance().AddCorpsesToGrid(GridPair(cell.GridX(),cell.GridY()),(*grid)(cell.CellX(), cell.CellY()), this);
|
||||
|
||||
ResetGridExpiry(*getNGrid(cell.GridX(), cell.GridY()), 0.1f);
|
||||
grid->SetGridState(GRID_STATE_ACTIVE);
|
||||
}
|
||||
else
|
||||
grid = getNGrid(cell.GridX(), cell.GridY());
|
||||
|
||||
if (player)
|
||||
AddToGrid(player,grid,cell);
|
||||
}
|
||||
|
||||
void
|
||||
Map::LoadGrid(const Cell& cell, bool no_unload)
|
||||
bool Map::EnsureGridLoaded(const Cell &cell)
|
||||
{
|
||||
EnsureGridCreated(GridPair(cell.GridX(), cell.GridY()));
|
||||
NGridType *grid = getNGrid(cell.GridX(), cell.GridY());
|
||||
|
|
@ -389,10 +378,18 @@ Map::LoadGrid(const Cell& cell, bool no_unload)
|
|||
ObjectAccessor::Instance().AddCorpsesToGrid(GridPair(cell.GridX(),cell.GridY()),(*grid)(cell.CellX(), cell.CellY()), this);
|
||||
|
||||
setGridObjectDataLoaded(true,cell.GridX(), cell.GridY());
|
||||
if(no_unload)
|
||||
getNGrid(cell.GridX(), cell.GridY())->setUnloadExplicitLock(true);
|
||||
return true;
|
||||
}
|
||||
LoadVMap(63-cell.GridX(),63-cell.GridY());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Map::LoadGrid(const Cell& cell, bool no_unload)
|
||||
{
|
||||
EnsureGridLoaded(cell);
|
||||
|
||||
if(no_unload)
|
||||
getNGrid(cell.GridX(), cell.GridY())->setUnloadExplicitLock(true);
|
||||
}
|
||||
|
||||
bool Map::Add(Player *player)
|
||||
|
|
@ -404,7 +401,7 @@ bool Map::Add(Player *player)
|
|||
// update player state for other player and visa-versa
|
||||
CellPair p = MaNGOS::ComputeCellPair(player->GetPositionX(), player->GetPositionY());
|
||||
Cell cell(p);
|
||||
EnsureGridLoaded(cell, player);
|
||||
EnsureGridLoadedAtEnter(cell, player);
|
||||
player->AddToWorld();
|
||||
|
||||
SendInitSelf(player);
|
||||
|
|
@ -433,7 +430,7 @@ Map::Add(T *obj)
|
|||
|
||||
Cell cell(p);
|
||||
if(obj->isActiveObject())
|
||||
EnsureGridLoaded(cell);
|
||||
EnsureGridLoadedAtEnter(cell);
|
||||
else
|
||||
EnsureGridCreated(GridPair(cell.GridX(), cell.GridY()));
|
||||
|
||||
|
|
@ -788,7 +785,7 @@ Map::PlayerRelocation(Player *player, float x, float y, float z, float orientati
|
|||
if( !old_cell.DiffGrid(new_cell) )
|
||||
AddToGrid(player, oldGrid,new_cell);
|
||||
else
|
||||
EnsureGridLoaded(new_cell, player);
|
||||
EnsureGridLoadedAtEnter(new_cell, player);
|
||||
}
|
||||
|
||||
// if move then update what player see and who seen
|
||||
|
|
@ -912,7 +909,7 @@ bool Map::CreatureCellRelocation(Creature *c, Cell new_cell)
|
|||
// in diff. grids but active creature
|
||||
if(c->isActiveObject())
|
||||
{
|
||||
EnsureGridLoaded(new_cell);
|
||||
EnsureGridLoadedAtEnter(new_cell);
|
||||
|
||||
#ifdef MANGOS_DEBUG
|
||||
if((sLog.getLogFilter() & LOG_FILTER_CREATURE_MOVES)==0)
|
||||
|
|
@ -1878,7 +1875,8 @@ void Map::SendInitTransports( Player * player )
|
|||
|
||||
for (MapManager::TransportSet::iterator i = tset.begin(); i != tset.end(); ++i)
|
||||
{
|
||||
if((*i) != player->GetTransport()) // send data for current transport in other place
|
||||
// send data for current transport in other place
|
||||
if((*i) != player->GetTransport() && (*i)->GetMapId()==i_id)
|
||||
{
|
||||
hasTransport = true;
|
||||
(*i)->BuildCreateUpdateBlockForPlayer(&transData, player);
|
||||
|
|
@ -1905,7 +1903,7 @@ void Map::SendRemoveTransports( Player * player )
|
|||
|
||||
// except used transport
|
||||
for (MapManager::TransportSet::iterator i = tset.begin(); i != tset.end(); ++i)
|
||||
if(player->GetTransport() != (*i))
|
||||
if((*i) != player->GetTransport() && (*i)->GetMapId()!=i_id)
|
||||
(*i)->BuildOutOfRangeUpdateBlock(&transData);
|
||||
|
||||
WorldPacket packet;
|
||||
|
|
|
|||
|
|
@ -299,9 +299,8 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
|
|||
time_t GetGridExpiry(void) const { return i_gridExpiry; }
|
||||
uint32 GetId(void) const { return i_id; }
|
||||
|
||||
static bool ExistMap(uint32 mapid, int x, int y);
|
||||
static bool ExistVMap(uint32 mapid, int x, int y);
|
||||
void LoadMapAndVMap(uint32 mapid, uint32 instanceid, int x, int y);
|
||||
static bool ExistMap(uint32 mapid, int gx, int gy);
|
||||
static bool ExistVMap(uint32 mapid, int gx, int gy);
|
||||
|
||||
static void InitStateMachine();
|
||||
static void DeleteStateMachine();
|
||||
|
|
@ -404,8 +403,9 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
|
|||
|
||||
void RemoveFromActive(Creature* obj);
|
||||
private:
|
||||
void LoadVMap(int pX, int pY);
|
||||
void LoadMap(uint32 mapid, uint32 instanceid, int x,int y);
|
||||
void LoadMapAndVMap(int gx, int gy);
|
||||
void LoadVMap(int gx, int gy);
|
||||
void LoadMap(int gx,int gy);
|
||||
GridMap *GetGrid(float x, float y);
|
||||
|
||||
void SetTimer(uint32 t) { i_gridExpiry = t < MIN_GRID_DELAY ? MIN_GRID_DELAY : t; }
|
||||
|
|
@ -425,8 +425,9 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
|
|||
CreatureMoveList i_creaturesToMove;
|
||||
|
||||
bool loaded(const GridPair &) const;
|
||||
void EnsureGridLoaded(const Cell&, Player* player = NULL);
|
||||
void EnsureGridCreated(const GridPair &);
|
||||
void EnsureGridCreated(const GridPair &);
|
||||
bool EnsureGridLoaded(Cell const&);
|
||||
void EnsureGridLoadedAtEnter(Cell const&, Player* player = NULL);
|
||||
|
||||
void buildNGridLinkage(NGridType* pNGridType) { pNGridType->link(this); }
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ class MANGOS_DLL_DECL MapInstanced : public Map
|
|||
SetUnloadReferenceLock(GridPair(63-p.x_coord, 63-p.y_coord), true);
|
||||
}
|
||||
|
||||
void RemoveGridMapReference(const GridPair &p)
|
||||
void RemoveGridMapReference(GridPair const& p)
|
||||
{
|
||||
--GridMapReference[p.x_coord][p.y_coord];
|
||||
if (!GridMapReference[p.x_coord][p.y_coord])
|
||||
|
|
|
|||
|
|
@ -1773,7 +1773,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
|
|||
// if the player is saved before worldportack (at logout for example)
|
||||
// this will be used instead of the current location in SaveToDB
|
||||
|
||||
RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CHANGE_MAP);
|
||||
RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CHANGE_MAP | AURA_INTERRUPT_FLAG_MOVE | AURA_INTERRUPT_FLAG_TURNING);
|
||||
|
||||
// move packet sent by client always after far teleport
|
||||
// SetPosition(final_x, final_y, final_z, final_o, true);
|
||||
|
|
@ -14384,15 +14384,17 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff)
|
|||
else
|
||||
remaincharges = 0;
|
||||
|
||||
//do not load single target auras (unless they were cast by the player)
|
||||
if (caster_guid != GetGUID() && IsSingleTargetSpell(spellproto))
|
||||
continue;
|
||||
|
||||
for(uint32 i=0; i<stackcount; i++)
|
||||
{
|
||||
Aura* aura = CreateAura(spellproto, effindex, NULL, this, NULL);
|
||||
if(!damage)
|
||||
damage = aura->GetModifier()->m_amount;
|
||||
|
||||
// reset stolen single target auras
|
||||
if (caster_guid != GetGUID() && aura->IsSingleTarget())
|
||||
aura->SetIsSingleTarget(false);
|
||||
|
||||
aura->SetLoadedState(caster_guid,damage,maxduration,remaintime,remaincharges);
|
||||
AddAura(aura);
|
||||
sLog.outDetail("Added aura spellid %u, effect %u", spellproto->Id, effindex);
|
||||
|
|
@ -15422,7 +15424,7 @@ void Player::_SaveAuras()
|
|||
if (!(itr2->second->IsPassive() || itr2->second->IsRemovedOnShapeLost()))
|
||||
{
|
||||
//do not save single target auras (unless they were cast by the player)
|
||||
if (!(itr2->second->GetCasterGUID() != GetGUID() && IsSingleTargetSpell(spellInfo)))
|
||||
if (!(itr2->second->GetCasterGUID() != GetGUID() && itr2->second->IsSingleTarget()))
|
||||
{
|
||||
uint8 i;
|
||||
// or apply at cast SPELL_AURA_MOD_SHAPESHIFT or SPELL_AURA_MOD_STEALTH auras
|
||||
|
|
|
|||
|
|
@ -2487,7 +2487,7 @@ void Spell::cast(bool skipCheck)
|
|||
|
||||
if (m_caster->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
if (m_CastItem)
|
||||
if (!m_IsTriggeredSpell && 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);
|
||||
|
|
@ -4991,8 +4991,8 @@ SpellCastResult Spell::CheckItems()
|
|||
focusObject = ok; // game object found in range
|
||||
}
|
||||
|
||||
// check reagents
|
||||
if (!p_caster->CanNoReagentCast(m_spellInfo))
|
||||
// check reagents (ignore triggered spells with reagents processed by original spell) and special reagent ignore case.
|
||||
if (!m_IsTriggeredSpell && !p_caster->CanNoReagentCast(m_spellInfo))
|
||||
{
|
||||
for(uint32 i=0;i<8;i++)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -365,6 +365,8 @@ m_updated(false), m_isRemovedOnShapeLost(true), m_in_use(false)
|
|||
m_isPassive = IsPassiveSpell(GetId());
|
||||
m_positive = IsPositiveEffect(GetId(), m_effIndex);
|
||||
|
||||
m_isSingleTargetAura = IsSingleTargetSpell(m_spellProto);
|
||||
|
||||
m_applyTime = time(NULL);
|
||||
|
||||
int32 damage;
|
||||
|
|
@ -3489,52 +3491,56 @@ void Aura::HandleAuraModStun(bool apply, bool Real)
|
|||
|
||||
void Aura::HandleModStealth(bool apply, bool Real)
|
||||
{
|
||||
if(apply)
|
||||
Unit* pTarget = m_target;
|
||||
|
||||
if (apply)
|
||||
{
|
||||
// drop flag at stealth in bg
|
||||
m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
|
||||
pTarget->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
|
||||
|
||||
// only at real aura add
|
||||
if(Real)
|
||||
if (Real)
|
||||
{
|
||||
m_target->SetStandFlags(UNIT_STAND_FLAGS_CREEP);
|
||||
if(m_target->GetTypeId()==TYPEID_PLAYER)
|
||||
m_target->SetFlag(PLAYER_FIELD_BYTES2, 0x2000);
|
||||
pTarget->SetStandFlags(UNIT_STAND_FLAGS_CREEP);
|
||||
|
||||
if (pTarget->GetTypeId()==TYPEID_PLAYER)
|
||||
pTarget->SetFlag(PLAYER_FIELD_BYTES2, 0x2000);
|
||||
|
||||
// apply only if not in GM invisibility (and overwrite invisibility state)
|
||||
if(m_target->GetVisibility()!=VISIBILITY_OFF)
|
||||
if (pTarget->GetVisibility()!=VISIBILITY_OFF)
|
||||
{
|
||||
m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT);
|
||||
m_target->SetVisibility(VISIBILITY_GROUP_STEALTH);
|
||||
pTarget->SetVisibility(VISIBILITY_GROUP_NO_DETECT);
|
||||
pTarget->SetVisibility(VISIBILITY_GROUP_STEALTH);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// only at real aura remove
|
||||
if(Real)
|
||||
if (Real)
|
||||
{
|
||||
// if last SPELL_AURA_MOD_STEALTH and no GM invisibility
|
||||
if(!m_target->HasAuraType(SPELL_AURA_MOD_STEALTH) && m_target->GetVisibility()!=VISIBILITY_OFF)
|
||||
if (!pTarget->HasAuraType(SPELL_AURA_MOD_STEALTH) && pTarget->GetVisibility()!=VISIBILITY_OFF)
|
||||
{
|
||||
m_target->RemoveStandFlags(UNIT_STAND_FLAGS_CREEP);
|
||||
if(m_target->GetTypeId()==TYPEID_PLAYER)
|
||||
m_target->RemoveFlag(PLAYER_FIELD_BYTES2, 0x2000);
|
||||
pTarget->RemoveStandFlags(UNIT_STAND_FLAGS_CREEP);
|
||||
|
||||
if (pTarget->GetTypeId()==TYPEID_PLAYER)
|
||||
pTarget->RemoveFlag(PLAYER_FIELD_BYTES2, 0x2000);
|
||||
|
||||
// restore invisibility if any
|
||||
if(m_target->HasAuraType(SPELL_AURA_MOD_INVISIBILITY))
|
||||
if (pTarget->HasAuraType(SPELL_AURA_MOD_INVISIBILITY))
|
||||
{
|
||||
m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT);
|
||||
m_target->SetVisibility(VISIBILITY_GROUP_INVISIBILITY);
|
||||
pTarget->SetVisibility(VISIBILITY_GROUP_NO_DETECT);
|
||||
pTarget->SetVisibility(VISIBILITY_GROUP_INVISIBILITY);
|
||||
}
|
||||
else
|
||||
m_target->SetVisibility(VISIBILITY_ON);
|
||||
pTarget->SetVisibility(VISIBILITY_ON);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Master of Subtlety
|
||||
Unit::AuraList const& mDummyAuras = m_target->GetAurasByType(SPELL_AURA_DUMMY);
|
||||
Unit::AuraList const& mDummyAuras = pTarget->GetAurasByType(SPELL_AURA_DUMMY);
|
||||
for(Unit::AuraList::const_iterator i = mDummyAuras.begin();i != mDummyAuras.end(); ++i)
|
||||
{
|
||||
if ((*i)->GetSpellProto()->SpellIconID == 2114)
|
||||
|
|
@ -3542,10 +3548,10 @@ void Aura::HandleModStealth(bool apply, bool Real)
|
|||
if (apply)
|
||||
{
|
||||
int32 bp = (*i)->GetModifier()->m_amount;
|
||||
m_target->CastCustomSpell(m_target,31665,&bp,NULL,NULL,true);
|
||||
pTarget->CastCustomSpell(pTarget,31665,&bp,NULL,NULL,true);
|
||||
}
|
||||
else
|
||||
m_target->CastSpell(m_target,31666,true);
|
||||
pTarget->CastSpell(pTarget,31666,true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -6747,3 +6753,21 @@ void Aura::HandlePhase(bool apply, bool Real)
|
|||
m_target->SetVisibility(m_target->GetVisibility());
|
||||
}
|
||||
|
||||
void Aura::UnregisterSingleCastAura()
|
||||
{
|
||||
if (IsSingleTarget())
|
||||
{
|
||||
Unit* caster = NULL;
|
||||
caster = GetCaster();
|
||||
if(caster)
|
||||
{
|
||||
caster->GetSingleCastAuras().remove(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
sLog.outError("Couldn't find the caster of the single target aura, may crash later!");
|
||||
assert(false);
|
||||
}
|
||||
m_isSingleTargetAura = false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -267,6 +267,8 @@ class MANGOS_DLL_SPEC Aura
|
|||
return m_procCharges == 0;
|
||||
}
|
||||
|
||||
void UnregisterSingleCastAura();
|
||||
|
||||
void SetAura(bool remove) { m_target->SetVisibleAura(m_auraSlot, remove ? 0 : GetId()); }
|
||||
void SendAuraUpdate(bool remove);
|
||||
|
||||
|
|
@ -296,6 +298,10 @@ class MANGOS_DLL_SPEC Aura
|
|||
|
||||
bool IsUpdated() { return m_updated; }
|
||||
void SetUpdated(bool val) { m_updated = val; }
|
||||
|
||||
bool IsSingleTarget() {return m_isSingleTargetAura;}
|
||||
void SetIsSingleTarget(bool val) { m_isSingleTargetAura = val;}
|
||||
|
||||
void SetRemoveMode(AuraRemoveMode mode) { m_removeMode = mode; }
|
||||
|
||||
virtual Unit* GetTriggerTarget() const { return m_target; }
|
||||
|
|
@ -352,6 +358,7 @@ class MANGOS_DLL_SPEC Aura
|
|||
bool m_isRemovedOnShapeLost:1;
|
||||
bool m_updated:1; // Prevent remove aura by stack if set
|
||||
bool m_in_use:1; // true while in Aura::ApplyModifier call
|
||||
bool m_isSingleTargetAura:1; // true if it's a single target spell and registered at caster - can change at spell steal for example
|
||||
|
||||
private:
|
||||
void CleanupTriggeredSpells();
|
||||
|
|
|
|||
|
|
@ -1748,6 +1748,26 @@ void Spell::EffectDummy(uint32 i)
|
|||
return;
|
||||
}
|
||||
break;
|
||||
case SPELLFAMILY_DEATHKNIGHT:
|
||||
// Death Coil
|
||||
if(m_spellInfo->SpellFamilyFlags & 0x002000LL)
|
||||
{
|
||||
if(m_caster->IsFriendlyTo(unitTarget))
|
||||
{
|
||||
if(unitTarget->GetCreatureType() != CREATURE_TYPE_UNDEAD)
|
||||
return;
|
||||
|
||||
int32 bp = damage * 1.5f;
|
||||
m_caster->CastCustomSpell(unitTarget,47633,&bp,NULL,NULL,true);
|
||||
}
|
||||
else
|
||||
{
|
||||
int32 bp = damage;
|
||||
m_caster->CastCustomSpell(unitTarget,47632,&bp,NULL,NULL,true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// pet auras
|
||||
|
|
@ -2375,6 +2395,14 @@ void Spell::EffectPowerBurn(uint32 i)
|
|||
if(damage < 0)
|
||||
return;
|
||||
|
||||
// burn x% of target's mana, up to maximum of 2x% of caster's mana (Mana Burn)
|
||||
if(m_spellInfo->ManaCostPercentage)
|
||||
{
|
||||
uint32 maxdamage = m_caster->GetMaxPower(powertype) * damage * 2 / 100;
|
||||
damage = unitTarget->GetMaxPower(powertype) * damage / 100;
|
||||
if(damage > maxdamage) damage = maxdamage;
|
||||
}
|
||||
|
||||
int32 curPower = int32(unitTarget->GetPower(powertype));
|
||||
|
||||
// resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
|
||||
|
|
|
|||
|
|
@ -234,6 +234,15 @@ void WorldSession::HandleGameobjectReportUse(WorldPacket& recvPacket)
|
|||
recvPacket >> guid;
|
||||
|
||||
sLog.outDebug( "WORLD: Recvd CMSG_GAMEOBJ_REPORT_USE Message [in game guid: %u]", GUID_LOPART(guid));
|
||||
|
||||
GameObject* go = ObjectAccessor::GetGameObject(*_player,guid);
|
||||
if(!go)
|
||||
return;
|
||||
|
||||
if(!go->IsWithinDistInMap(_player,INTERACTION_DISTANCE))
|
||||
return;
|
||||
|
||||
_player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT, go->GetEntry());
|
||||
}
|
||||
|
||||
void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
|
||||
|
|
|
|||
|
|
@ -85,8 +85,6 @@ void MapManager::LoadTransports()
|
|||
continue;
|
||||
}
|
||||
|
||||
t->m_name = goinfo->name;
|
||||
|
||||
float x, y, z, o;
|
||||
uint32 mapid;
|
||||
x = t->m_WayPoints[0].x; y = t->m_WayPoints[0].y; z = t->m_WayPoints[0].z; mapid = t->m_WayPoints[0].mapid; o = 1;
|
||||
|
|
@ -181,6 +179,8 @@ bool Transport::Create(uint32 guidlow, uint32 mapid, float x, float y, float z,
|
|||
if(dynflags)
|
||||
SetUInt32Value(GAMEOBJECT_DYNAMIC, MAKE_PAIR32(0, dynflags));
|
||||
|
||||
SetName(goinfo->name);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -432,11 +432,9 @@ Transport::WayPointMap::iterator Transport::GetNextWayPoint()
|
|||
|
||||
void Transport::TeleportTransport(uint32 newMapid, float x, float y, float z)
|
||||
{
|
||||
//GetMap()->Remove((GameObject *)this, false);
|
||||
Map const* oldMap = GetMap();
|
||||
SetMapId(newMapid);
|
||||
//MapManager::Instance().LoadGrid(newMapid,x,y,true);
|
||||
Relocate(x, y, z);
|
||||
//GetMap()->Add<GameObject>((GameObject *)this);
|
||||
|
||||
for(PlayerSet::iterator itr = m_passengers.begin(); itr != m_passengers.end();)
|
||||
{
|
||||
|
|
@ -460,13 +458,21 @@ void Transport::TeleportTransport(uint32 newMapid, float x, float y, float z)
|
|||
//data << uint32(0);
|
||||
//plr->GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
||||
Map const* newMap = GetMap();
|
||||
|
||||
if(oldMap != newMap)
|
||||
{
|
||||
UpdateForMap(oldMap);
|
||||
UpdateForMap(newMap);
|
||||
}
|
||||
}
|
||||
|
||||
bool Transport::AddPassenger(Player* passenger)
|
||||
{
|
||||
if (m_passengers.find(passenger) == m_passengers.end())
|
||||
{
|
||||
sLog.outDetail("Player %s boarded transport %s.", passenger->GetName(), m_name.c_str());
|
||||
sLog.outDetail("Player %s boarded transport %s.", passenger->GetName(), GetName());
|
||||
m_passengers.insert(passenger);
|
||||
}
|
||||
return true;
|
||||
|
|
@ -475,7 +481,7 @@ bool Transport::AddPassenger(Player* passenger)
|
|||
bool Transport::RemovePassenger(Player* passenger)
|
||||
{
|
||||
if (m_passengers.erase(passenger))
|
||||
sLog.outDetail("Player %s removed from transport %s.", passenger->GetName(), m_name.c_str());
|
||||
sLog.outDetail("Player %s removed from transport %s.", passenger->GetName(), GetName());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -497,7 +503,6 @@ void Transport::Update(uint32 /*p_time*/)
|
|||
}
|
||||
else
|
||||
{
|
||||
//MapManager::Instance().GetMap(m_curr->second.mapid)->GameobjectRelocation((GameObject *)this, m_curr->second.x, m_curr->second.y, m_curr->second.z, m_orientation);
|
||||
Relocate(m_curr->second.x, m_curr->second.y, m_curr->second.z);
|
||||
}
|
||||
|
||||
|
|
@ -513,13 +518,42 @@ void Transport::Update(uint32 /*p_time*/)
|
|||
m_nextNodeTime = m_curr->first;
|
||||
|
||||
if (m_curr == m_WayPoints.begin() && (sLog.getLogFilter() & LOG_FILTER_TRANSPORT_MOVES)==0)
|
||||
sLog.outDetail(" ************ BEGIN ************** %s", m_name.c_str());
|
||||
|
||||
// MapManager::Instance().GetMap(m_curr->second.mapid)->Add(&this); // -> // ->Add(t);
|
||||
//MapManager::Instance().GetMap(m_curr->second.mapid)->Remove((GameObject *)this, false); // -> // ->Add(t);
|
||||
//MapManager::Instance().GetMap(m_curr->second.mapid)->Add((GameObject *)this); // -> // ->Add(t);
|
||||
sLog.outDetail(" ************ BEGIN ************** %s", GetName());
|
||||
|
||||
if ((sLog.getLogFilter() & LOG_FILTER_TRANSPORT_MOVES)==0)
|
||||
sLog.outDetail("%s moved to %f %f %f %d", m_name.c_str(), m_curr->second.x, m_curr->second.y, m_curr->second.z, m_curr->second.mapid);
|
||||
sLog.outDetail("%s moved to %f %f %f %d", GetName(), m_curr->second.x, m_curr->second.y, m_curr->second.z, m_curr->second.mapid);
|
||||
}
|
||||
}
|
||||
|
||||
void Transport::UpdateForMap(Map const* targetMap)
|
||||
{
|
||||
Map::PlayerList const& pl = targetMap->GetPlayers();
|
||||
if(pl.isEmpty())
|
||||
return;
|
||||
|
||||
if(GetMapId()==targetMap->GetId())
|
||||
{
|
||||
for(Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr)
|
||||
{
|
||||
if(this != itr->getSource()->GetTransport())
|
||||
{
|
||||
UpdateData transData;
|
||||
BuildCreateUpdateBlockForPlayer(&transData, itr->getSource());
|
||||
WorldPacket packet;
|
||||
transData.BuildPacket(&packet, true);
|
||||
itr->getSource()->SendDirectMessage(&packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateData transData;
|
||||
BuildOutOfRangeUpdateBlock(&transData);
|
||||
WorldPacket out_packet;
|
||||
transData.BuildPacket(&out_packet, true);
|
||||
|
||||
for(Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr)
|
||||
if(this != itr->getSource()->GetTransport())
|
||||
itr->getSource()->SendDirectMessage(&out_packet);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ class TransportPath
|
|||
std::vector<PathNode> i_nodes;
|
||||
};
|
||||
|
||||
class Transport : private GameObject
|
||||
class Transport : protected GameObject
|
||||
{
|
||||
public:
|
||||
explicit Transport();
|
||||
|
|
@ -81,7 +81,6 @@ class Transport : private GameObject
|
|||
typedef std::set<Player*> PlayerSet;
|
||||
PlayerSet const& GetPassengers() const { return m_passengers; }
|
||||
|
||||
std::string m_name;
|
||||
private:
|
||||
struct WayPoint
|
||||
{
|
||||
|
|
@ -111,6 +110,7 @@ class Transport : private GameObject
|
|||
|
||||
private:
|
||||
void TeleportTransport(uint32 newMapid, float x, float y, float z);
|
||||
void UpdateForMap(Map const* map);
|
||||
WayPointMap::iterator GetNextWayPoint();
|
||||
};
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -3411,7 +3411,7 @@ bool Unit::AddAura(Aura *Aur)
|
|||
}
|
||||
|
||||
// update single target auras list (before aura add to aura list, to prevent unexpected remove recently added aura)
|
||||
if (IsSingleTargetSpell(aurSpellInfo) && Aur->GetTarget())
|
||||
if (Aur->IsSingleTarget() && Aur->GetTarget())
|
||||
{
|
||||
// caster pointer can be deleted in time aura remove, find it by guid at each iteration
|
||||
for(;;)
|
||||
|
|
@ -3692,10 +3692,9 @@ void Unit::RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit
|
|||
if (aur->GetId() == spellId && aur->GetCasterGUID() == casterGUID)
|
||||
{
|
||||
int32 basePoints = aur->GetBasePoints();
|
||||
// construct the new aura for the attacker
|
||||
Aura * new_aur = CreateAura(aur->GetSpellProto(), aur->GetEffIndex(), &basePoints, stealer);
|
||||
if(!new_aur)
|
||||
continue;
|
||||
// construct the new aura for the attacker - will never return NULL, it's just a wrapper for
|
||||
// some different constructors
|
||||
Aura * new_aur = CreateAura(aur->GetSpellProto(), aur->GetEffIndex(), &basePoints, stealer, this);
|
||||
|
||||
// set its duration and maximum duration
|
||||
// max duration 2 minutes (in msecs)
|
||||
|
|
@ -3704,6 +3703,12 @@ void Unit::RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit
|
|||
new_aur->SetAuraMaxDuration( max_dur > dur ? dur : max_dur );
|
||||
new_aur->SetAuraDuration( max_dur > dur ? dur : max_dur );
|
||||
|
||||
// Unregister _before_ adding to stealer
|
||||
aur->UnregisterSingleCastAura();
|
||||
|
||||
// strange but intended behaviour: Stolen single target auras won't be treated as single targeted
|
||||
new_aur->SetIsSingleTarget(false);
|
||||
|
||||
// add the new aura to stealer
|
||||
stealer->AddAura(new_aur);
|
||||
|
||||
|
|
@ -3830,21 +3835,7 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
|
|||
Aura* Aur = i->second;
|
||||
SpellEntry const* AurSpellInfo = Aur->GetSpellProto();
|
||||
|
||||
Unit* caster = NULL;
|
||||
if (IsSingleTargetSpell(AurSpellInfo))
|
||||
{
|
||||
caster = Aur->GetCaster();
|
||||
if(caster)
|
||||
{
|
||||
AuraList& scAuras = caster->GetSingleCastAuras();
|
||||
scAuras.remove(Aur);
|
||||
}
|
||||
else
|
||||
{
|
||||
sLog.outError("Couldn't find the caster of the single target aura, may crash later!");
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
Aur->UnregisterSingleCastAura();
|
||||
|
||||
// remove from list before mods removing (prevent cyclic calls, mods added before including to aura list - use reverse order)
|
||||
if (Aur->GetModifier()->m_auraname < TOTAL_AURAS)
|
||||
|
|
@ -3864,8 +3855,7 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
|
|||
bool caster_channeled = false;
|
||||
if(IsChanneledSpell(AurSpellInfo))
|
||||
{
|
||||
if(!caster) // can be already located for IsSingleTargetSpell case
|
||||
caster = Aur->GetCaster();
|
||||
Unit* caster = Aur->GetCaster();
|
||||
|
||||
if(caster)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ void WaypointManager::Load()
|
|||
node.y = fields[1].GetFloat();
|
||||
node.z = fields[2].GetFloat();
|
||||
node.orientation = fields[3].GetFloat();
|
||||
node.delay = fields[6].GetUInt16();
|
||||
node.delay = fields[6].GetUInt32();
|
||||
|
||||
// prevent using invalid coordinates
|
||||
if(!MaNGOS::IsValidMapCoord(node.x, node.y, node.z, node.orientation))
|
||||
|
|
|
|||
|
|
@ -1267,6 +1267,7 @@ void World::SetInitialWorldSettings()
|
|||
|
||||
sLog.outString( "Loading Achievements..." );
|
||||
sLog.outString();
|
||||
achievementmgr.LoadAchievementReferenceList();
|
||||
achievementmgr.LoadAchievementCriteriaList();
|
||||
achievementmgr.LoadRewards();
|
||||
achievementmgr.LoadRewardLocales();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "7590"
|
||||
#define REVISION_NR "7608"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue