Merge commit 'origin/master' into 310 (at [7360])

This commit is contained in:
VladimirMangos 2009-03-01 01:18:20 +03:00
commit ce8bd43bef
69 changed files with 2352 additions and 1751 deletions

View file

@ -2,9 +2,9 @@ alter table `item_template`
drop column `dmg_type3`,
drop column `dmg_max3`,
drop column `dmg_min3`,
drop column `dmg_type5`,
drop column `dmg_max5`,
drop column `dmg_min5`,
drop column `dmg_type4`,
drop column `dmg_max4`,
drop column `dmg_min4`;
drop column `dmg_min4`,
drop column `dmg_type5`,
drop column `dmg_max5`,
drop column `dmg_min5`;

View file

@ -22,7 +22,7 @@
DROP TABLE IF EXISTS `db_version`;
CREATE TABLE `db_version` (
`version` varchar(120) default NULL,
`required_7331_01_mangos_command` bit(1) default NULL
`required_7349_01_mangos_spell_area` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
--
@ -275,7 +275,7 @@ INSERT INTO `command` VALUES
('demorph',2,'Syntax: .demorph\r\n\r\nDemorph the selected player.'),
('die',3,'Syntax: .die\r\n\r\nKill the selected player. If no player is selected, it will kill you.'),
('dismount',0,'Syntax: .dismount\r\n\r\nDismount you, if you are mounted.'),
('distance',3,'Syntax: .distance\r\n\r\nDisplay the distance from your character to the selected creature.'),
('distance',3,'Syntax: .distance [$name/$link]\r\n\r\nDisplay the distance from your character to the selected creature/player, or player with name $name, or player/creature/gameobject pointed to shift-link with guid.'),
('event',2,'Syntax: .event #event_id\r\nShow details about event with #event_id.'),
('event activelist',2,'Syntax: .event activelist\r\nShow list of currently active events.'),
('event start',2,'Syntax: .event start #event_id\r\nStart event #event_id. Set start time for event to current moment (change not saved in DB).'),
@ -13288,6 +13288,33 @@ LOCK TABLES `spell_affect` WRITE;
/*!40000 ALTER TABLE `spell_affect` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `spell_area`
--
DROP TABLE IF EXISTS `spell_area`;
CREATE TABLE `spell_area` (
`spell` mediumint(8) unsigned NOT NULL default '0',
`area` mediumint(8) unsigned NOT NULL default '0',
`quest_start` mediumint(8) unsigned NOT NULL default '0',
`quest_start_active` tinyint(1) unsigned NOT NULL default '0',
`quest_end` mediumint(8) unsigned NOT NULL default '0',
`aura_spell` mediumint(8) unsigned NOT NULL default '0',
`racemask` mediumint(8) unsigned NOT NULL default '0',
`gender` tinyint(1) unsigned NOT NULL default '2',
`autocast` tinyint(1) unsigned NOT NULL default '0',
PRIMARY KEY (`spell`,`area`,`quest_start`,`quest_start_active`,`aura_spell`,`racemask`,`gender`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
--
-- Dumping data for table `spell_area`
--
LOCK TABLES `spell_area` WRITE;
/*!40000 ALTER TABLE `spell_area` DISABLE KEYS */;
/*!40000 ALTER TABLE `spell_area` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `spell_chain`
--

View file

@ -0,0 +1,6 @@
ALTER TABLE db_version CHANGE COLUMN required_7331_01_mangos_command required_7332_01_mangos_command bit;
DELETE FROM `command` WHERE `name` = 'distance';
INSERT INTO `command` VALUES
('distance',3,'Syntax: .distance [$name/$link]\r\n\r\nDisplay the distance from your character to the selected creature/player, or player with name $name, or player/creature/gameobject pointed to shift-link with guid.');

View file

@ -0,0 +1,15 @@
ALTER TABLE db_version CHANGE COLUMN required_7332_01_mangos_command required_7349_01_mangos_spell_area bit;
DROP TABLE IF EXISTS `spell_area`;
CREATE TABLE `spell_area` (
`spell` mediumint(8) unsigned NOT NULL default '0',
`area` mediumint(8) unsigned NOT NULL default '0',
`quest_start` mediumint(8) unsigned NOT NULL default '0',
`quest_start_active` tinyint(1) unsigned NOT NULL default '0',
`quest_end` mediumint(8) unsigned NOT NULL default '0',
`aura_spell` mediumint(8) unsigned NOT NULL default '0',
`racemask` mediumint(8) unsigned NOT NULL default '0',
`gender` tinyint(1) unsigned NOT NULL default '2',
`autocast` tinyint(1) unsigned NOT NULL default '0',
PRIMARY KEY (`spell`,`area`,`quest_start`,`quest_start_active`,`aura_spell`,`racemask`,`gender`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

View file

@ -186,6 +186,8 @@ pkgdata_DATA = \
7324_01_characters_character_spell.sql \
7324_02_characters_character_aura.sql \
7331_01_mangos_command.sql \
7332_01_mangos_command.sql \
7349_01_mangos_spell_area.sql \
README
## Additional files to include when running 'make dist'
@ -352,4 +354,6 @@ EXTRA_DIST = \
7324_01_characters_character_spell.sql \
7324_02_characters_character_aura.sql \
7331_01_mangos_command.sql \
7332_01_mangos_command.sql \
7349_01_mangos_spell_area.sql \
README

View file

@ -25,13 +25,13 @@ AM_CPPFLAGS = $(MANGOS_INCLUDES) -I$(srcdir) -I$(srcdir)/../../../dep/include -I
# libmangosscript shared library will later be reused by world server daemon.
lib_LTLIBRARIES = libmangosscript.la
libmangosscript_la_SOURCES = \
ScriptMgr.cpp \
ScriptMgr.h \
config.h \
system.cpp \
Scripts/sc_default.cpp \
Scripts/sc_defines.cpp \
Scripts/sc_defines.h
ScriptMgr.cpp \
ScriptMgr.h \
config.h \
system.cpp \
Scripts/sc_default.cpp \
Scripts/sc_defines.cpp \
Scripts/sc_defines.h
## libtool settings
# API versioning
@ -51,6 +51,6 @@ libmangosscript_la_LIBFLAGS = -version-info $(LTMANGOS_CURRENT):$(LTMANGOS_REVIS
## Additional files to include when running 'make dist'
# Scripts defaults.
EXTRA_DIST = \
Scripts/sc_default.cpp \
Scripts/sc_defines.cpp \
Scripts/sc_defines.h
Scripts/sc_default.cpp \
Scripts/sc_defines.cpp \
Scripts/sc_defines.h

View file

@ -103,7 +103,7 @@ class MANGOS_DLL_DECL Grid
/** Returns the number of object within the grid.
*/
unsigned int ActiveObjectsInGrid(void) const { return i_objects.template Count<ACTIVE_OBJECT>(); }
unsigned int ActiveObjectsInGrid(void) const { return m_activeGridObjects.size()+i_objects.template Count<ACTIVE_OBJECT>(); }
/** Accessors: Returns a specific type of object in the GRID_OBJECT_TYPES
*/
@ -112,11 +112,21 @@ class MANGOS_DLL_DECL Grid
/** Inserts a container type object into the grid.
*/
template<class SPECIFIC_OBJECT> bool AddGridObject(SPECIFIC_OBJECT *obj, OBJECT_HANDLE hdl) { return i_container.template insert<SPECIFIC_OBJECT>(hdl, obj); }
template<class SPECIFIC_OBJECT> bool AddGridObject(SPECIFIC_OBJECT *obj, OBJECT_HANDLE hdl)
{
if(obj->isActiveObject())
m_activeGridObjects.insert(obj);
return i_container.template insert<SPECIFIC_OBJECT>(hdl, obj);
}
/** Removes a containter type object from the grid
*/
template<class SPECIFIC_OBJECT> bool RemoveGridObject(SPECIFIC_OBJECT *obj, OBJECT_HANDLE hdl) { return i_container.template remove<SPECIFIC_OBJECT>(obj, hdl); }
template<class SPECIFIC_OBJECT> bool RemoveGridObject(SPECIFIC_OBJECT *obj, OBJECT_HANDLE hdl)
{
if(obj->isActiveObject())
m_activeGridObjects.erase(obj);
return i_container.template remove<SPECIFIC_OBJECT>(obj, hdl);
}
private:
@ -125,5 +135,7 @@ class MANGOS_DLL_DECL Grid
TypeMapContainer<GRID_OBJECT_TYPES> i_container;
TypeMapContainer<WORLD_OBJECT_TYPES> i_objects;
typedef std::set<void*> ActiveGridObjects;
ActiveGridObjects m_activeGridObjects;
};
#endif

View file

@ -29,18 +29,26 @@
class GridInfo
{
public:
GridInfo() : i_timer(0) {}
GridInfo(time_t expiry, bool unload = true ) : i_timer(expiry), i_unloadflag(unload) {}
GridInfo()
: i_timer(0), i_unloadActiveLockCount(0), i_unloadExplicitLock(false), i_unloadReferenceLock(false) {}
GridInfo(time_t expiry, bool unload = true )
: i_timer(expiry), i_unloadActiveLockCount(0), i_unloadExplicitLock(!unload), i_unloadReferenceLock(false) {}
const TimeTracker& getTimeTracker() const { return i_timer; }
bool getUnloadFlag() const { return i_unloadflag; }
void setUnloadFlag( bool pFlag) { i_unloadflag = pFlag; }
bool getUnloadLock() const { return i_unloadActiveLockCount || i_unloadExplicitLock || i_unloadReferenceLock; }
void setUnloadExplicitLock( bool on ) { i_unloadExplicitLock = on; }
void setUnloadReferenceLock( bool on ) { i_unloadReferenceLock = on; }
void incUnloadActiveLock() { ++i_unloadActiveLockCount; }
void decUnloadActiveLock() { if(i_unloadActiveLockCount) --i_unloadActiveLockCount; }
void setTimer(const TimeTracker& pTimer) { i_timer = pTimer; }
void ResetTimeTracker(time_t interval) { i_timer.Reset(interval); }
void UpdateTimeTracker(time_t diff) { i_timer.Update(diff); }
private:
TimeTracker i_timer;
bool i_unloadflag;
uint16 i_unloadActiveLockCount : 16; // lock from active object spawn points (prevent clone loading)
bool i_unloadExplicitLock : 1; // explicit manual lock or config setting
bool i_unloadReferenceLock : 1; // lock from instance map copy
};
typedef enum
@ -90,8 +98,11 @@ class MANGOS_DLL_DECL NGrid
GridInfo* getGridInfoRef() { return &i_GridInfo; }
const TimeTracker& getTimeTracker() const { return i_GridInfo.getTimeTracker(); }
bool getUnloadFlag() const { return i_GridInfo.getUnloadFlag(); }
void setUnloadFlag( bool pFlag) { i_GridInfo.setUnloadFlag(pFlag); }
bool getUnloadLock() const { return i_GridInfo.getUnloadLock(); }
void setUnloadExplicitLock( bool on ) { i_GridInfo.setUnloadExplicitLock(on); }
void setUnloadReferenceLock( bool on ) { i_GridInfo.setUnloadReferenceLock(on); }
void incUnloadActiveLock() { i_GridInfo.incUnloadActiveLock(); }
void decUnloadActiveLock() { i_GridInfo.decUnloadActiveLock(); }
void ResetTimeTracker(time_t interval) { i_GridInfo.ResetTimeTracker(interval); }
void UpdateTimeTracker(time_t diff) { i_GridInfo.UpdateTimeTracker(diff); }

View file

@ -25,39 +25,39 @@ AM_CPPFLAGS = $(MANGOS_INCLUDES) -I$(srcdir)
# libMaNGOSScript shared library will later be reused by world server daemon.
noinst_LIBRARIES = libmangosframework.a
libmangosframework_a_SOURCES = \
Policies/ObjectLifeTime.cpp \
Utilities/EventProcessor.cpp
Policies/ObjectLifeTime.cpp \
Utilities/EventProcessor.cpp
## Additional files to include when running 'make dist'
# Source and header files for the Framework.
EXTRA_DIST = \
Dynamic/FactoryHolder.h \
Dynamic/ObjectRegistry.h \
GameSystem/Grid.h \
GameSystem/GridLoader.h \
GameSystem/GridRefManager.h \
GameSystem/GridReference.h \
GameSystem/NGrid.h \
GameSystem/TypeContainer.h \
GameSystem/TypeContainerFunctions.h \
GameSystem/TypeContainerFunctionsPtr.h \
GameSystem/TypeContainerVisitor.h \
Network/SocketDefines.h \
Platform/CompilerDefs.h \
Platform/Define.h \
Policies/CreationPolicy.h \
Policies/ObjectLifeTime.h \
Policies/Singleton.h \
Policies/SingletonImp.h \
Policies/ThreadingModel.h \
Utilities/CountedReference/Reference.h \
Utilities/CountedReference/ReferenceHolder.h \
Utilities/CountedReference/ReferenceImpl.h \
Utilities/LinkedReference/RefManager.h \
Utilities/LinkedReference/Reference.h \
Utilities/ByteConverter.h \
Utilities/Callback.h \
Utilities/EventProcessor.h \
Utilities/UnorderedMap.h \
Utilities/LinkedList.h \
Utilities/TypeList.h
Dynamic/FactoryHolder.h \
Dynamic/ObjectRegistry.h \
GameSystem/Grid.h \
GameSystem/GridLoader.h \
GameSystem/GridRefManager.h \
GameSystem/GridReference.h \
GameSystem/NGrid.h \
GameSystem/TypeContainer.h \
GameSystem/TypeContainerFunctions.h \
GameSystem/TypeContainerFunctionsPtr.h \
GameSystem/TypeContainerVisitor.h \
Network/SocketDefines.h \
Platform/CompilerDefs.h \
Platform/Define.h \
Policies/CreationPolicy.h \
Policies/ObjectLifeTime.h \
Policies/Singleton.h \
Policies/SingletonImp.h \
Policies/ThreadingModel.h \
Utilities/CountedReference/Reference.h \
Utilities/CountedReference/ReferenceHolder.h \
Utilities/CountedReference/ReferenceImpl.h \
Utilities/LinkedReference/RefManager.h \
Utilities/LinkedReference/Reference.h \
Utilities/ByteConverter.h \
Utilities/Callback.h \
Utilities/EventProcessor.h \
Utilities/UnorderedMap.h \
Utilities/LinkedList.h \
Utilities/TypeList.h

View file

