mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 04:37:00 +00:00
Merge branch 'master' into 303
Conflicts: src/game/CharacterHandler.cpp src/game/Pet.cpp src/game/Player.cpp
This commit is contained in:
commit
768fa2d2de
22 changed files with 451 additions and 355 deletions
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `character_db_version`;
|
DROP TABLE IF EXISTS `character_db_version`;
|
||||||
CREATE TABLE `character_db_version` (
|
CREATE TABLE `character_db_version` (
|
||||||
`required_2008_11_07_03_characters_guild_bank_tab` bit(1) default NULL
|
`required_2008_11_12_01_character_character_aura` bit(1) default NULL
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB';
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB';
|
||||||
|
|
||||||
--
|
--
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
DROP TABLE IF EXISTS `db_version`;
|
DROP TABLE IF EXISTS `db_version`;
|
||||||
CREATE TABLE `db_version` (
|
CREATE TABLE `db_version` (
|
||||||
`version` varchar(120) default NULL,
|
`version` varchar(120) default NULL,
|
||||||
`required_2008_11_11_02_mangos_scripts` bit(1) default NULL
|
`required_2008_11_14_01_mangos_scripts` bit(1) default NULL
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
|
||||||
|
|
||||||
--
|
--
|
||||||
|
|
|
||||||
5
sql/updates/2008_11_12_01_character_character_aura.sql
Normal file
5
sql/updates/2008_11_12_01_character_character_aura.sql
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
ALTER TABLE character_db_version CHANGE COLUMN required_2008_11_07_03_characters_guild_bank_tab required_2008_11_12_01_character_character_aura bit;
|
||||||
|
|
||||||
|
ALTER TABLE `character_aura` ADD `stackcount` INT NOT NULL DEFAULT '1' AFTER `effect_index` ;
|
||||||
|
ALTER TABLE `pet_aura` ADD `stackcount` INT NOT NULL DEFAULT '1' AFTER `effect_index` ;
|
||||||
|
|
||||||
16
sql/updates/2008_11_14_01_mangos_scripts.sql
Normal file
16
sql/updates/2008_11_14_01_mangos_scripts.sql
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
ALTER TABLE db_version CHANGE COLUMN required_2008_11_11_02_mangos_scripts required_2008_11_14_01_mangos_scripts bit;
|
||||||
|
|
||||||
|
ALTER TABLE event_scripts
|
||||||
|
CHANGE COLUMN dataint dataint int(11) NOT NULL default '0' AFTER datalong2;
|
||||||
|
|
||||||
|
ALTER TABLE gameobject_scripts
|
||||||
|
CHANGE COLUMN dataint dataint int(11) NOT NULL default '0' AFTER datalong2;
|
||||||
|
|
||||||
|
ALTER TABLE quest_end_scripts
|
||||||
|
CHANGE COLUMN dataint dataint int(11) NOT NULL default '0' AFTER datalong2;
|
||||||
|
|
||||||
|
ALTER TABLE quest_start_scripts
|
||||||
|
CHANGE COLUMN dataint dataint int(11) NOT NULL default '0' AFTER datalong2;
|
||||||
|
|
||||||
|
ALTER TABLE spell_scripts
|
||||||
|
CHANGE COLUMN dataint dataint int(11) NOT NULL default '0' AFTER datalong2;
|
||||||
|
|
@ -132,6 +132,7 @@ pkgdata_DATA = \
|
||||||
2008_11_09_03_mangos_mangos_string.sql \
|
2008_11_09_03_mangos_mangos_string.sql \
|
||||||
2008_11_11_01_mangos_db_script_string.sql \
|
2008_11_11_01_mangos_db_script_string.sql \
|
||||||
2008_11_11_02_mangos_scripts.sql \
|
2008_11_11_02_mangos_scripts.sql \
|
||||||
|
2008_11_14_01_mangos_scripts.sql \
|
||||||
README
|
README
|
||||||
|
|
||||||
## Additional files to include when running 'make dist'
|
## Additional files to include when running 'make dist'
|
||||||
|
|
@ -245,4 +246,6 @@ EXTRA_DIST = \
|
||||||
2008_11_09_03_mangos_mangos_string.sql \
|
2008_11_09_03_mangos_mangos_string.sql \
|
||||||
2008_11_11_01_mangos_db_script_string.sql \
|
2008_11_11_01_mangos_db_script_string.sql \
|
||||||
2008_11_11_02_mangos_scripts.sql \
|
2008_11_11_02_mangos_scripts.sql \
|
||||||
|
2008_11_12_01_character_character_aura.sql \
|
||||||
|
2008_11_14_01_mangos_scripts.sql \
|
||||||
README
|
README
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ bool LoginQueryHolder::Initialize()
|
||||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADFROM, "SELECT guid, account, data, name, race, class, position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, dungeon_difficulty FROM characters WHERE guid = '%u'", GUID_LOPART(m_guid));
|
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADFROM, "SELECT guid, account, data, name, race, class, position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, dungeon_difficulty FROM characters WHERE guid = '%u'", GUID_LOPART(m_guid));
|
||||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADGROUP, "SELECT leaderGuid FROM group_member WHERE memberGuid ='%u'", GUID_LOPART(m_guid));
|
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADGROUP, "SELECT leaderGuid FROM group_member WHERE memberGuid ='%u'", GUID_LOPART(m_guid));
|
||||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADBOUNDINSTANCES, "SELECT id, permanent, map, difficulty, resettime FROM character_instance LEFT JOIN instance ON instance = id WHERE guid = '%u'", GUID_LOPART(m_guid));
|
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADBOUNDINSTANCES, "SELECT id, permanent, map, difficulty, resettime FROM character_instance LEFT JOIN instance ON instance = id WHERE guid = '%u'", GUID_LOPART(m_guid));
|
||||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADAURAS, "SELECT caster_guid,spell,effect_index,amount,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u' ORDER by spell,effect_index", GUID_LOPART(m_guid));
|
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADAURAS, "SELECT caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'", GUID_LOPART(m_guid));
|
||||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADSPELLS, "SELECT spell,slot,active,disabled FROM character_spell WHERE guid = '%u'", GUID_LOPART(m_guid));
|
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADSPELLS, "SELECT spell,slot,active,disabled FROM character_spell WHERE guid = '%u'", GUID_LOPART(m_guid));
|
||||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADQUESTSTATUS, "SELECT quest,status,rewarded,explored,timer,mobcount1,mobcount2,mobcount3,mobcount4,itemcount1,itemcount2,itemcount3,itemcount4 FROM character_queststatus WHERE guid = '%u'", GUID_LOPART(m_guid));
|
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADQUESTSTATUS, "SELECT quest,status,rewarded,explored,timer,mobcount1,mobcount2,mobcount3,mobcount4,itemcount1,itemcount2,itemcount3,itemcount4 FROM character_queststatus WHERE guid = '%u'", GUID_LOPART(m_guid));
|
||||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADDAILYQUESTSTATUS,"SELECT quest,time FROM character_queststatus_daily WHERE guid = '%u'", GUID_LOPART(m_guid));
|
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADDAILYQUESTSTATUS,"SELECT quest,time FROM character_queststatus_daily WHERE guid = '%u'", GUID_LOPART(m_guid));
|
||||||
|
|
|
||||||
|
|
@ -6326,7 +6326,8 @@ bool ChatHandler::HandleSendMoneyCommand(const char* args)
|
||||||
if (!msgText)
|
if (!msgText)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int32 money = atoi(strtok(NULL, ""));
|
char* money_str = strtok(NULL, "");
|
||||||
|
int32 money = money_str ? atoi(money_str) : 0;
|
||||||
if (money <= 0)
|
if (money <= 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -562,6 +562,63 @@ bool Map::loaded(const GridPair &p) const
|
||||||
|
|
||||||
void Map::Update(const uint32 &t_diff)
|
void Map::Update(const uint32 &t_diff)
|
||||||
{
|
{
|
||||||
|
resetMarkedCells();
|
||||||
|
|
||||||
|
//TODO: Player guard
|
||||||
|
HashMapHolder<Player>::MapType& playerMap = HashMapHolder<Player>::GetContainer();
|
||||||
|
for(HashMapHolder<Player>::MapType::iterator iter = playerMap.begin(); iter != playerMap.end(); ++iter)
|
||||||
|
{
|
||||||
|
WorldObject* obj = iter->second;
|
||||||
|
|
||||||
|
if(!obj->IsInWorld())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(obj->GetMapId() != GetId())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(obj->GetInstanceId() != GetInstanceId())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
CellPair standing_cell(MaNGOS::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY()));
|
||||||
|
|
||||||
|
// Check for correctness of standing_cell, it also avoids problems with update_cell
|
||||||
|
if (standing_cell.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || standing_cell.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// the overloaded operators handle range checking
|
||||||
|
// so ther's no need for range checking inside the loop
|
||||||
|
CellPair begin_cell(standing_cell), end_cell(standing_cell);
|
||||||
|
begin_cell << 1; begin_cell -= 1; // upper left
|
||||||
|
end_cell >> 1; end_cell += 1; // lower right
|
||||||
|
|
||||||
|
for(uint32 x = begin_cell.x_coord; x <= end_cell.x_coord; ++x)
|
||||||
|
for(uint32 y = begin_cell.y_coord; y <= end_cell.y_coord; ++y)
|
||||||
|
markCell(x,y);
|
||||||
|
}
|
||||||
|
|
||||||
|
MaNGOS::ObjectUpdater updater(t_diff);
|
||||||
|
// for creature
|
||||||
|
TypeContainerVisitor<MaNGOS::ObjectUpdater, GridTypeMapContainer > grid_object_update(updater);
|
||||||
|
// for pets
|
||||||
|
TypeContainerVisitor<MaNGOS::ObjectUpdater, WorldTypeMapContainer > world_object_update(updater);
|
||||||
|
|
||||||
|
for(int x = 0; x < TOTAL_NUMBER_OF_CELLS_PER_MAP; ++x)
|
||||||
|
{
|
||||||
|
for(int y = 0; y < TOTAL_NUMBER_OF_CELLS_PER_MAP; ++y)
|
||||||
|
{
|
||||||
|
if(isCellMarked(x,y))
|
||||||
|
{
|
||||||
|
CellPair pair(x,y);
|
||||||
|
Cell cell(pair);
|
||||||
|
cell.data.Part.reserved = CENTER_DISTRICT;
|
||||||
|
cell.SetNoCreate();
|
||||||
|
CellLock<NullGuard> cell_lock(cell, pair);
|
||||||
|
cell_lock->Visit(cell_lock, grid_object_update, *this);
|
||||||
|
cell_lock->Visit(cell_lock, world_object_update, *this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Don't unload grids if it's battleground, since we may have manually added GOs,creatures, those doesn't load from DB at grid re-load !
|
// Don't unload grids if it's battleground, since we may have manually added GOs,creatures, those doesn't load from DB at grid re-load !
|
||||||
// This isn't really bother us, since as soon as we have instanced BG-s, the whole map unloads as the BG gets ended
|
// This isn't really bother us, since as soon as we have instanced BG-s, the whole map unloads as the BG gets ended
|
||||||
if (IsBattleGroundOrArena())
|
if (IsBattleGroundOrArena())
|
||||||
|
|
|
||||||
|
|
@ -241,8 +241,8 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
|
||||||
void UpdateObjectsVisibilityFor(Player* player, Cell cell, CellPair cellpair);
|
void UpdateObjectsVisibilityFor(Player* player, Cell cell, CellPair cellpair);
|
||||||
|
|
||||||
void resetMarkedCells() { marked_cells.reset(); }
|
void resetMarkedCells() { marked_cells.reset(); }
|
||||||
bool isCellMarked(uint32 pCellId) { return marked_cells.test(pCellId); }
|
bool isCellMarked(uint32 x, uint32 y) { return marked_cells.test(y * TOTAL_NUMBER_OF_CELLS_PER_MAP + x); }
|
||||||
void markCell(uint32 pCellId) { marked_cells.set(pCellId); }
|
void markCell(uint32 x, uint32 y) { marked_cells.set(y * TOTAL_NUMBER_OF_CELLS_PER_MAP + x); }
|
||||||
private:
|
private:
|
||||||
void LoadVMap(int pX, int pY);
|
void LoadVMap(int pX, int pY);
|
||||||
void LoadMap(uint32 mapid, uint32 instanceid, int x,int y);
|
void LoadMap(uint32 mapid, uint32 instanceid, int x,int y);
|
||||||
|
|
|
||||||
|
|
@ -245,6 +245,8 @@ MapManager::Update(time_t diff)
|
||||||
if( !i_timer.Passed() )
|
if( !i_timer.Passed() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
ObjectAccessor::Instance().UpdatePlayers(i_timer.GetCurrent());
|
||||||
|
|
||||||
for(MapMapType::iterator iter=i_maps.begin(); iter != i_maps.end(); ++iter)
|
for(MapMapType::iterator iter=i_maps.begin(); iter != i_maps.end(); ++iter)
|
||||||
{
|
{
|
||||||
checkAndCorrectGridStatesArray(); // debugging code, should be deleted some day
|
checkAndCorrectGridStatesArray(); // debugging code, should be deleted some day
|
||||||
|
|
|
||||||
|
|
@ -247,32 +247,6 @@ ObjectAccessor::SaveAllPlayers()
|
||||||
itr->second->SaveToDB();
|
itr->second->SaveToDB();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
ObjectAccessor::_update()
|
|
||||||
{
|
|
||||||
UpdateDataMapType update_players;
|
|
||||||
{
|
|
||||||
Guard guard(i_updateGuard);
|
|
||||||
while(!i_objects.empty())
|
|
||||||
{
|
|
||||||
Object* obj = *i_objects.begin();
|
|
||||||
i_objects.erase(i_objects.begin());
|
|
||||||
if (!obj)
|
|
||||||
continue;
|
|
||||||
_buildUpdateObject(obj, update_players);
|
|
||||||
obj->ClearUpdateMask(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
WorldPacket packet; // here we allocate a std::vector with a size of 0x10000
|
|
||||||
for(UpdateDataMapType::iterator iter = update_players.begin(); iter != update_players.end(); ++iter)
|
|
||||||
{
|
|
||||||
iter->second.BuildPacket(&packet);
|
|
||||||
iter->first->GetSession()->SendPacket(&packet);
|
|
||||||
packet.clear(); // clean the string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ObjectAccessor::UpdateObject(Object* obj, Player* exceptPlayer)
|
ObjectAccessor::UpdateObject(Object* obj, Player* exceptPlayer)
|
||||||
{
|
{
|
||||||
|
|
@ -513,72 +487,36 @@ ObjectAccessor::ConvertCorpseForPlayer(uint64 player_guid)
|
||||||
void
|
void
|
||||||
ObjectAccessor::Update(uint32 diff)
|
ObjectAccessor::Update(uint32 diff)
|
||||||
{
|
{
|
||||||
|
UpdateDataMapType update_players;
|
||||||
{
|
{
|
||||||
typedef std::multimap<uint32, Player *> CreatureLocationHolderType;
|
Guard guard(i_updateGuard);
|
||||||
CreatureLocationHolderType creature_locations;
|
while(!i_objects.empty())
|
||||||
//TODO: Player guard
|
|
||||||
HashMapHolder<Player>::MapType& playerMap = HashMapHolder<Player>::GetContainer();
|
|
||||||
for(HashMapHolder<Player>::MapType::iterator iter = playerMap.begin(); iter != playerMap.end(); ++iter)
|
|
||||||
{
|
{
|
||||||
if(iter->second->IsInWorld())
|
Object* obj = *i_objects.begin();
|
||||||
{
|
i_objects.erase(i_objects.begin());
|
||||||
iter->second->Update(diff);
|
if (!obj)
|
||||||
creature_locations.insert( CreatureLocationHolderType::value_type(iter->second->GetMapId(), iter->second) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Map *map;
|
|
||||||
|
|
||||||
MaNGOS::ObjectUpdater updater(diff);
|
|
||||||
// for creature
|
|
||||||
TypeContainerVisitor<MaNGOS::ObjectUpdater, GridTypeMapContainer > grid_object_update(updater);
|
|
||||||
// for pets
|
|
||||||
TypeContainerVisitor<MaNGOS::ObjectUpdater, WorldTypeMapContainer > world_object_update(updater);
|
|
||||||
|
|
||||||
for(CreatureLocationHolderType::iterator iter=creature_locations.begin(); iter != creature_locations.end(); ++iter)
|
|
||||||
{
|
|
||||||
MapManager::Instance().GetMap((*iter).first, (*iter).second)->resetMarkedCells();
|
|
||||||
}
|
|
||||||
|
|
||||||
for(CreatureLocationHolderType::iterator iter=creature_locations.begin(); iter != creature_locations.end(); ++iter)
|
|
||||||
{
|
|
||||||
Player *player = (*iter).second;
|
|
||||||
map = MapManager::Instance().GetMap((*iter).first, player);
|
|
||||||
|
|
||||||
CellPair standing_cell(MaNGOS::ComputeCellPair(player->GetPositionX(), player->GetPositionY()));
|
|
||||||
|
|
||||||
// Check for correctness of standing_cell, it also avoids problems with update_cell
|
|
||||||
if (standing_cell.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || standing_cell.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
|
|
||||||
continue;
|
continue;
|
||||||
|
_buildUpdateObject(obj, update_players);
|
||||||
// the overloaded operators handle range checking
|
obj->ClearUpdateMask(false);
|
||||||
// so ther's no need for range checking inside the loop
|
|
||||||
CellPair begin_cell(standing_cell), end_cell(standing_cell);
|
|
||||||
begin_cell << 1; begin_cell -= 1; // upper left
|
|
||||||
end_cell >> 1; end_cell += 1; // lower right
|
|
||||||
|
|
||||||
for(uint32 x = begin_cell.x_coord; x <= end_cell.x_coord; x++)
|
|
||||||
{
|
|
||||||
for(uint32 y = begin_cell.y_coord; y <= end_cell.y_coord; y++)
|
|
||||||
{
|
|
||||||
uint32 cell_id = (y * TOTAL_NUMBER_OF_CELLS_PER_MAP) + x;
|
|
||||||
if( !map->isCellMarked(cell_id) )
|
|
||||||
{
|
|
||||||
CellPair cell_pair(x,y);
|
|
||||||
map->markCell(cell_id);
|
|
||||||
Cell cell(cell_pair);
|
|
||||||
cell.data.Part.reserved = CENTER_DISTRICT;
|
|
||||||
cell.SetNoCreate();
|
|
||||||
CellLock<NullGuard> cell_lock(cell, cell_pair);
|
|
||||||
cell_lock->Visit(cell_lock, grid_object_update, *map);
|
|
||||||
cell_lock->Visit(cell_lock, world_object_update, *map);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_update();
|
WorldPacket packet; // here we allocate a std::vector with a size of 0x10000
|
||||||
|
for(UpdateDataMapType::iterator iter = update_players.begin(); iter != update_players.end(); ++iter)
|
||||||
|
{
|
||||||
|
iter->second.BuildPacket(&packet);
|
||||||
|
iter->first->GetSession()->SendPacket(&packet);
|
||||||
|
packet.clear(); // clean the string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ObjectAccessor::UpdatePlayers(uint32 diff)
|
||||||
|
{
|
||||||
|
HashMapHolder<Player>::MapType& playerMap = HashMapHolder<Player>::GetContainer();
|
||||||
|
for(HashMapHolder<Player>::MapType::iterator iter = playerMap.begin(); iter != playerMap.end(); ++iter)
|
||||||
|
if(iter->second->IsInWorld())
|
||||||
|
iter->second->Update(diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
||||||
|
|
@ -186,6 +186,7 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
|
||||||
void RemoveUpdateObject(Object *obj);
|
void RemoveUpdateObject(Object *obj);
|
||||||
|
|
||||||
void Update(uint32 diff);
|
void Update(uint32 diff);
|
||||||
|
void UpdatePlayers(uint32 diff);
|
||||||
|
|
||||||
Corpse* GetCorpseForPlayerGUID(uint64 guid);
|
Corpse* GetCorpseForPlayerGUID(uint64 guid);
|
||||||
void RemoveCorpse(Corpse *corpse);
|
void RemoveCorpse(Corpse *corpse);
|
||||||
|
|
@ -218,7 +219,6 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
|
||||||
|
|
||||||
static void _buildChangeObjectForPlayer(WorldObject *, UpdateDataMapType &);
|
static void _buildChangeObjectForPlayer(WorldObject *, UpdateDataMapType &);
|
||||||
static void _buildPacket(Player *, Object *, UpdateDataMapType &);
|
static void _buildPacket(Player *, Object *, UpdateDataMapType &);
|
||||||
void _update(void);
|
|
||||||
std::set<Object *> i_objects;
|
std::set<Object *> i_objects;
|
||||||
LockType i_playerGuard;
|
LockType i_playerGuard;
|
||||||
LockType i_updateGuard;
|
LockType i_updateGuard;
|
||||||
|
|
|
||||||
|
|
@ -3757,11 +3757,8 @@ void ObjectMgr::LoadScripts(ScriptMapMap& scripts, char const* tablename)
|
||||||
sLog.outErrorDb("Table `%s` has out of range text id (dataint = %i expected %u-%u) in SCRIPT_COMMAND_TALK for script id %u",tablename,tmp.dataint,MIN_DB_SCRIPT_STRING_ID,MAX_DB_SCRIPT_STRING_ID,tmp.id);
|
sLog.outErrorDb("Table `%s` has out of range text id (dataint = %i expected %u-%u) in SCRIPT_COMMAND_TALK for script id %u",tablename,tmp.dataint,MIN_DB_SCRIPT_STRING_ID,MAX_DB_SCRIPT_STRING_ID,tmp.id);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(!objmgr.GetMangosStringLocale(tmp.dataint))
|
|
||||||
{
|
// if(!objmgr.GetMangosStringLocale(tmp.dataint)) will checked after db_script_string loading
|
||||||
sLog.outErrorDb("Table `%s` has not existed text id (dataint = %i) in SCRIPT_COMMAND_TALK for script id %u",tablename,tmp.dataint,tmp.id);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -7287,10 +7284,11 @@ void ObjectMgr::CheckScripts(ScriptMapMap const& scripts,std::set<int32>& ids)
|
||||||
{
|
{
|
||||||
if(itrM->second.dataint)
|
if(itrM->second.dataint)
|
||||||
{
|
{
|
||||||
|
if(!GetMangosStringLocale (itrM->second.dataint))
|
||||||
|
sLog.outErrorDb( "Table `db_script_string` has not existed string id %u", *itrM);
|
||||||
|
|
||||||
if(ids.count(itrM->second.dataint))
|
if(ids.count(itrM->second.dataint))
|
||||||
ids.erase(itrM->second.dataint);
|
ids.erase(itrM->second.dataint);
|
||||||
else
|
|
||||||
sLog.outErrorDb( "Table `db_script_string` has not existed string id %u", *itrM);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1119,7 +1119,7 @@ void Pet::_LoadAuras(uint32 timediff)
|
||||||
for (int i = 0; i < TOTAL_AURAS; i++)
|
for (int i = 0; i < TOTAL_AURAS; i++)
|
||||||
m_modAuras[i].clear();
|
m_modAuras[i].clear();
|
||||||
|
|
||||||
QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_index,amount,maxduration,remaintime,remaincharges FROM pet_aura WHERE guid = '%u'",m_charmInfo->GetPetNumber());
|
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)
|
if(result)
|
||||||
{
|
{
|
||||||
|
|
@ -1129,10 +1129,11 @@ void Pet::_LoadAuras(uint32 timediff)
|
||||||
uint64 caster_guid = fields[0].GetUInt64();
|
uint64 caster_guid = fields[0].GetUInt64();
|
||||||
uint32 spellid = fields[1].GetUInt32();
|
uint32 spellid = fields[1].GetUInt32();
|
||||||
uint32 effindex = fields[2].GetUInt32();
|
uint32 effindex = fields[2].GetUInt32();
|
||||||
int32 damage = (int32)fields[3].GetUInt32();
|
uint32 stackcount= fields[3].GetUInt32();
|
||||||
int32 maxduration = (int32)fields[4].GetUInt32();
|
int32 damage = (int32)fields[4].GetUInt32();
|
||||||
int32 remaintime = (int32)fields[5].GetUInt32();
|
int32 maxduration = (int32)fields[5].GetUInt32();
|
||||||
int32 remaincharges = (int32)fields[6].GetUInt32();
|
int32 remaintime = (int32)fields[6].GetUInt32();
|
||||||
|
int32 remaincharges = (int32)fields[7].GetUInt32();
|
||||||
|
|
||||||
SpellEntry const* spellproto = sSpellStore.LookupEntry(spellid);
|
SpellEntry const* spellproto = sSpellStore.LookupEntry(spellid);
|
||||||
if(!spellproto)
|
if(!spellproto)
|
||||||
|
|
@ -1169,12 +1170,15 @@ void Pet::_LoadAuras(uint32 timediff)
|
||||||
if (caster_guid != GetGUID() && IsSingleTargetSpell(spellproto))
|
if (caster_guid != GetGUID() && IsSingleTargetSpell(spellproto))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Aura* aura = CreateAura(spellproto, effindex, NULL, this, NULL);
|
for(uint32 i=0; i<stackcount; i++)
|
||||||
|
{
|
||||||
|
Aura* aura = CreateAura(spellproto, effindex, NULL, this, NULL);
|
||||||
|
|
||||||
if(!damage)
|
if(!damage)
|
||||||
damage = aura->GetModifier()->m_amount;
|
damage = aura->GetModifier()->m_amount;
|
||||||
aura->SetLoadedState(caster_guid,damage,maxduration,remaintime,remaincharges);
|
aura->SetLoadedState(caster_guid,damage,maxduration,remaintime,remaincharges);
|
||||||
AddAura(aura);
|
AddAura(aura);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
while( result->NextRow() );
|
while( result->NextRow() );
|
||||||
|
|
||||||
|
|
@ -1187,30 +1191,52 @@ void Pet::_SaveAuras()
|
||||||
CharacterDatabase.PExecute("DELETE FROM pet_aura WHERE guid = '%u'", m_charmInfo->GetPetNumber());
|
CharacterDatabase.PExecute("DELETE FROM pet_aura WHERE guid = '%u'", m_charmInfo->GetPetNumber());
|
||||||
|
|
||||||
AuraMap const& auras = GetAuras();
|
AuraMap const& auras = GetAuras();
|
||||||
for(AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
|
if (auras.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
spellEffectPair lastEffectPair = auras.begin()->first;
|
||||||
|
uint32 stackCounter = 1;
|
||||||
|
|
||||||
|
for(AuraMap::const_iterator itr = auras.begin(); ; ++itr)
|
||||||
{
|
{
|
||||||
// skip all auras from spell that apply at cast SPELL_AURA_MOD_SHAPESHIFT or pet area auras.
|
if(itr == auras.end() || lastEffectPair != itr->first)
|
||||||
SpellEntry const *spellInfo = itr->second->GetSpellProto();
|
{
|
||||||
uint8 i;
|
AuraMap::const_iterator itr2 = itr;
|
||||||
for (i = 0; i < 3; i++)
|
// save previous spellEffectPair to db
|
||||||
if (spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_STEALTH ||
|
itr2--;
|
||||||
spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_OWNER ||
|
SpellEntry const *spellInfo = itr2->second->GetSpellProto();
|
||||||
spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PET )
|
/// do not save single target auras (unless they were cast by the player)
|
||||||
|
if (!(itr2->second->GetCasterGUID() != GetGUID() && IsSingleTargetSpell(spellInfo)))
|
||||||
|
{
|
||||||
|
if(!itr2->second->IsPassive())
|
||||||
|
{
|
||||||
|
// skip all auras from spell that apply at cast SPELL_AURA_MOD_SHAPESHIFT or pet area auras.
|
||||||
|
uint8 i;
|
||||||
|
for (i = 0; i < 3; i++)
|
||||||
|
if (spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_STEALTH ||
|
||||||
|
spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_OWNER ||
|
||||||
|
spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PET )
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (i == 3)
|
||||||
|
{
|
||||||
|
CharacterDatabase.PExecute("INSERT INTO pet_aura (guid,caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges) "
|
||||||
|
"VALUES ('%u', '" I64FMTD "', '%u', '%u', '%u', '%d', '%d', '%d', '%d')",
|
||||||
|
m_charmInfo->GetPetNumber(), itr2->second->GetCasterGUID(),(uint32)itr2->second->GetId(), (uint32)itr2->second->GetEffIndex(), stackCounter, itr2->second->GetModifier()->m_amount,int(itr2->second->GetAuraMaxDuration()),int(itr2->second->GetAuraDuration()),int(itr2->second->m_procCharges));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(itr == auras.end())
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (i != 3)
|
if (lastEffectPair == itr->first)
|
||||||
continue;
|
stackCounter++;
|
||||||
|
else
|
||||||
if(itr->second->IsPassive())
|
{
|
||||||
continue;
|
lastEffectPair = itr->first;
|
||||||
|
stackCounter = 1;
|
||||||
/// do not save single target auras (unless they were cast by the player)
|
}
|
||||||
if (itr->second->GetCasterGUID() != GetGUID() && IsSingleTargetSpell(spellInfo))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
CharacterDatabase.PExecute("INSERT INTO pet_aura (guid,caster_guid,spell,effect_index,amount,maxduration,remaintime,remaincharges) "
|
|
||||||
"VALUES ('%u', '" I64FMTD "', '%u', '%u', '%d', '%d', '%d', '%d')",
|
|
||||||
m_charmInfo->GetPetNumber(), itr->second->GetCasterGUID(),(uint32)(*itr).second->GetId(), (uint32)(*itr).second->GetEffIndex(),(*itr).second->GetModifier()->m_amount,int((*itr).second->GetAuraMaxDuration()),int((*itr).second->GetAuraDuration()),int((*itr).second->m_procCharges));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14160,7 +14160,7 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff)
|
||||||
for (int i = 0; i < TOTAL_AURAS; i++)
|
for (int i = 0; i < TOTAL_AURAS; i++)
|
||||||
m_modAuras[i].clear();
|
m_modAuras[i].clear();
|
||||||
|
|
||||||
//QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_index,amount,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'",GetGUIDLow());
|
//QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'",GetGUIDLow());
|
||||||
|
|
||||||
if(result)
|
if(result)
|
||||||
{
|
{
|
||||||
|
|
@ -14170,10 +14170,11 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff)
|
||||||
uint64 caster_guid = fields[0].GetUInt64();
|
uint64 caster_guid = fields[0].GetUInt64();
|
||||||
uint32 spellid = fields[1].GetUInt32();
|
uint32 spellid = fields[1].GetUInt32();
|
||||||
uint32 effindex = fields[2].GetUInt32();
|
uint32 effindex = fields[2].GetUInt32();
|
||||||
int32 damage = (int32)fields[3].GetUInt32();
|
uint32 stackcount = fields[3].GetUInt32();
|
||||||
int32 maxduration = (int32)fields[4].GetUInt32();
|
int32 damage = (int32)fields[4].GetUInt32();
|
||||||
int32 remaintime = (int32)fields[5].GetUInt32();
|
int32 maxduration = (int32)fields[5].GetUInt32();
|
||||||
int32 remaincharges = (int32)fields[6].GetUInt32();
|
int32 remaintime = (int32)fields[6].GetUInt32();
|
||||||
|
int32 remaincharges = (int32)fields[7].GetUInt32();
|
||||||
|
|
||||||
SpellEntry const* spellproto = sSpellStore.LookupEntry(spellid);
|
SpellEntry const* spellproto = sSpellStore.LookupEntry(spellid);
|
||||||
if(!spellproto)
|
if(!spellproto)
|
||||||
|
|
@ -14210,11 +14211,15 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff)
|
||||||
if (caster_guid != GetGUID() && IsSingleTargetSpell(spellproto))
|
if (caster_guid != GetGUID() && IsSingleTargetSpell(spellproto))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Aura* aura = CreateAura(spellproto, effindex, NULL, this, NULL);
|
for(uint32 i=0; i<stackcount; i++)
|
||||||
if(!damage)
|
{
|
||||||
damage = aura->GetModifier()->m_amount;
|
Aura* aura = CreateAura(spellproto, effindex, NULL, this, NULL);
|
||||||
aura->SetLoadedState(caster_guid,damage,maxduration,remaintime,remaincharges);
|
if(!damage)
|
||||||
AddAura(aura);
|
damage = aura->GetModifier()->m_amount;
|
||||||
|
aura->SetLoadedState(caster_guid,damage,maxduration,remaintime,remaincharges);
|
||||||
|
AddAura(aura);
|
||||||
|
sLog.outString("Added aura spellid %u, effect %u", spellproto->Id, effindex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
while( result->NextRow() );
|
while( result->NextRow() );
|
||||||
|
|
||||||
|
|
@ -15253,31 +15258,54 @@ void Player::_SaveAuras()
|
||||||
CharacterDatabase.PExecute("DELETE FROM character_aura WHERE guid = '%u'",GetGUIDLow());
|
CharacterDatabase.PExecute("DELETE FROM character_aura WHERE guid = '%u'",GetGUIDLow());
|
||||||
|
|
||||||
AuraMap const& auras = GetAuras();
|
AuraMap const& auras = GetAuras();
|
||||||
for(AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
|
|
||||||
|
if (auras.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
spellEffectPair lastEffectPair = auras.begin()->first;
|
||||||
|
uint32 stackCounter = 1;
|
||||||
|
|
||||||
|
for(AuraMap::const_iterator itr = auras.begin(); ; ++itr)
|
||||||
{
|
{
|
||||||
SpellEntry const *spellInfo = itr->second->GetSpellProto();
|
if(itr == auras.end() || lastEffectPair != itr->first)
|
||||||
|
|
||||||
//skip all auras from spells that are passive or need a shapeshift
|
|
||||||
if (itr->second->IsPassive() || itr->second->IsRemovedOnShapeLost())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
//do not save single target auras (unless they were cast by the player)
|
|
||||||
if (itr->second->GetCasterGUID() != GetGUID() && IsSingleTargetSpell(spellInfo))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
uint8 i;
|
|
||||||
// or apply at cast SPELL_AURA_MOD_SHAPESHIFT or SPELL_AURA_MOD_STEALTH auras
|
|
||||||
for (i = 0; i < 3; i++)
|
|
||||||
if (spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_SHAPESHIFT ||
|
|
||||||
spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_STEALTH)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (i == 3)
|
|
||||||
{
|
{
|
||||||
CharacterDatabase.PExecute("DELETE FROM character_aura WHERE guid = '%u' and spell = '%u' and effect_index= '%u'",GetGUIDLow(),(uint32)(*itr).second->GetId(), (uint32)(*itr).second->GetEffIndex());
|
AuraMap::const_iterator itr2 = itr;
|
||||||
CharacterDatabase.PExecute("INSERT INTO character_aura (guid,caster_guid,spell,effect_index,amount,maxduration,remaintime,remaincharges) "
|
// save previous spellEffectPair to db
|
||||||
"VALUES ('%u', '" I64FMTD "' ,'%u', '%u', '%d', '%d', '%d', '%d')",
|
itr2--;
|
||||||
GetGUIDLow(), itr->second->GetCasterGUID(), (uint32)(*itr).second->GetId(), (uint32)(*itr).second->GetEffIndex(), (*itr).second->GetModifier()->m_amount,int((*itr).second->GetAuraMaxDuration()),int((*itr).second->GetAuraDuration()),int((*itr).second->m_procCharges));
|
SpellEntry const *spellInfo = itr2->second->GetSpellProto();
|
||||||
|
|
||||||
|
//skip all auras from spells that are passive or need a shapeshift
|
||||||
|
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)))
|
||||||
|
{
|
||||||
|
uint8 i;
|
||||||
|
// or apply at cast SPELL_AURA_MOD_SHAPESHIFT or SPELL_AURA_MOD_STEALTH auras
|
||||||
|
for (i = 0; i < 3; i++)
|
||||||
|
if (spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_SHAPESHIFT ||
|
||||||
|
spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_STEALTH)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (i == 3)
|
||||||
|
{
|
||||||
|
CharacterDatabase.PExecute("INSERT INTO character_aura (guid,caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges) "
|
||||||
|
"VALUES ('%u', '" I64FMTD "' ,'%u', '%u', '%u', '%d', '%d', '%d', '%d')",
|
||||||
|
GetGUIDLow(), itr2->second->GetCasterGUID(), (uint32)itr2->second->GetId(), (uint32)itr2->second->GetEffIndex(), stackCounter, itr2->second->GetModifier()->m_amount,int(itr2->second->GetAuraMaxDuration()),int(itr2->second->GetAuraDuration()),int(itr2->second->m_procCharges));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(itr == auras.end())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastEffectPair == itr->first)
|
||||||
|
stackCounter++;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lastEffectPair = itr->first;
|
||||||
|
stackCounter = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4590,8 +4590,10 @@ void Unit::CastMeleeProcDamageAndSpell(Unit* pVictim, uint32 damage, SpellSchool
|
||||||
ProcDamageAndSpell(pVictim, procAttacker, procVictim, damage, damageSchoolMask, spellCasted, isTriggeredSpell, attType);
|
ProcDamageAndSpell(pVictim, procAttacker, procVictim, damage, damageSchoolMask, spellCasted, isTriggeredSpell, attType);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Unit::HandleHasteAuraProc(Unit *pVictim, SpellEntry const *hasteSpell, uint32 /*effIndex*/, uint32 damage, Aura* triggeredByAura, SpellEntry const * /*procSpell*/, uint32 /*procFlag*/, uint32 cooldown)
|
bool Unit::HandleHasteAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const * /*procSpell*/, uint32 /*procFlag*/, uint32 cooldown)
|
||||||
{
|
{
|
||||||
|
SpellEntry const *hasteSpell = triggeredByAura->GetSpellProto();
|
||||||
|
|
||||||
Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER
|
Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER
|
||||||
? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL;
|
? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL;
|
||||||
|
|
||||||
|
|
@ -4651,8 +4653,11 @@ bool Unit::HandleHasteAuraProc(Unit *pVictim, SpellEntry const *hasteSpell, uint
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Unit::HandleDummyAuraProc(Unit *pVictim, SpellEntry const *dummySpell, uint32 effIndex, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 procFlag, uint32 cooldown)
|
bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 procFlag, uint32 cooldown)
|
||||||
{
|
{
|
||||||
|
SpellEntry const *dummySpell = triggeredByAura->GetSpellProto ();
|
||||||
|
uint32 effIndex = triggeredByAura->GetEffIndex ();
|
||||||
|
|
||||||
Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER
|
Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER
|
||||||
? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL;
|
? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL;
|
||||||
|
|
||||||
|
|
@ -6466,8 +6471,10 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Unit::HandleOverrideClassScriptAuraProc(Unit *pVictim, int32 scriptId, uint32 /*damage*/, Aura *triggeredByAura, SpellEntry const *procSpell, uint32 cooldown)
|
bool Unit::HandleOverrideClassScriptAuraProc(Unit *pVictim, Aura *triggeredByAura, SpellEntry const *procSpell, uint32 cooldown)
|
||||||
{
|
{
|
||||||
|
int32 scriptId = triggeredByAura->GetModifier()->m_miscvalue;
|
||||||
|
|
||||||
if(!pVictim || !pVictim->isAlive())
|
if(!pVictim || !pVictim->isAlive())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
@ -10020,17 +10027,15 @@ bool Unit::isFrozen() const
|
||||||
|
|
||||||
struct ProcTriggeredData
|
struct ProcTriggeredData
|
||||||
{
|
{
|
||||||
ProcTriggeredData(SpellEntry const * _spellInfo, uint32 _spellParam, Aura* _triggeredByAura, uint32 _cooldown)
|
ProcTriggeredData(Aura* _triggeredByAura, uint32 _cooldown)
|
||||||
: spellInfo(_spellInfo), spellParam(_spellParam), triggeredByAura(_triggeredByAura),
|
: triggeredByAura(_triggeredByAura),
|
||||||
triggeredByAura_SpellPair(Unit::spellEffectPair(triggeredByAura->GetId(),triggeredByAura->GetEffIndex())),
|
triggeredByAura_SpellPair(Unit::spellEffectPair(triggeredByAura->GetId(),triggeredByAura->GetEffIndex())),
|
||||||
cooldown(_cooldown)
|
cooldown(_cooldown)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
SpellEntry const * spellInfo;
|
Aura* triggeredByAura; // triggred aura, can be invalidate at triggered aura proccessing
|
||||||
uint32 spellParam;
|
Unit::spellEffectPair triggeredByAura_SpellPair; // spell pair, used for re-find aura (by pointer comparison in range)
|
||||||
Aura* triggeredByAura;
|
uint32 cooldown; // possible hidden cooldown
|
||||||
Unit::spellEffectPair triggeredByAura_SpellPair;
|
|
||||||
uint32 cooldown;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::list< ProcTriggeredData > ProcTriggeredList;
|
typedef std::list< ProcTriggeredData > ProcTriggeredList;
|
||||||
|
|
@ -10047,87 +10052,13 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
|
||||||
{
|
{
|
||||||
next = i; ++next;
|
next = i; ++next;
|
||||||
|
|
||||||
SpellEntry const *spellProto = (*i)->GetSpellProto();
|
Aura* i_aura = *i;
|
||||||
if(!spellProto)
|
|
||||||
|
uint32 cooldown; // returned at next line
|
||||||
|
if(!IsTriggeredAtSpellProcEvent(i_aura->GetSpellProto(), procSpell, procFlag,attType,isVictim,cooldown))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
SpellProcEventEntry const *spellProcEvent = spellmgr.GetSpellProcEvent(spellProto->Id);
|
procTriggered.push_back( ProcTriggeredData(i_aura, cooldown) );
|
||||||
if(!spellProcEvent)
|
|
||||||
{
|
|
||||||
// used to prevent spam in log about same non-handled spells
|
|
||||||
static std::set<uint32> nonHandledSpellProcSet;
|
|
||||||
|
|
||||||
if(spellProto->procFlags != 0 && nonHandledSpellProcSet.find(spellProto->Id)==nonHandledSpellProcSet.end())
|
|
||||||
{
|
|
||||||
sLog.outError("ProcDamageAndSpell: spell %u (%s aura source) not have record in `spell_proc_event`)",spellProto->Id,(isVictim?"a victim's":"an attacker's"));
|
|
||||||
nonHandledSpellProcSet.insert(spellProto->Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// spell.dbc use totally different flags, that only can create problems if used.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check spellProcEvent data requirements
|
|
||||||
if(!SpellMgr::IsSpellProcEventCanTriggeredBy(spellProcEvent, procSpell,procFlag))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Check if current equipment allows aura to proc
|
|
||||||
if(!isVictim && GetTypeId() == TYPEID_PLAYER )
|
|
||||||
{
|
|
||||||
if(spellProto->EquippedItemClass == ITEM_CLASS_WEAPON)
|
|
||||||
{
|
|
||||||
Item *item = ((Player*)this)->GetWeaponForAttack(attType,true);
|
|
||||||
|
|
||||||
if(!item || !((1<<item->GetProto()->SubClass) & spellProto->EquippedItemSubClassMask))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if(spellProto->EquippedItemClass == ITEM_CLASS_ARMOR)
|
|
||||||
{
|
|
||||||
// Check if player is wearing shield
|
|
||||||
Item *item = ((Player*)this)->GetShield(true);
|
|
||||||
if(!item || !((1<<item->GetProto()->SubClass) & spellProto->EquippedItemSubClassMask))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
float chance = (float)spellProto->procChance;
|
|
||||||
|
|
||||||
if(Player* modOwner = GetSpellModOwner())
|
|
||||||
modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_CHANCE_OF_SUCCESS,chance);
|
|
||||||
|
|
||||||
if(!isVictim && spellProcEvent->ppmRate != 0)
|
|
||||||
{
|
|
||||||
uint32 WeaponSpeed = GetAttackTime(attType);
|
|
||||||
chance = GetPPMProcChance(WeaponSpeed, spellProcEvent->ppmRate);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(roll_chance_f(chance))
|
|
||||||
{
|
|
||||||
uint32 cooldown = spellProcEvent->cooldown;
|
|
||||||
|
|
||||||
uint32 i_spell_eff = (*i)->GetEffIndex();
|
|
||||||
|
|
||||||
int32 i_spell_param;
|
|
||||||
switch(*aur)
|
|
||||||
{
|
|
||||||
case SPELL_AURA_PROC_TRIGGER_SPELL:
|
|
||||||
i_spell_param = procFlag;
|
|
||||||
break;
|
|
||||||
case SPELL_AURA_DUMMY:
|
|
||||||
case SPELL_AURA_PRAYER_OF_MENDING:
|
|
||||||
case SPELL_AURA_MOD_HASTE:
|
|
||||||
i_spell_param = i_spell_eff;
|
|
||||||
break;
|
|
||||||
case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS:
|
|
||||||
i_spell_param = (*i)->GetModifier()->m_miscvalue;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
i_spell_param = (*i)->GetModifier()->m_amount;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
procTriggered.push_back( ProcTriggeredData(spellProto,i_spell_param,*i, cooldown) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle effects proceed this time
|
// Handle effects proceed this time
|
||||||
|
|
@ -10160,106 +10091,71 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// save charges existence before processing to prevent crash at access to deleted triggered aura after
|
/// this is aura triggering code call
|
||||||
bool triggeredByAuraWithCharges = i->triggeredByAura->m_procCharges > 0;
|
Aura* triggeredByAura = i->triggeredByAura;
|
||||||
|
|
||||||
|
/// save charges existence before processing to prevent crash at access to deleted triggered aura after
|
||||||
|
/// used in speedup code check before check aura existance.
|
||||||
|
bool triggeredByAuraWithCharges = triggeredByAura->m_procCharges > 0;
|
||||||
|
|
||||||
|
/// success in event proccesing
|
||||||
|
/// used in speedup code check before check aura existance.
|
||||||
bool casted = false;
|
bool casted = false;
|
||||||
|
|
||||||
|
/// process triggered code
|
||||||
switch(*aur)
|
switch(*aur)
|
||||||
{
|
{
|
||||||
case SPELL_AURA_PROC_TRIGGER_SPELL:
|
case SPELL_AURA_PROC_TRIGGER_SPELL:
|
||||||
{
|
{
|
||||||
sLog.outDebug("ProcDamageAndSpell: casting spell %u (triggered by %s aura of spell %u)", i->spellInfo->Id,(isVictim?"a victim's":"an attacker's"),i->triggeredByAura->GetId());
|
sLog.outDebug("ProcDamageAndSpell: casting spell (triggered by %s proc aura of spell %u)",
|
||||||
casted = HandleProcTriggerSpell(pTarget, damage, i->triggeredByAura, procSpell,i->spellParam,attType,i->cooldown);
|
(isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId());
|
||||||
|
casted = HandleProcTriggerSpell(pTarget, damage, triggeredByAura, procSpell, procFlag, attType, i->cooldown);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SPELL_AURA_PROC_TRIGGER_DAMAGE:
|
case SPELL_AURA_PROC_TRIGGER_DAMAGE:
|
||||||
{
|
{
|
||||||
sLog.outDebug("ProcDamageAndSpell: doing %u damage from spell id %u (triggered by %s aura of spell %u)", i->spellParam, i->spellInfo->Id,(isVictim?"a victim's":"an attacker's"),i->triggeredByAura->GetId());
|
uint32 triggered_damage = triggeredByAura->GetModifier()->m_amount;
|
||||||
uint32 damage = i->spellParam;
|
sLog.outDebug("ProcDamageAndSpell: doing %u damage (triggered by %s aura of spell %u)",
|
||||||
SpellNonMeleeDamageLog(pTarget, i->spellInfo->Id, damage, true, true);
|
triggered_damage, (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId());
|
||||||
|
SpellNonMeleeDamageLog(pTarget, triggeredByAura->GetId(), triggered_damage, true, true);
|
||||||
casted = true;
|
casted = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SPELL_AURA_DUMMY:
|
case SPELL_AURA_DUMMY:
|
||||||
{
|
{
|
||||||
sLog.outDebug("ProcDamageAndSpell: casting spell id %u (triggered by %s dummy aura of spell %u)", i->spellInfo->Id,(isVictim?"a victim's":"an attacker's"),i->triggeredByAura->GetId());
|
uint32 effect = triggeredByAura->GetEffIndex();
|
||||||
casted = HandleDummyAuraProc(pTarget, i->spellInfo, i->spellParam, damage, i->triggeredByAura, procSpell, procFlag,i->cooldown);
|
sLog.outDebug("ProcDamageAndSpell: casting spell (triggered by %s dummy aura of spell %u)",
|
||||||
|
(isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId());
|
||||||
|
casted = HandleDummyAuraProc(pTarget, damage, triggeredByAura, procSpell, procFlag,i->cooldown);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SPELL_AURA_PRAYER_OF_MENDING:
|
case SPELL_AURA_PRAYER_OF_MENDING:
|
||||||
{
|
{
|
||||||
sLog.outDebug("ProcDamageAndSpell(mending): casting spell id %u (triggered by %s dummy aura of spell %u)", i->spellInfo->Id,(isVictim?"a victim's":"an attacker's"),i->triggeredByAura->GetId());
|
sLog.outDebug("ProcDamageAndSpell: casting mending (triggered by %s dummy aura of spell %u)",
|
||||||
|
(isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId());
|
||||||
|
|
||||||
// aura can be deleted at casts
|
casted = HandleMeandingAuraProc(triggeredByAura);
|
||||||
int32 heal = i->triggeredByAura->GetModifier()->m_amount;
|
|
||||||
uint64 caster_guid = i->triggeredByAura->GetCasterGUID();
|
|
||||||
|
|
||||||
// jumps
|
|
||||||
int32 jumps = i->triggeredByAura->m_procCharges-1;
|
|
||||||
|
|
||||||
// current aura expire
|
|
||||||
i->triggeredByAura->m_procCharges = 1; // will removed at next charges decrease
|
|
||||||
|
|
||||||
// next target selection
|
|
||||||
if(jumps > 0 && GetTypeId()==TYPEID_PLAYER && IS_PLAYER_GUID(caster_guid))
|
|
||||||
{
|
|
||||||
Aura* aura = i->triggeredByAura;
|
|
||||||
|
|
||||||
SpellEntry const* spellProto = aura->GetSpellProto();
|
|
||||||
uint32 effIdx = aura->GetEffIndex();
|
|
||||||
|
|
||||||
float radius;
|
|
||||||
if (spellProto->EffectRadiusIndex[effIdx])
|
|
||||||
radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(spellProto->EffectRadiusIndex[effIdx]));
|
|
||||||
else
|
|
||||||
radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(spellProto->rangeIndex));
|
|
||||||
|
|
||||||
if(Player* caster = ((Player*)aura->GetCaster()))
|
|
||||||
{
|
|
||||||
caster->ApplySpellMod(spellProto->Id, SPELLMOD_RADIUS, radius,NULL);
|
|
||||||
|
|
||||||
if(Player* target = ((Player*)this)->GetNextRandomRaidMember(radius))
|
|
||||||
{
|
|
||||||
// aura will applied from caster, but spell casted from current aura holder
|
|
||||||
SpellModifier *mod = new SpellModifier;
|
|
||||||
mod->op = SPELLMOD_CHARGES;
|
|
||||||
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;
|
|
||||||
|
|
||||||
caster->AddSpellMod(mod, true);
|
|
||||||
CastCustomSpell(target,spellProto->Id,&heal,NULL,NULL,true,NULL,aura,caster->GetGUID());
|
|
||||||
caster->AddSpellMod(mod, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// heal
|
|
||||||
CastCustomSpell(this,33110,&heal,NULL,NULL,true,NULL,NULL,caster_guid);
|
|
||||||
casted = true;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SPELL_AURA_MOD_HASTE:
|
case SPELL_AURA_MOD_HASTE:
|
||||||
{
|
{
|
||||||
sLog.outDebug("ProcDamageAndSpell: casting spell id %u (triggered by %s haste aura of spell %u)", i->spellInfo->Id,(isVictim?"a victim's":"an attacker's"),i->triggeredByAura->GetId());
|
sLog.outDebug("ProcDamageAndSpell: casting spell (triggered by %s haste aura of spell %u)",
|
||||||
casted = HandleHasteAuraProc(pTarget, i->spellInfo, i->spellParam, damage, i->triggeredByAura, procSpell, procFlag,i->cooldown);
|
(isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId());
|
||||||
|
casted = HandleHasteAuraProc(pTarget, damage, triggeredByAura, procSpell, procFlag,i->cooldown);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN:
|
case SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN:
|
||||||
{
|
{
|
||||||
// nothing do, just charges counter
|
// nothing do, just charges counter
|
||||||
// but count only in case appropriate school damage
|
// but count only in case appropriate school damage
|
||||||
casted = i->triggeredByAura->GetModifier()->m_miscvalue & damageSchoolMask;
|
casted = triggeredByAura->GetModifier()->m_miscvalue & damageSchoolMask;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS:
|
case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS:
|
||||||
{
|
{
|
||||||
sLog.outDebug("ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", i->spellInfo->Id,(isVictim?"a victim's":"an attacker's"),i->triggeredByAura->GetId());
|
sLog.outDebug("ProcDamageAndSpell: casting spell id %u (triggered by %s class script aura of spell %u)",
|
||||||
casted = HandleOverrideClassScriptAuraProc(pTarget, i->spellParam, damage, i->triggeredByAura, procSpell,i->cooldown);
|
(isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId());
|
||||||
|
casted = HandleOverrideClassScriptAuraProc(pTarget, triggeredByAura, procSpell,i->cooldown);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
@ -10270,27 +10166,27 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update charge (aura can be removed by triggers)
|
/// Update charge (aura can be removed by triggers)
|
||||||
if(casted && triggeredByAuraWithCharges)
|
if(casted && triggeredByAuraWithCharges)
|
||||||
{
|
{
|
||||||
// need found aura (can be dropped by triggers)
|
/// need re-found aura (can be dropped by triggers)
|
||||||
AuraMap::const_iterator lower = GetAuras().lower_bound(i->triggeredByAura_SpellPair);
|
AuraMap::const_iterator lower = GetAuras().lower_bound(i->triggeredByAura_SpellPair);
|
||||||
AuraMap::const_iterator upper = GetAuras().upper_bound(i->triggeredByAura_SpellPair);
|
AuraMap::const_iterator upper = GetAuras().upper_bound(i->triggeredByAura_SpellPair);
|
||||||
for(AuraMap::const_iterator itr = lower; itr!= upper; ++itr)
|
for(AuraMap::const_iterator itr = lower; itr!= upper; ++itr)
|
||||||
{
|
{
|
||||||
if(itr->second == i->triggeredByAura)
|
if(itr->second == triggeredByAura) // pointer still valid
|
||||||
{
|
{
|
||||||
if(i->triggeredByAura->m_procCharges > 0)
|
if(triggeredByAura->m_procCharges > 0)
|
||||||
i->triggeredByAura->m_procCharges -= 1;
|
triggeredByAura->m_procCharges -= 1;
|
||||||
|
|
||||||
i->triggeredByAura->UpdateAuraCharges();
|
triggeredByAura->UpdateAuraCharges();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Safely remove auras with zero charges
|
/// Safely remove auras with zero charges
|
||||||
for(AuraList::const_iterator i = auras.begin(), next; i != auras.end(); i = next)
|
for(AuraList::const_iterator i = auras.begin(), next; i != auras.end(); i = next)
|
||||||
{
|
{
|
||||||
next = i; ++next;
|
next = i; ++next;
|
||||||
|
|
@ -10911,3 +10807,112 @@ Pet* Unit::CreateTamedPetFrom(Creature* creatureTarget,uint32 spell_id)
|
||||||
|
|
||||||
return pet;
|
return pet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Unit::IsTriggeredAtSpellProcEvent(SpellEntry const* spellProto, SpellEntry const* procSpell, uint32 procFlag, WeaponAttackType attType, bool isVictim, uint32& cooldown )
|
||||||
|
{
|
||||||
|
SpellProcEventEntry const * spellProcEvent = spellmgr.GetSpellProcEvent(spellProto->Id);
|
||||||
|
|
||||||
|
if(!spellProcEvent)
|
||||||
|
{
|
||||||
|
// used to prevent spam in log about same non-handled spells
|
||||||
|
static std::set<uint32> nonHandledSpellProcSet;
|
||||||
|
|
||||||
|
if(spellProto->procFlags != 0 && nonHandledSpellProcSet.find(spellProto->Id)==nonHandledSpellProcSet.end())
|
||||||
|
{
|
||||||
|
sLog.outError("ProcDamageAndSpell: spell %u (%s aura source) not have record in `spell_proc_event`)",spellProto->Id,(isVictim?"a victim's":"an attacker's"));
|
||||||
|
nonHandledSpellProcSet.insert(spellProto->Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// spell.dbc use totally different flags, that only can create problems if used.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check spellProcEvent data requirements
|
||||||
|
if(!SpellMgr::IsSpellProcEventCanTriggeredBy(spellProcEvent, procSpell,procFlag))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check if current equipment allows aura to proc
|
||||||
|
if(!isVictim && GetTypeId() == TYPEID_PLAYER )
|
||||||
|
{
|
||||||
|
if(spellProto->EquippedItemClass == ITEM_CLASS_WEAPON)
|
||||||
|
{
|
||||||
|
Item *item = ((Player*)this)->GetWeaponForAttack(attType,true);
|
||||||
|
|
||||||
|
if(!item || !((1<<item->GetProto()->SubClass) & spellProto->EquippedItemSubClassMask))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if(spellProto->EquippedItemClass == ITEM_CLASS_ARMOR)
|
||||||
|
{
|
||||||
|
// Check if player is wearing shield
|
||||||
|
Item *item = ((Player*)this)->GetShield(true);
|
||||||
|
if(!item || !((1<<item->GetProto()->SubClass) & spellProto->EquippedItemSubClassMask))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float chance = (float)spellProto->procChance;
|
||||||
|
|
||||||
|
if(Player* modOwner = GetSpellModOwner())
|
||||||
|
modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_CHANCE_OF_SUCCESS,chance);
|
||||||
|
|
||||||
|
if(!isVictim && spellProcEvent && spellProcEvent->ppmRate != 0)
|
||||||
|
{
|
||||||
|
uint32 WeaponSpeed = GetAttackTime(attType);
|
||||||
|
chance = GetPPMProcChance(WeaponSpeed, spellProcEvent->ppmRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
cooldown = spellProcEvent ? spellProcEvent->cooldown : 0;
|
||||||
|
return roll_chance_f(chance);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Unit::HandleMeandingAuraProc( Aura* triggeredByAura )
|
||||||
|
{
|
||||||
|
// aura can be deleted at casts
|
||||||
|
SpellEntry const* spellProto = triggeredByAura->GetSpellProto();
|
||||||
|
uint32 effIdx = triggeredByAura->GetEffIndex();
|
||||||
|
int32 heal = triggeredByAura->GetModifier()->m_amount;
|
||||||
|
uint64 caster_guid = triggeredByAura->GetCasterGUID();
|
||||||
|
|
||||||
|
// jumps
|
||||||
|
int32 jumps = triggeredByAura->m_procCharges-1;
|
||||||
|
|
||||||
|
// current aura expire
|
||||||
|
triggeredByAura->m_procCharges = 1; // will removed at next charges decrease
|
||||||
|
|
||||||
|
// next target selection
|
||||||
|
if(jumps > 0 && GetTypeId()==TYPEID_PLAYER && IS_PLAYER_GUID(caster_guid))
|
||||||
|
{
|
||||||
|
float radius;
|
||||||
|
if (spellProto->EffectRadiusIndex[effIdx])
|
||||||
|
radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(spellProto->EffectRadiusIndex[effIdx]));
|
||||||
|
else
|
||||||
|
radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(spellProto->rangeIndex));
|
||||||
|
|
||||||
|
if(Player* caster = ((Player*)triggeredByAura->GetCaster()))
|
||||||
|
{
|
||||||
|
caster->ApplySpellMod(spellProto->Id, SPELLMOD_RADIUS, radius,NULL);
|
||||||
|
|
||||||
|
if(Player* target = ((Player*)this)->GetNextRandomRaidMember(radius))
|
||||||
|
{
|
||||||
|
// aura will applied from caster, but spell casted from current aura holder
|
||||||
|
SpellModifier *mod = new SpellModifier;
|
||||||
|
mod->op = SPELLMOD_CHARGES;
|
||||||
|
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;
|
||||||
|
|
||||||
|
caster->AddSpellMod(mod, true);
|
||||||
|
CastCustomSpell(target,spellProto->Id,&heal,NULL,NULL,true,NULL,triggeredByAura,caster->GetGUID());
|
||||||
|
caster->AddSpellMod(mod, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// heal
|
||||||
|
CastCustomSpell(this,33110,&heal,NULL,NULL,true,NULL,NULL,caster_guid);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
@ -1371,10 +1371,12 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
|
||||||
void SendAttackStart(Unit* pVictim); // only from Unit::AttackStart(Unit*)
|
void SendAttackStart(Unit* pVictim); // only from Unit::AttackStart(Unit*)
|
||||||
|
|
||||||
void ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag, AuraTypeSet const& procAuraTypes, WeaponAttackType attType, SpellEntry const * procSpell, uint32 damage, SpellSchoolMask damageSchoolMask );
|
void ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag, AuraTypeSet const& procAuraTypes, WeaponAttackType attType, SpellEntry const * procSpell, uint32 damage, SpellSchoolMask damageSchoolMask );
|
||||||
bool HandleDummyAuraProc(Unit *pVictim, SpellEntry const *spellProto, uint32 effIndex, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 procFlag,uint32 cooldown);
|
bool IsTriggeredAtSpellProcEvent( SpellEntry const* spellProto, SpellEntry const* procSpell, uint32 procFlag, WeaponAttackType attType, bool isVictim, uint32& cooldown );
|
||||||
bool HandleProcTriggerSpell(Unit *pVictim,uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlags,WeaponAttackType attType,uint32 cooldown);
|
bool HandleDummyAuraProc( Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const* procSpell, uint32 procFlag, uint32 cooldown);
|
||||||
bool HandleHasteAuraProc(Unit *pVictim, SpellEntry const *spellProto, uint32 effIndex, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 procFlag,uint32 cooldown);
|
bool HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const* procSpell, uint32 procFlag, WeaponAttackType attType, uint32 cooldown);
|
||||||
bool HandleOverrideClassScriptAuraProc(Unit *pVictim, int32 scriptId, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell,uint32 cooldown);
|
bool HandleHasteAuraProc( Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const* procSpell, uint32 procFlag, uint32 cooldown);
|
||||||
|
bool HandleOverrideClassScriptAuraProc(Unit *pVictim, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 cooldown);
|
||||||
|
bool HandleMeandingAuraProc(Aura* triggeredByAura);
|
||||||
|
|
||||||
uint32 m_state; // Even derived shouldn't modify
|
uint32 m_state; // Even derived shouldn't modify
|
||||||
uint32 m_CombatTimer;
|
uint32 m_CombatTimer;
|
||||||
|
|
|
||||||
|
|
@ -83,9 +83,9 @@ bool Vehicle::Create(uint32 guidlow, Map *map, uint32 Entry, uint32 vehicleId, u
|
||||||
|
|
||||||
SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
|
SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
|
||||||
SetUInt32Value(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_UNKNOWN1);
|
SetUInt32Value(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_UNKNOWN1);
|
||||||
SetUInt32Value(UNIT_FIELD_BYTES_1, 0x02000001);
|
//SetUInt32Value(UNIT_FIELD_BYTES_1, 0x02000001);
|
||||||
SetUInt32Value(UNIT_FIELD_BYTES_2, 0x00000001);
|
//SetUInt32Value(UNIT_FIELD_BYTES_2, 0x00000001);
|
||||||
SetFloatValue(UNIT_FIELD_HOVERHEIGHT, 3.0f);
|
SetFloatValue(UNIT_FIELD_HOVERHEIGHT, 1.0f);
|
||||||
|
|
||||||
CreatureInfo const *ci = GetCreatureInfo();
|
CreatureInfo const *ci = GetCreatureInfo();
|
||||||
setFaction(team == ALLIANCE ? ci->faction_A : ci->faction_H);
|
setFaction(team == ALLIANCE ? ci->faction_A : ci->faction_H);
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,8 @@
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Master.h"
|
#include "Master.h"
|
||||||
#include "SystemConfig.h"
|
#include "SystemConfig.h"
|
||||||
|
#include "revision.h"
|
||||||
|
#include "revision_nr.h"
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include "ServiceWin32.h"
|
#include "ServiceWin32.h"
|
||||||
|
|
@ -51,6 +53,7 @@ uint32 realmID; ///< Id of the realm
|
||||||
void usage(const char *prog)
|
void usage(const char *prog)
|
||||||
{
|
{
|
||||||
sLog.outString("Usage: \n %s [<options>]\n"
|
sLog.outString("Usage: \n %s [<options>]\n"
|
||||||
|
" --version print version and exist\n\r"
|
||||||
" -c config_file use config_file as configuration file\n\r"
|
" -c config_file use config_file as configuration file\n\r"
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
" Running as service functions:\n\r"
|
" Running as service functions:\n\r"
|
||||||
|
|
@ -86,6 +89,12 @@ extern int main(int argc, char **argv)
|
||||||
cfg_file = argv[c];
|
cfg_file = argv[c];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( strcmp(argv[c],"--version") == 0)
|
||||||
|
{
|
||||||
|
printf("%s\n", _FULLVERSION(REVISION_DATE,REVISION_TIME,REVISION_NR,REVISION_ID));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
////////////
|
////////////
|
||||||
//Services//
|
//Services//
|
||||||
|
|
@ -131,6 +140,22 @@ extern int main(int argc, char **argv)
|
||||||
sLog.outError("Could not find configuration file %s.", cfg_file);
|
sLog.outError("Could not find configuration file %s.", cfg_file);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sLog.outString( "%s [world-daemon]", _FULLVERSION(REVISION_DATE,REVISION_TIME,REVISION_NR,REVISION_ID) );
|
||||||
|
sLog.outString( "<Ctrl-C> to stop.\n\n" );
|
||||||
|
|
||||||
|
sLog.outTitle( "MM MM MM MM MMMMM MMMM MMMMM");
|
||||||
|
sLog.outTitle( "MM MM MM MM MMM MMM MM MM MMM MMM");
|
||||||
|
sLog.outTitle( "MMM MMM MMM MM MMM MMM MM MM MMM");
|
||||||
|
sLog.outTitle( "MM M MM MMMM MM MMM MM MM MMM");
|
||||||
|
sLog.outTitle( "MM M MM MMMMM MM MMMM MMM MM MM MMM");
|
||||||
|
sLog.outTitle( "MM M MM M MMM MM MMM MMMMMMM MM MM MMM");
|
||||||
|
sLog.outTitle( "MM MM MMM MM MM MM MMM MM MM MMM");
|
||||||
|
sLog.outTitle( "MM MM MMMMMMM MM MM MMM MMM MM MM MMM MMM");
|
||||||
|
sLog.outTitle( "MM MM MM MMM MM MM MMMMMM MMMM MMMMM");
|
||||||
|
sLog.outTitle( " MM MMM http://getmangos.com");
|
||||||
|
sLog.outTitle( " MMMMMM\n\n");
|
||||||
|
|
||||||
sLog.outString("Using configuration file %s.", cfg_file);
|
sLog.outString("Using configuration file %s.", cfg_file);
|
||||||
|
|
||||||
///- and run the 'Master'
|
///- and run the 'Master'
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,6 @@
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
#include "Policies/SingletonImp.h"
|
#include "Policies/SingletonImp.h"
|
||||||
#include "SystemConfig.h"
|
#include "SystemConfig.h"
|
||||||
#include "revision.h"
|
|
||||||
#include "revision_nr.h"
|
|
||||||
#include "Config/ConfigEnv.h"
|
#include "Config/ConfigEnv.h"
|
||||||
#include "Database/DatabaseEnv.h"
|
#include "Database/DatabaseEnv.h"
|
||||||
#include "CliRunnable.h"
|
#include "CliRunnable.h"
|
||||||
|
|
@ -197,21 +195,6 @@ Master::~Master()
|
||||||
/// Main function
|
/// Main function
|
||||||
int Master::Run()
|
int Master::Run()
|
||||||
{
|
{
|
||||||
sLog.outString( "%s [world-daemon]", _FULLVERSION(REVISION_DATE,REVISION_TIME,REVISION_NR,REVISION_ID) );
|
|
||||||
sLog.outString( "<Ctrl-C> to stop.\n\n" );
|
|
||||||
|
|
||||||
sLog.outTitle( "MM MM MM MM MMMMM MMMM MMMMM");
|
|
||||||
sLog.outTitle( "MM MM MM MM MMM MMM MM MM MMM MMM");
|
|
||||||
sLog.outTitle( "MMM MMM MMM MM MMM MMM MM MM MMM");
|
|
||||||
sLog.outTitle( "MM M MM MMMM MM MMM MM MM MMM");
|
|
||||||
sLog.outTitle( "MM M MM MMMMM MM MMMM MMM MM MM MMM");
|
|
||||||
sLog.outTitle( "MM M MM M MMM MM MMM MMMMMMM MM MM MMM");
|
|
||||||
sLog.outTitle( "MM MM MMM MM MM MM MMM MM MM MMM");
|
|
||||||
sLog.outTitle( "MM MM MMMMMMM MM MM MMM MMM MM MM MMM MMM");
|
|
||||||
sLog.outTitle( "MM MM MM MMM MM MM MMMMMM MMMM MMMMM");
|
|
||||||
sLog.outTitle( " MM MMM http://getmangos.com");
|
|
||||||
sLog.outTitle( " MMMMMM\n\n");
|
|
||||||
|
|
||||||
/// worldd PID file creation
|
/// worldd PID file creation
|
||||||
std::string pidfile = sConfig.GetStringDefault("PidFile", "");
|
std::string pidfile = sConfig.GetStringDefault("PidFile", "");
|
||||||
if(!pidfile.empty())
|
if(!pidfile.empty())
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,7 @@ DatabaseType dbRealmServer; ///< Accessor to the
|
||||||
void usage(const char *prog)
|
void usage(const char *prog)
|
||||||
{
|
{
|
||||||
sLog.outString("Usage: \n %s [<options>]\n"
|
sLog.outString("Usage: \n %s [<options>]\n"
|
||||||
|
" --version print version and exist\n\r"
|
||||||
" -c config_file use config_file as configuration file\n\r"
|
" -c config_file use config_file as configuration file\n\r"
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
" Running as service functions:\n\r"
|
" Running as service functions:\n\r"
|
||||||
|
|
@ -90,6 +91,12 @@ extern int main(int argc, char **argv)
|
||||||
cfg_file = argv[c];
|
cfg_file = argv[c];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( strcmp(argv[c],"--version") == 0)
|
||||||
|
{
|
||||||
|
printf("%s\n", _FULLVERSION(REVISION_DATE,REVISION_TIME,REVISION_NR,REVISION_ID));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
////////////
|
////////////
|
||||||
//Services//
|
//Services//
|
||||||
|
|
@ -135,6 +142,9 @@ extern int main(int argc, char **argv)
|
||||||
sLog.outError("Could not find configuration file %s.", cfg_file);
|
sLog.outError("Could not find configuration file %s.", cfg_file);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sLog.outString( "%s [realm-daemon]", _FULLVERSION(REVISION_DATE,REVISION_TIME,REVISION_NR,REVISION_ID) );
|
||||||
|
sLog.outString( "<Ctrl-C> to stop.\n" );
|
||||||
sLog.outString("Using configuration file %s.", cfg_file);
|
sLog.outString("Using configuration file %s.", cfg_file);
|
||||||
|
|
||||||
///- Check the version of the configuration file
|
///- Check the version of the configuration file
|
||||||
|
|
@ -151,9 +161,6 @@ extern int main(int argc, char **argv)
|
||||||
while (pause > clock()) {}
|
while (pause > clock()) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
sLog.outString( "%s [realm-daemon]", _FULLVERSION(REVISION_DATE,REVISION_TIME,REVISION_NR,REVISION_ID) );
|
|
||||||
sLog.outString( "<Ctrl-C> to stop.\n" );
|
|
||||||
|
|
||||||
/// realmd PID file creation
|
/// realmd PID file creation
|
||||||
std::string pidfile = sConfig.GetStringDefault("PidFile", "");
|
std::string pidfile = sConfig.GetStringDefault("PidFile", "");
|
||||||
if(!pidfile.empty())
|
if(!pidfile.empty())
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "6818"
|
#define REVISION_NR "6824"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue