Merge branch 'master' into 310

Conflicts:
	src/game/Unit.cpp
This commit is contained in:
tomrus88 2009-04-03 11:28:51 +04:00
commit 17d86309fa
22 changed files with 373 additions and 190 deletions

View file

@ -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)];

View file

@ -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;

View file

@ -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()
{

View file

@ -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;

View file

@ -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

View file

@ -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";

View file

@ -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;

View file

@ -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); }

View file

@ -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])

View file

@ -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

View file

@ -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++)
{

View file

@ -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;
}
}

View file

@ -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();

View file

@ -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)

View file

@ -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)

View file

@ -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);
}
}

View file

@ -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

View file

@ -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)
{

View file

@ -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))

View file

@ -1267,6 +1267,7 @@ void World::SetInitialWorldSettings()
sLog.outString( "Loading Achievements..." );
sLog.outString();
achievementmgr.LoadAchievementReferenceList();
achievementmgr.LoadAchievementCriteriaList();
achievementmgr.LoadRewards();
achievementmgr.LoadRewardLocales();

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "7590"
#define REVISION_NR "7608"
#endif // __REVISION_NR_H__