@ -86,7 +86,6 @@ const CriteriaCastSpellRequirement AchievementGlobalMgr::m_criteriaCastSpellRequ
{6662, 31261, 0, 0}
};
namespace MaNGOS
{
class AchievementChatBuilder
@ -573,11 +572,11 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
uint32 spellCount = 0;
for (PlayerSpellMap::const_iterator spellIter = GetPlayer()->GetSpellMap().begin();
spellIter != GetPlayer()->GetSpellMap().end();
spellIter++)
++spellIter)
{
for(SkillLineAbilityMap::const_iterator skillIter = spellmgr.GetBeginSkillLineAbilityMap(spellIter->first);
skillIter != spellmgr.GetEndSkillLineAbilityMap(spellIter->first);
skillIter++)
++skillIter)
{
if(skillIter->second->skillId == achievementCriteria->learn_skilline_spell.skillLine)
spellCount++;
@ -605,7 +604,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
{
uint32 counter = 0;
const FactionStateList factionStateList = GetPlayer()->GetFactionStateList();
for (FactionStateList::const_iterator iter = factionStateList.begin(); iter!= factionStateList.end(); iter++)
for (FactionStateList::const_iterator iter = factionStateList.begin(); iter!= factionStateList.end(); ++iter)
{
if(GetPlayer()->ReputationToRank(iter->second.Standing) >= REP_EXALTED)
++counter;
@ -727,6 +726,9 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
}
}
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)
{
AchievementEntry const* achievement = sAchievementStore.LookupEntry(achievementCriteria->referredAchievement);
@ -753,29 +755,12 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve
switch(achievementCriteria->requiredType)
{
case ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL:
if ((achievement->ID == 467 && GetPlayer()->getClass() != CLASS_SHAMAN ) ||
(achievement->ID == 466 && GetPlayer()->getClass() != CLASS_DRUID ) ||
(achievement->ID == 465 && GetPlayer()->getClass() != CLASS_PALADIN ) ||
(achievement->ID == 464 && GetPlayer()->getClass() != CLASS_PRIEST ) ||
(achievement->ID == 463 && GetPlayer()->getClass() != CLASS_WARLOCK ) ||
(achievement->ID == 462 && GetPlayer()->getClass() != CLASS_HUNTER ) ||
(achievement->ID == 461 && GetPlayer()->getClass() != CLASS_DEATH_KNIGHT)||
(achievement->ID == 460 && GetPlayer()->getClass() != CLASS_MAGE ) ||
(achievement->ID == 459 && GetPlayer()->getClass() != CLASS_WARRIOR ) ||
(achievement->ID == 458 && GetPlayer()->getClass() != CLASS_ROGUE ) ||
(achievement->ID == 1404 && GetPlayer()->getRace() != RACE_GNOME ) ||
(achievement->ID == 1405 && GetPlayer()->getRace() != RACE_BLOODELF ) ||
(achievement->ID == 1406 && GetPlayer()->getRace() != RACE_DRAENEI ) ||
(achievement->ID == 1407 && GetPlayer()->getRace() != RACE_DWARF ) ||
(achievement->ID == 1408 && GetPlayer()->getRace() != RACE_HUMAN ) ||
(achievement->ID == 1409 && GetPlayer()->getRace() != RACE_NIGHTELF ) ||
(achievement->ID == 1410 && GetPlayer()->getRace() != RACE_ORC ) ||
(achievement->ID == 1411 && GetPlayer()->getRace() != RACE_TAUREN ) ||
(achievement->ID == 1412 && GetPlayer()->getRace() != RACE_TROLL ) ||
(achievement->ID == 1413 && GetPlayer()->getRace() != RACE_UNDEAD_PLAYER) )
return false;
return progress->counter >= achievementCriteria->reach_level.level;
{
if (achievIdByClass[GetPlayer()->getClass()] == achievement->ID ||
achievIdByRace[GetPlayer()->getRace()] == achievement->ID)
return progress->counter >= achievementCriteria->reach_level.level;
return false;
}
case ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT:
return progress->counter >= achievementCriteria->buy_bank_slot.numberOfSlots;
case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE:

View file

@ -49,6 +49,9 @@ AuctionHouseMgr::~AuctionHouseMgr()
AuctionHouseObject * AuctionHouseMgr::GetAuctionsMap( uint32 factionTemplateId )
{
if(sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION))
return &mNeutralAuctions;
// team have linked auction houses
FactionTemplateEntry const* u_entry = sFactionTemplateStore.LookupEntry(factionTemplateId);
if(!u_entry)
@ -456,7 +459,7 @@ void AuctionHouseMgr::Update()
AuctionHouseEntry const* AuctionHouseMgr::GetAuctionHouseEntry(uint32 factionTemplateId)
{
uint32 houseid = 1; // human auction house
uint32 houseid = 1; // dwarf auction house (used for normal cut/etc percents)
if(!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION))
{

View file

@ -39,7 +39,7 @@ BattleGround::BattleGround()
m_Status = 0;
m_EndTime = 0;
m_LastResurrectTime = 0;
m_QueueId = MAX_BATTLEGROUND_QUEUES;
m_QueueId = QUEUE_ID_MAX_LEVEL_19;
m_InvitedAlliance = 0;
m_InvitedHorde = 0;
m_ArenaType = 0;
@ -115,7 +115,7 @@ BattleGround::~BattleGround()
// remove from battlegrounds
}
sBattleGroundMgr.RemoveBattleGround(GetInstanceID());
sBattleGroundMgr.RemoveBattleGround(GetInstanceID(), GetTypeID());
// unload map
if(Map * map = MapManager::Instance().FindMap(GetMapId(), GetInstanceID()))
if(map->IsBattleGroundOrArena())
@ -130,8 +130,6 @@ void BattleGround::Update(uint32 diff)
//BG is empty
return;
WorldPacket data;
if(GetRemovedPlayersSize())
{
for(std::map<uint64, uint8>::iterator itr = m_RemovedPlayers.begin(); itr != m_RemovedPlayers.end(); ++itr)
@ -139,16 +137,6 @@ void BattleGround::Update(uint32 diff)
Player *plr = objmgr.GetPlayer(itr->first);
switch(itr->second)
{
//following code is handled by event:
/*case 0:
sBattleGroundMgr.m_BattleGroundQueues[GetTypeID()].RemovePlayer(itr->first);
//RemovePlayerFromQueue(itr->first);
if(plr)
{
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetTeam(), plr->GetBattleGroundQueueIndex(m_TypeID), STATUS_NONE, 0, 0);
plr->GetSession()->SendPacket(&data);
}
break;*/
case 1: // currently in bg and was removed from bg
if(plr)
RemovePlayerAtLeave(itr->first, true, true);
@ -827,7 +815,7 @@ void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac
DecreaseInvitedCount(team);
//we should update battleground queue, but only if bg isn't ending
if (GetQueueId() < MAX_BATTLEGROUND_QUEUES)
if (GetStatus() < STATUS_WAIT_LEAVE)
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, GetQueueId());
Group * group = plr->GetGroup();
@ -847,7 +835,7 @@ void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac
}
// Do next only if found in battleground
plr->SetBattleGroundId(0); // We're not in BG.
plr->SetBattleGroundId(0, BATTLEGROUND_TYPE_NONE); // We're not in BG.
// reset destination bg team
plr->SetBGTeam(0);
@ -874,7 +862,7 @@ void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac
// this method is called when no players remains in battleground
void BattleGround::Reset()
{
SetQueueId(MAX_BATTLEGROUND_QUEUES);
SetQueueId(QUEUE_ID_MAX_LEVEL_19);
SetWinner(WINNER_NONE);
SetStatus(STATUS_WAIT_QUEUE);
SetStartTime(0);
@ -1009,7 +997,7 @@ void BattleGround::AddOrSetPlayerToCorrectBgGroup(Player *plr, uint64 plr_guid,
void BattleGround::AddToBGFreeSlotQueue()
{
// make sure to add only once
if(!m_InBGFreeSlotQueue)
if(!m_InBGFreeSlotQueue && isBattleGround())
{
sBattleGroundMgr.BGFreeSlotQueue[m_TypeID].push_front(this);
m_InBGFreeSlotQueue = true;
@ -1022,7 +1010,7 @@ void BattleGround::RemoveFromBGFreeSlotQueue()
// set to be able to re-add if needed
m_InBGFreeSlotQueue = false;
// uncomment this code when battlegrounds will work like instances
for (std::deque<BattleGround*>::iterator itr = sBattleGroundMgr.BGFreeSlotQueue[m_TypeID].begin(); itr != sBattleGroundMgr.BGFreeSlotQueue[m_TypeID].end(); ++itr)
for (BGFreeSlotQueueType::iterator itr = sBattleGroundMgr.BGFreeSlotQueue[m_TypeID].begin(); itr != sBattleGroundMgr.BGFreeSlotQueue[m_TypeID].end(); ++itr)
{
if ((*itr)->GetInstanceID() == m_InstanceID)
{
@ -1033,61 +1021,12 @@ void BattleGround::RemoveFromBGFreeSlotQueue()
}
// get the number of free slots for team
// works in similar way that HasFreeSlotsForTeam did, but this is needed for join as group
// returns the number how many players can join battleground to MaxPlayersPerTeam
uint32 BattleGround::GetFreeSlotsForTeam(uint32 Team) const
{
//if BG is starting ... invite anyone
if (GetStatus() == STATUS_WAIT_JOIN)
if (GetStatus() == STATUS_WAIT_JOIN || GetStatus() == STATUS_IN_PROGRESS)
return (GetInvitedCount(Team) < GetMaxPlayersPerTeam()) ? GetMaxPlayersPerTeam() - GetInvitedCount(Team) : 0;
//if BG is already started .. do not allow to join too much players of one faction
uint32 otherTeam;
uint32 otherIn;
if (Team == ALLIANCE)
{
otherTeam = GetInvitedCount(HORDE);
otherIn = GetPlayersCountByTeam(HORDE);
}
else
{
otherTeam = GetInvitedCount(ALLIANCE);
otherIn = GetPlayersCountByTeam(ALLIANCE);
}
if (GetStatus() == STATUS_IN_PROGRESS)
{
// difference based on ppl invited (not necessarily entered battle)
// default: allow 0
uint32 diff = 0;
// allow join one person if the sides are equal (to fill up bg to minplayersperteam)
if (otherTeam == GetInvitedCount(Team))
diff = 1;
// allow join more ppl if the other side has more players
else if(otherTeam > GetInvitedCount(Team))
diff = otherTeam - GetInvitedCount(Team);
// difference based on max players per team (don't allow inviting more)
uint32 diff2 = (GetInvitedCount(Team) < GetMaxPlayersPerTeam()) ? GetMaxPlayersPerTeam() - GetInvitedCount(Team) : 0;
// difference based on players who already entered
// default: allow 0
uint32 diff3 = 0;
// allow join one person if the sides are equal (to fill up bg minplayersperteam)
if (otherIn == GetPlayersCountByTeam(Team))
diff3 = 1;
// allow join more ppl if the other side has more players
else if (otherIn > GetPlayersCountByTeam(Team))
diff3 = otherIn - GetPlayersCountByTeam(Team);
// or other side has less than minPlayersPerTeam
else if (GetInvitedCount(Team) <= GetMinPlayersPerTeam())
diff3 = GetMinPlayersPerTeam() - GetInvitedCount(Team) + 1;
// return the minimum of the 3 differences
// min of diff and diff 2
diff = diff < diff2 ? diff : diff2;
// min of diff, diff2 and diff3
return diff < diff3 ? diff : diff3 ;
}
return 0;
}

View file

@ -86,6 +86,7 @@ enum BattleGroundTimeIntervals
{
RESURRECTION_INTERVAL = 30000, // ms
REMIND_INTERVAL = 30000, // ms
INVITATION_REMIND_TIME = 60000, // ms
INVITE_ACCEPT_WAIT_TIME = 80000, // ms
TIME_TO_AUTOREMOVE = 120000, // ms
MAX_OFFLINE_TIME = 300000, // ms
@ -135,16 +136,30 @@ struct BattleGroundObjectInfo
// handle the queue types and bg types separately to enable joining queue for different sized arenas at the same time
enum BattleGroundQueueTypeId
{
BATTLEGROUND_QUEUE_NONE = 0,
BATTLEGROUND_QUEUE_AV = 1,
BATTLEGROUND_QUEUE_WS = 2,
BATTLEGROUND_QUEUE_AB = 3,
BATTLEGROUND_QUEUE_EY = 4,
BATTLEGROUND_QUEUE_SA = 5,
BATTLEGROUND_QUEUE_2v2 = 6,
BATTLEGROUND_QUEUE_3v3 = 7,
BATTLEGROUND_QUEUE_5v5 = 8,
BATTLEGROUND_QUEUE_NONE = 0,
BATTLEGROUND_QUEUE_AV = 1,
BATTLEGROUND_QUEUE_WS = 2,
BATTLEGROUND_QUEUE_AB = 3,
BATTLEGROUND_QUEUE_EY = 4,
BATTLEGROUND_QUEUE_SA = 5,
BATTLEGROUND_QUEUE_2v2 = 6,
BATTLEGROUND_QUEUE_3v3 = 7,
BATTLEGROUND_QUEUE_5v5 = 8
};
#define MAX_BATTLEGROUND_QUEUE_TYPES 9
enum BGQueueIdBasedOnLevel // queue_id for level ranges
{
QUEUE_ID_MAX_LEVEL_19 = 0,
QUEUE_ID_MAX_LEVEL_29 = 1,
QUEUE_ID_MAX_LEVEL_39 = 2,
QUEUE_ID_MAX_LEVEL_49 = 3,
QUEUE_ID_MAX_LEVEL_59 = 4,
QUEUE_ID_MAX_LEVEL_69 = 5,
QUEUE_ID_MAX_LEVEL_79 = 6,
QUEUE_ID_MAX_LEVEL_80 = 7
};
#define MAX_BATTLEGROUND_QUEUES 8
enum ScoreType
{
@ -197,6 +212,7 @@ enum BattleGroundTeamId
BG_TEAM_ALLIANCE = 0,
BG_TEAM_HORDE = 1
};
#define BG_TEAMS_COUNT 2
enum BattleGroundJoinError
{
@ -255,7 +271,7 @@ class BattleGround
// Get methods:
char const* GetName() const { return m_Name; }
BattleGroundTypeId GetTypeID() const { return m_TypeID; }
uint32 GetQueueId() const { return m_QueueId; }
BGQueueIdBasedOnLevel GetQueueId() const { return m_QueueId; }
uint32 GetInstanceID() const { return m_InstanceID; }
uint32 GetStatus() const { return m_Status; }
uint32 GetStartTime() const { return m_StartTime; }
@ -278,7 +294,13 @@ class BattleGround
// Set methods:
void SetName(char const* Name) { m_Name = Name; }
void SetTypeID(BattleGroundTypeId TypeID) { m_TypeID = TypeID; }
void SetQueueId(uint32 ID) { m_QueueId = ID; }
//here we can count minlevel and maxlevel for players
void SetQueueId(BGQueueIdBasedOnLevel ID)
{
m_QueueId = ID;
uint8 diff = (m_TypeID == BATTLEGROUND_AV) ? 1 : 0;
this->SetLevelRange((ID + 1) * 10 + diff, (ID + 2) * 10 - ((diff + 1) % 2));
}
void SetInstanceID(uint32 InstanceID) { m_InstanceID = InstanceID; }
void SetStatus(uint32 Status) { m_Status = Status; }
void SetStartTime(uint32 Time) { m_StartTime = Time; }
@ -310,7 +332,6 @@ class BattleGround
else
return m_InvitedHorde;
}
bool HasFreeSlotsForTeam(uint32 Team) const;
bool HasFreeSlots() const;
uint32 GetFreeSlotsForTeam(uint32 Team) const;
@ -472,7 +493,7 @@ class BattleGround
uint32 m_StartTime;
uint32 m_EndTime;
uint32 m_LastResurrectTime;
uint32 m_QueueId;
BGQueueIdBasedOnLevel m_QueueId;
uint8 m_ArenaType; // 2=2v2, 3=3v3, 5=5v5
bool m_InBGFreeSlotQueue; // used to make sure that BG is only once inserted into the BattleGroundMgr.BGFreeSlotQueue[bgTypeId] deque
bool m_SetDeleteThis; // used for safe deletion of the bg after end / all players leave
@ -498,15 +519,15 @@ class BattleGround
uint32 m_InvitedHorde;
/* Raid Group */
Group *m_BgRaids[2]; // 0 - alliance, 1 - horde
Group *m_BgRaids[BG_TEAMS_COUNT]; // 0 - alliance, 1 - horde
/* Players count by team */
uint32 m_PlayersCount[2];
uint32 m_PlayersCount[BG_TEAMS_COUNT];
/* Arena team ids by team */
uint32 m_ArenaTeamIds[2];
uint32 m_ArenaTeamIds[BG_TEAMS_COUNT];
int32 m_ArenaTeamRatingChanges[2];
int32 m_ArenaTeamRatingChanges[BG_TEAMS_COUNT];
/* Limits */
uint32 m_LevelMin;
@ -518,9 +539,9 @@ class BattleGround
/* Location */
uint32 m_MapId;
float m_TeamStartLocX[2];
float m_TeamStartLocY[2];
float m_TeamStartLocZ[2];
float m_TeamStartLocO[2];
float m_TeamStartLocX[BG_TEAMS_COUNT];
float m_TeamStartLocY[BG_TEAMS_COUNT];
float m_TeamStartLocZ[BG_TEAMS_COUNT];
float m_TeamStartLocO[BG_TEAMS_COUNT];
};
#endif

View file

@ -78,6 +78,7 @@ void WorldSession::HandleBattleGroundJoinOpcode( WorldPacket & recv_data )
uint32 bgTypeId_;
uint32 instanceId;
uint8 joinAsGroup;
bool isPremade = false;
Group * grp;
recv_data >> guid; // battlemaster guid
@ -112,7 +113,7 @@ void WorldSession::HandleBattleGroundJoinOpcode( WorldPacket & recv_data )
// get bg instance or bg template if instance not found
BattleGround * bg = 0;
if(instanceId)
BattleGround *bg = sBattleGroundMgr.GetBattleGround(instanceId);
BattleGround *bg = sBattleGroundMgr.GetBattleGround(instanceId, bgTypeId);
if(!bg && !(bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId)))
{
@ -146,6 +147,7 @@ void WorldSession::HandleBattleGroundJoinOpcode( WorldPacket & recv_data )
if(!grp)
return;
uint32 err = grp->CanJoinBattleGroundQueue(bgTypeId, bgQueueTypeId, 0, bg->GetMaxPlayersPerTeam(), false, 0);
isPremade = (grp->GetMembersCount() >= bg->GetMinPlayersPerTeam());
if (err != BG_JOIN_ERR_OK)
{
SendBattleGroundOrArenaJoinError(err);
@ -158,7 +160,7 @@ void WorldSession::HandleBattleGroundJoinOpcode( WorldPacket & recv_data )
if(joinAsGroup /* && _player->GetGroup()*/)
{
sLog.outDebug("Battleground: the following players are joining as group:");
GroupQueueInfo * ginfo = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, 0, false, 0);
GroupQueueInfo * ginfo = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, 0, false, isPremade, 0);
for(GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
{
Player *member = itr->getSource();
@ -195,7 +197,7 @@ void WorldSession::HandleBattleGroundJoinOpcode( WorldPacket & recv_data )
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, _player->GetTeam(), queueSlot, STATUS_WAIT_QUEUE, 0, 0);
SendPacket(&data);
GroupQueueInfo * ginfo = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, 0, false, 0);
GroupQueueInfo * ginfo = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, 0, false, false, 0);
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddPlayer(_player, ginfo);
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattleGroundQueueIdFromLevel(bgTypeId));
if(!ginfo->IsInvitedToBGInstanceGUID)
@ -316,8 +318,7 @@ void WorldSession::HandleBattleGroundPlayerPortOpcode( WorldPacket &recv_data )
if(!bgQueueTypeId)
continue;
BattleGroundTypeId bgTypeId = BattleGroundMgr::BGTemplateId(bgQueueTypeId);
uint32 queue_id = _player->GetBattleGroundQueueIdFromLevel(bgTypeId);
BattleGroundQueue::QueuedPlayersMap& qpMap = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers[queue_id];
BattleGroundQueue::QueuedPlayersMap& qpMap = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers;
BattleGroundQueue::QueuedPlayersMap::iterator itrPlayerStatus = qpMap.find(_player->GetGUID());
// if the player is not in queue, continue
if(itrPlayerStatus == qpMap.end())
@ -344,7 +345,7 @@ void WorldSession::HandleBattleGroundPlayerPortOpcode( WorldPacket &recv_data )
else
{
// get the bg we're invited to
BattleGround * bg = sBattleGroundMgr.GetBattleGround(itrPlayerStatus->second.GroupInfo->IsInvitedToBGInstanceGUID);
BattleGround * bg = sBattleGroundMgr.GetBattleGround(itrPlayerStatus->second.GroupInfo->IsInvitedToBGInstanceGUID, bgTypeId);
status = STATUS_WAIT_JOIN;
}
@ -370,7 +371,7 @@ void WorldSession::HandleBattleGroundPlayerPortOpcode( WorldPacket &recv_data )
BattleGroundQueueTypeId bgQueueTypeId = BATTLEGROUND_QUEUE_NONE;
// get the bg what we were invited to
bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId,type);
BattleGroundQueue::QueuedPlayersMap& qpMap = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers[_player->GetBattleGroundQueueIdFromLevel(bgTypeId)];
BattleGroundQueue::QueuedPlayersMap& qpMap = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers;
BattleGroundQueue::QueuedPlayersMap::iterator itrPlayerStatus = qpMap.find(_player->GetGUID());
if(itrPlayerStatus == qpMap.end())
{
@ -386,7 +387,7 @@ void WorldSession::HandleBattleGroundPlayerPortOpcode( WorldPacket &recv_data )
return;
}
BattleGround *bg = sBattleGroundMgr.GetBattleGround(instanceId);
BattleGround *bg = sBattleGroundMgr.GetBattleGround(instanceId, bgTypeId);
// bg template might and must be used in case of leaving queue, when instance is not created yet
if(!bg && action == 0)
@ -410,7 +411,7 @@ void WorldSession::HandleBattleGroundPlayerPortOpcode( WorldPacket &recv_data )
uint32 opponentsRating = 0;
// get the team info from the queue
BattleGroundQueue::QueuedPlayersMap& qpMap2 = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers[_player->GetBattleGroundQueueIdFromLevel(bgTypeId)];
BattleGroundQueue::QueuedPlayersMap& qpMap2 = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers;
BattleGroundQueue::QueuedPlayersMap::iterator pitr = qpMap2.find(_player->GetGUID());
if (pitr !=qpMap2.end() && pitr->second.GroupInfo)
{
@ -455,11 +456,11 @@ void WorldSession::HandleBattleGroundPlayerPortOpcode( WorldPacket &recv_data )
currentBg->RemovePlayerAtLeave(_player->GetGUID(), false, true);
// set the destination instance id
_player->SetBattleGroundId(bg->GetInstanceID());
_player->SetBattleGroundId(bg->GetInstanceID(), bgTypeId);
// set the destination team
_player->SetBGTeam(team);
// bg->HandleBeforeTeleportToBattleGround(_player);
sBattleGroundMgr.SendToBattleGround(_player, instanceId);
sBattleGroundMgr.SendToBattleGround(_player, instanceId, bgTypeId);
// add only in HandleMoveWorldPortAck()
// bg->AddPlayer(_player,team);
sLog.outDebug("Battleground: player %s (%u) joined battle for bg %u, bgtype %u, queue type %u.",_player->GetName(),_player->GetGUIDLow(),bg->GetInstanceID(),bg->GetTypeID(),bgQueueTypeId);
@ -546,8 +547,7 @@ void WorldSession::HandleBattlefieldStatusOpcode( WorldPacket & /*recv_data*/ )
BattleGroundTypeId bgTypeId = BattleGroundMgr::BGTemplateId(bgQueueTypeId);
uint8 arenatype = BattleGroundMgr::BGArenaType(bgQueueTypeId);
uint8 isRated = 0;
uint32 queue_id = _player->GetBattleGroundQueueIdFromLevel(bgTypeId);
BattleGroundQueue::QueuedPlayersMap& qpMap = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers[queue_id];
BattleGroundQueue::QueuedPlayersMap& qpMap = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers;
BattleGroundQueue::QueuedPlayersMap::iterator itrPlayerStatus = qpMap.find(_player->GetGUID());
if(itrPlayerStatus == qpMap.end())
continue;
@ -578,9 +578,8 @@ void WorldSession::HandleBattlefieldStatusOpcode( WorldPacket & /*recv_data*/ )
BattleGroundTypeId bgTypeId = BattleGroundMgr::BGTemplateId(bgQueueTypeId);
uint8 arenatype = BattleGroundMgr::BGArenaType(bgQueueTypeId);
uint8 isRated = 0;
uint32 queue_id = _player->GetBattleGroundQueueIdFromLevel(bgTypeId);
BattleGround *bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId);
BattleGroundQueue::QueuedPlayersMap& qpMap = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers[queue_id];
BattleGroundQueue::QueuedPlayersMap& qpMap = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers;
BattleGroundQueue::QueuedPlayersMap::iterator itrPlayerStatus = qpMap.find(_player->GetGUID());
if(itrPlayerStatus == qpMap.end())
continue;
@ -768,7 +767,7 @@ void WorldSession::HandleBattleGroundArenaJoin( WorldPacket & recv_data )
if(asGroup)
{
GroupQueueInfo * ginfo = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, arenatype, isRated, arenaRating, ateamId);
GroupQueueInfo * ginfo = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, arenatype, isRated, false, arenaRating, ateamId);
sLog.outDebug("Battleground: arena join as group start");
if(isRated)
sLog.outDebug("Battleground: arena team id %u, leader %s queued with rating %u for type %u",_player->GetArenaTeamId(arenaslot),_player->GetName(),arenaRating,arenatype);
@ -807,7 +806,7 @@ void WorldSession::HandleBattleGroundArenaJoin( WorldPacket & recv_data )
// send status packet (in queue)
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, _player->GetTeam(), queueSlot, STATUS_WAIT_QUEUE, 0, 0, arenatype, isRated);
SendPacket(&data);
GroupQueueInfo * ginfo = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, arenatype, isRated, arenaRating);
GroupQueueInfo * ginfo = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, arenatype, isRated, false, arenaRating);
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddPlayer(_player, ginfo);
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattleGroundQueueIdFromLevel(bgTypeId), arenatype, isRated, arenaRating);
sLog.outDebug("Battleground: player joined queue for arena, skirmish, bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,_player->GetGUIDLow(), _player->GetName());

File diff suppressed because it is too large Load diff

View file

@ -22,18 +22,12 @@
#include "Common.h"
#include "BattleGround.h"
//TODO it is not possible to have this structure, because we should have BattlegroundSet for each queue
//so i propose to change this type to array 1..MAX_BATTLEGROUND_TYPES of sets or maps..
typedef std::map<uint32, BattleGround*> BattleGroundSet;
//typedef std::map<uint32, BattleGroundQueue*> BattleGroundQueueSet;
typedef std::deque<BattleGround*> BGFreeSlotQueueType;
typedef UNORDERED_MAP<uint32, BattleGroundTypeId> BattleMastersMap;
#define MAX_BATTLEGROUND_QUEUES 8 // for level ranges 10-19, 20-29, 30-39, 40-49, 50-59, 60-69, 70-79, 80+
#define MAX_BATTLEGROUND_QUEUE_TYPES 9
#define BATTLEGROUND_ARENA_POINT_DISTRIBUTION_DAY 86400 // seconds in a day
struct GroupQueueInfo; // type predefinition
@ -59,6 +53,15 @@ struct GroupQueueInfo // stores informatio
uint32 OpponentsTeamRating; // for rated arena matches
};
enum BattleGroundQueueGroupTypes
{
BG_QUEUE_PREMADE_ALLIANCE = 0,
BG_QUEUE_PREMADE_HORDE = 1,
BG_QUEUE_NORMAL_ALLIANCE = 2,
BG_QUEUE_NORMAL_HORDE = 3
};
#define BG_QUEUE_GROUP_TYPES_COUNT 4
class BattleGround;
class BattleGroundQueue
{
@ -66,9 +69,12 @@ class BattleGroundQueue
BattleGroundQueue();
~BattleGroundQueue();
void Update(BattleGroundTypeId bgTypeId, uint32 queue_id, uint8 arenatype = 0, bool isRated = false, uint32 minRating = 0);
void Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id, uint8 arenaType = 0, bool isRated = false, uint32 minRating = 0);
GroupQueueInfo * AddGroup(Player * leader, BattleGroundTypeId bgTypeId, uint8 ArenaType, bool isRated, uint32 ArenaRating, uint32 ArenaTeamId = 0);
void FillPlayersToBG(BattleGround* bg, BGQueueIdBasedOnLevel queue_id);
bool CheckPremadeMatch(BGQueueIdBasedOnLevel queue_id, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam);
bool CheckNormalMatch(BattleGround* bg_template, BGQueueIdBasedOnLevel queue_id, uint32 minPlayers, uint32 maxPlayers);
GroupQueueInfo * AddGroup(Player * leader, BattleGroundTypeId bgTypeId, uint8 ArenaType, bool isRated, bool isPremade, uint32 ArenaRating, uint32 ArenaTeamId = 0);
void AddPlayer(Player *plr, GroupQueueInfo *ginfo);
void RemovePlayer(const uint64& guid, bool decreaseInvitedCount);
void DecreaseGroupLength(uint32 queueId, uint32 AsGroup);
@ -76,52 +82,38 @@ class BattleGroundQueue
void AnnounceWorld(GroupQueueInfo *ginfo, const uint64& playerGUID, bool isAddedToQueue);
typedef std::map<uint64, PlayerQueueInfo> QueuedPlayersMap;
QueuedPlayersMap m_QueuedPlayers[MAX_BATTLEGROUND_QUEUES];
QueuedPlayersMap m_QueuedPlayers;
typedef std::list<GroupQueueInfo*> QueuedGroupsList;
QueuedGroupsList m_QueuedGroups[MAX_BATTLEGROUND_QUEUES];
//we need constant add to begin and constant remove / add from the end, therefore deque suits our problem well
typedef std::list<GroupQueueInfo*> GroupsQueueType;
// class to hold pointers to the groups eligible for a specific selection pool building mode
class EligibleGroups : public std::list<GroupQueueInfo *>
{
public:
void Init(QueuedGroupsList * source, BattleGroundTypeId BgTypeId, uint32 side, uint32 MaxPlayers, uint8 ArenaType = 0, bool IsRated = false, uint32 MinRating = 0, uint32 MaxRating = 0, uint32 DisregardTime = 0, uint32 excludeTeam = 0);
void RemoveGroup(GroupQueueInfo * ginfo);
};
EligibleGroups m_EligibleGroups;
/*
This two dimensional array is used to store All queued groups
First dimension specifies the bgTypeId
Second dimension specifies the player's group types -
BG_QUEUE_PREMADE_ALLIANCE is used for premade alliance groups and alliance rated arena teams
BG_QUEUE_PREMADE_HORDE is used for premade horde groups and horde rated arena teams
BG_QUEUE_NORMAL_ALLIANCE is used for normal (or small) alliance groups or non-rated arena matches
BG_QUEUE_NORMAL_HORDE is used for normal (or small) horde groups or non-rated arena matches
*/
GroupsQueueType m_QueuedGroups[MAX_BATTLEGROUND_QUEUES][BG_QUEUE_GROUP_TYPES_COUNT];
// class to select and invite groups to bg
class SelectionPool
{
public:
void Init();
void AddGroup(GroupQueueInfo * group);
GroupQueueInfo * GetMaximalGroup();
void RemoveGroup(GroupQueueInfo * group);
bool AddGroup(GroupQueueInfo *ginfo, uint32 desiredCount);
bool KickGroup(uint32 size);
uint32 GetPlayerCount() const {return PlayerCount;}
public:
std::list<GroupQueueInfo *> SelectedGroups;
GroupsQueueType SelectedGroups;
private:
uint32 PlayerCount;
GroupQueueInfo * MaxGroup;
};
enum SelectionPoolBuildMode
{
NORMAL_ALLIANCE,
NORMAL_HORDE,
ONESIDE_ALLIANCE_TEAM1,
ONESIDE_ALLIANCE_TEAM2,
ONESIDE_HORDE_TEAM1,
ONESIDE_HORDE_TEAM2,
NUM_SELECTION_POOL_TYPES
};
SelectionPool m_SelectionPools[NUM_SELECTION_POOL_TYPES];
bool BuildSelectionPool(BattleGroundTypeId bgTypeId, uint32 queue_id, uint32 MinPlayers, uint32 MaxPlayers, SelectionPoolBuildMode mode, uint8 ArenaType = 0, bool isRated = false, uint32 MinRating = 0, uint32 MaxRating = 0, uint32 DisregardTime = 0, uint32 excludeTeam = 0);
//one selection pool for horde, other one for alliance
SelectionPool m_SelectionPools[BG_TEAMS_COUNT];
private:
@ -135,7 +127,10 @@ class BattleGroundQueue
class BGQueueInviteEvent : public BasicEvent
{
public:
BGQueueInviteEvent(const uint64& pl_guid, uint32 BgInstanceGUID) : m_PlayerGuid(pl_guid), m_BgInstanceGUID(BgInstanceGUID) {};
BGQueueInviteEvent(const uint64& pl_guid, uint32 BgInstanceGUID, BattleGroundTypeId BgTypeId) :
m_PlayerGuid(pl_guid), m_BgInstanceGUID(BgInstanceGUID), m_BgTypeId(BgTypeId)
{
};
virtual ~BGQueueInviteEvent() {};
virtual bool Execute(uint64 e_time, uint32 p_time);
@ -143,6 +138,7 @@ class BGQueueInviteEvent : public BasicEvent
private:
uint64 m_PlayerGuid;
uint32 m_BgInstanceGUID;
BattleGroundTypeId m_BgTypeId;
};
/*
@ -151,8 +147,8 @@ class BGQueueInviteEvent : public BasicEvent
class BGQueueRemoveEvent : public BasicEvent
{
public:
BGQueueRemoveEvent(const uint64& pl_guid, uint32 bgInstanceGUID, uint32 playersTeam) :
m_PlayerGuid(pl_guid), m_BgInstanceGUID(bgInstanceGUID), m_PlayersTeam(playersTeam)
BGQueueRemoveEvent(const uint64& pl_guid, uint32 bgInstanceGUID, BattleGroundTypeId BgTypeId, uint32 playersTeam) :
m_PlayerGuid(pl_guid), m_BgInstanceGUID(bgInstanceGUID), m_BgTypeId(BgTypeId), m_PlayersTeam(playersTeam)
{
};
virtual ~BGQueueRemoveEvent() {};
@ -163,6 +159,7 @@ class BGQueueRemoveEvent : public BasicEvent
uint64 m_PlayerGuid;
uint32 m_BgInstanceGUID;
uint32 m_PlayersTeam;
BattleGroundTypeId m_BgTypeId;
};
class BattleGroundMgr
@ -182,34 +179,27 @@ class BattleGroundMgr
void BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg);
void BuildBattleGroundStatusPacket(WorldPacket *data, BattleGround *bg, uint32 team, uint8 QueueSlot, uint8 StatusID, uint32 Time1, uint32 Time2, uint32 arenatype = 0, uint8 israted = 0);
void BuildPlaySoundPacket(WorldPacket *data, uint32 soundid);
void SendAreaSpiritHealerQueryOpcode(Player *pl, BattleGround *bg, const uint64& guid);
/* Player invitation */
// called from Queue update, or from Addplayer to queue
void InvitePlayer(Player* plr, uint32 bgInstanceGUID, uint32 team);
void InvitePlayer(Player* plr, uint32 bgInstanceGUID, BattleGroundTypeId bgTypeId, uint32 team);
/* Battlegrounds */
BattleGroundSet::iterator GetBattleGroundsBegin() { return m_BattleGrounds.begin(); };
BattleGroundSet::iterator GetBattleGroundsEnd() { return m_BattleGrounds.end(); };
BattleGround* GetBattleGround(uint32 InstanceID)
{
BattleGroundSet::iterator i = m_BattleGrounds.find(InstanceID);
return ( (i != m_BattleGrounds.end()) ? i->second : NULL );
};
BattleGround* GetBattleGround(uint32 InstanceID, BattleGroundTypeId bgTypeId); //there must be uint32 because MAX_BATTLEGROUND_TYPE_ID means unknown
BattleGround * GetBattleGroundTemplate(BattleGroundTypeId bgTypeId);
BattleGround * CreateNewBattleGround(BattleGroundTypeId bgTypeId);
BattleGround * CreateNewBattleGround(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id, uint8 arenaType, bool isRated);
uint32 CreateBattleGround(BattleGroundTypeId bgTypeId, bool IsArena, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam, uint32 LevelMin, uint32 LevelMax, char* BattleGroundName, uint32 MapID, float Team1StartLocX, float Team1StartLocY, float Team1StartLocZ, float Team1StartLocO, float Team2StartLocX, float Team2StartLocY, float Team2StartLocZ, float Team2StartLocO);
void AddBattleGround(uint32 InstanceID, BattleGround* BG) { m_BattleGrounds[InstanceID] = BG; };
void RemoveBattleGround(uint32 instanceID) { m_BattleGrounds.erase(instanceID); }
void AddBattleGround(uint32 InstanceID, BattleGroundTypeId bgTypeId, BattleGround* BG) { m_BattleGrounds[bgTypeId][InstanceID] = BG; };
void RemoveBattleGround(uint32 instanceID, BattleGroundTypeId bgTypeId) { m_BattleGrounds[bgTypeId].erase(instanceID); }
void CreateInitialBattleGrounds();
void DeleteAlllBattleGrounds();
void SendToBattleGround(Player *pl, uint32 InstanceID);
void SendToBattleGround(Player *pl, uint32 InstanceID, BattleGroundTypeId bgTypeId);
/* Battleground queues */
//these queues are instantiated when creating BattlegroundMrg
@ -247,7 +237,7 @@ class BattleGroundMgr
BattleMastersMap mBattleMastersMap;
/* Battlegrounds */
BattleGroundSet m_BattleGrounds;
BattleGroundSet m_BattleGrounds[MAX_BATTLEGROUND_TYPE_ID];
uint32 m_NextRatingDiscardUpdate;
uint64 m_NextAutoDistributionTime;
uint32 m_AutoDistributionTimeChecker;

View file

@ -309,6 +309,7 @@ ChatCommand * ChatHandler::getCommandTable()
{ "skill_fishing_base_level", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSkillFishingBaseLevelCommand, "", NULL },
{ "skinning_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesSkinningCommand, "", NULL },
{ "spell_affect", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellAffectCommand, "", NULL },
{ "spell_area", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellAreaCommand, "", NULL },
{ "spell_chain", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellChainCommand, "", NULL },
{ "spell_elixir", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellElixirCommand, "", NULL },
{ "spell_learn_spell", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellLearnSpellCommand, "", NULL },

View file

@ -259,6 +259,7 @@ class ChatHandler
bool HandleReloadSkillExtraItemTemplateCommand(const char* args);
bool HandleReloadSkillFishingBaseLevelCommand(const char* args);
bool HandleReloadSpellAffectCommand(const char* args);
bool HandleReloadSpellAreaCommand(const char* args);
bool HandleReloadSpellChainCommand(const char* args);
bool HandleReloadSpellElixirCommand(const char* args);
bool HandleReloadSpellLearnSpellCommand(const char* args);

View file

@ -100,12 +100,21 @@ void Corpse::SaveToDB()
std::ostringstream ss;
ss << "INSERT INTO corpse (guid,player,position_x,position_y,position_z,orientation,zone,map,data,time,corpse_type,instance,phaseMask) VALUES ("
<< GetGUIDLow() << ", " << GUID_LOPART(GetOwnerGUID()) << ", " << GetPositionX() << ", " << GetPositionY() << ", " << GetPositionZ() << ", "
<< GetOrientation() << ", " << GetZoneId() << ", " << GetMapId() << ", '";
<< GetGUIDLow() << ", "
<< GUID_LOPART(GetOwnerGUID()) << ", "
<< GetPositionX() << ", "
<< GetPositionY() << ", "
<< GetPositionZ() << ", "
<< GetOrientation() << ", "
<< GetZoneId() << ", "
<< GetMapId() << ", '";
for(uint16 i = 0; i < m_valuesCount; i++ )
ss << GetUInt32Value(i) << " ";
ss << "'," << uint64(m_time) <<", " << uint32(GetType())
<< ", " << int(GetInstanceId()) << ", " << int(GetPhaseMask()) << ")";
ss << "',"
<< uint64(m_time) <<", "
<< uint32(GetType()) << ", "
<< int(GetInstanceId()) << ", "
<< uint16(GetPhaseMask()) << ")"; // prevent out of range error
CharacterDatabase.Execute( ss.str().c_str() );
CharacterDatabase.CommitTransaction();
}

View file

@ -86,6 +86,8 @@ class Corpse : public WorldObject
void Whisper(int32 textId,uint64 receiver) { MonsterWhisper(textId,receiver); }
GridReference<Corpse> &GetGridRef() { return m_gridRef; }
bool isActiveObject() const { return false; }
private:
GridReference<Corpse> m_gridRef;

View file

@ -114,7 +114,7 @@ m_deathTimer(0), m_respawnTime(0), m_respawnDelay(25), m_corpseDelay(60), m_resp
m_gossipOptionLoaded(false), m_emoteState(0), m_isPet(false), m_isVehicle(false), m_isTotem(false),
m_defaultMovementType(IDLE_MOTION_TYPE), m_DBTableGuid(0), m_equipmentId(0), m_AlreadyCallAssistance(false),
m_regenHealth(true), m_AI_locked(false), m_isDeadByDefault(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL),
m_creatureInfo(NULL)
m_creatureInfo(NULL), m_isActiveObject(false)
{
m_regenTimer = 200;
m_valuesCount = UNIT_END;
@ -1124,8 +1124,8 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
<< m_DBTableGuid << ","
<< GetEntry() << ","
<< mapid <<","
<< (uint32)spawnMask << ","
<< (uint32)GetPhaseMask() << ","
<< uint32(spawnMask) << "," // cast to prevent save as symbol
<< uint16(GetPhaseMask()) << "," // prevent out of range error
<< displayId <<","
<< GetEquipmentId() <<","
<< GetPositionX() << ","
@ -2098,3 +2098,23 @@ const char* Creature::GetNameForLocaleIdx(int32 loc_idx) const
return GetName();
}
void Creature::SetActiveObjectState( bool on )
{
if(m_isActiveObject==on)
return;
bool world = IsInWorld();
Map* map;
if(world)
{
map = GetMap();
map->Remove(this,false);
}
m_isActiveObject = on;
if(world)
map->Add(this);
}

View file

@ -609,7 +609,10 @@ class MANGOS_DLL_SPEC Creature : public Unit
uint32 GetGlobalCooldown() const { return m_GlobalCooldown; }
void SetDeadByDefault (bool death_state) {m_isDeadByDefault = death_state;}
void SetDeadByDefault (bool death_state) { m_isDeadByDefault = death_state; }
bool isActiveObject() const { return m_isActiveObject; }
void SetActiveObjectState(bool on);
protected:
bool CreateFromProto(uint32 guidlow,uint32 Entry,uint32 team, const CreatureData *data = NULL);
@ -661,6 +664,7 @@ class MANGOS_DLL_SPEC Creature : public Unit
private:
GridReference<Creature> m_gridRef;
CreatureInfo const* m_creatureInfo; // in heroic mode can different from ObjMgr::GetCreatureTemplate(GetEntry())
bool m_isActiveObject;
};
class AssistDelayEvent : public BasicEvent

View file

@ -83,20 +83,7 @@ DestinationHolder<TRAVELLER>::StartTravel(TRAVELLER &traveller, bool sendMove)
i_fromY = traveller.GetPositionY();
i_fromZ = traveller.GetPositionZ();
float dx = i_destX - i_fromX;
float dy = i_destY - i_fromY;
float dz = i_destZ - i_fromZ;
float dist;
//Should be for Creature Flying and Swimming.
if(traveller.GetTraveller().hasUnitState(UNIT_STAT_IN_FLIGHT))
dist = sqrt((dx*dx) + (dy*dy) + (dz*dz));
else //Walking on the ground
dist = sqrt((dx*dx) + (dy*dy));
float speed = traveller.Speed();
speed *= 0.001f; // speed is in seconds so convert from second to millisecond
i_totalTravelTime = static_cast<uint32>(dist/speed);
i_totalTravelTime = traveller.GetTotalTrevelTimeTo(i_destX,i_destY,i_destZ);
i_timeElapsed = 0;
if(sendMove)
traveller.MoveTo(i_destX, i_destY, i_destZ, i_totalTravelTime);

View file

@ -54,6 +54,8 @@ class DynamicObject : public WorldObject
void Whisper(int32 textId,uint64 receiver) { MonsterWhisper(textId,receiver); }
GridReference<DynamicObject> &GetGridRef() { return m_gridRef; }
bool isActiveObject() const { return false; }
protected:
uint64 m_casterGuid;
uint32 m_spellId;

View file

@ -531,8 +531,8 @@ void GameObject::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
<< m_DBTableGuid << ", "
<< GetEntry() << ", "
<< mapid << ", "
<< (uint32)spawnMask << ", "
<< (uint32)GetPhaseMask() << ","
<< uint32(spawnMask) << "," // cast to prevent save as symbol
<< uint16(GetPhaseMask()) << "," // prevent out of range error
<< GetPositionX() << ", "
<< GetPositionY() << ", "
<< GetPositionZ() << ", "

View file

@ -575,6 +575,8 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject
GameObject* LookupFishingHoleAround(float range);
GridReference<GameObject> &GetGridRef() { return m_gridRef; }
bool isActiveObject() const { return false; }
protected:
uint32 m_charges; // Spell charges for GAMEOBJECT_TYPE_SPELLCASTER (22)
uint32 m_spellId;

View file

@ -151,7 +151,7 @@ void PlayerMenu::SendGossipMenu( uint32 TitleTextId, uint64 npcGUID )
data << uint32(questID);
data << uint32( qItem.m_qIcon );
data << uint32(pQuest && pQuest->GetQuestLevel() ? pQuest->GetQuestLevel() : pSession->GetPlayer()->getLevel());
data << uint32(pSession->GetPlayer()->GetQuestLevel(pQuest));
std::string Title = pQuest->GetTitle();
int loc_idx = pSession->GetSessionDbLocaleIndex();
@ -400,7 +400,7 @@ void PlayerMenu::SendQuestGiverQuestList( QEmote eEmote, const std::string& Titl
data << uint32(questID);
data << uint32(qmi.m_qIcon);
data << uint32(pQuest && pQuest->GetQuestLevel() ? pQuest->GetQuestLevel() : pSession->GetPlayer()->getLevel());
data << uint32(pSession->GetPlayer()->GetQuestLevel(pQuest));
data << title;
}
pSession->SendPacket( &data );
@ -547,7 +547,7 @@ void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest )
data << uint32(pQuest->GetQuestId());
data << uint32(pQuest->GetQuestMethod()); // Accepted values: 0, 1 or 2. 0==IsAutoComplete() (skip objectives/details)
data << uint32(pQuest->GetQuestLevel()); // may be 0
data << uint32(pQuest->GetQuestLevel()); // may be 0, static data, in other cases must be used dynamic level: Player::GetQuestLevel
data << uint32(pQuest->GetZoneOrSort()); // zone or sort to display in quest log
data << uint32(pQuest->GetType());

View file

@ -130,11 +130,17 @@ VisibleNotifier::Notify()
// Now do operations that required done at object visibility change to visible
// target aura duration for caster show only if target exist at caster client
// send data at target visibility change (adding to client)
for(std::set<WorldObject*>::const_iterator vItr = i_visibleNow.begin(); vItr != i_visibleNow.end(); ++vItr)
{
// target aura duration for caster show only if target exist at caster client
if((*vItr)!=&i_player && (*vItr)->isType(TYPEMASK_UNIT))
i_player.SendAurasForTarget((Unit*)(*vItr));
// non finished movements show to player
if((*vItr)->GetTypeId()==TYPEID_UNIT && ((Creature*)(*vItr))->isAlive())
((Creature*)(*vItr))->SendMonsterMoveWithSpeedToCurrentDestination(&i_player);
}
}
void

View file

@ -34,7 +34,7 @@ ActiveState::Update(Map &m, NGridType &grid, GridInfo & info, const uint32 &x, c
info.UpdateTimeTracker(t_diff);
if( info.getTimeTracker().Passed() )
{
if( grid.ActiveObjectsInGrid() == 0 && !m.PlayersNearGrid(x, y) )
if( grid.ActiveObjectsInGrid() == 0 && !m.ActiveObjectsNearGrid(x, y) )
{
ObjectGridStoper stoper(grid);
stoper.StopN();
@ -58,14 +58,14 @@ IdleState::Update(Map &m, NGridType &grid, GridInfo &, const uint32 &x, const ui
void
RemovalState::Update(Map &m, NGridType &grid, GridInfo &info, const uint32 &x, const uint32 &y, const uint32 &t_diff) const
{
if(info.getUnloadFlag())
if(!info.getUnloadLock())
{
info.UpdateTimeTracker(t_diff);
if( info.getTimeTracker().Passed() )
{
if( !m.UnloadGrid(x, y, false) )
{
sLog.outDebug("Grid[%u,%u] for map %u differed unloading due to players nearby", x, y, m.GetId());
sLog.outDebug("Grid[%u,%u] for map %u differed unloading due to players or active objects nearby", x, y, m.GetId());
m.ResetGridExpiry(grid);
}
}

View file

@ -1344,7 +1344,7 @@ uint32 Group::CanJoinBattleGroundQueue(BattleGroundTypeId bgTypeId, BattleGround
if(!reference)
return BG_JOIN_ERR_OFFLINE_MEMBER;
uint32 queue_id = reference->GetBattleGroundQueueIdFromLevel(bgTypeId);
BGQueueIdBasedOnLevel queue_id = reference->GetBattleGroundQueueIdFromLevel(bgTypeId);
uint32 arenaTeamId = reference->GetArenaTeamId(arenaSlot);
uint32 team = reference->GetTeam();

View file

@ -263,7 +263,7 @@ bool Item::Create( uint32 guidlow, uint32 itemid, Player const* owner)
SetUInt32Value(ITEM_FIELD_MAXDURABILITY, itemProto->MaxDurability);
SetUInt32Value(ITEM_FIELD_DURABILITY, itemProto->MaxDurability);
for(int i = 0; i < 5; ++i)
for(int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
SetSpellCharges(i,itemProto->Spells[i].SpellCharges);
SetUInt32Value(ITEM_FIELD_FLAGS, itemProto->Flags);

View file

@ -165,7 +165,7 @@ enum EnchantmentSlot
#define MAX_VISIBLE_ITEM_OFFSET 18 // 18 fields per visible item (creator(2) + enchantments(13) + properties(1) + seed(1) + pad(1))
#define MAX_GEM_SOCKETS 3 // (BONUS_ENCHANTMENT_SLOT-SOCK_ENCHANTMENT_SLOT)
#define MAX_GEM_SOCKETS MAX_ITEM_PROTO_SOCKETS// (BONUS_ENCHANTMENT_SLOT-SOCK_ENCHANTMENT_SLOT) and item proto size, equal value expected
enum EnchantmentOffset
{

View file

@ -355,7 +355,7 @@ void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data )
}
data << pProto->ScalingStatDistribution; // scaling stats distribution
data << pProto->ScalingStatValue; // some kind of flags used to determine stat values column
for(int i = 0; i < 2; ++i)
for(int i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
{
data << pProto->Damage[i].DamageMin;
data << pProto->Damage[i].DamageMax;
@ -375,7 +375,7 @@ void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data )
data << pProto->AmmoType;
data << pProto->RangedModRange;
for(int s = 0; s < 5; s++)
for(int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
{
// send DBC data for cooldowns in same way as it used in Spell::SendSpellCooldown
// use `item_template` or if not set then only use spell cooldowns
@ -429,7 +429,7 @@ void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data )
data << pProto->Map; // Added in 1.12.x & 2.0.1 client branch
data << pProto->BagFamily;
data << pProto->TotemCategory;
for(int s = 0; s < 3; s++)
for(int s = 0; s < MAX_ITEM_PROTO_SOCKETS; ++s)
{
data << pProto->Socket[s].Color;
data << pProto->Socket[s].Content;

View file

@ -491,6 +491,11 @@ struct _Socket
uint32 Content;
};
#define MAX_ITEM_PROTO_DAMAGES 2 // changed in 3.1.0
#define MAX_ITEM_PROTO_SOCKETS 3
#define MAX_ITEM_PROTO_SPELLS 5
#define MAX_ITEM_PROTO_STATS 10
struct ItemPrototype
{
uint32 ItemId;
@ -520,10 +525,10 @@ struct ItemPrototype
int32 Stackable; // 0: not allowed, -1: put in player coin info tab and don't limit stacking (so 1 slot)
uint32 ContainerSlots;
uint32 StatsCount;
_ItemStat ItemStat[10];
_ItemStat ItemStat[MAX_ITEM_PROTO_STATS];
uint32 ScalingStatDistribution; // id from ScalingStatDistribution.dbc
uint32 ScalingStatValue; // mask for selecting column in ScalingStatValues.dbc
_Damage Damage[2];
_Damage Damage[MAX_ITEM_PROTO_DAMAGES];
uint32 Armor;
uint32 HolyRes;
uint32 FireRes;
@ -534,7 +539,7 @@ struct ItemPrototype
uint32 Delay;
uint32 AmmoType;
float RangedModRange;
_Spell Spells[5];
_Spell Spells[MAX_ITEM_PROTO_SPELLS];
uint32 Bonding;
char* Description;
uint32 PageText;
@ -553,7 +558,7 @@ struct ItemPrototype
uint32 Map; // id from Map.dbc
uint32 BagFamily; // id from ItemBagFamily.dbc
uint32 TotemCategory; // id from TotemCategory.dbc
_Socket Socket[3];
_Socket Socket[MAX_ITEM_PROTO_SOCKETS];
uint32 socketBonus; // id from SpellItemEnchantment.dbc
uint32 GemProperties; // id from GemProperties.dbc
uint32 RequiredDisenchantSkill;
@ -634,8 +639,8 @@ struct ItemPrototype
if (Delay == 0)
return 0;
float temp = 0;
for (int i = 0; i < 2; ++i)
temp += Damage[i].DamageMin + Damage[i].DamageMax;
for (int i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
temp+=Damage[i].DamageMin + Damage[i].DamageMax;
return temp*500/Delay;
}

View file

@ -381,7 +381,7 @@ bool ChatHandler::HandleNamegoCommand(const char* args)
}
// all's well, set bg id
// when porting out from the bg, it will be reset to 0
chr->SetBattleGroundId(m_session->GetPlayer()->GetBattleGroundId());
chr->SetBattleGroundId(m_session->GetPlayer()->GetBattleGroundId(), m_session->GetPlayer()->GetBattleGroundTypeId());
// remember current position as entry point for return at bg end teleportation
chr->SetBattleGroundEntryPoint(chr->GetMapId(),chr->GetPositionX(),chr->GetPositionY(),chr->GetPositionZ(),chr->GetOrientation());
}
@ -499,7 +499,7 @@ bool ChatHandler::HandleGonameCommand(const char* args)
}
// all's well, set bg id
// when porting out from the bg, it will be reset to 0
_player->SetBattleGroundId(chr->GetBattleGroundId());
_player->SetBattleGroundId(chr->GetBattleGroundId(), chr->GetBattleGroundTypeId());
// remember current position as entry point for return at bg end teleportation
_player->SetBattleGroundEntryPoint(_player->GetMapId(),_player->GetPositionX(),_player->GetPositionY(),_player->GetPositionZ(),_player->GetOrientation());
}

View file

@ -134,6 +134,7 @@ bool ChatHandler::HandleReloadAllSpellCommand(const char*)
HandleReloadSkillDiscoveryTemplateCommand("a");
HandleReloadSkillExtraItemTemplateCommand("a");
HandleReloadSpellAffectCommand("a");
HandleReloadSpellAreaCommand("a");
HandleReloadSpellChainCommand("a");
HandleReloadSpellElixirCommand("a");
HandleReloadSpellLearnSpellCommand("a");
@ -444,6 +445,14 @@ bool ChatHandler::HandleReloadSpellAffectCommand(const char*)
return true;
}
bool ChatHandler::HandleReloadSpellAreaCommand(const char*)
{
sLog.outString( "Re-Loading SpellArea Data..." );
spellmgr.LoadSpellAreas();
SendGlobalSysMessage("DB table `spell_area` (spell dependences from area/quest/auras state) reloaded.");
return true;
}
bool ChatHandler::HandleReloadSpellChainCommand(const char*)
{
sLog.outString( "Re-Loading Spell Chain Data... " );
@ -3218,18 +3227,36 @@ bool ChatHandler::HandleGuildDeleteCommand(const char* args)
return true;
}
bool ChatHandler::HandleGetDistanceCommand(const char* /*args*/)
bool ChatHandler::HandleGetDistanceCommand(const char* args)
{
Unit* pUnit = getSelectedUnit();
WorldObject* obj;
if(!pUnit)
if (*args)
{
SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
SetSentErrorMessage(true);
return false;
uint64 guid = extractGuidFromLink((char*)args);
if(guid)
obj = (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*m_session->GetPlayer(),guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
if(!obj)
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
return false;
}
}
else
{
obj = getSelectedUnit();
if(!obj)
{
SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
SetSentErrorMessage(true);
return false;
}
}
PSendSysMessage(LANG_DISTANCE, m_session->GetPlayer()->GetDistance(pUnit),m_session->GetPlayer()->GetDistance2d(pUnit));
PSendSysMessage(LANG_DISTANCE, m_session->GetPlayer()->GetDistance(obj),m_session->GetPlayer()->GetDistance2d(obj));
return true;
}
@ -3825,7 +3852,7 @@ bool ChatHandler::HandleLevelUpCommand(const char* args)
return false;
}
name = GetNameLink(chr);
name = chr->GetName();
}
assert(chr || chr_guid);

View file

@ -55,7 +55,7 @@ class LootTemplate::LootGroup // A set of loot def
bool HasQuestDrop() const; // True if group includes at least 1 quest drop entry
bool HasQuestDropForPlayer(Player const * player) const;
// The same for active quests of the player
void Process(Loot& loot, bool rate) const; // Rolls an item from the group (if any) and adds the item to the loot
void Process(Loot& loot) const; // Rolls an item from the group (if any) and adds the item to the loot
float RawTotalChance() const; // Overall chance for the group (without equal chanced items)
float TotalChance() const; // Overall chance for the group
@ -66,7 +66,7 @@ class LootTemplate::LootGroup // A set of loot def
LootStoreItemList ExplicitlyChanced; // Entries with chances defined in DB
LootStoreItemList EqualChanced; // Zero chances - every entry takes the same chance
LootStoreItem const * Roll(bool rate) const; // Rolls an item from the group, returns NULL if all miss their chances
LootStoreItem const * Roll() const; // Rolls an item from the group, returns NULL if all miss their chances
};
//Remove all data and free all memory
@ -789,7 +789,7 @@ void LootTemplate::LootGroup::AddEntry(LootStoreItem& item)
}
// Rolls an item from the group, returns NULL if all miss their chances
LootStoreItem const * LootTemplate::LootGroup::Roll(bool rate) const
LootStoreItem const * LootTemplate::LootGroup::Roll() const
{
if (!ExplicitlyChanced.empty()) // First explicitly chanced entries are checked
{
@ -800,9 +800,7 @@ LootStoreItem const * LootTemplate::LootGroup::Roll(bool rate) const
if(ExplicitlyChanced[i].chance>=100.f)
return &ExplicitlyChanced[i];
ItemPrototype const *pProto = objmgr.GetItemPrototype(ExplicitlyChanced[i].itemid);
float qualityMultiplier = pProto && rate ? sWorld.getRate(qualityToRate[pProto->Quality]) : 1.0f;
Roll -= ExplicitlyChanced[i].chance * qualityMultiplier;
Roll -= ExplicitlyChanced[i].chance;
if (Roll < 0)
return &ExplicitlyChanced[i];
}
@ -838,9 +836,9 @@ bool LootTemplate::LootGroup::HasQuestDropForPlayer(Player const * player) const
}
// Rolls an item from the group (if any takes its chance) and adds the item to the loot
void LootTemplate::LootGroup::Process(Loot& loot, bool rate) const
void LootTemplate::LootGroup::Process(Loot& loot) const
{
LootStoreItem const * item = Roll(rate);
LootStoreItem const * item = Roll();
if (item != NULL)
loot.AddItem(*item);
}
@ -932,7 +930,7 @@ void LootTemplate::Process(Loot& loot, LootStore const& store, bool rate, uint8
if (groupId > Groups.size())
return; // Error message already printed at loading stage
Groups[groupId-1].Process(loot,rate);
Groups[groupId-1].Process(loot);
return;
}
@ -958,7 +956,7 @@ void LootTemplate::Process(Loot& loot, LootStore const& store, bool rate, uint8
// Now processing groups
for (LootGroups::const_iterator i = Groups.begin( ) ; i != Groups.end( ) ; ++i )
i->Process(loot,rate);
i->Process(loot);
}
// True if template includes at least 1 quest drop entry

View file

@ -28,261 +28,261 @@ noinst_LIBRARIES = libmangosgame.a
# libmangossgame library will later be reused by ...
libmangosgame_a_SOURCES = \
AccountMgr.cpp \
AccountMgr.h \
AchievementMgr.h \
AchievementMgr.cpp \
AddonHandler.cpp \
AddonHandler.h \
AggressorAI.cpp \
AggressorAI.h \
AnimalRandomMovementGenerator.h \
ArenaTeam.cpp \
ArenaTeam.h \
ArenaTeamHandler.cpp \
AuctionHouseHandler.cpp \
AuctionHouseMgr.cpp \
AuctionHouseMgr.h \
Bag.cpp \
Bag.h \
BattleGround.cpp \
BattleGroundAA.cpp \
BattleGroundAB.cpp \
BattleGroundAV.cpp \
BattleGroundBE.cpp \
BattleGroundDS.cpp \
BattleGroundEY.cpp \
BattleGroundNA.cpp \
BattleGroundRL.cpp \
BattleGroundRV.cpp \
BattleGroundSA.cpp \
BattleGroundWS.cpp \
BattleGround.h \
BattleGroundAA.h \
BattleGroundAB.h \
BattleGroundAV.h \
BattleGroundBE.h \
BattleGroundDS.h \
BattleGroundEY.h \
BattleGroundNA.h \
BattleGroundRL.h \
BattleGroundRV.h \
BattleGroundSA.h \
BattleGroundWS.h \
BattleGroundHandler.cpp \
BattleGroundMgr.cpp \
BattleGroundMgr.h \
Calendar.cpp \
Calendar.h \
CalendarHandler.cpp \
Cell.h \
CellImpl.h \
Channel.cpp \
Channel.h \
ChannelHandler.cpp \
ChannelMgr.h \
CharacterHandler.cpp \
Chat.cpp \
Chat.h \
ChatHandler.cpp \
CombatHandler.cpp \
ConfusedMovementGenerator.cpp \
ConfusedMovementGenerator.h \
Corpse.cpp \
Corpse.h \
CreatureAI.cpp \
CreatureAI.h \
CreatureAIImpl.h \
CreatureAIRegistry.cpp \
CreatureAIRegistry.h \
CreatureAISelector.cpp \
CreatureAISelector.h \
Creature.cpp \
Creature.h \
debugcmds.cpp \
DestinationHolder.cpp \
DestinationHolder.h \
DestinationHolderImp.h \
DuelHandler.cpp \
DynamicObject.cpp \
DynamicObject.h \
FleeingMovementGenerator.cpp \
FleeingMovementGenerator.h \
Formulas.h \
GameEvent.cpp \
GameEvent.h \
GameObject.cpp \
GameObject.h \
GlobalEvents.cpp \
GlobalEvents.h \
GMTicketHandler.cpp \
GMTicketMgr.cpp \
GMTicketMgr.h \
GossipDef.cpp \
GossipDef.h \
GridDefines.h \
GridNotifiers.cpp \
GridNotifiers.h \
GridNotifiersImpl.h \
GridStates.cpp \
GridStates.h \
Group.cpp \
Group.h \
GroupHandler.cpp \
GuardAI.cpp \
GuardAI.h \
Guild.cpp \
Guild.h \
GuildHandler.cpp \
HomeMovementGenerator.cpp \
HomeMovementGenerator.h \
HostilRefManager.cpp \
HostilRefManager.h \
IdleMovementGenerator.cpp \
IdleMovementGenerator.h \
InstanceData.cpp \
InstanceData.h \
InstanceSaveMgr.cpp \
InstanceSaveMgr.h \
Item.cpp \
Item.h \
ItemEnchantmentMgr.cpp \
ItemEnchantmentMgr.h \
ItemHandler.cpp \
ItemPrototype.h \
Language.h \
Level0.cpp \
Level1.cpp \
Level2.cpp \
Level3.cpp \
LFGHandler.cpp \
LootHandler.cpp \
LootMgr.cpp \
LootMgr.h \
Mail.cpp \
Mail.h \
Map.cpp \
Map.h \
MapInstanced.cpp \
MapInstanced.h \
MapManager.cpp \
MapManager.h \
MapReference.h \
MapRefManager.h \
MiscHandler.cpp \
MotionMaster.cpp \
MotionMaster.h \
MovementGenerator.cpp \
MovementGenerator.h \
MovementGeneratorImpl.h \
MovementHandler.cpp \
NPCHandler.cpp \
NPCHandler.h \
NullCreatureAI.cpp \
NullCreatureAI.h \
ObjectAccessor.cpp \
ObjectAccessor.h \
Object.cpp \
ObjectDefines.h \
ObjectGridLoader.cpp \
ObjectGridLoader.h \
Object.h \
ObjectMgr.cpp \
ObjectMgr.h \
ObjectPosSelector.cpp \
ObjectPosSelector.h \
Opcodes.cpp \
Opcodes.h \
Path.h \
PetAI.cpp \
PetAI.h \
Pet.cpp \
Pet.h \
PetHandler.cpp \
PetitionsHandler.cpp \
Player.cpp \
Player.h \
PlayerDump.cpp \
PlayerDump.h \
PointMovementGenerator.cpp \
PointMovementGenerator.h \
PoolHandler.cpp \
PoolHandler.h \
QueryHandler.cpp \
QuestDef.cpp \
QuestDef.h \
QuestHandler.cpp \
RandomMovementGenerator.cpp \
RandomMovementGenerator.h \
ReactorAI.cpp \
ReactorAI.h \
ScriptCalls.cpp \
ScriptCalls.h \
SharedDefines.h \
SkillHandler.cpp \
SpellAuraDefines.h \
SpellAuras.cpp \
SpellAuras.h \
Spell.cpp \
SpellEffects.cpp \
Spell.h \
SkillDiscovery.cpp \
SkillDiscovery.h \
SkillExtraItems.cpp \
SkillExtraItems.h \
SpellHandler.cpp \
SocialMgr.cpp \
SocialMgr.h \
SpellMgr.cpp \
SpellMgr.h \
StatSystem.cpp \
TargetedMovementGenerator.cpp \
TargetedMovementGenerator.h \
TaxiHandler.cpp \
TemporarySummon.cpp \
TemporarySummon.h \
TotemAI.cpp \
TotemAI.h \
Totem.cpp \
Totem.h \
TradeHandler.cpp \
Transports.cpp \
Transports.h \
ThreatManager.cpp \
ThreatManager.h \
Traveller.h \
Unit.cpp \
Unit.h \
UnitEvents.h \
UpdateData.cpp \
UpdateData.h \
UpdateFields.h \
UpdateMask.h \
Vehicle.cpp \
Vehicle.h \
VoiceChatHandler.cpp \
WaypointManager.cpp \
WaypointManager.h \
WaypointMovementGenerator.cpp \
WaypointMovementGenerator.h \
Weather.cpp \
Weather.h \
World.cpp \
World.h \
WorldLog.cpp \
WorldLog.h \
WorldSession.cpp \
WorldSession.h \
WorldSocket.cpp \
WorldSocket.h \
WorldSocketMgr.cpp \
WorldSocketMgr.h \
FollowerReference.cpp \
FollowerReference.h \
FollowerRefManager.h \
GroupReference.cpp \
GroupReference.h \
GroupRefManager.h
AccountMgr.cpp \
AccountMgr.h \
AchievementMgr.h \
AchievementMgr.cpp \
AddonHandler.cpp \
AddonHandler.h \
AggressorAI.cpp \
AggressorAI.h \
AnimalRandomMovementGenerator.h \
ArenaTeam.cpp \
ArenaTeam.h \
ArenaTeamHandler.cpp \
AuctionHouseHandler.cpp \
AuctionHouseMgr.cpp \
AuctionHouseMgr.h \
Bag.cpp \
Bag.h \
BattleGround.cpp \
BattleGroundAA.cpp \
BattleGroundAB.cpp \
BattleGroundAV.cpp \
BattleGroundBE.cpp \
BattleGroundDS.cpp \
BattleGroundEY.cpp \
BattleGroundNA.cpp \
BattleGroundRL.cpp \
BattleGroundRV.cpp \
BattleGroundSA.cpp \
BattleGroundWS.cpp \
BattleGround.h \
BattleGroundAA.h \
BattleGroundAB.h \
BattleGroundAV.h \
BattleGroundBE.h \
BattleGroundDS.h \
BattleGroundEY.h \
BattleGroundNA.h \
BattleGroundRL.h \
BattleGroundRV.h \
BattleGroundSA.h \
BattleGroundWS.h \
BattleGroundHandler.cpp \
BattleGroundMgr.cpp \
BattleGroundMgr.h \
Calendar.cpp \
Calendar.h \
CalendarHandler.cpp \
Cell.h \
CellImpl.h \
Channel.cpp \
Channel.h \
ChannelHandler.cpp \
ChannelMgr.h \
CharacterHandler.cpp \
Chat.cpp \
Chat.h \
ChatHandler.cpp \
CombatHandler.cpp \
ConfusedMovementGenerator.cpp \
ConfusedMovementGenerator.h \
Corpse.cpp \
Corpse.h \
CreatureAI.cpp \
CreatureAI.h \
CreatureAIImpl.h \
CreatureAIRegistry.cpp \
CreatureAIRegistry.h \
CreatureAISelector.cpp \
CreatureAISelector.h \
Creature.cpp \
Creature.h \
debugcmds.cpp \
DestinationHolder.cpp \
DestinationHolder.h \
DestinationHolderImp.h \
DuelHandler.cpp \
DynamicObject.cpp \
DynamicObject.h \
FleeingMovementGenerator.cpp \
FleeingMovementGenerator.h \
Formulas.h \
GameEvent.cpp \
GameEvent.h \
GameObject.cpp \
GameObject.h \
GlobalEvents.cpp \
GlobalEvents.h \
GMTicketHandler.cpp \
GMTicketMgr.cpp \
GMTicketMgr.h \
GossipDef.cpp \
GossipDef.h \
GridDefines.h \
GridNotifiers.cpp \
GridNotifiers.h \
GridNotifiersImpl.h \
GridStates.cpp \
GridStates.h \
Group.cpp \
Group.h \
GroupHandler.cpp \
GuardAI.cpp \
GuardAI.h \
Guild.cpp \
Guild.h \
GuildHandler.cpp \
HomeMovementGenerator.cpp \
HomeMovementGenerator.h \
HostilRefManager.cpp \
HostilRefManager.h \
IdleMovementGenerator.cpp \
IdleMovementGenerator.h \
InstanceData.cpp \
InstanceData.h \
InstanceSaveMgr.cpp \
InstanceSaveMgr.h \
Item.cpp \
Item.h \
ItemEnchantmentMgr.cpp \
ItemEnchantmentMgr.h \
ItemHandler.cpp \
ItemPrototype.h \
Language.h \
Level0.cpp \
Level1.cpp \
Level2.cpp \
Level3.cpp \
LFGHandler.cpp \
LootHandler.cpp \
LootMgr.cpp \
LootMgr.h \
Mail.cpp \
Mail.h \
Map.cpp \
Map.h \
MapInstanced.cpp \
MapInstanced.h \
MapManager.cpp \
MapManager.h \
MapReference.h \
MapRefManager.h \
MiscHandler.cpp \
MotionMaster.cpp \
MotionMaster.h \
MovementGenerator.cpp \
MovementGenerator.h \
MovementGeneratorImpl.h \
MovementHandler.cpp \
NPCHandler.cpp \
NPCHandler.h \
NullCreatureAI.cpp \
NullCreatureAI.h \
ObjectAccessor.cpp \
ObjectAccessor.h \
Object.cpp \
ObjectDefines.h \
ObjectGridLoader.cpp \
ObjectGridLoader.h \
Object.h \
ObjectMgr.cpp \
ObjectMgr.h \
ObjectPosSelector.cpp \
ObjectPosSelector.h \
Opcodes.cpp \
Opcodes.h \
Path.h \
PetAI.cpp \
PetAI.h \
Pet.cpp \
Pet.h \
PetHandler.cpp \
PetitionsHandler.cpp \
Player.cpp \
Player.h \
PlayerDump.cpp \
PlayerDump.h \
PointMovementGenerator.cpp \
PointMovementGenerator.h \
PoolHandler.cpp \
PoolHandler.h \
QueryHandler.cpp \
QuestDef.cpp \
QuestDef.h \
QuestHandler.cpp \
RandomMovementGenerator.cpp \
RandomMovementGenerator.h \
ReactorAI.cpp \
ReactorAI.h \
ScriptCalls.cpp \
ScriptCalls.h \
SharedDefines.h \
SkillHandler.cpp \
SpellAuraDefines.h \
SpellAuras.cpp \
SpellAuras.h \
Spell.cpp \
SpellEffects.cpp \
Spell.h \
SkillDiscovery.cpp \
SkillDiscovery.h \
SkillExtraItems.cpp \
SkillExtraItems.h \
SpellHandler.cpp \
SocialMgr.cpp \
SocialMgr.h \
SpellMgr.cpp \
SpellMgr.h \
StatSystem.cpp \
TargetedMovementGenerator.cpp \
TargetedMovementGenerator.h \
TaxiHandler.cpp \
TemporarySummon.cpp \
TemporarySummon.h \
TotemAI.cpp \
TotemAI.h \
Totem.cpp \
Totem.h \
TradeHandler.cpp \
Transports.cpp \
Transports.h \
ThreatManager.cpp \
ThreatManager.h \
Traveller.h \
Unit.cpp \
Unit.h \
UnitEvents.h \
UpdateData.cpp \
UpdateData.h \
UpdateFields.h \
UpdateMask.h \
Vehicle.cpp \
Vehicle.h \
VoiceChatHandler.cpp \
WaypointManager.cpp \
WaypointManager.h \
WaypointMovementGenerator.cpp \
WaypointMovementGenerator.h \
Weather.cpp \
Weather.h \
World.cpp \
World.h \
WorldLog.cpp \
WorldLog.h \
WorldSession.cpp \
WorldSession.h \
WorldSocket.cpp \
WorldSocket.h \
WorldSocketMgr.cpp \
WorldSocketMgr.h \
FollowerReference.cpp \
FollowerReference.h \
FollowerRefManager.h \
GroupReference.cpp \
GroupReference.h \
GroupRefManager.h
## Link against shared library
libmangosgame_a_LIBADD = ../shared/libmangosshared.a ../shared/Auth/libmangosauth.a ../shared/Config/libmangosconfig.a ../shared/Database/libmangosdatabase.a ../shared/vmap/libmangosvmaps.a

View file

@ -138,7 +138,6 @@ void Map::LoadMap(uint32 mapid, uint32 instanceid, int x,int y)
// return;
((MapInstanced*)(baseMap))->AddGridMapReference(GridPair(x,y));
baseMap->SetUnloadFlag(GridPair(63-x,63-y), false);
GridMaps[x][y] = baseMap->GridMaps[x][y];
return;
}
@ -209,7 +208,8 @@ void Map::DeleteStateMachine()
Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode)
: i_mapEntry (sMapStore.LookupEntry(id)), i_spawnMode(SpawnMode),
i_id(id), i_InstanceId(InstanceId), m_unloadTimer(0), i_gridExpiry(expiry)
i_id(id), i_InstanceId(InstanceId), m_unloadTimer(0), i_gridExpiry(expiry),
m_activeNonPlayersIter(m_activeNonPlayers.end())
{
for(unsigned int idx=0; idx < MAX_NUMBER_OF_GRIDS; ++idx)
{
@ -360,22 +360,22 @@ Map::EnsureGridCreated(const GridPair &p)
}
void
Map::EnsureGridLoadedForPlayer(const Cell &cell, Player *player, bool add_player)
Map::EnsureGridLoaded(const Cell &cell, Player *player)
{
EnsureGridCreated(GridPair(cell.GridX(), cell.GridY()));
NGridType *grid = getNGrid(cell.GridX(), cell.GridY());
assert(grid != NULL);
if( !isGridObjectDataLoaded(cell.GridX(), cell.GridY()) )
if (!isGridObjectDataLoaded(cell.GridX(), cell.GridY()))
{
if( player != NULL )
if (player)
{
player->SendDelayResponse(MAX_GRID_LOAD_TIME);
DEBUG_LOG("Player %s enter cell[%u,%u] triggers of loading grid[%u,%u] on map %u", player->GetName(), cell.CellX(), cell.CellY(), cell.GridX(), cell.GridY(), i_id);
}
else
{
DEBUG_LOG("Player nearby triggers of loading grid [%u,%u] on map %u", cell.GridX(), cell.GridY(), i_id);
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);
@ -387,11 +387,9 @@ Map::EnsureGridLoadedForPlayer(const Cell &cell, Player *player, bool add_player
ResetGridExpiry(*getNGrid(cell.GridX(), cell.GridY()), 0.1f);
grid->SetGridState(GRID_STATE_ACTIVE);
if( add_player && player != NULL )
(*grid)(cell.CellX(), cell.CellY()).AddWorldObject(player, player->GetGUID());
}
else if( player && add_player )
if (player)
AddToGrid(player,grid,cell);
}
@ -412,7 +410,7 @@ Map::LoadGrid(const Cell& cell, bool no_unload)
setGridObjectDataLoaded(true,cell.GridX(), cell.GridY());
if(no_unload)
getNGrid(cell.GridX(), cell.GridY())->setUnloadFlag(false);
getNGrid(cell.GridX(), cell.GridY())->setUnloadExplicitLock(true);
}
LoadVMap(63-cell.GridX(),63-cell.GridY());
}
@ -426,7 +424,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);
EnsureGridLoadedForPlayer(cell, player, true);
EnsureGridLoaded(cell, player);
player->AddToWorld();
SendInitSelf(player);
@ -454,13 +452,20 @@ Map::Add(T *obj)
}
Cell cell(p);
EnsureGridCreated(GridPair(cell.GridX(), cell.GridY()));
if(obj->isActiveObject())
EnsureGridLoaded(cell);
else
EnsureGridCreated(GridPair(cell.GridX(), cell.GridY()));
NGridType *grid = getNGrid(cell.GridX(), cell.GridY());
assert( grid != NULL );
AddToGrid(obj,grid,cell);
obj->AddToWorld();
if(obj->isActiveObject())
AddToActive(obj);
DEBUG_LOG("Object %u enters grid[%u,%u]", GUID_LOPART(obj->GetGUID()), cell.GridX(), cell.GridY());
UpdateObjectVisibility(obj,cell,p);
@ -616,6 +621,56 @@ void Map::Update(const uint32 &t_diff)
}
}
// non-player active objects
if(!m_activeNonPlayers.empty())
{
for(m_activeNonPlayersIter = m_activeNonPlayers.begin(); m_activeNonPlayersIter != m_activeNonPlayers.end(); )
{
// skip not in world
WorldObject* obj = *m_activeNonPlayersIter;
// step before processing, in this case if Map::Remove remove next object we correctly
// step to next-next, and if we step to end() then newly added objects can wait next update.
++m_activeNonPlayersIter;
if(!obj->IsInWorld())
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)
{
// marked cells are those that have been visited
// don't visit the same cell twice
uint32 cell_id = (y * TOTAL_NUMBER_OF_CELLS_PER_MAP) + x;
if(!isCellMarked(cell_id))
{
markCell(cell_id);
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 !
// 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())
@ -708,6 +763,9 @@ Map::Remove(T *obj, bool remove)
NGridType *grid = getNGrid(cell.GridX(), cell.GridY());
assert( grid != NULL );
if(obj->isActiveObject())
RemoveFromActive(obj);
obj->RemoveFromWorld();
RemoveFromGrid(obj,grid,cell);
@ -749,9 +807,8 @@ Map::PlayerRelocation(Player *player, float x, float y, float z, float orientati
RemoveFromGrid(player, oldGrid,old_cell);
if( !old_cell.DiffGrid(new_cell) )
AddToGrid(player, oldGrid,new_cell);
if( old_cell.DiffGrid(new_cell) )
EnsureGridLoadedForPlayer(new_cell, player, true);
else
EnsureGridLoaded(new_cell, player);
}
// if move then update what player see and who seen
@ -868,8 +925,27 @@ bool Map::CreatureCellRelocation(Creature *c, Cell new_cell)
sLog.outDebug("Creature (GUID: %u Entry: %u) move in same grid[%u,%u]cell[%u,%u].", c->GetGUIDLow(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY());
#endif
}
return true;
}
else // in diff. grids
// in diff. grids but active creature
if(c->isActiveObject())
{
EnsureGridLoaded(new_cell);
#ifdef MANGOS_DEBUG
if((sLog.getLogFilter() & LOG_FILTER_CREATURE_MOVES)==0)
sLog.outDebug("Active creature (GUID: %u Entry: %u) moved from grid[%u,%u]cell[%u,%u] to grid[%u,%u]cell[%u,%u].", c->GetGUIDLow(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
#endif
RemoveFromGrid(c,getNGrid(old_cell.GridX(), old_cell.GridY()),old_cell);
AddToGrid(c,getNGrid(new_cell.GridX(), new_cell.GridY()),new_cell);
return true;
}
// in diff. loaded grid normal creature
if(loaded(GridPair(new_cell.GridX(), new_cell.GridY())))
{
#ifdef MANGOS_DEBUG
@ -882,17 +958,16 @@ bool Map::CreatureCellRelocation(Creature *c, Cell new_cell)
EnsureGridCreated(GridPair(new_cell.GridX(), new_cell.GridY()));
AddToGrid(c,getNGrid(new_cell.GridX(), new_cell.GridY()),new_cell);
}
}
else
{
#ifdef MANGOS_DEBUG
if((sLog.getLogFilter() & LOG_FILTER_CREATURE_MOVES)==0)
sLog.outDebug("Creature (GUID: %u Entry: %u) attempt move from grid[%u,%u]cell[%u,%u] to unloaded grid[%u,%u]cell[%u,%u].", c->GetGUIDLow(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
#endif
return false;
return true;
}
return true;
// fail to move: normal creature attempt move to unloaded grid
#ifdef MANGOS_DEBUG
if((sLog.getLogFilter() & LOG_FILTER_CREATURE_MOVES)==0)
sLog.outDebug("Creature (GUID: %u Entry: %u) attempt move from grid[%u,%u]cell[%u,%u] to unloaded grid[%u,%u]cell[%u,%u].", c->GetGUIDLow(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
#endif
return false;
}
bool Map::CreatureRespawnRelocation(Creature *c)
@ -929,7 +1004,7 @@ bool Map::UnloadGrid(const uint32 &x, const uint32 &y, bool pForce)
assert( grid != NULL);
{
if(!pForce && PlayersNearGrid(x, y) )
if(!pForce && ActiveObjectsNearGrid(x, y) )
return false;
DEBUG_LOG("Unloading grid[%u,%u] for map %u", x,y, i_id);
@ -1513,7 +1588,7 @@ void Map::SendToPlayers(WorldPacket const* data) const
itr->getSource()->GetSession()->SendPacket(data);
}
bool Map::PlayersNearGrid(uint32 x, uint32 y) const
bool Map::ActiveObjectsNearGrid(uint32 x, uint32 y) const
{
CellPair cell_min(x*MAX_NUMBER_OF_CELLS, y*MAX_NUMBER_OF_CELLS);
CellPair cell_max(cell_min.x_coord + MAX_NUMBER_OF_CELLS, cell_min.y_coord+MAX_NUMBER_OF_CELLS);
@ -1532,9 +1607,61 @@ bool Map::PlayersNearGrid(uint32 x, uint32 y) const
return true;
}
for(ActiveNonPlayers::const_iterator iter = m_activeNonPlayers.begin(); iter != m_activeNonPlayers.end(); ++iter)
{
WorldObject* obj = *iter;
CellPair p = MaNGOS::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY());
if( (cell_min.x_coord <= p.x_coord && p.x_coord <= cell_max.x_coord) &&
(cell_min.y_coord <= p.y_coord && p.y_coord <= cell_max.y_coord) )
return true;
}
return false;
}
void Map::AddToActive( Creature* c )
{
AddToActiveHelper(c);
// also not allow unloading spawn grid to prevent creating creature clone at load
if(!c->isPet() && c->GetDBTableGUIDLow())
{
float x,y,z;
c->GetRespawnCoord(x,y,z);
GridPair p = MaNGOS::ComputeGridPair(x, y);
if(getNGrid(p.x_coord, p.y_coord))
getNGrid(p.x_coord, p.y_coord)->incUnloadActiveLock();
else
{
GridPair p2 = MaNGOS::ComputeGridPair(c->GetPositionX(), c->GetPositionY());
sLog.outError("Active creature (GUID: %u Entry: %u) added to grid[%u,%u] but spawn grid[%u,%u] not loaded.",
c->GetGUIDLow(), c->GetEntry(), p.x_coord, p.y_coord, p2.x_coord, p2.y_coord);
}
}
}
void Map::RemoveFromActive( Creature* c )
{
RemoveFromActiveHelper(c);
// also allow unloading spawn grid
if(!c->isPet() && c->GetDBTableGUIDLow())
{
float x,y,z;
c->GetRespawnCoord(x,y,z);
GridPair p = MaNGOS::ComputeGridPair(x, y);
if(getNGrid(p.x_coord, p.y_coord))
getNGrid(p.x_coord, p.y_coord)->decUnloadActiveLock();
else
{
GridPair p2 = MaNGOS::ComputeGridPair(c->GetPositionX(), c->GetPositionY());
sLog.outError("Active creature (GUID: %u Entry: %u) removed from grid[%u,%u] but spawn grid[%u,%u] not loaded.",
c->GetGUIDLow(), c->GetEntry(), p.x_coord, p.y_coord, p2.x_coord, p2.y_coord);
}
}
}
template void Map::Add(Corpse *);
template void Map::Add(Creature *);
template void Map::Add(GameObject *);

View file

@ -164,8 +164,8 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
return( !getNGrid(p.x_coord, p.y_coord) || getNGrid(p.x_coord, p.y_coord)->GetGridState() == GRID_STATE_REMOVAL );
}
bool GetUnloadFlag(const GridPair &p) const { return getNGrid(p.x_coord, p.y_coord)->getUnloadFlag(); }
void SetUnloadFlag(const GridPair &p, bool unload) { getNGrid(p.x_coord, p.y_coord)->setUnloadFlag(unload); }
bool GetUnloadLock(const GridPair &p) const { return getNGrid(p.x_coord, p.y_coord)->getUnloadLock(); }
void SetUnloadLock(const GridPair &p, bool on) { getNGrid(p.x_coord, p.y_coord)->setUnloadExplicitLock(on); }
void LoadGrid(const Cell& cell, bool no_unload = false);
bool UnloadGrid(const uint32 &x, const uint32 &y, bool pForce);
virtual void UnloadAll(bool pForce);
@ -216,8 +216,8 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
// assert print helper
bool CheckGridIntegrity(Creature* c, bool moved) const;
uint32 GetInstanceId() { return i_InstanceId; }
uint8 GetSpawnMode() { return (i_spawnMode); }
uint32 GetInstanceId() const { return i_InstanceId; }
uint8 GetSpawnMode() const { return (i_spawnMode); }
virtual bool CanEnter(Player* /*player*/) { return true; }
const char* GetMapName() const;
@ -256,12 +256,24 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
bool HavePlayers() const { return !m_mapRefManager.isEmpty(); }
uint32 GetPlayersCountExceptGMs() const;
bool PlayersNearGrid(uint32 x,uint32 y) const;
bool ActiveObjectsNearGrid(uint32 x,uint32 y) const;
void SendToPlayers(WorldPacket const* data) const;
typedef MapRefManager PlayerList;
PlayerList const& GetPlayers() const { return m_mapRefManager; }
// must called with AddToWorld
template<class T>
void AddToActive(T* obj) { AddToActiveHelper(obj); }
void AddToActive(Creature* obj);
// must called with RemoveFromWorld
template<class T>
void RemoveFromActive(T* obj) { RemoveFromActiveHelper(obj); }
void RemoveFromActive(Creature* obj);
private:
void LoadVMap(int pX, int pY);
void LoadMap(uint32 mapid, uint32 instanceid, int x,int y);
@ -283,7 +295,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
CreatureMoveList i_creaturesToMove;
bool loaded(const GridPair &) const;
void EnsureGridLoadedForPlayer(const Cell&, Player*, bool add_player);
void EnsureGridLoaded(const Cell&, Player* player = NULL);
void EnsureGridCreated(const GridPair &);
void buildNGridLinkage(NGridType* pNGridType) { pNGridType->link(this); }
@ -302,6 +314,8 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
void setNGrid(NGridType* grid, uint32 x, uint32 y);
protected:
void SetUnloadReferenceLock(const GridPair &p, bool on) { getNGrid(p.x_coord, p.y_coord)->setUnloadReferenceLock(on); }
typedef MaNGOS::ObjectLevelLockable<Map, ZThread::Mutex>::Lock Guard;
MapEntry const* i_mapEntry;
@ -312,6 +326,10 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
MapRefManager m_mapRefManager;
MapRefManager::iterator m_mapRefIter;
typedef std::set<WorldObject*> ActiveNonPlayers;
ActiveNonPlayers m_activeNonPlayers;
ActiveNonPlayers::iterator m_activeNonPlayersIter;
private:
typedef GridReadGuard ReadGuard;
typedef GridWriteGuard WriteGuard;
@ -336,6 +354,27 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
template<class T>
void DeleteFromWorld(T*);
template<class T>
void AddToActiveHelper(T* obj)
{
m_activeNonPlayers.insert(obj);
}
template<class T>
void RemoveFromActiveHelper(T* obj)
{
// Map::Update for active object in proccess
if(m_activeNonPlayersIter != m_activeNonPlayers.end())
{
ActiveNonPlayers::iterator itr = m_activeNonPlayers.find(obj);
if(itr==m_activeNonPlayersIter)
++m_activeNonPlayersIter;
m_activeNonPlayers.erase(itr);
}
else
m_activeNonPlayers.erase(obj);
}
};
enum InstanceResetMethod
@ -408,7 +447,7 @@ Map::Visit(const CellLock<LOCK_TYPE> &cell, TypeContainerVisitor<T, CONTAINER> &
if( !cell->NoCreate() || loaded(GridPair(x,y)) )
{
EnsureGridLoadedForPlayer(cell, NULL, false);
EnsureGridLoaded(cell);
//LOCK_TYPE guard(i_info[x][y]->i_lock);
getNGrid(x, y)->Visit(cell_x, cell_y, visitor);
}

View file

@ -42,11 +42,18 @@ class MANGOS_DLL_DECL MapInstanced : public Map
Map* FindMap(uint32 InstanceId) { return _FindMap(InstanceId); }
void DestroyInstance(uint32 InstanceId);
void DestroyInstance(InstancedMaps::iterator &itr);
void AddGridMapReference(const GridPair &p) { ++GridMapReference[p.x_coord][p.y_coord]; }
void AddGridMapReference(const GridPair &p)
{
++GridMapReference[p.x_coord][p.y_coord];
SetUnloadReferenceLock(GridPair(63-p.x_coord, 63-p.y_coord), true);
}
void RemoveGridMapReference(const GridPair &p)
{
--GridMapReference[p.x_coord][p.y_coord];
if (!GridMapReference[p.x_coord][p.y_coord]) { SetUnloadFlag(GridPair(63-p.x_coord,63-p.y_coord), true); }
if (!GridMapReference[p.x_coord][p.y_coord])
SetUnloadReferenceLock(GridPair(63-p.x_coord, 63-p.y_coord), false);
}
InstancedMaps &GetInstancedMaps() { return m_InstancedMaps; }

View file

@ -87,7 +87,6 @@ void WorldSession::HandleMoveWorldportAckOpcode()
return;
}
//this will set player's team ... so IT MUST BE CALLED BEFORE SendInitialPacketsAfterAddToMap()
// battleground state prepare (in case join to BG), at relogin/tele player not invited
// only add to bg group and object, if the player was invited (else he entered through command)
if(_player->InBattleGround())
@ -95,7 +94,7 @@ void WorldSession::HandleMoveWorldportAckOpcode()
// cleanup seting if outdated
if(!mEntry->IsBattleGroundOrArena())
{
_player->SetBattleGroundId(0); // We're not in BG.
_player->SetBattleGroundId(0, BATTLEGROUND_TYPE_NONE); // We're not in BG.
// reset destination bg team
_player->SetBGTeam(0);
}

View file

@ -125,6 +125,9 @@ void LoadHelper(CellGuidSet const& guid_set, CellPair &cell, GridRefManager<T> &
addUnitState(obj,cell);
obj->AddToWorld();
if(obj->isActiveObject())
map->AddToActive(obj);
++count;
}
@ -150,6 +153,9 @@ void LoadHelper(CellCorpseSet const& cell_corpses, CellPair &cell, CorpseMapType
addUnitState(obj,cell);
obj->AddToWorld();
if(obj->isActiveObject())
map->AddToActive(obj);
++count;
}
}

View file

@ -932,6 +932,13 @@ void ObjectMgr::LoadCreatures()
data.curhealth = cInfo->minhealth;
}
if(cInfo->flags_extra & CREATURE_FLAG_EXTRA_INSTANCE_BIND)
{
MapEntry const* map = sMapStore.LookupEntry(data.mapid);
if(!map || !map->IsDungeon())
sLog.outErrorDb("Table `creature` have creature (GUID: %u Entry: %u) with `creature_template`.`flags_extra` including CREATURE_FLAG_EXTRA_INSTANCE_BIND but creature are not in instance.",guid,data.id);
}
if(data.curmana < cInfo->minmana)
{
sLog.outErrorDb("Table `creature` have creature (GUID: %u Entry: %u) with low current mana (%u), `creature_template`.`minmana`=%u.",guid,data.id,data.curmana, cInfo->minmana );
@ -1470,7 +1477,7 @@ void ObjectMgr::LoadItemPrototypes()
bool req = proto->InventoryType!=INVTYPE_NON_EQUIP || proto->PageText;
if(!req)
{
for (int j = 0; j < 5; ++j)
for (int j = 0; j < MAX_ITEM_PROTO_SPELLS; ++j)
{
if(proto->Spells[j].SpellId)
{
@ -1535,7 +1542,13 @@ void ObjectMgr::LoadItemPrototypes()
const_cast<ItemPrototype*>(proto)->Stackable = 255;
}
for (int j = 0; j < 10; j++)
if(proto->StatsCount > MAX_ITEM_PROTO_STATS)
{
sLog.outErrorDb("Item (Entry: %u) has too large value in statscount (%u), replace by hardcoded limit (%u).",i,proto->StatsCount,MAX_ITEM_PROTO_STATS);
const_cast<ItemPrototype*>(proto)->StatsCount = MAX_ITEM_PROTO_STATS;
}
for (int j = 0; j < MAX_ITEM_PROTO_STATS; ++j)
{
// for ItemStatValue != 0
if(proto->ItemStat[j].ItemStatValue && proto->ItemStat[j].ItemStatType >= MAX_ITEM_MOD)
@ -1545,7 +1558,7 @@ void ObjectMgr::LoadItemPrototypes()
}
}
for (int j = 0; j < 2; j++)
for (int j = 0; j < MAX_ITEM_PROTO_DAMAGES; ++j)
{
if(proto->Damage[j].DamageType >= MAX_SPELL_SCHOOL)
{
@ -1602,7 +1615,7 @@ void ObjectMgr::LoadItemPrototypes()
}
// spell_3*,spell_4*,spell_5* is empty
for (int j = 2; j < 5; j++)
for (int j = 2; j < MAX_ITEM_PROTO_SPELLS; ++j)
{
if(proto->Spells[j].SpellTrigger != ITEM_SPELLTRIGGER_ON_USE)
{
@ -1620,7 +1633,7 @@ void ObjectMgr::LoadItemPrototypes()
// normal spell list
else
{
for (int j = 0; j < 5; j++)
for (int j = 0; j < MAX_ITEM_PROTO_SPELLS; ++j)
{
if(proto->Spells[j].SpellTrigger >= MAX_ITEM_SPELLTRIGGER || proto->Spells[j].SpellTrigger == ITEM_SPELLTRIGGER_LEARN_SPELL_ID)
{
@ -1689,7 +1702,7 @@ void ObjectMgr::LoadItemPrototypes()
if(proto->TotemCategory && !sTotemCategoryStore.LookupEntry(proto->TotemCategory))
sLog.outErrorDb("Item (Entry: %u) has wrong TotemCategory (%u)",i,proto->TotemCategory);
for (int j = 0; j < 3; j++)
for (int j = 0; j < MAX_ITEM_PROTO_SOCKETS; j++)
{
if(proto->Socket[j].Color && (proto->Socket[j].Color & SOCKET_COLOR_ALL) != proto->Socket[j].Color)
{

View file

@ -366,6 +366,7 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this)
m_DetectInvTimer = 1000;
m_bgBattleGroundID = 0;
m_bgTypeID = BATTLEGROUND_TYPE_NONE;
for (int j=0; j < PLAYER_MAX_BATTLEGROUND_QUEUES; j++)
{
m_bgBattleGroundQueueID[j].bgQueueTypeId = BATTLEGROUND_QUEUE_NONE;
@ -3857,12 +3858,12 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)
SetPower(POWER_ENERGY, uint32(GetMaxPower(POWER_ENERGY)*restore_percent));
}
// trigger update zone for alive state zone updates
UpdateZone(GetZoneId());
// update visibility
ObjectAccessor::UpdateVisibilityForPlayer(this);
// some items limited to specific map
DestroyZoneLimitedItem( true, GetZoneId());
if(!applySickness)
return;
@ -4231,7 +4232,7 @@ void Player::RepopAtGraveyard()
WorldSafeLocsEntry const *ClosestGrave = NULL;
// Special handle for battleground maps
BattleGround *bg = sBattleGroundMgr.GetBattleGround(GetBattleGroundId());
BattleGround *bg = sBattleGroundMgr.GetBattleGround(GetBattleGroundId(), m_bgTypeID);
if(bg && (bg->GetTypeID() == BATTLEGROUND_AB || bg->GetTypeID() == BATTLEGROUND_EY))
ClosestGrave = bg->GetClosestGraveYard(GetPositionX(), GetPositionY(), GetPositionZ(), GetTeam());
@ -6004,7 +6005,7 @@ void Player::RewardReputation(Quest const *pQuest)
{
if(pQuest->RewRepFaction[i] && pQuest->RewRepValue[i] )
{
int32 rep = CalculateReputationGain(pQuest->GetQuestLevel(),pQuest->RewRepValue[i],true);
int32 rep = CalculateReputationGain(GetQuestLevel(pQuest),pQuest->RewRepValue[i],true);
FactionEntry const* factionEntry = sFactionStore.LookupEntry(pQuest->RewRepFaction[i]);
if(factionEntry)
ModifyFactionReputation(factionEntry, rep);
@ -6566,7 +6567,7 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl
if(slot >= INVENTORY_SLOT_BAG_END || !proto)
return;
for (int i = 0; i < 10; i++)
for (int i = 0; i < MAX_ITEM_PROTO_STATS; ++i)
{
uint32 statType = 0;
int32 val = 0;
@ -6899,7 +6900,7 @@ void Player::ApplyItemEquipSpell(Item *item, bool apply, bool form_change)
if(!proto)
return;
for (int i = 0; i < 5; i++)
for (int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
{
_Spell const& spellData = proto->Spells[i];
@ -7012,7 +7013,7 @@ void Player::CastItemCombatSpell(Item *item,Unit* Target, WeaponAttackType attTy
if (!Target || Target == this )
return;
for (int i = 0; i < 5; i++)
for (int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
{
_Spell const& spellData = proto->Spells[i];
@ -7110,7 +7111,7 @@ void Player::CastItemUseSpell(Item *item,SpellCastTargets const& targets,uint8 c
int count = 0;
// item spells casted at use
for(int i = 0; i < 5; ++i)
for(int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
{
_Spell const& spellData = proto->Spells[i];
@ -12621,6 +12622,19 @@ void Player::AddQuest( Quest const *pQuest, Object *questGiver )
if(questGiver && pQuest->GetQuestStartScript()!=0)
sWorld.ScriptsStart(sQuestStartScripts, pQuest->GetQuestStartScript(), questGiver, this);
// Some spells applied at quest activation
SpellAreaForQuestMapBounds saBounds = spellmgr.GetSpellAreaForQuestMapBounds(quest_id,true);
if(saBounds.first != saBounds.second)
{
uint32 zone = GetZoneId();
uint32 area = GetAreaId();
for(SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
if(itr->second->autocast && itr->second->IsFitToRequirements(this,zone,area))
if( !HasAura(itr->second->spellId,0) )
CastSpell(this,itr->second->spellId,true);
}
UpdateForQuestsGO();
}
@ -12811,6 +12825,34 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver
if (q_status.uState != QUEST_NEW) q_status.uState = QUEST_CHANGED;
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT);
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST);
uint32 zone = 0;
uint32 area = 0;
// remove auras from spells with quest reward state limitations
SpellAreaForQuestMapBounds saEndBounds = spellmgr.GetSpellAreaForQuestEndMapBounds(quest_id);
if(saEndBounds.first != saEndBounds.second)
{
uint32 zone = GetZoneId();
uint32 area = GetAreaId();
for(SpellAreaForAreaMap::const_iterator itr = saEndBounds.first; itr != saEndBounds.second; ++itr)
if(!itr->second->IsFitToRequirements(this,zone,area))
RemoveAurasDueToSpell(itr->second->spellId);
}
// Some spells applied at quest reward
SpellAreaForQuestMapBounds saBounds = spellmgr.GetSpellAreaForQuestMapBounds(quest_id,false);
if(saBounds.first != saBounds.second)
{
if(!zone) zone = GetZoneId();
if(!area) area = GetAreaId();
for(SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
if(itr->second->autocast && itr->second->IsFitToRequirements(this,zone,area))
if( !HasAura(itr->second->spellId,0) )
CastSpell(this,itr->second->spellId,true);
}
}
void Player::FailQuest( uint32 quest_id )
@ -14179,14 +14221,14 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
if(!mapEntry || mapEntry->Instanceable() || !MapManager::IsValidMapCoord(m_bgEntryPoint))
SetBattleGroundEntryPoint(m_homebindMapId,m_homebindX,m_homebindY,m_homebindZ,0.0f);
BattleGround *currentBg = sBattleGroundMgr.GetBattleGround(bgid);
BattleGround *currentBg = sBattleGroundMgr.GetBattleGround(bgid, BATTLEGROUND_TYPE_NONE);
if(currentBg && currentBg->IsPlayerInBattleGround(GetGUID()))
{
BattleGroundQueueTypeId bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(currentBg->GetTypeID(), currentBg->GetArenaType());
uint32 queueSlot = AddBattleGroundQueueId(bgQueueTypeId);
SetBattleGroundId(currentBg->GetInstanceID());
SetBattleGroundId(currentBg->GetInstanceID(), currentBg->GetTypeID());
SetBGTeam(bgteam);
//join player to battleground group
@ -15560,8 +15602,7 @@ void Player::SaveToDB()
uint32 tmp_displayid = GetDisplayId();
// Set player sit state to standing on save, also stealth and shifted form
SetStandState(UNIT_STAND_STATE_STAND); // stand state
RemoveStandFlags(UNIT_STAND_FLAGS_ALL); // stand flags?
SetByteValue(UNIT_FIELD_BYTES_1, 0, UNIT_STAND_STATE_STAND);
SetByteValue(UNIT_FIELD_BYTES_2, 3, 0); // shapeshift
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
SetDisplayId(GetNativeDisplayId());
@ -18169,7 +18210,7 @@ void Player::SendInstanceResetWarning(uint32 mapid, uint32 time)
void Player::ApplyEquipCooldown( Item * pItem )
{
for(int i = 0; i <5; ++i)
for(int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
{
_Spell const& spellData = pItem->GetProto()->Spells[i];
@ -18419,7 +18460,7 @@ BattleGround* Player::GetBattleGround() const
if(GetBattleGroundId()==0)
return NULL;
return sBattleGroundMgr.GetBattleGround(GetBattleGroundId());
return sBattleGroundMgr.GetBattleGround(GetBattleGroundId(), m_bgTypeID);
}
bool Player::InArena() const
@ -18444,34 +18485,20 @@ bool Player::GetBGAccessByLevel(BattleGroundTypeId bgTypeId) const
return true;
}
uint32 Player::GetMinLevelForBattleGroundQueueId(uint32 queue_id, BattleGroundTypeId bgTypeId)
BGQueueIdBasedOnLevel Player::GetBattleGroundQueueIdFromLevel(BattleGroundTypeId bgTypeId) const
{
BattleGround *bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId);
assert(bg);
return (queue_id*10)+bg->GetMinLevel();
}
//returned to hardcoded version of this function, because there is no way to code it dynamic
uint32 level = getLevel();
if( bgTypeId == BATTLEGROUND_AV )
level--;
uint32 Player::GetMaxLevelForBattleGroundQueueId(uint32 queue_id, BattleGroundTypeId bgTypeId)
{
return GetMinLevelForBattleGroundQueueId(queue_id, bgTypeId)+10;
}
uint32 Player::GetBattleGroundQueueIdFromLevel(BattleGroundTypeId bgTypeId) const
{
BattleGround *bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId);
assert(bg);
if(getLevel()<bg->GetMinLevel())
uint32 queue_id = (level / 10) - 1; // for ranges 0 - 19, 20 - 29, 30 - 39, 40 - 49, 50 - 59, 60 - 69, 70 -79, 80
if( queue_id >= MAX_BATTLEGROUND_QUEUES )
{
sLog.outError("getting queue_id for player who doesn't meet the requirements - this shouldn't happen");
return 0;
sLog.outError("BattleGround: too high queue_id %u this shouldn't happen", queue_id);
return QUEUE_ID_MAX_LEVEL_80;
}
uint32 queue_id = (getLevel() - bg->GetMinLevel()) / 10;
if(queue_id>MAX_BATTLEGROUND_QUEUES)
{
sLog.outError("to high queue_id %u this shouldn't happen",queue_id);
return 0;
}
return queue_id;
return BGQueueIdBasedOnLevel(queue_id);
}
float Player::GetReputationPriceDiscount( Creature const* pCreature ) const
@ -18966,26 +18993,12 @@ void Player::UpdateZoneDependentAuras( uint32 newZone )
RemoveSpellsCausingAura(SPELL_AURA_FLY);
}
// Some spells applied at enter into zone (with subzones)
switch(newZone)
{
case 2367: // Old Hillsbrad Foothills
{
// Human Illusion
// NOTE: these are removed by RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CHANGE_MAP);
uint32 spellid = 0;
// all horde races
if( GetTeam() == HORDE )
spellid = getGender() == GENDER_FEMALE ? 35481 : 35480;
// and some alliance races
else if( getRace() == RACE_NIGHTELF || getRace() == RACE_DRAENEI )
spellid = getGender() == GENDER_FEMALE ? 35483 : 35482;
if(spellid && !HasAura(spellid,0) )
CastSpell(this,spellid,true);
break;
}
}
// Some spells applied at enter into zone (with subzones), aura removed in UpdateAreaDependentAuras that called always at zone->area update
SpellAreaForAreaMapBounds saBounds = spellmgr.GetSpellAreaForAreaMapBounds(newZone);
for(SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
if(itr->second->autocast && itr->second->IsFitToRequirements(this,newZone,0))
if( !HasAura(itr->second->spellId,0) )
CastSpell(this,itr->second->spellId,true);
}
void Player::UpdateAreaDependentAuras( uint32 newArea )
@ -18994,42 +19007,18 @@ void Player::UpdateAreaDependentAuras( uint32 newArea )
for(AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end();)
{
// use m_zoneUpdateId for speed: UpdateArea called from UpdateZone or instead UpdateZone in both cases m_zoneUpdateId up-to-date
if(GetSpellAllowedInLocationError(iter->second->GetSpellProto(),GetMapId(),m_zoneUpdateId,newArea,GetBattleGroundId())!=0)
if(spellmgr.GetSpellAllowedInLocationError(iter->second->GetSpellProto(),GetMapId(),m_zoneUpdateId,newArea,this)!=0)
RemoveAura(iter);
else
++iter;
}
// some auras applied at subzone enter
switch(newArea)
{
// Dragonmaw Illusion
case 3759: // Netherwing Ledge
case 3939: // Dragonmaw Fortress
case 3966: // Dragonmaw Base Camp
if( GetDummyAura(40214) )
{
if( !HasAura(40216,0) )
CastSpell(this,40216,true);
if( !HasAura(42016,0) )
CastSpell(this,42016,true);
}
break;
// Dominion Over Acherus
case 4281: // Acherus: The Ebon Hold
case 4342: // Acherus: The Ebon Hold
if( HasSpell(51721) )
if( !HasAura(51721,0) )
CastSpell(this,51721,true);
break;
// Mist of the Kvaldir
case 4028: //Riplash Strand
case 4029: //Riplash Ruins
case 4106: //Garrosh's Landing
case 4031: //Pal'ea
CastSpell(this,54119,true);
break;
}
SpellAreaForAreaMapBounds saBounds = spellmgr.GetSpellAreaForAreaMapBounds(newArea);
for(SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
if(itr->second->autocast && itr->second->IsFitToRequirements(this,m_zoneUpdateId,newArea))
if( !HasAura(itr->second->spellId,0) )
CastSpell(this,itr->second->spellId,true);
}
uint32 Player::GetCorpseReclaimDelay(bool pvp) const

View file

@ -1199,6 +1199,8 @@ class MANGOS_DLL_SPEC Player : public Unit
/*** QUEST SYSTEM ***/
/*********************************************************/
uint32 GetQuestLevel( Quest const* pQuest ) const { return pQuest && pQuest->GetQuestLevel() ? pQuest->GetQuestLevel() : getLevel(); }
void PrepareQuestMenu( uint64 guid );
void SendPreparedQuest( uint64 guid );
bool IsActiveQuest( uint32 quest_id ) const;
@ -1865,14 +1867,14 @@ class MANGOS_DLL_SPEC Player : public Unit
/*** BATTLEGROUND SYSTEM ***/
/*********************************************************/
bool InBattleGround() const { return m_bgBattleGroundID != 0; }
uint32 GetBattleGroundId() const { return m_bgBattleGroundID; }
bool InBattleGround() const { return m_bgBattleGroundID != 0; }
bool InArena() const;
uint32 GetBattleGroundId() const { return m_bgBattleGroundID; }
BattleGroundTypeId GetBattleGroundTypeId() const { return m_bgTypeID; }
BattleGround* GetBattleGround() const;
bool InArena() const;
static uint32 GetMinLevelForBattleGroundQueueId(uint32 queue_id, BattleGroundTypeId bgTypeId);
static uint32 GetMaxLevelForBattleGroundQueueId(uint32 queue_id, BattleGroundTypeId bgTypeId);
uint32 GetBattleGroundQueueIdFromLevel(BattleGroundTypeId bgTypeId) const;
BGQueueIdBasedOnLevel GetBattleGroundQueueIdFromLevel(BattleGroundTypeId bgTypeId) const;
bool InBattleGroundQueue() const
{
@ -1902,7 +1904,11 @@ class MANGOS_DLL_SPEC Player : public Unit
return GetBattleGroundQueueIndex(bgQueueTypeId) < PLAYER_MAX_BATTLEGROUND_QUEUES;
}
void SetBattleGroundId(uint32 val) { m_bgBattleGroundID = val; }
void SetBattleGroundId(uint32 val, BattleGroundTypeId bgTypeId)
{
m_bgBattleGroundID = val;
m_bgTypeID = bgTypeId;
}
uint32 AddBattleGroundQueueId(BattleGroundQueueTypeId val)
{
for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++)
@ -2142,6 +2148,7 @@ class MANGOS_DLL_SPEC Player : public Unit
bool HasTitle(CharTitlesEntry const* title) { return HasTitle(title->bit_index); }
void SetTitle(CharTitlesEntry const* title);
bool isActiveObject() const { return true; }
protected:
/*********************************************************/
@ -2150,6 +2157,7 @@ class MANGOS_DLL_SPEC Player : public Unit
/* this variable is set to bg->m_InstanceID, when player is teleported to BG - (it is battleground's GUID)*/
uint32 m_bgBattleGroundID;
BattleGroundTypeId m_bgTypeID;
/*
this is an array of BG queues (BgTypeIDs) in which is player
*/

View file

@ -570,7 +570,7 @@ uint32 WorldSession::getDialogStatus(Player *pPlayer, Object* questgiver, uint32
{
if ( pQuest->IsAutoComplete() || (pQuest->IsRepeatable() && pPlayer->getQuestStatusMap()[quest_id].m_rewarded))
result2 = DIALOG_STATUS_REWARD_REP;
else if (pPlayer->getLevel() <= pQuest->GetQuestLevel() + sWorld.getConfig(CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF) )
else if (pPlayer->getLevel() <= pPlayer->GetQuestLevel(pQuest) + sWorld.getConfig(CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF) )
{
if (pQuest->HasFlag(QUEST_FLAGS_DAILY))
result2 = DIALOG_STATUS_AVAILABLE_REP;

View file

@ -2218,6 +2218,7 @@ enum BanReturn
// indexes of BattlemasterList.dbc
enum BattleGroundTypeId
{
BATTLEGROUND_TYPE_NONE = 0,
BATTLEGROUND_AV = 1,
BATTLEGROUND_WS = 2,
BATTLEGROUND_AB = 3,

View file

@ -321,7 +321,7 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi
if((m_caster->getClassMask() & CLASSMASK_WAND_USERS) != 0 && m_caster->GetTypeId()==TYPEID_PLAYER)
{
if(Item* pItem = ((Player*)m_caster)->GetWeaponForAttack(RANGED_ATTACK))
m_spellSchoolMask = SpellSchoolMask(1 << pItem->GetProto()->Damage->DamageType);
m_spellSchoolMask = SpellSchoolMask(1 << pItem->GetProto()->Damage[0].DamageType);
}
}
// Set health leech amount to zero
@ -2542,7 +2542,7 @@ void Spell::SendSpellCooldown()
ItemPrototype const* proto = m_CastItem->GetProto();
if(proto)
{
for(int idx = 0; idx < 5; ++idx)
for(int idx = 0; idx < MAX_ITEM_PROTO_SPELLS; ++idx)
{
if(proto->Spells[idx].SpellId == m_spellInfo->Id)
{
@ -3324,7 +3324,7 @@ void Spell::TakeCastItem()
bool expendable = false;
bool withoutCharges = false;
for (int i = 0; i<5; i++)
for (int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
{
if (proto->Spells[i].SpellId)
{
@ -3824,8 +3824,8 @@ uint8 Spell::CanCast(bool strict)
return SPELL_FAILED_NOT_IN_ARENA;
// zone check
if (uint8 res= GetSpellAllowedInLocationError(m_spellInfo,m_caster->GetMapId(),m_caster->GetZoneId(),m_caster->GetAreaId(),
m_caster->GetTypeId()==TYPEID_PLAYER ? ((Player*)m_caster)->GetBattleGroundId() : 0))
if (uint8 res= spellmgr.GetSpellAllowedInLocationError(m_spellInfo,m_caster->GetMapId(),m_caster->GetZoneId(),m_caster->GetAreaId(),
m_caster->GetTypeId()==TYPEID_PLAYER ? ((Player*)m_caster) : NULL))
return res;
// not let players cast spells at mount (and let do it to creatures)
@ -4998,7 +4998,7 @@ uint8 Spell::CheckItems()
ItemPrototype const *proto = m_CastItem->GetProto();
if(!proto)
return SPELL_FAILED_ITEM_NOT_READY;
for(int s=0;s<5;s++)
for(int s=0; s < MAX_ITEM_PROTO_SPELLS; ++s)
{
// CastItem will be used up and does not count as reagent
int32 charges = m_CastItem->GetSpellCharges(s);

View file

@ -2067,6 +2067,22 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
m_modifier.m_amount = caster->SpellHealingBonus(m_target, GetSpellProto(), m_modifier.m_amount, SPELL_DIRECT_DAMAGE);
return;
}
// some auras applied at aura apply
if(GetEffIndex()==0 && m_target->GetTypeId()==TYPEID_PLAYER)
{
SpellAreaForAreaMapBounds saBounds = spellmgr.GetSpellAreaForAuraMapBounds(GetId());
if(saBounds.first != saBounds.second)
{
uint32 zone = m_target->GetZoneId();
uint32 area = m_target->GetAreaId();
for(SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
if(itr->second->autocast && itr->second->IsFitToRequirements((Player*)m_target,zone,area))
if( !m_target->HasAura(itr->second->spellId,0) )
m_target->CastSpell(m_target,itr->second->spellId,true);
}
}
}
// AT REMOVE
else
@ -2156,6 +2172,21 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
}
}
// some auras remove at aura remove
if(GetEffIndex()==0 && m_target->GetTypeId()==TYPEID_PLAYER)
{
SpellAreaForAreaMapBounds saBounds = spellmgr.GetSpellAreaForAuraMapBounds(GetId());
if(saBounds.first != saBounds.second)
{
uint32 zone = m_target->GetZoneId();
uint32 area = m_target->GetAreaId();
for(SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
if(!itr->second->IsFitToRequirements((Player*)m_target,zone,area))
m_target->RemoveAurasDueToSpell(itr->second->spellId);
}
}
}
// AT APPLY & REMOVE

View file

@ -94,7 +94,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
if (pUser->isInCombat())
{
for(int i = 0; i < 5; ++i)
for(int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
{
if (SpellEntry const *spellInfo = sSpellStore.LookupEntry(proto->Spells[i].SpellId))
{

View file

@ -2348,7 +2348,193 @@ bool SpellMgr::IsSpellValid(SpellEntry const* spellInfo, Player* pl, bool msg)
return true;
}
uint8 GetSpellAllowedInLocationError(SpellEntry const *spellInfo,uint32 map_id,uint32 zone_id,uint32 area_id, uint32 bgInstanceId)
void SpellMgr::LoadSpellAreas()
{
mSpellAreaMap.clear(); // need for reload case
mSpellAreaForQuestMap.clear();
mSpellAreaForActiveQuestMap.clear();
mSpellAreaForQuestEndMap.clear();
mSpellAreaForAuraMap.clear();
uint32 count = 0;
// 0 1 2 3 4 5 6 7 8
QueryResult *result = WorldDatabase.Query("SELECT spell, area, quest_start, quest_start_active, quest_end, aura_spell, racemask, gender, autocast FROM spell_area");
if( !result )
{
barGoLink bar( 1 );
bar.step();
sLog.outString();
sLog.outString( ">> Loaded %u spell area requirements", count );
return;
}
barGoLink bar( result->GetRowCount() );
do
{
Field *fields = result->Fetch();
bar.step();
uint32 spell = fields[0].GetUInt32();
SpellArea spellArea;
spellArea.spellId = spell;
spellArea.areaId = fields[1].GetUInt32();
spellArea.questStart = fields[2].GetUInt32();
spellArea.questStartCanActive = fields[3].GetBool();
spellArea.questEnd = fields[4].GetUInt32();
spellArea.auraSpell = fields[5].GetUInt32();
spellArea.raceMask = fields[6].GetUInt32();
spellArea.gender = Gender(fields[7].GetUInt8());
spellArea.autocast = fields[8].GetBool();
if(!sSpellStore.LookupEntry(spell))
{
sLog.outErrorDb("Spell %u listed in `spell_area` does not exist", spell);
continue;
}
if(mSpellAreaForAuraMap.find(spellArea.spellId)!=mSpellAreaForAuraMap.end())
{
sLog.outErrorDb("Spell %u listed in `spell_area` have aura spell (%u) requirement that already listed in table itself", spell,spellArea.auraSpell);
continue;
}
if(spellArea.areaId && !GetAreaEntryByAreaID(spellArea.areaId))
{
sLog.outErrorDb("Spell %u listed in `spell_area` have wrong area (%u) requirement", spell,spellArea.areaId);
continue;
}
if(spellArea.questStart && !objmgr.GetQuestTemplate(spellArea.questStart))
{
sLog.outErrorDb("Spell %u listed in `spell_area` have wrong start quest (%u) requirement", spell,spellArea.questStart);
continue;
}
if(spellArea.questEnd)
{
if(!objmgr.GetQuestTemplate(spellArea.questEnd))
{
sLog.outErrorDb("Spell %u listed in `spell_area` have wrong end quest (%u) requirement", spell,spellArea.questEnd);
continue;
}
if(spellArea.questEnd==spellArea.questStart && !spellArea.questStartCanActive)
{
sLog.outErrorDb("Spell %u listed in `spell_area` have quest (%u) requirement for start and end in same time", spell,spellArea.questEnd);
continue;
}
}
if(spellArea.auraSpell)
{
SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellArea.auraSpell);
if(!spellInfo)
{
sLog.outErrorDb("Spell %u listed in `spell_area` have wrong aura spell (%u) requirement", spell,spellArea.auraSpell);
continue;
}
if(spellInfo->EffectApplyAuraName[0]!=SPELL_AURA_DUMMY)
{
sLog.outErrorDb("Spell %u listed in `spell_area` have aura spell requirement (%u) without dummy aura in effect 0", spell,spellArea.auraSpell);
continue;
}
if(spellArea.auraSpell==spellArea.spellId)
{
sLog.outErrorDb("Spell %u listed in `spell_area` have aura spell (%u) requirement for itself", spell,spellArea.auraSpell);
continue;
}
// not allow autocast chains by auraSpell field
if(spellArea.autocast)
{
bool chain = false;
SpellAreaForAuraMapBounds saBound = GetSpellAreaForAuraMapBounds(spellArea.spellId);
for(SpellAreaForAuraMap::const_iterator itr = saBound.first; itr != saBound.second; ++itr)
{
if(itr->second->autocast)
{
chain = true;
break;
}
}
if(chain)
{
sLog.outErrorDb("Spell %u listed in `spell_area` have aura spell (%u) requirement that itself autocast from aura", spell,spellArea.auraSpell);
continue;
}
SpellAreaMapBounds saBound2 = GetSpellAreaMapBounds(spellArea.auraSpell);
for(SpellAreaMap::const_iterator itr2 = saBound2.first; itr2 != saBound2.second; ++itr2)
{
if(itr2->second.autocast && itr2->second.auraSpell)
{
chain = true;
break;
}
}
if(chain)
{
sLog.outErrorDb("Spell %u listed in `spell_area` have aura spell (%u) requirement that itself autocast from aura", spell,spellArea.auraSpell);
continue;
}
}
}
if(spellArea.raceMask && (spellArea.raceMask & RACEMASK_ALL_PLAYABLE)==0)
{
sLog.outErrorDb("Spell %u listed in `spell_area` have wrong race mask (%u) requirement", spell,spellArea.raceMask);
continue;
}
if(spellArea.gender!=GENDER_NONE && spellArea.gender!=GENDER_FEMALE && spellArea.gender!=GENDER_MALE)
{
sLog.outErrorDb("Spell %u listed in `spell_area` have wrong gender (%u) requirement", spell,spellArea.gender);
continue;
}
SpellArea const* sa = &mSpellAreaMap.insert(SpellAreaMap::value_type(spell,spellArea))->second;
// for search by current zone/subzone at zone/subzone change
if(spellArea.areaId)
mSpellAreaForAreaMap.insert(SpellAreaForAreaMap::value_type(spellArea.areaId,sa));
// for search at quest start/reward
if(spellArea.questStart)
{
if(spellArea.questStartCanActive)
mSpellAreaForActiveQuestMap.insert(SpellAreaForQuestMap::value_type(spellArea.questStart,sa));
else
mSpellAreaForQuestMap.insert(SpellAreaForQuestMap::value_type(spellArea.questStart,sa));
}
// for search at quest start/reward
if(spellArea.questEnd)
mSpellAreaForQuestEndMap.insert(SpellAreaForQuestMap::value_type(spellArea.questEnd,sa));
// for search at aura apply
if(spellArea.auraSpell)
mSpellAreaForAuraMap.insert(SpellAreaForAuraMap::value_type(spellArea.auraSpell,sa));
++count;
} while( result->NextRow() );
delete result;
sLog.outString();
sLog.outString( ">> Loaded %u spell area requirements", count );
}
uint8 SpellMgr::GetSpellAllowedInLocationError(SpellEntry const *spellInfo, uint32 map_id, uint32 zone_id, uint32 area_id, Player const* player)
{
// normal case
if( spellInfo->AreaGroupId > 0)
@ -2367,75 +2553,26 @@ uint8 GetSpellAllowedInLocationError(SpellEntry const *spellInfo,uint32 map_id,u
return SPELL_FAILED_INCORRECT_AREA;
}
// elixirs (all area dependent elixirs have family SPELLFAMILY_POTION, use this for speedup)
if(spellInfo->SpellFamilyName==SPELLFAMILY_POTION)
// DB base check (if non empty then must fit at least single for allow)
SpellAreaMapBounds saBounds = spellmgr.GetSpellAreaMapBounds(spellInfo->Id);
if(saBounds.first != saBounds.second)
{
if(uint32 mask = spellmgr.GetSpellElixirMask(spellInfo->Id))
for(SpellAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
{
if(mask & ELIXIR_BATTLE_MASK)
{
if(spellInfo->Id==45373) // Bloodberry Elixir
return zone_id==4075 ? 0 : SPELL_FAILED_REQUIRES_AREA;
}
if(mask & ELIXIR_UNSTABLE_MASK)
{
// in the Blade's Edge Mountains Plateaus and Gruul's Lair.
return zone_id ==3522 || map_id==565 ? 0 : SPELL_FAILED_INCORRECT_AREA;
}
if(mask & ELIXIR_SHATTRATH_MASK)
{
// in Tempest Keep, Serpentshrine Cavern, Caverns of Time: Mount Hyjal, Black Temple, Sunwell Plateau
if(zone_id ==3607 || map_id==534 || map_id==564 || zone_id==4075)
return 0;
MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
if(!mapEntry)
return SPELL_FAILED_INCORRECT_AREA;
return mapEntry->multimap_id==206 ? 0 : SPELL_FAILED_INCORRECT_AREA;
}
// elixirs not have another limitations
return 0;
if(itr->second.IsFitToRequirements(player,zone_id,area_id))
return 0;
}
return SPELL_FAILED_INCORRECT_AREA;
}
// special cases zone check (maps checked by multimap common id)
// bg spell checks
switch(spellInfo->Id)
{
case 41618: // Bottled Nethergon Energy
case 41620: // Bottled Nethergon Vapor
{
MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
if(!mapEntry)
return SPELL_FAILED_INCORRECT_AREA;
return mapEntry->multimap_id==206 ? 0 : SPELL_FAILED_REQUIRES_AREA;
}
case 41617: // Cenarion Mana Salve
case 41619: // Cenarion Healing Salve
{
MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
if(!mapEntry)
return SPELL_FAILED_INCORRECT_AREA;
return mapEntry->multimap_id==207 ? 0 : SPELL_FAILED_REQUIRES_AREA;
}
case 40216: // Dragonmaw Illusion
case 42016: // Dragonmaw Illusion
return area_id == 3759 || area_id == 3966 || area_id == 3939 ? 0 : SPELL_FAILED_INCORRECT_AREA;
case 51721: // Dominion Over Acherus
case 54055: // Dominion Over Acherus
return area_id == 4281 || area_id == 4342 ? 0 : SPELL_FAILED_INCORRECT_AREA;
case 51852: // The Eye of Acherus
return map_id == 609 ? 0 : SPELL_FAILED_REQUIRES_AREA;
case 54119: // Mist of the Kvaldir
return area_id == 4028 || area_id == 4029 || area_id == 4106 || area_id == 4031 ? 0 : SPELL_FAILED_INCORRECT_AREA;
case 23333: // Warsong Flag
case 23335: // Silverwing Flag
return map_id == 489 && bgInstanceId ? 0 : SPELL_FAILED_REQUIRES_AREA;
return map_id == 489 && player && player->InBattleGround() ? 0 : SPELL_FAILED_REQUIRES_AREA;
case 34976: // Netherstorm Flag
return map_id == 566 && bgInstanceId ? 0 : SPELL_FAILED_REQUIRES_AREA;
return map_id == 566 && player && player->InBattleGround() ? 0 : SPELL_FAILED_REQUIRES_AREA;
case 2584: // Waiting to Resurrect
case 22011: // Spirit Heal Channel
case 22012: // Spirit Heal
@ -2448,11 +2585,11 @@ uint8 GetSpellAllowedInLocationError(SpellEntry const *spellInfo,uint32 map_id,u
if(!mapEntry)
return SPELL_FAILED_INCORRECT_AREA;
return mapEntry->IsBattleGround() && bgInstanceId ? 0 : SPELL_FAILED_REQUIRES_AREA;
return mapEntry->IsBattleGround() && player && player->InBattleGround() ? 0 : SPELL_FAILED_REQUIRES_AREA;
}
case 44521: // Preparation
{
if(!bgInstanceId)
if(!player)
return SPELL_FAILED_REQUIRES_AREA;
MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
@ -2462,7 +2599,7 @@ uint8 GetSpellAllowedInLocationError(SpellEntry const *spellInfo,uint32 map_id,u
if(!mapEntry->IsBattleGround())
return SPELL_FAILED_REQUIRES_AREA;
BattleGround* bg = sBattleGroundMgr.GetBattleGround(bgInstanceId);
BattleGround* bg = player->GetBattleGround();
return bg && bg->GetStatus()==STATUS_WAIT_JOIN ? 0 : SPELL_FAILED_REQUIRES_AREA;
}
case 32724: // Gold Team (Alliance)
@ -2474,11 +2611,11 @@ uint8 GetSpellAllowedInLocationError(SpellEntry const *spellInfo,uint32 map_id,u
if(!mapEntry)
return SPELL_FAILED_INCORRECT_AREA;
return mapEntry->IsBattleArena() && bgInstanceId ? 0 : SPELL_FAILED_REQUIRES_AREA;
return mapEntry->IsBattleArena() && player && player->InBattleGround() ? 0 : SPELL_FAILED_REQUIRES_AREA;
}
case 32727: // Arena Preparation
{
if(!bgInstanceId)
if(!player)
return SPELL_FAILED_REQUIRES_AREA;
MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
@ -2488,7 +2625,7 @@ uint8 GetSpellAllowedInLocationError(SpellEntry const *spellInfo,uint32 map_id,u
if(!mapEntry->IsBattleArena())
return SPELL_FAILED_REQUIRES_AREA;
BattleGround* bg = sBattleGroundMgr.GetBattleGround(bgInstanceId);
BattleGround* bg = player->GetBattleGround();
return bg && bg->GetStatus()==STATUS_WAIT_JOIN ? 0 : SPELL_FAILED_REQUIRES_AREA;
}
}
@ -2632,3 +2769,50 @@ DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group)
return DRTYPE_NONE;
}
bool SpellArea::IsFitToRequirements(Player const* player, uint32 newZone, uint32 newArea) const
{
if(gender!=GENDER_NONE)
{
// not in expected gender
if(!player || gender != player->getGender())
return false;
}
if(raceMask)
{
// not in expected race
if(!player || !(raceMask & player->getRaceMask()))
return false;
}
if(areaId)
{
// not in expected zone
if(newZone!=areaId && newArea!=areaId)
return false;
}
if(questStart)
{
// not in expected required quest state
if(!player || (!questStartCanActive || !player->IsActiveQuest(questStart)) && !player->GetQuestRewardStatus(questStart))
return false;
}
if(questEnd)
{
// not in expected forbidden quest state
if(!player || player->GetQuestRewardStatus(questEnd))
return false;
}
if(auraSpell)
{
// not have expected aura
if(!player || !player->HasAura(auraSpell,0))
return false;
}
return true;
}

View file

@ -338,14 +338,6 @@ inline bool IsPassiveSpellStackableWithRanks(SpellEntry const* spellProto)
inline bool IsDeathPersistentSpell(SpellEntry const *spellInfo)
{
switch(spellInfo->Id)
{
case 40214: // Dragonmaw Illusion
case 35480: case 35481: case 35482: // Human Illusion
case 35483: case 39824: // Human Illusion
return true;
}
return spellInfo->AttributesEx3 & SPELL_ATTR_EX3_DEATH_PERSISTENT;
}
@ -363,8 +355,6 @@ bool IsSingleTargetSpells(SpellEntry const *spellInfo1, SpellEntry const *spellI
bool IsAuraAddedBySpell(uint32 auraType, uint32 spellId);
uint8 GetSpellAllowedInLocationError(SpellEntry const *spellInfo,uint32 map_id,uint32 zone_id,uint32 area_id,uint32 bgInstanceId);
inline bool IsAreaEffectTarget( Targets target )
{
switch (target )
@ -687,6 +677,32 @@ class PetAura
};
typedef std::map<uint16, PetAura> SpellPetAuraMap;
struct SpellArea
{
uint32 spellId;
uint32 areaId; // zone/subzone/or 0 is not limited to zone
uint32 questStart; // quest start (quest must be active or rewarded for spell apply)
uint32 questEnd; // quest end (quest don't must be rewarded for spell apply)
uint32 auraSpell; // spell aura must be applied for spell apply
uint32 raceMask; // can be applied only to races
Gender gender; // can be applied only to gender
bool questStartCanActive; // if true then quest start can be active (not only rewarded)
bool autocast; // if true then auto applied at area enter, in other case just allowed to cast
// helpers
bool IsFitToRequirements(Player const* player, uint32 newZone, uint32 newArea) const;
};
typedef std::multimap<uint32,SpellArea> SpellAreaMap;
typedef std::multimap<uint32,SpellArea const*> SpellAreaForQuestMap;
typedef std::multimap<uint32,SpellArea const*> SpellAreaForAuraMap;
typedef std::multimap<uint32,SpellArea const*> SpellAreaForAreaMap;
typedef std::pair<SpellAreaMap::const_iterator,SpellAreaMap::const_iterator> SpellAreaMapBounds;
typedef std::pair<SpellAreaForQuestMap::const_iterator,SpellAreaForQuestMap::const_iterator> SpellAreaForQuestMapBounds;
typedef std::pair<SpellAreaForAuraMap::const_iterator, SpellAreaForAuraMap::const_iterator> SpellAreaForAuraMapBounds;
typedef std::pair<SpellAreaForAreaMap::const_iterator, SpellAreaForAreaMap::const_iterator> SpellAreaForAreaMapBounds;
// Spell rank chain (accessed using SpellMgr functions)
struct SpellChainNode
{
@ -973,6 +989,36 @@ class SpellMgr
return NULL;
}
uint8 GetSpellAllowedInLocationError(SpellEntry const *spellInfo, uint32 map_id, uint32 zone_id, uint32 area_id, Player const* player = NULL);
SpellAreaMapBounds GetSpellAreaMapBounds(uint32 spell_id) const
{
return SpellAreaMapBounds(mSpellAreaMap.lower_bound(spell_id),mSpellAreaMap.upper_bound(spell_id));
}
SpellAreaForQuestMapBounds GetSpellAreaForQuestMapBounds(uint32 quest_id, bool active) const
{
if(active)
return SpellAreaForQuestMapBounds(mSpellAreaForActiveQuestMap.lower_bound(quest_id),mSpellAreaForActiveQuestMap.upper_bound(quest_id));
else
return SpellAreaForQuestMapBounds(mSpellAreaForQuestMap.lower_bound(quest_id),mSpellAreaForQuestMap.upper_bound(quest_id));
}
SpellAreaForQuestMapBounds GetSpellAreaForQuestEndMapBounds(uint32 quest_id) const
{
return SpellAreaForQuestMapBounds(mSpellAreaForQuestEndMap.lower_bound(quest_id),mSpellAreaForQuestEndMap.upper_bound(quest_id));
}
SpellAreaForAuraMapBounds GetSpellAreaForAuraMapBounds(uint32 spell_id) const
{
return SpellAreaForAuraMapBounds(mSpellAreaForAuraMap.lower_bound(spell_id),mSpellAreaForAuraMap.upper_bound(spell_id));
}
SpellAreaForAreaMapBounds GetSpellAreaForAreaMapBounds(uint32 area_id) const
{
return SpellAreaForAreaMapBounds(mSpellAreaForAreaMap.lower_bound(area_id),mSpellAreaForAreaMap.upper_bound(area_id));
}
// Modifiers
public:
static SpellMgr& Instance();
@ -991,6 +1037,7 @@ class SpellMgr
void LoadSkillLineAbilityMap();
void LoadSpellPetAuras();
void LoadPetLevelupSpellMap();
void LoadSpellAreas();
private:
SpellScriptTarget mSpellScriptTarget;
@ -1005,7 +1052,13 @@ class SpellMgr
SpellBonusMap mSpellBonusMap;
SkillLineAbilityMap mSkillLineAbilityMap;
SpellPetAuraMap mSpellPetAuraMap;
PetLevelupSpellMap mPetLevelupSpellMap;
PetLevelupSpellMap mPetLevelupSpellMap;
SpellAreaMap mSpellAreaMap;
SpellAreaForQuestMap mSpellAreaForQuestMap;
SpellAreaForQuestMap mSpellAreaForActiveQuestMap;
SpellAreaForQuestMap mSpellAreaForQuestEndMap;
SpellAreaForAuraMap mSpellAreaForAuraMap;
SpellAreaForAreaMap mSpellAreaForAreaMap;
};
#define spellmgr SpellMgr::Instance()

View file

@ -50,11 +50,24 @@ struct MANGOS_DLL_DECL Traveller
T& GetTraveller(void) { return i_traveller; }
float Speed(void) { assert(false); return 0.0f; }
float GetMoveDestinationTo(float x, float y, float z);
uint32 GetTotalTrevelTimeTo(float x, float y, float z);
void Relocation(float x, float y, float z, float orientation) {}
void Relocation(float x, float y, float z) { Relocation(x, y, z, i_traveller.GetOrientation()); }
void MoveTo(float x, float y, float z, uint32 t) {}
};
template<class T>
inline uint32 Traveller<T>::GetTotalTrevelTimeTo(float x, float y, float z)
{
float dist = GetMoveDestinationTo(x,y,z);
double speed = Speed();
speed *= 0.001f; // speed is in seconds so convert from second to millisecond
return static_cast<uint32>(dist/speed);
}
// specialization for creatures
template<>
inline float Traveller<Creature>::Speed()
@ -73,6 +86,20 @@ inline void Traveller<Creature>::Relocation(float x, float y, float z, float ori
i_traveller.GetMap()->CreatureRelocation(&i_traveller, x, y, z, orientation);
}
template<>
inline float Traveller<Creature>::GetMoveDestinationTo(float x, float y, float z)
{
float dx = x - GetPositionX();
float dy = y - GetPositionY();
float dz = z - GetPositionZ();
if(i_traveller.hasUnitState(UNIT_STAT_IN_FLIGHT))
return sqrt((dx*dx) + (dy*dy) + (dz*dz));
else //Walking on the ground
return sqrt((dx*dx) + (dy*dy));
}
template<>
inline void Traveller<Creature>::MoveTo(float x, float y, float z, uint32 t)
{
@ -89,6 +116,19 @@ inline float Traveller<Player>::Speed()
return i_traveller.GetSpeed(i_traveller.HasUnitMovementFlag(MOVEMENTFLAG_WALK_MODE) ? MOVE_WALK : MOVE_RUN);
}
template<>
inline float Traveller<Player>::GetMoveDestinationTo(float x, float y, float z)
{
float dx = x - GetPositionX();
float dy = y - GetPositionY();
float dz = z - GetPositionZ();
if (i_traveller.isInFlight())
return sqrt((dx*dx) + (dy*dy) + (dz*dz));
else //Walking on the ground
return sqrt((dx*dx) + (dy*dy));
}
template<>
inline void Traveller<Player>::Relocation(float x, float y, float z, float orientation)
{

View file

@ -43,6 +43,7 @@
#include "GridNotifiersImpl.h"
#include "CellImpl.h"
#include "Path.h"
#include "Traveller.h"
#include <math.h>
@ -232,31 +233,26 @@ void Unit::SendMonsterMoveWithSpeedToCurrentDestination(Player* player)
{
float x, y, z;
if(GetMotionMaster()->GetDestination(x, y, z))
SendMonsterMoveWithSpeed(x, y, z, GetUnitMovementFlags(), 0, player);
SendMonsterMoveWithSpeed(x, y, z, 0, player);
}
void Unit::SendMonsterMoveWithSpeed(float x, float y, float z, uint32 MovementFlags, uint32 transitTime, Player* player)
void Unit::SendMonsterMoveWithSpeed(float x, float y, float z, uint32 transitTime, Player* player)
{
if (!transitTime)
{
float dx = x - GetPositionX();
float dy = y - GetPositionY();
float dz = z - GetPositionZ();
float dist = ((dx*dx) + (dy*dy) + (dz*dz));
if(dist<0)
dist = 0;
if(GetTypeId()==TYPEID_PLAYER)
{
Traveller<Player> traveller(*(Player*)this);
transitTime = traveller.GetTotalTrevelTimeTo(x,y,z);
}
else
dist = sqrt(dist);
double speed = GetSpeed((MovementFlags & MOVEMENTFLAG_WALK_MODE) ? MOVE_WALK : MOVE_RUN);
if(speed<=0)
speed = 2.5f;
speed *= 0.001f;
transitTime = static_cast<uint32>(dist / speed + 0.5);
{
Traveller<Creature> traveller(*(Creature*)this);
transitTime = traveller.GetTotalTrevelTimeTo(x,y,z);
}
}
//float orientation = (float)atan2((double)dy, (double)dx);
SendMonsterMove(x, y, z, 0, MovementFlags, transitTime, player);
SendMonsterMove(x, y, z, 0, GetUnitMovementFlags(), transitTime, player);
}
void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, uint32 MovementFlags, uint32 Time, Player* player)
@ -1722,7 +1718,6 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
Unit* caster = (*i)->GetCaster();
if (!caster)
break;
int32 reflectDamage = 0;
AuraList const& vOverRideCS = caster->GetAurasByType(SPELL_AURA_DUMMY);
for(AuraList::const_iterator k = vOverRideCS.begin(); k != vOverRideCS.end(); ++k)
{

View file

@ -1068,7 +1068,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, uint32 MovementFlags, uint32 Time, Player* player = NULL);
void SendMonsterMoveByPath(Path const& path, uint32 start, uint32 end, uint32 MovementFlags);
void SendMonsterMoveWithSpeed(float x, float y, float z, uint32 MovementFlags, uint32 transitTime = 0, Player* player = NULL);
void SendMonsterMoveWithSpeed(float x, float y, float z, uint32 transitTime = 0, Player* player = NULL);
void SendMonsterMoveWithSpeedToCurrentDestination(Player* player = NULL);
virtual void MoveOutOfRange(Player &) { };

View file

@ -105,6 +105,10 @@ public PathMovementBase<Creature, WaypointPath*>
// statics
static void Initialize(void);
// allow use for overwrite empty implementation
bool GetDestination(float& x, float& y, float& z) const { return PathMovementBase<Creature, WaypointPath*>::GetDestination(x,y,z); }
private:
void ClearWaypoints();
@ -138,5 +142,8 @@ public PathMovementBase<Player>
bool HasArrived() const { return (i_currentNode >= i_path.Size()); }
void SetCurrentNodeAfterTeleport();
void SkipCurrentNode() { ++i_currentNode; }
// allow use for overwrite empty implementation
bool GetDestination(float& x, float& y, float& z) const { return PathMovementBase<Player>::GetDestination(x,y,z); }
};
#endif

View file

@ -615,20 +615,20 @@ void World::LoadConfigSettings(bool reload)
else
m_configs[CONFIG_REALM_ZONE] = sConfig.GetIntDefault("RealmZone", REALM_ZONE_DEVELOPMENT);
m_configs[CONFIG_ALLOW_TWO_SIDE_ACCOUNTS] = sConfig.GetBoolDefault("AllowTwoSide.Accounts", false);
m_configs[CONFIG_ALLOW_TWO_SIDE_ACCOUNTS] = sConfig.GetBoolDefault("AllowTwoSide.Accounts", false);
m_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT] = sConfig.GetBoolDefault("AllowTwoSide.Interaction.Chat",false);
m_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL] = sConfig.GetBoolDefault("AllowTwoSide.Interaction.Channel",false);
m_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP] = sConfig.GetBoolDefault("AllowTwoSide.Interaction.Group",false);
m_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD] = sConfig.GetBoolDefault("AllowTwoSide.Interaction.Guild",false);
m_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION] = sConfig.GetBoolDefault("AllowTwoSide.Interaction.Auction",false);
m_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL] = sConfig.GetBoolDefault("AllowTwoSide.Interaction.Mail",false);
m_configs[CONFIG_ALLOW_TWO_SIDE_WHO_LIST] = sConfig.GetBoolDefault("AllowTwoSide.WhoList", false);
m_configs[CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND] = sConfig.GetBoolDefault("AllowTwoSide.AddFriend", false);
m_configs[CONFIG_STRICT_PLAYER_NAMES] = sConfig.GetIntDefault("StrictPlayerNames", 0);
m_configs[CONFIG_STRICT_CHARTER_NAMES] = sConfig.GetIntDefault("StrictCharterNames", 0);
m_configs[CONFIG_STRICT_PET_NAMES] = sConfig.GetIntDefault("StrictPetNames", 0);
m_configs[CONFIG_ALLOW_TWO_SIDE_WHO_LIST] = sConfig.GetBoolDefault("AllowTwoSide.WhoList", false);
m_configs[CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND] = sConfig.GetBoolDefault("AllowTwoSide.AddFriend", false);
m_configs[CONFIG_STRICT_PLAYER_NAMES] = sConfig.GetIntDefault ("StrictPlayerNames", 0);
m_configs[CONFIG_STRICT_CHARTER_NAMES] = sConfig.GetIntDefault ("StrictCharterNames", 0);
m_configs[CONFIG_STRICT_PET_NAMES] = sConfig.GetIntDefault ("StrictPetNames", 0);
m_configs[CONFIG_CHARACTERS_CREATING_DISABLED] = sConfig.GetIntDefault("CharactersCreatingDisabled", 0);
m_configs[CONFIG_CHARACTERS_CREATING_DISABLED] = sConfig.GetIntDefault ("CharactersCreatingDisabled", 0);
m_configs[CONFIG_CHARACTERS_PER_REALM] = sConfig.GetIntDefault("CharactersPerRealm", 10);
if(m_configs[CONFIG_CHARACTERS_PER_REALM] < 1 || m_configs[CONFIG_CHARACTERS_PER_REALM] > 10)
@ -762,13 +762,6 @@ void World::LoadConfigSettings(bool reload)
m_configs[CONFIG_INSTANCE_IGNORE_LEVEL] = sConfig.GetBoolDefault("Instance.IgnoreLevel", false);
m_configs[CONFIG_INSTANCE_IGNORE_RAID] = sConfig.GetBoolDefault("Instance.IgnoreRaid", false);
m_configs[CONFIG_BATTLEGROUND_CAST_DESERTER] = sConfig.GetBoolDefault("Battleground.CastDeserter", true);
m_configs[CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE] = sConfig.GetBoolDefault("Battleground.QueueAnnouncer.Enable", false);
m_configs[CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY] = sConfig.GetBoolDefault("Battleground.QueueAnnouncer.PlayerOnly", false);
m_configs[CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE] = sConfig.GetBoolDefault("Arena.QueueAnnouncer.Enable", false);
m_configs[CONFIG_ARENA_SEASON_ID] = sConfig.GetIntDefault ("Arena.ArenaSeason.ID", 1);
m_configs[CONFIG_ARENA_SEASON_IN_PROGRESS] = sConfig.GetBoolDefault("Arena.ArenaSeason.InProgress", true);
m_configs[CONFIG_CAST_UNSTUCK] = sConfig.GetBoolDefault("CastUnstuck", true);
m_configs[CONFIG_INSTANCE_RESET_TIME_HOUR] = sConfig.GetIntDefault("Instance.ResetTimeHour", 4);
m_configs[CONFIG_INSTANCE_UNLOAD_DELAY] = sConfig.GetIntDefault("Instance.UnloadDelay", 1800000);
@ -905,23 +898,23 @@ void World::LoadConfigSettings(bool reload)
m_configs[CONFIG_DETECT_POS_COLLISION] = sConfig.GetBoolDefault("DetectPosCollision", true);
m_configs[CONFIG_RESTRICTED_LFG_CHANNEL] = sConfig.GetBoolDefault("Channel.RestrictedLfg", true);
m_configs[CONFIG_RESTRICTED_LFG_CHANNEL] = sConfig.GetBoolDefault("Channel.RestrictedLfg", true);
m_configs[CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL] = sConfig.GetBoolDefault("Channel.SilentlyGMJoin", false);
m_configs[CONFIG_TALENTS_INSPECTING] = sConfig.GetBoolDefault("TalentsInspecting", true);
m_configs[CONFIG_TALENTS_INSPECTING] = sConfig.GetBoolDefault("TalentsInspecting", true);
m_configs[CONFIG_CHAT_FAKE_MESSAGE_PREVENTING] = sConfig.GetBoolDefault("ChatFakeMessagePreventing", false);
m_configs[CONFIG_CORPSE_DECAY_NORMAL] = sConfig.GetIntDefault("Corpse.Decay.NORMAL", 60);
m_configs[CONFIG_CORPSE_DECAY_RARE] = sConfig.GetIntDefault("Corpse.Decay.RARE", 300);
m_configs[CONFIG_CORPSE_DECAY_ELITE] = sConfig.GetIntDefault("Corpse.Decay.ELITE", 300);
m_configs[CONFIG_CORPSE_DECAY_NORMAL] = sConfig.GetIntDefault("Corpse.Decay.NORMAL", 60);
m_configs[CONFIG_CORPSE_DECAY_RARE] = sConfig.GetIntDefault("Corpse.Decay.RARE", 300);
m_configs[CONFIG_CORPSE_DECAY_ELITE] = sConfig.GetIntDefault("Corpse.Decay.ELITE", 300);
m_configs[CONFIG_CORPSE_DECAY_RAREELITE] = sConfig.GetIntDefault("Corpse.Decay.RAREELITE", 300);
m_configs[CONFIG_CORPSE_DECAY_WORLDBOSS] = sConfig.GetIntDefault("Corpse.Decay.WORLDBOSS", 3600);
m_configs[CONFIG_DEATH_SICKNESS_LEVEL] = sConfig.GetIntDefault("Death.SicknessLevel", 11);
m_configs[CONFIG_DEATH_SICKNESS_LEVEL] = sConfig.GetIntDefault ("Death.SicknessLevel", 11);
m_configs[CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVP] = sConfig.GetBoolDefault("Death.CorpseReclaimDelay.PvP", true);
m_configs[CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVE] = sConfig.GetBoolDefault("Death.CorpseReclaimDelay.PvE", true);
m_configs[CONFIG_DEATH_BONES_WORLD] = sConfig.GetBoolDefault("Death.Bones.World", true);
m_configs[CONFIG_DEATH_BONES_BG_OR_ARENA] = sConfig.GetBoolDefault("Death.Bones.BattlegroundOrArena", true);
m_configs[CONFIG_DEATH_BONES_WORLD] = sConfig.GetBoolDefault("Death.Bones.World", true);
m_configs[CONFIG_DEATH_BONES_BG_OR_ARENA] = sConfig.GetBoolDefault("Death.Bones.BattlegroundOrArena", true);
m_configs[CONFIG_THREAT_RADIUS] = sConfig.GetIntDefault("ThreatRadius", 100);
@ -933,12 +926,20 @@ void World::LoadConfigSettings(bool reload)
m_configs[CONFIG_LISTEN_RANGE_TEXTEMOTE] = sConfig.GetIntDefault("ListenRange.TextEmote", 25);
m_configs[CONFIG_LISTEN_RANGE_YELL] = sConfig.GetIntDefault("ListenRange.Yell", 300);
m_configs[CONFIG_ARENA_MAX_RATING_DIFFERENCE] = sConfig.GetIntDefault("Arena.MaxRatingDifference", 0);
m_configs[CONFIG_ARENA_RATING_DISCARD_TIMER] = sConfig.GetIntDefault("Arena.RatingDiscardTimer",300000);
m_configs[CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS] = sConfig.GetBoolDefault("Arena.AutoDistributePoints", false);
m_configs[CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS] = sConfig.GetIntDefault("Arena.AutoDistributeInterval", 7);
m_configs[CONFIG_BATTLEGROUND_CAST_DESERTER] = sConfig.GetBoolDefault("Battleground.CastDeserter", true);
m_configs[CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE] = sConfig.GetBoolDefault("Battleground.QueueAnnouncer.Enable", false);
m_configs[CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY] = sConfig.GetBoolDefault("Battleground.QueueAnnouncer.PlayerOnly", false);
m_configs[CONFIG_BATTLEGROUND_INVITATION_TYPE] = sConfig.GetIntDefault ("Battleground.InvitationType", 0);
m_configs[CONFIG_BATTLEGROUND_PREMATURE_FINISH_TIMER] = sConfig.GetIntDefault ("BattleGround.PrematureFinishTimer", 5 * MINUTE * IN_MILISECONDS);
m_configs[CONFIG_BATTLEGROUND_PREMADE_GROUP_WAIT_FOR_MATCH] = sConfig.GetIntDefault ("BattleGround.PremadeGroupWaitForMatch", 30 * MINUTE * IN_MILISECONDS);
m_configs[CONFIG_ARENA_MAX_RATING_DIFFERENCE] = sConfig.GetIntDefault ("Arena.MaxRatingDifference", 100);
m_configs[CONFIG_ARENA_RATING_DISCARD_TIMER] = sConfig.GetIntDefault ("Arena.RatingDiscardTimer", 10 * MINUTE * IN_MILISECONDS);
m_configs[CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS] = sConfig.GetBoolDefault("Arena.AutoDistributePoints", false);
m_configs[CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS] = sConfig.GetIntDefault ("Arena.AutoDistributeInterval", 7);
m_configs[CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE] = sConfig.GetBoolDefault("Arena.QueueAnnouncer.Enable", false);
m_configs[CONFIG_ARENA_SEASON_ID] = sConfig.GetIntDefault ("Arena.ArenaSeason.ID", 1);
m_configs[CONFIG_ARENA_SEASON_IN_PROGRESS] = sConfig.GetBoolDefault("Arena.ArenaSeason.InProgress", true);
m_configs[CONFIG_BATTLEGROUND_PREMATURE_FINISH_TIMER] = sConfig.GetIntDefault("BattleGround.PrematureFinishTimer", 0);
m_configs[CONFIG_INSTANT_LOGOUT] = sConfig.GetIntDefault("InstantLogout", SEC_MODERATOR);
m_VisibleUnitGreyDistance = sConfig.GetFloatDefault("Visibility.Distance.Grey.Unit", 1);
@ -1201,6 +1202,9 @@ void World::SetInitialWorldSettings()
sLog.outString( ">>> Quests Relations loaded" );
sLog.outString();
sLog.outString( "Loading SpellArea Data..." ); // must be after quest load
spellmgr.LoadSpellAreas();
sLog.outString( "Loading AreaTrigger definitions..." );
objmgr.LoadAreaTriggerTeleports(); // must be after item template load
@ -1799,7 +1803,7 @@ void World::ScriptsProcess()
sLog.outError("SCRIPT_COMMAND_MOVE_TO call for non-creature (TypeId: %u), skipping.",source->GetTypeId());
break;
}
((Unit *)source)->SendMonsterMoveWithSpeed(step.script->x, step.script->y, step.script->z, ((Unit *)source)->GetUnitMovementFlags(), step.script->datalong2 );
((Unit *)source)->SendMonsterMoveWithSpeed(step.script->x, step.script->y, step.script->z, step.script->datalong2 );
((Unit *)source)->GetMap()->CreatureRelocation(((Creature *)source), step.script->x, step.script->y, step.script->z, 0);
break;
case SCRIPT_COMMAND_FLAG_SET:

View file

@ -113,9 +113,6 @@ enum WorldConfigs
CONFIG_START_ARENA_POINTS,
CONFIG_INSTANCE_IGNORE_LEVEL,
CONFIG_INSTANCE_IGNORE_RAID,
CONFIG_BATTLEGROUND_CAST_DESERTER,
CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE,
CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY,
CONFIG_INSTANCE_RESET_TIME_HOUR,
CONFIG_INSTANCE_UNLOAD_DELAY,
CONFIG_CAST_UNSTUCK,
@ -184,6 +181,13 @@ enum WorldConfigs
CONFIG_LISTEN_RANGE_SAY,
CONFIG_LISTEN_RANGE_TEXTEMOTE,
CONFIG_LISTEN_RANGE_YELL,
CONFIG_SKILL_MILLING,
CONFIG_BATTLEGROUND_CAST_DESERTER,
CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE,
CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY,
CONFIG_BATTLEGROUND_INVITATION_TYPE,
CONFIG_BATTLEGROUND_PREMATURE_FINISH_TIMER,
CONFIG_BATTLEGROUND_PREMADE_GROUP_WAIT_FOR_MATCH,
CONFIG_ARENA_MAX_RATING_DIFFERENCE,
CONFIG_ARENA_RATING_DISCARD_TIMER,
CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS,
@ -191,8 +195,6 @@ enum WorldConfigs
CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE,
CONFIG_ARENA_SEASON_ID,
CONFIG_ARENA_SEASON_IN_PROGRESS,
CONFIG_BATTLEGROUND_PREMATURE_FINISH_TIMER,
CONFIG_SKILL_MILLING,
CONFIG_VALUE_COUNT
};

View file

@ -302,6 +302,9 @@ void WorldSession::LogoutPlayer(bool Save)
_player->BuildPlayerRepop();
_player->RepopAtGraveyard();
}
//drop a flag if player is carrying it
if(BattleGround *bg = _player->GetBattleGround())
bg->EventPlayerDroppedFlag(_player);
///- Teleport to home if the player is in an invalid instance
if(!_player->m_InstanceValid && !_player->isGameMaster())

View file

@ -22,15 +22,15 @@ AM_CPPFLAGS = $(MANGOS_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir)/../../
## Build world list daemon as standalone program
bin_PROGRAMS = mangos-worldd
mangos_worldd_SOURCES = \
CliRunnable.cpp \
CliRunnable.h \
Main.cpp \
Master.cpp \
Master.h \
RASocket.cpp \
RASocket.h \
WorldRunnable.cpp \
WorldRunnable.h
CliRunnable.cpp \
CliRunnable.h \
Main.cpp \
Master.cpp \
Master.h \
RASocket.cpp \
RASocket.h \
WorldRunnable.cpp \
WorldRunnable.h
## Link world daemon against the shared library
mangos_worldd_LDADD = ../bindings/universal/libmangosscript.la ../game/libmangosgame.a ../shared/Database/libmangosdatabase.a ../shared/Config/libmangosconfig.a ../shared/Auth/libmangosauth.a ../shared/libmangosshared.a ../shared/vmap/libmangosvmaps.a ../framework/libmangosframework.a ../../dep/src/sockets/libmangossockets.a ../../dep/src/zthread/libZThread.la ../../dep/src/g3dlite/libg3dlite.a
@ -39,22 +39,23 @@ mangos_worldd_LDFLAGS = -L../../dep/src/sockets -L../../dep/src/zthread -L../../
## Additional files to include when running 'make dist'
# Include world daemon configuration
EXTRA_DIST = \
mangosd.conf.dist
mangosd.conf.dist
## Additional files to install
sysconf_DATA = \
mangosd.conf.dist
mangosd.conf.dist
install-data-hook:
@list='$(sysconf_DATA)'; for p in $$list; do \
dest=`echo $$p | sed -e s/.dist//`; \
if test -f $(DESTDIR)$(sysconfdir)/$$dest; then \
echo "$@ will not overwrite existing $(DESTDIR)$(sysconfdir)/$$dest"; \
else \
echo " $(INSTALL_DATA) $$p $(DESTDIR)$(sysconfdir)/$$dest"; \
$(INSTALL_DATA) $$p $(DESTDIR)$(sysconfdir)/$$dest; \
fi; \
done
@list='$(sysconf_DATA)'
for p in $$list; do \
dest=`echo $$p | sed -e s/.dist//`; \
if test -f $(DESTDIR)$(sysconfdir)/$$dest; then \
echo "$@ will not overwrite existing $(DESTDIR)$(sysconfdir)/$$dest"; \
else \
echo " $(INSTALL_DATA) $$p $(DESTDIR)$(sysconfdir)/$$dest"; \
$(INSTALL_DATA) $$p $(DESTDIR)$(sysconfdir)/$$dest; \
fi; \
done
clean-local:
rm -f $(sysconf_DATA)

View file

@ -483,25 +483,6 @@ LogColors = ""
# Default: 1 (true)
# 0 (false)
#
# Battleground.CastDeserter
# Cast or not Deserter spell at player who leave battleground in progress
# Default: 1 (true)
# 0 (false)
#
# Battleground.QueueAnnouncer.Enable
# Enable queue announcer posting to chat
# Default: 0 (false)
# 1 (true)
#
# Battleground.QueueAnnouncer.PlayerOnly
# Enable queue announcer posting to chat
# Default: 0 (false)
# 1 (true)
#
# Arena.QueueAnnouncer.Enable: Enable queue announcer posting to chat
# Default: 0 (false)
# 1 (true)
#
# CastUnstuck
# Allow cast or not Unstuck spell at .start or client Help option use
# Default: 1 (true)
@ -606,10 +587,6 @@ DisableWaterBreath = 4
AllFlightPaths = 0
AlwaysMaxSkillForLevel = 0
ActivateWeather = 1
Battleground.CastDeserter = 1
Battleground.QueueAnnouncer.Enable = 0
Battleground.QueueAnnouncer.PlayerOnly = 0
Arena.QueueAnnouncer.Enable = 0
CastUnstuck = 1
Instance.IgnoreLevel = 0
Instance.IgnoreRaid = 0
@ -1128,59 +1105,101 @@ Death.CorpseReclaimDelay.PvE = 1
Death.Bones.World = 1
Death.Bones.BattlegroundOrArena = 1
###################################################################################################################
# BATTLEGROUND CONFIG
#
# Rated arena matches config
# Battleground.CastDeserter
# Cast or not Deserter spell at player who leave battleground in progress
# Default: 1 (true)
# 0 (false)
#
# MaxRatingDifference: the maximum rating difference between two groups in rated matches
# Default: 0 (disable, rating difference is discarded)
# Battleground.QueueAnnouncer.Enable
# Enable queue announcer posting to chat
# Default: 0 (false)
# 1 (true)
#
# RatingDiscardTimer: after the specified milliseconds has passed,
# rating information will be discarded when selecting teams for matches
# also initiates an update by this timer
# Default: 60000
# Battleground.QueueAnnouncer.PlayerOnly
# Enable queue announcer posting to chat
# Default: 0 (false)
# 1 (true)
#
# AutoDistributePoints: set if arena points should be distributed automatically, or by GM command
# Default: 0 (disable) (recommended): use gm command or sql query to distribute the points
# 1 (enable): arena points are distributed automatically
# Battleground.InvitationType
# Set Battleground invitation type
# Default: 0 (normal - invite as much players to bg as possible, don't bother with ballance)
# 1 (Experimental - don't allow to invite much more players of one faction)
#
# AutoDistributeInterval: how often should the distribution take place
# if automatic distribution is enabled
# in days
# Default: 7 (weekly)
# Battleground.PrematureFinishTimer
# The time to end the bg if there are less than MinPlayersPerTeam on one side in milliseconds
# Default: 300000 (5 minutes)
# 0 - disable (not recommended)
#
# ArenaSeason.ID: current area season id show in client
# Default: 1
#
# ArenaSeason.InProgress: current area season state
# Default: 1 (active)
# 0 (finished)
# BattleGround.PremadeGroupWaitForMatch
# The time in which premade group of 1 faction waits in BG Queue for premade group of other faction
# Default: 1800000 (30 minutes)
# 0 - disable (not recommended)
#
###################################################################################################################
Arena.MaxRatingDifference = 0
Arena.RatingDiscardTimer = 60000
Battleground.CastDeserter = 1
Battleground.QueueAnnouncer.Enable = 0
Battleground.QueueAnnouncer.PlayerOnly = 0
Battleground.InvitationType = 0
BattleGround.PrematureFinishTimer = 300000
BattleGround.PremadeGroupWaitForMatch = 1800000
###################################################################################################################
# ARENA CONFIG
#
# Arena.MaxRatingDifference
# The maximum rating difference between two groups in rated matches
# Default: 100 (enable, recommended)
# 0 (disable, rating difference is discarded)
#
# Arena.RatingDiscardTimer
# After the specified milliseconds has passed,
# rating information will be discarded when selecting teams for matches
# also initiates an update by this timer
# Default: 600000 (10 minutes, recommended)
# 0 (disable, DO NOT USE - it will cause lags)
#
# Arena.AutoDistributePoints
# Set if arena points should be distributed automatically, or by GM command
# Default: 0 (disable) (recommended): use gm command or sql query to distribute the points
# 1 (enable) arena points are distributed automatically
#
# Arena.AutoDistributeInterval
# How often should the distribution take place
# If automatic distribution is enabled in days
# Default: 7 (weekly)
#
# Arena.QueueAnnouncer.Enable
# Enable bg queue announcer posting to chat
# Default: 0 (false)
# 1 (true)
#
# Arena.ArenaSeason.ID
# Current area season id show in client
# Default: 1
#
# Arena.ArenaSeason.InProgress
# Current area season state
# Default: 1 (active)
# 0 (finished)
#
###################################################################################################################
Arena.MaxRatingDifference = 100
Arena.RatingDiscardTimer = 600000
Arena.AutoDistributePoints = 0
Arena.AutoDistributeInterval = 7
Arena.QueueAnnouncer.Enable = 0
Arena.ArenaSeason.ID = 1
Arena.ArenaSeason.InProgress = 1
###################################################################################################################
#
# Battleground config
#
# PrematureFinishTimer: the time to end the bg if there are less than minplayersperteam on one side
# in milliseconds
# Default: 300000
# 0 - disable
#
###################################################################################################################
BattleGround.PrematureFinishTimer = 300000
###################################################################################################################
#
# NETWORK CONFIG
#
# Network.Threads

View file

@ -22,12 +22,12 @@ AM_CPPFLAGS = $(MANGOS_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir)/../../
## Build realm list daemon as standalone program
bin_PROGRAMS = mangos-realmd
mangos_realmd_SOURCES = \
AuthCodes.h \
AuthSocket.cpp \
AuthSocket.h \
Main.cpp \
RealmList.cpp \
RealmList.h
AuthCodes.h \
AuthSocket.cpp \
AuthSocket.h \
Main.cpp \
RealmList.cpp \
RealmList.h
## Link realm list daemon against the shared library
mangos_realmd_LDADD = ../shared/Database/libmangosdatabase.a ../shared/Config/libmangosconfig.a ../shared/Auth/libmangosauth.a ../shared/libmangosshared.a ../framework/libmangosframework.a ../../dep/src/sockets/libmangossockets.a ../../dep/src/zthread/libZThread.la
@ -36,22 +36,23 @@ mangos_realmd_LDFLAGS = -L../../dep/src/sockets -L../../dep/src/zthread -L$(libd
## Additional files to include when running 'make dist'
# Include realm list daemon configuration
EXTRA_DIST = \
realmd.conf.dist
realmd.conf.dist
## Additional files to install
sysconf_DATA = \
realmd.conf.dist
realmd.conf.dist
install-data-hook:
@list='$(sysconf_DATA)'; for p in $$list; do \
dest=`echo $$p | sed -e s/.dist//`; \
if test -f $(DESTDIR)$(sysconfdir)/$$dest; then \
echo "$@ will not overwrite existing $(DESTDIR)$(sysconfdir)/$$dest"; \
else \
echo " $(INSTALL_DATA) $$p $(DESTDIR)$(sysconfdir)/$$dest"; \
$(INSTALL_DATA) $$p $(DESTDIR)$(sysconfdir)/$$dest; \
fi; \
done
@list='$(sysconf_DATA)'
for p in $$list; do \
dest=`echo $$p | sed -e s/.dist//`; \
if test -f $(DESTDIR)$(sysconfdir)/$$dest; then \
echo "$@ will not overwrite existing $(DESTDIR)$(sysconfdir)/$$dest"; \
else \
echo " $(INSTALL_DATA) $$p $(DESTDIR)$(sysconfdir)/$$dest"; \
$(INSTALL_DATA) $$p $(DESTDIR)$(sysconfdir)/$$dest; \
fi; \
done
clean-local:
rm -f $(sysconf_DATA)

View file

@ -27,13 +27,13 @@ AM_CPPFLAGS = $(MANGOS_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir) -I$(sr
noinst_LIBRARIES = libmangosauth.a
libmangosauth_a_SOURCES = \
AuthCrypt.cpp \
AuthCrypt.h \
BigNumber.cpp \
BigNumber.h \
Hmac.cpp \
Hmac.h \
Sha1.cpp \
Sha1.h \
md5.c \
md5.h
AuthCrypt.cpp \
AuthCrypt.h \
BigNumber.cpp \
BigNumber.h \
Hmac.cpp \
Hmac.h \
Sha1.cpp \
Sha1.h \
md5.c \
md5.h

View file

@ -157,7 +157,8 @@ enum TimeConstants
MINUTE = 60,
HOUR = MINUTE*60,
DAY = HOUR*24,
MONTH = DAY*30
MONTH = DAY*30,
IN_MILISECONDS = 1000
};
enum AccountTypes

View file

@ -27,38 +27,38 @@ AM_CPPFLAGS = $(MANGOS_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir) -I$(sr
noinst_LIBRARIES = libmangosdatabase.a
libmangosdatabase_a_SOURCES = \
DBCStores.cpp \
DBCStores.h \
DBCStructure.h \
DBCfmt.cpp \
Database.cpp \
Database.h \
DatabaseEnv.h \
DatabaseImpl.h \
DatabaseMysql.cpp \
DatabasePostgre.cpp \
DatabaseMysql.h \
DatabasePostgre.h \
DatabaseSqlite.cpp \
DatabaseSqlite.h \
DBCEnums.h \
Field.cpp \
Field.h \
MySQLDelayThread.h \
PGSQLDelayThread.h \
QueryResult.h \
QueryResultMysql.cpp \
QueryResultMysql.h \
QueryResultPostgre.cpp \
QueryResultPostgre.h \
QueryResultSqlite.cpp \
QueryResultSqlite.h \
SQLStorage.cpp \
SQLStorage.h \
SQLStorageImpl.h \
SqlDelayThread.cpp \
SqlDelayThread.h \
SqlOperations.cpp \
SqlOperations.h \
dbcfile.cpp \
dbcfile.h
DBCStores.cpp \
DBCStores.h \
DBCStructure.h \
DBCfmt.cpp \
Database.cpp \
Database.h \
DatabaseEnv.h \
DatabaseImpl.h \
DatabaseMysql.cpp \
DatabasePostgre.cpp \
DatabaseMysql.h \
DatabasePostgre.h \
DatabaseSqlite.cpp \
DatabaseSqlite.h \
DBCEnums.h \
Field.cpp \
Field.h \
MySQLDelayThread.h \
PGSQLDelayThread.h \
QueryResult.h \
QueryResultMysql.cpp \
QueryResultMysql.h \
QueryResultPostgre.cpp \
QueryResultPostgre.h \
QueryResultSqlite.cpp \
QueryResultSqlite.h \
SQLStorage.cpp \
SQLStorage.h \
SQLStorageImpl.h \
SqlDelayThread.cpp \
SqlDelayThread.h \
SqlOperations.cpp \
SqlOperations.h \
dbcfile.cpp \
dbcfile.h

View file

@ -30,24 +30,24 @@ noinst_LIBRARIES = libmangosshared.a
# libmangosshared library will later be reused by ...
libmangosshared_a_SOURCES = \
Base.cpp \
Base.h \
ByteBuffer.h \
Common.cpp \
Common.h \
Errors.h \
Log.cpp \
Log.h \
MemoryLeaks.cpp \
MemoryLeaks.h \
ProgressBar.cpp \
ProgressBar.h \
Timer.h \
Util.cpp \
Util.h \
WorldPacket.h \
revision_nr.h \
revision.h
Base.cpp \
Base.h \
ByteBuffer.h \
Common.cpp \
Common.h \
Errors.h \
Log.cpp \
Log.h \
MemoryLeaks.cpp \
MemoryLeaks.h \
ProgressBar.cpp \
ProgressBar.h \
Timer.h \
Util.cpp \
Util.h \
WorldPacket.h \
revision_nr.h \
revision.h
# Get revision (git or svn)
REVISION_FILE = revision.h
@ -63,16 +63,16 @@ $(REVISION_FILE) : $(top_builddir)/src/tools/genrevision/genrevision FORCE
## Additional files to include when running 'make dist'
# Disabled packet logger
EXTRA_DIST = \
PacketLog.cpp \
PacketLog.h
PacketLog.cpp \
PacketLog.h
# System configuration
EXTRA_DIST += \
SystemConfig.h
SystemConfig.h
# System Win32 files
EXTRA_DIST += \
ServiceWin32.cpp \
ServiceWin32.h \
WheatyExceptionReport.cpp \
WheatyExceptionReport.h
ServiceWin32.cpp \
ServiceWin32.h \
WheatyExceptionReport.cpp \
WheatyExceptionReport.h

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "7331"
#define REVISION_NR "7360"
#endif // __REVISION_NR_H__

View file

@ -27,30 +27,30 @@ AM_CPPFLAGS = $(MANGOS_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir) -I$(sr
noinst_LIBRARIES = libmangosvmaps.a
libmangosvmaps_a_SOURCES = \
AABSPTree.h \
BaseModel.cpp \
BaseModel.h \
CoordModelMapping.cpp \
CoordModelMapping.h \
DebugCmdLogger.cpp \
DebugCmdLogger.h \
IVMapManager.h \
ManagedModelContainer.cpp \
ManagedModelContainer.h \
ModelContainer.cpp \
ModelContainer.h \
NodeValueAccess.h \
ShortBox.h \
ShortVector.h \
SubModel.cpp \
SubModel.h \
TileAssembler.cpp \
TileAssembler.h \
TreeNode.cpp \
TreeNode.h \
VMapDefinitions.h \
VMapFactory.cpp \
VMapFactory.h \
VMapManager.cpp \
VMapManager.h \
VMapTools.h
AABSPTree.h \
BaseModel.cpp \
BaseModel.h \
CoordModelMapping.cpp \
CoordModelMapping.h \
DebugCmdLogger.cpp \
DebugCmdLogger.h \
IVMapManager.h \
ManagedModelContainer.cpp \
ManagedModelContainer.h \
ModelContainer.cpp \
ModelContainer.h \
NodeValueAccess.h \
ShortBox.h \
ShortVector.h \
SubModel.cpp \
SubModel.h \
TileAssembler.cpp \
TileAssembler.h \
TreeNode.cpp \
TreeNode.h \
VMapDefinitions.h \
VMapFactory.cpp \
VMapFactory.h \
VMapManager.cpp \
VMapManager.h \
VMapTools.h