mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 22:37:03 +00:00
Merge branch 'master' into 310
Conflicts: src/game/BattleGroundHandler.cpp src/game/Unit.cpp
This commit is contained in:
commit
769a24252b
22 changed files with 795 additions and 774 deletions
|
|
@ -22,7 +22,7 @@
|
|||
DROP TABLE IF EXISTS `db_version`;
|
||||
CREATE TABLE `db_version` (
|
||||
`version` varchar(120) default NULL,
|
||||
`required_7627_01_mangos_achievement_criteria_data` bit(1) default NULL
|
||||
`required_7633_01_mangos_achievement_criteria_data` bit(1) default NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
|
||||
|
||||
--
|
||||
|
|
@ -46,7 +46,7 @@ CREATE TABLE `achievement_criteria_data` (
|
|||
`type` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`value1` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
||||
`value2` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`criteria_id`)
|
||||
PRIMARY KEY (`criteria_id`,`type`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Achievment system';
|
||||
|
||||
--
|
||||
|
|
|
|||
5
sql/updates/7633_01_mangos_achievement_criteria_data.sql
Normal file
5
sql/updates/7633_01_mangos_achievement_criteria_data.sql
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
ALTER TABLE db_version CHANGE COLUMN required_7627_01_mangos_achievement_criteria_data required_7633_01_mangos_achievement_criteria_data bit;
|
||||
|
||||
ALTER TABLE `achievement_criteria_data`
|
||||
DROP PRIMARY KEY,
|
||||
ADD PRIMARY KEY (`criteria_id`,`type`);
|
||||
|
|
@ -218,6 +218,7 @@ pkgdata_DATA = \
|
|||
7622_02_mangos_creature_ai_summons.sql \
|
||||
7622_03_mangos_creature_ai_texts.sql \
|
||||
7627_01_mangos_achievement_criteria_data.sql \
|
||||
7633_01_mangos_achievement_criteria_data.sql \
|
||||
README
|
||||
|
||||
## Additional files to include when running 'make dist'
|
||||
|
|
@ -416,4 +417,5 @@ EXTRA_DIST = \
|
|||
7622_02_mangos_creature_ai_summons.sql \
|
||||
7622_03_mangos_creature_ai_texts.sql \
|
||||
7627_01_mangos_achievement_criteria_data.sql \
|
||||
7633_01_mangos_achievement_criteria_data.sql \
|
||||
README
|
||||
|
|
|
|||
|
|
@ -79,17 +79,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
|
|||
switch(criteria->requiredType)
|
||||
{
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2:
|
||||
switch(dataType)
|
||||
{
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE:
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_CREATURE:
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_CLASS_RACE:
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_LESS_HEALTH:
|
||||
break;
|
||||
default:
|
||||
sLog.outErrorDb( "Table `achievement_criteria_data` for criteria (Entry: %u Type: %u) have wrong data type (%u), ignore.", criteria->ID, criteria->requiredType,dataType);
|
||||
return false;
|
||||
}
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE:
|
||||
break;
|
||||
default:
|
||||
sLog.outErrorDb( "Table `achievement_criteria_data` have data for not supported criteria type (Entry: %u Type: %u), ignore.", criteria->ID, criteria->requiredType);
|
||||
|
|
@ -100,7 +90,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
|
|||
{
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE:
|
||||
return true;
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_CREATURE:
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_CREATURE:
|
||||
if(!creature.id || !objmgr.GetCreatureTemplate(creature.id))
|
||||
{
|
||||
sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_CREATURE (%u) have not existed creature id in value1 (%u), ignore.",
|
||||
|
|
@ -108,7 +98,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
|
|||
return false;
|
||||
}
|
||||
return true;
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_CLASS_RACE:
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE:
|
||||
if(!classRace.class_id && !classRace.race_id)
|
||||
{
|
||||
sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_CLASS_RACE (%u) must have not 0 in one from value fields, ignore.",
|
||||
|
|
@ -128,14 +118,48 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
|
|||
return false;
|
||||
}
|
||||
return true;
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_LESS_HEALTH:
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_LESS_HEALTH:
|
||||
if(health.percent < 1 || health.percent > 100)
|
||||
{
|
||||
sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_LESS_HEALTH (%u) have prong percent value in value1 (%u), ignore.",
|
||||
sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_LESS_HEALTH (%u) have wrong percent value in value1 (%u), ignore.",
|
||||
criteria->ID, criteria->requiredType,dataType,health.percent);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_DEAD:
|
||||
return true;
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA:
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA:
|
||||
{
|
||||
SpellEntry const* spellEntry = sSpellStore.LookupEntry(aura.spell_id);
|
||||
if(!spellEntry)
|
||||
{
|
||||
sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type %s (%u) have wrong spell id in value1 (%u), ignore.",
|
||||
criteria->ID, criteria->requiredType,(dataType==ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA?"ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA":"ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA"),dataType,aura.spell_id);
|
||||
return false;
|
||||
}
|
||||
if(aura.effect_idx >= 3)
|
||||
{
|
||||
sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type %s (%u) have wrong spell effect index in value2 (%u), ignore.",
|
||||
criteria->ID, criteria->requiredType,(dataType==ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA?"ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA":"ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA"),dataType,aura.effect_idx);
|
||||
return false;
|
||||
}
|
||||
if(!spellEntry->EffectApplyAuraName[aura.effect_idx])
|
||||
{
|
||||
sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type %s (%u) have non-aura spell effect (ID: %u Effect: %u), ignore.",
|
||||
criteria->ID, criteria->requiredType,(dataType==ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA?"ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA":"ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA"),dataType,aura.spell_id,aura.effect_idx);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA:
|
||||
if(!GetAreaEntryByAreaID(area.id))
|
||||
{
|
||||
sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA (%u) have wrong area id in value1 (%u), ignore.",
|
||||
criteria->ID, criteria->requiredType,dataType,area.id);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
default:
|
||||
sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) have data for not supported data type (%u), ignore.", criteria->ID, criteria->requiredType,dataType);
|
||||
return false;
|
||||
|
|
@ -143,38 +167,56 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool AchievementCriteriaData::Meets( Unit const* target ) const
|
||||
bool AchievementCriteriaData::Meets(Player const* source, Unit const* target) const
|
||||
{
|
||||
if (!target)
|
||||
return false;
|
||||
|
||||
switch(dataType)
|
||||
{
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE:
|
||||
return true;
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_CREATURE:
|
||||
if (target->GetTypeId()!=TYPEID_UNIT)
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_CREATURE:
|
||||
if (!target || target->GetTypeId()!=TYPEID_UNIT)
|
||||
return false;
|
||||
if (target->GetEntry() != creature.id)
|
||||
return false;
|
||||
return true;
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_CLASS_RACE:
|
||||
if (target->GetTypeId()!=TYPEID_PLAYER)
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE:
|
||||
if (!target || target->GetTypeId()!=TYPEID_PLAYER)
|
||||
return false;
|
||||
if(classRace.class_id && classRace.class_id != ((Player*)target)->getClass())
|
||||
return false;
|
||||
if(classRace.race_id && classRace.race_id != ((Player*)target)->getRace())
|
||||
return false;
|
||||
return true;
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_LESS_HEALTH:
|
||||
if (target->GetTypeId()!=TYPEID_PLAYER)
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_LESS_HEALTH:
|
||||
if (!target || target->GetTypeId()!=TYPEID_PLAYER)
|
||||
return false;
|
||||
return target->GetHealth()*100 <= health.percent*target->GetMaxHealth();
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_DEAD:
|
||||
return target && target->GetTypeId() == TYPEID_PLAYER && !target->isAlive() && ((Player*)target)->GetDeathTimer() != 0;
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA:
|
||||
return source->HasAura(aura.spell_id,aura.effect_idx);
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA:
|
||||
{
|
||||
uint32 zone_id,area_id;
|
||||
source->GetZoneAndAreaId(zone_id,area_id);
|
||||
return area.id==zone_id || area.id==area_id;
|
||||
}
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA:
|
||||
return target && target->HasAura(aura.spell_id,aura.effect_idx);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AchievementCriteriaDataSet::Meets(Player const* source, Unit const* target) const
|
||||
{
|
||||
for(Storage::const_iterator itr = storage.begin(); itr != storage.end(); ++itr)
|
||||
if(!itr->Meets(source,target))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
AchievementMgr::AchievementMgr(Player *player)
|
||||
{
|
||||
m_player = player;
|
||||
|
|
@ -863,22 +905,18 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
|
|||
case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE:
|
||||
{
|
||||
// miscvalue1 = emote
|
||||
// miscvalue2 = achievement->ID for special requirement
|
||||
if(!miscvalue1)
|
||||
continue;
|
||||
if(miscvalue1 != achievementCriteria->do_emote.emoteID)
|
||||
continue;
|
||||
if(achievementCriteria->do_emote.count)
|
||||
{
|
||||
// harcoded case
|
||||
if(achievement->ID==247)
|
||||
{
|
||||
if (!unit || unit->GetTypeId() != TYPEID_PLAYER ||
|
||||
unit->isAlive() || ((Player*)unit)->GetDeathTimer() == 0)
|
||||
// those requirements couldn't be found in the dbc
|
||||
AchievementCriteriaDataSet const* data = achievementmgr.GetCriteriaDataSet(achievementCriteria);
|
||||
if(!data)
|
||||
continue;
|
||||
}
|
||||
// expected as scripted case
|
||||
else if(!miscvalue2 || !achievement->ID != miscvalue2)
|
||||
|
||||
if(!data->Meets(GetPlayer(),unit))
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -949,11 +987,11 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
|
|||
continue;
|
||||
|
||||
// those requirements couldn't be found in the dbc
|
||||
AchievementCriteriaData const* data = achievementmgr.GetCriteriaData(achievementCriteria);
|
||||
AchievementCriteriaDataSet const* data = achievementmgr.GetCriteriaDataSet(achievementCriteria);
|
||||
if(!data)
|
||||
continue;
|
||||
|
||||
if(!data->Meets(unit))
|
||||
if(!data->Meets(GetPlayer(),unit))
|
||||
continue;
|
||||
|
||||
SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
|
||||
|
|
@ -1478,7 +1516,14 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData()
|
|||
if(!data.IsValid(criteria))
|
||||
continue;
|
||||
|
||||
m_criteriaDataMap[criteria_id] = data;
|
||||
// this will allocate empty data set storage
|
||||
AchievementCriteriaDataSet& dataSet = m_criteriaDataMap[criteria_id];
|
||||
|
||||
// add real data only for not NONE data types
|
||||
if(data.dataType!=ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE)
|
||||
dataSet.Add(data);
|
||||
|
||||
// counting data by and data types
|
||||
++count;
|
||||
} while(result->NextRow());
|
||||
|
||||
|
|
@ -1494,7 +1539,11 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData()
|
|||
switch(criteria->requiredType)
|
||||
{
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2:
|
||||
if(!GetCriteriaData(criteria))
|
||||
if(!GetCriteriaDataSet(criteria))
|
||||
sLog.outErrorDb( "Table `achievement_criteria_data` not have expected data for for criteria (Entry: %u Type: %u).", criteria->ID, criteria->requiredType);
|
||||
break;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE: // need skip generic cases
|
||||
if(criteria->do_emote.count && !GetCriteriaDataSet(criteria))
|
||||
sLog.outErrorDb( "Table `achievement_criteria_data` not have expected data for for criteria (Entry: %u Type: %u).", criteria->ID, criteria->requiredType);
|
||||
break;
|
||||
default: // unexpected case processed in IsValid check
|
||||
|
|
|
|||
|
|
@ -41,15 +41,20 @@ struct CriteriaProgress
|
|||
};
|
||||
|
||||
enum AchievementCriteriaDataType
|
||||
{ // value1 value2 for the Condition enumed
|
||||
{ // value1 value2 comment
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE = 0, // 0 0
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_CREATURE = 1, // creature_id
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_CLASS_RACE = 2, // class_id race_id
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_LESS_HEALTH = 3, // health_percent
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_CREATURE = 1, // creature_id 0
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE = 2, // class_id race_id
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_LESS_HEALTH= 3, // health_percent 0
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_DEAD = 4, // 0 0 not corpse (not released body)
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA = 5, // spell_id effect_idx
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA = 6, // area id 0
|
||||
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA = 7, // spell_id effect_idx
|
||||
};
|
||||
|
||||
#define MAX_ACHIEVEMENT_CRITERIA_DATA_TYPE 4 // maximum value in AchievementCriteriaDataType enum
|
||||
#define MAX_ACHIEVEMENT_CRITERIA_DATA_TYPE 8 // maximum value in AchievementCriteriaDataType enum
|
||||
|
||||
class Player;
|
||||
class Unit;
|
||||
|
||||
struct AchievementCriteriaData
|
||||
|
|
@ -57,23 +62,35 @@ struct AchievementCriteriaData
|
|||
AchievementCriteriaDataType dataType;
|
||||
union
|
||||
{
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_CREATURE
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_T_CREATURE
|
||||
struct
|
||||
{
|
||||
uint32 id;
|
||||
} creature;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_CLASS_RACE
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE
|
||||
struct
|
||||
{
|
||||
uint32 class_id;
|
||||
uint32 race_id;
|
||||
} classRace;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_LESS_HEALTH
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_LESS_HEALTH
|
||||
struct
|
||||
{
|
||||
uint32 percent;
|
||||
} health;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA
|
||||
struct
|
||||
{
|
||||
uint32 spell_id;
|
||||
uint32 effect_idx;
|
||||
} aura;
|
||||
// ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA
|
||||
struct
|
||||
{
|
||||
uint32 id;
|
||||
} area;
|
||||
// ...
|
||||
struct
|
||||
{
|
||||
uint32 value1;
|
||||
|
|
@ -94,11 +111,20 @@ struct AchievementCriteriaData
|
|||
}
|
||||
|
||||
bool IsValid(AchievementCriteriaEntry const* criteria);
|
||||
// Checks correctness of values
|
||||
bool Meets(Unit const* target) const;// Checks if the target meets the requirement
|
||||
bool Meets(Player const* source, Unit const* target) const;
|
||||
};
|
||||
|
||||
typedef std::map<uint32,AchievementCriteriaData> AchievementCriteriaDataMap;
|
||||
struct AchievementCriteriaDataSet
|
||||
{
|
||||
typedef std::vector<AchievementCriteriaData> Storage;
|
||||
void Add(AchievementCriteriaData const& data) { storage.push_back(data); }
|
||||
bool Meets(Player const* source, Unit const* target) const;
|
||||
private:
|
||||
Storage storage;
|
||||
};
|
||||
|
||||
|
||||
typedef std::map<uint32,AchievementCriteriaDataSet> AchievementCriteriaDataMap;
|
||||
|
||||
struct AchievementReward
|
||||
{
|
||||
|
|
@ -194,7 +220,7 @@ class AchievementGlobalMgr
|
|||
return iter!=m_achievementRewardLocales.end() ? &iter->second : NULL;
|
||||
}
|
||||
|
||||
AchievementCriteriaData const* GetCriteriaData(AchievementCriteriaEntry const *achievementCriteria)
|
||||
AchievementCriteriaDataSet const* GetCriteriaDataSet(AchievementCriteriaEntry const *achievementCriteria)
|
||||
{
|
||||
AchievementCriteriaDataMap::const_iterator iter = m_criteriaDataMap.find(achievementCriteria->ID);
|
||||
return iter!=m_criteriaDataMap.end() ? &iter->second : NULL;
|
||||
|
|
|
|||
|
|
@ -739,9 +739,6 @@ void BattleGround::EndBattleGround(uint32 winner)
|
|||
loser_arena_team->NotifyStatsChanged();
|
||||
}
|
||||
|
||||
// inform invited players about the removal
|
||||
sBattleGroundMgr.m_BattleGroundQueues[BattleGroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType())].BGEndedRemoveInvites(this);
|
||||
|
||||
if (winmsg_id)
|
||||
SendMessageToAll(winmsg_id, CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
||||
}
|
||||
|
|
@ -1603,8 +1600,6 @@ void BattleGround::EndNow()
|
|||
RemoveFromBGFreeSlotQueue();
|
||||
SetStatus(STATUS_WAIT_LEAVE);
|
||||
SetEndTime(0);
|
||||
// inform invited players about the removal
|
||||
sBattleGroundMgr.m_BattleGroundQueues[BattleGroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType())].BGEndedRemoveInvites(this);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -430,8 +430,16 @@ bool BattleGroundQueue::InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * b
|
|||
// not yet invited
|
||||
// set invitation
|
||||
ginfo->IsInvitedToBGInstanceGUID = bg->GetInstanceID();
|
||||
BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType());
|
||||
BattleGroundTypeId bgTypeId = bg->GetTypeID();
|
||||
BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, bg->GetArenaType());
|
||||
BGQueueIdBasedOnLevel queue_id = bg->GetQueueId();
|
||||
|
||||
// set ArenaTeamId for rated matches
|
||||
if (bg->isArena() && bg->isRated())
|
||||
bg->SetArenaTeamIdForTeam(ginfo->Team, ginfo->ArenaTeamId);
|
||||
|
||||
ginfo->RemoveInviteTime = getMSTime() + INVITE_ACCEPT_WAIT_TIME;
|
||||
|
||||
// loop through the players
|
||||
for(std::map<uint64,PlayerQueueInfo*>::iterator itr = ginfo->Players.begin(); itr != ginfo->Players.end(); ++itr)
|
||||
{
|
||||
|
|
@ -443,8 +451,19 @@ bool BattleGroundQueue::InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * b
|
|||
|
||||
// invite the player
|
||||
PlayerInvitedToBGUpdateAverageWaitTime(ginfo, queue_id);
|
||||
ginfo->RemoveInviteTime = getMSTime() + INVITE_ACCEPT_WAIT_TIME;
|
||||
sBattleGroundMgr.InvitePlayer(plr, bg->GetInstanceID(), bg->GetTypeID(), ginfo->Team);
|
||||
//sBattleGroundMgr.InvitePlayer(plr, bg, ginfo->Team);
|
||||
|
||||
// set invited player counters
|
||||
bg->IncreaseInvitedCount(ginfo->Team);
|
||||
|
||||
plr->SetInviteForBattleGroundQueueType(bgQueueTypeId, ginfo->IsInvitedToBGInstanceGUID);
|
||||
|
||||
// create remind invite events
|
||||
BGQueueInviteEvent* inviteEvent = new BGQueueInviteEvent(plr->GetGUID(), ginfo->IsInvitedToBGInstanceGUID, bgTypeId, ginfo->RemoveInviteTime);
|
||||
plr->m_Events.AddEvent(inviteEvent, plr->m_Events.CalculateTime(INVITATION_REMIND_TIME));
|
||||
// create automatic remove events
|
||||
BGQueueRemoveEvent* removeEvent = new BGQueueRemoveEvent(plr->GetGUID(), ginfo->IsInvitedToBGInstanceGUID, bgTypeId, bgQueueTypeId, ginfo->RemoveInviteTime);
|
||||
plr->m_Events.AddEvent(removeEvent, plr->m_Events.CalculateTime(INVITE_ACCEPT_WAIT_TIME));
|
||||
|
||||
WorldPacket data;
|
||||
|
||||
|
|
@ -462,63 +481,6 @@ bool BattleGroundQueue::InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * b
|
|||
return false;
|
||||
}
|
||||
|
||||
// used to remove the Enter Battle window if the battle has already ended, but someone still has it
|
||||
// (this can happen in arenas mainly, since the preparation is shorter than the timer for the bgqueueremove event
|
||||
void BattleGroundQueue::BGEndedRemoveInvites(BattleGround *bg)
|
||||
{
|
||||
BGQueueIdBasedOnLevel queue_id = bg->GetQueueId();
|
||||
uint32 bgInstanceId = bg->GetInstanceID();
|
||||
BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType());
|
||||
GroupsQueueType::iterator itr, next;
|
||||
for(uint32 i = 0; i < BG_QUEUE_GROUP_TYPES_COUNT; i++)
|
||||
{
|
||||
itr = m_QueuedGroups[queue_id][i].begin();
|
||||
next = itr;
|
||||
while (next != m_QueuedGroups[queue_id][i].end())
|
||||
{
|
||||
// must do this way, because the groupinfo will be deleted when all playerinfos are removed
|
||||
itr = next;
|
||||
++next;
|
||||
GroupQueueInfo * ginfo = (*itr);
|
||||
// if group was invited to this bg instance, then remove all references
|
||||
if( ginfo->IsInvitedToBGInstanceGUID == bgInstanceId )
|
||||
{
|
||||
// after removing this much playerinfos, the ginfo will be deleted, so we'll use a for loop
|
||||
uint32 to_remove = ginfo->Players.size();
|
||||
for(uint32 j = 0; j < to_remove; j++)
|
||||
{
|
||||
// always remove the first one in the group
|
||||
std::map<uint64, PlayerQueueInfo * >::iterator itr2 = ginfo->Players.begin();
|
||||
if( itr2 == ginfo->Players.end() )
|
||||
{
|
||||
sLog.outError("Empty Players in ginfo, this should never happen!");
|
||||
return;
|
||||
}
|
||||
// get the player
|
||||
Player * plr = objmgr.GetPlayer(itr2->first);
|
||||
if( !plr )
|
||||
{
|
||||
sLog.outError("Player offline when trying to remove from GroupQueueInfo, this should never happen.");
|
||||
continue;
|
||||
}
|
||||
|
||||
// get the queueslot
|
||||
uint32 queueSlot = plr->GetBattleGroundQueueIndex(bgQueueTypeId);
|
||||
if (queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES) // player is in queue
|
||||
{
|
||||
plr->RemoveBattleGroundQueueId(bgQueueTypeId);
|
||||
// remove player from queue, this might delete the ginfo as well! don't use that pointer after this!
|
||||
RemovePlayer(itr2->first, true);
|
||||
WorldPacket data;
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0);
|
||||
plr->GetSession()->SendPacket(&data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
This function is inviting players to already running battlegrounds
|
||||
Invitation type is based on config file
|
||||
|
|
@ -1048,28 +1010,27 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve
|
|||
bool BGQueueInviteEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
|
||||
{
|
||||
Player* plr = objmgr.GetPlayer( m_PlayerGuid );
|
||||
|
||||
// player logged off (we should do nothing, he is correctly removed from queue in another procedure)
|
||||
if (!plr)
|
||||
return true;
|
||||
|
||||
// Player can be in another BG queue and must be removed in normal way in any case
|
||||
|
||||
BattleGround* bg = sBattleGroundMgr.GetBattleGround(m_BgInstanceGUID, m_BgTypeId);
|
||||
//if battleground ended and its instance deleted - do nothing
|
||||
if (!bg)
|
||||
return true;
|
||||
|
||||
BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType());
|
||||
uint32 queueSlot = plr->GetBattleGroundQueueIndex(bgQueueTypeId);
|
||||
if (queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES) // player is in queue
|
||||
if( queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES ) // player is in queue or in battleground
|
||||
{
|
||||
// check if player is invited to this bg ... this check must be here, because when player leaves queue and joins another, it would cause a problems
|
||||
// check if player is invited to this bg
|
||||
BattleGroundQueue::QueuedPlayersMap const& qpMap = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers;
|
||||
BattleGroundQueue::QueuedPlayersMap::const_iterator qItr = qpMap.find(m_PlayerGuid);
|
||||
if (qItr != qpMap.end() && qItr->second.GroupInfo->IsInvitedToBGInstanceGUID == m_BgInstanceGUID)
|
||||
if( qItr != qpMap.end() && qItr->second.GroupInfo->IsInvitedToBGInstanceGUID == m_BgInstanceGUID
|
||||
&& qItr->second.GroupInfo->RemoveInviteTime == m_RemoveTime )
|
||||
{
|
||||
WorldPacket data;
|
||||
//here must be remaining time
|
||||
//we must send remaining time in queue
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME - INVITATION_REMIND_TIME, 0, qItr->second.GroupInfo->ArenaType);
|
||||
plr->GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
|
@ -1079,10 +1040,18 @@ bool BGQueueInviteEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
|
|||
|
||||
void BGQueueInviteEvent::Abort(uint64 /*e_time*/)
|
||||
{
|
||||
//this should not be called
|
||||
sLog.outError("Battleground invite event ABORTED!");
|
||||
//do nothing
|
||||
}
|
||||
|
||||
/*
|
||||
this event has many possibilities when it is executed:
|
||||
1. player is in battleground ( he clicked enter on invitation window )
|
||||
2. player left battleground queue and he isn't there any more
|
||||
3. player left battleground queue and he joined it again and IsInvitedToBGInstanceGUID = 0
|
||||
4. player left queue and he joined again and he has been invited to same battleground again -> we should not remove him from queue yet
|
||||
5. player is invited to bg and he didn't choose what to do and timer expired - only in this condition we should call queue::RemovePlayer
|
||||
we must remove player in the 5. case even if battleground object doesn't exist!
|
||||
*/
|
||||
bool BGQueueRemoveEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
|
||||
{
|
||||
Player* plr = objmgr.GetPlayer( m_PlayerGuid );
|
||||
|
|
@ -1091,30 +1060,32 @@ bool BGQueueRemoveEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
|
|||
return true;
|
||||
|
||||
BattleGround* bg = sBattleGroundMgr.GetBattleGround(m_BgInstanceGUID, m_BgTypeId);
|
||||
if (!bg)
|
||||
return true;
|
||||
//battleground can be deleted already when we are removing queue info
|
||||
//bg pointer can be NULL! so use it carefully!
|
||||
|
||||
uint32 queueSlot = plr->GetBattleGroundQueueIndex(m_BgQueueTypeId);
|
||||
if( queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES ) // player is in queue, or in Battleground
|
||||
{
|
||||
// check if player is in queue for this BG and if we are removing his invite event
|
||||
BattleGroundQueue::QueuedPlayersMap& qpMap = sBattleGroundMgr.m_BattleGroundQueues[m_BgQueueTypeId].m_QueuedPlayers;
|
||||
BattleGroundQueue::QueuedPlayersMap::iterator qMapItr = qpMap.find(m_PlayerGuid);
|
||||
if( qMapItr != qpMap.end() && qMapItr->second.GroupInfo
|
||||
&& qMapItr->second.GroupInfo->IsInvitedToBGInstanceGUID == m_BgInstanceGUID
|
||||
&& qMapItr->second.GroupInfo->RemoveInviteTime == m_RemoveTime )
|
||||
{
|
||||
sLog.outDebug("Battleground: removing player %u from bg queue for instance %u because of not pressing enter battle in time.",plr->GetGUIDLow(),m_BgInstanceGUID);
|
||||
|
||||
BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType());
|
||||
uint32 queueSlot = plr->GetBattleGroundQueueIndex(bgQueueTypeId);
|
||||
if (queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES) // player is in queue
|
||||
{
|
||||
// check if player is invited to this bg ... this check must be here, because when player leaves queue and joins another, it would cause a problems
|
||||
BattleGroundQueue::QueuedPlayersMap& qpMap = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers;
|
||||
BattleGroundQueue::QueuedPlayersMap::iterator qMapItr = qpMap.find(m_PlayerGuid);
|
||||
if (qMapItr != qpMap.end() && qMapItr->second.GroupInfo && qMapItr->second.GroupInfo->IsInvitedToBGInstanceGUID == m_BgInstanceGUID)
|
||||
{
|
||||
plr->RemoveBattleGroundQueueId(bgQueueTypeId);
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].RemovePlayer(m_PlayerGuid, true);
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bg->GetTypeID(), bg->GetQueueId());
|
||||
plr->RemoveBattleGroundQueueId(m_BgQueueTypeId);
|
||||
sBattleGroundMgr.m_BattleGroundQueues[m_BgQueueTypeId].RemovePlayer(m_PlayerGuid, true);
|
||||
//update queues if battleground isn't ended
|
||||
if (bg)
|
||||
sBattleGroundMgr.m_BattleGroundQueues[m_BgQueueTypeId].Update(m_BgTypeId, bg->GetQueueId());
|
||||
|
||||
WorldPacket data;
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0);
|
||||
plr->GetSession()->SendPacket(&data);
|
||||
}
|
||||
}
|
||||
else
|
||||
sLog.outDebug("Battleground: Player was already removed from queue");
|
||||
|
||||
//event will be deleted
|
||||
return true;
|
||||
|
|
@ -1122,8 +1093,7 @@ bool BGQueueRemoveEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
|
|||
|
||||
void BGQueueRemoveEvent::Abort(uint64 /*e_time*/)
|
||||
{
|
||||
//this should not be called
|
||||
sLog.outError("Battleground remove event ABORTED!");
|
||||
//do nothing
|
||||
}
|
||||
|
||||
/*********************************************************/
|
||||
|
|
@ -1232,7 +1202,8 @@ void BattleGroundMgr::Update(uint32 diff)
|
|||
void BattleGroundMgr::BuildBattleGroundStatusPacket(WorldPacket *data, BattleGround *bg, uint8 QueueSlot, uint8 StatusID, uint32 Time1, uint32 Time2, uint8 arenatype)
|
||||
{
|
||||
// we can be in 3 queues in same time...
|
||||
if(StatusID == 0)
|
||||
|
||||
if (StatusID == 0 || !bg)
|
||||
{
|
||||
data->Initialize(SMSG_BATTLEFIELD_STATUS, 4*3);
|
||||
*data << uint32(QueueSlot); // queue id (0...2)
|
||||
|
|
@ -1465,43 +1436,6 @@ void BattleGroundMgr::BuildPlayerJoinedBattleGroundPacket(WorldPacket *data, Pla
|
|||
*data << uint64(plr->GetGUID());
|
||||
}
|
||||
|
||||
void BattleGroundMgr::InvitePlayer(Player* plr, uint32 bgInstanceGUID, BattleGroundTypeId bgTypeId, uint32 team)
|
||||
{
|
||||
// set invited player counters:
|
||||
BattleGround* bg = GetBattleGround(bgInstanceGUID, bgTypeId);
|
||||
if(!bg)
|
||||
return;
|
||||
bg->IncreaseInvitedCount(team);
|
||||
|
||||
plr->SetInviteForBattleGroundQueueType(BGQueueTypeId(bg->GetTypeID(),bg->GetArenaType()), bgInstanceGUID);
|
||||
|
||||
// set the arena teams for rated matches
|
||||
if(bg->isArena() && bg->isRated())
|
||||
{
|
||||
switch(bg->GetArenaType())
|
||||
{
|
||||
case ARENA_TYPE_2v2:
|
||||
bg->SetArenaTeamIdForTeam(team, plr->GetArenaTeamId(0));
|
||||
break;
|
||||
case ARENA_TYPE_3v3:
|
||||
bg->SetArenaTeamIdForTeam(team, plr->GetArenaTeamId(1));
|
||||
break;
|
||||
case ARENA_TYPE_5v5:
|
||||
bg->SetArenaTeamIdForTeam(team, plr->GetArenaTeamId(2));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// create invite events:
|
||||
//add events to player's counters ---- this is not good way - there should be something like global event processor, where we should add those events
|
||||
BGQueueInviteEvent* inviteEvent = new BGQueueInviteEvent(plr->GetGUID(), bgInstanceGUID, bgTypeId);
|
||||
plr->m_Events.AddEvent(inviteEvent, plr->m_Events.CalculateTime(INVITATION_REMIND_TIME));
|
||||
BGQueueRemoveEvent* removeEvent = new BGQueueRemoveEvent(plr->GetGUID(), bgInstanceGUID, bgTypeId, team);
|
||||
plr->m_Events.AddEvent(removeEvent, plr->m_Events.CalculateTime(INVITE_ACCEPT_WAIT_TIME));
|
||||
}
|
||||
|
||||
BattleGround * BattleGroundMgr::GetBattleGroundThroughClientInstance(uint32 instanceId, BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id)
|
||||
{
|
||||
//cause at HandleBattleGroundJoinOpcode the clients sends the instanceid he gets from
|
||||
|
|
|
|||
|
|
@ -84,7 +84,6 @@ class BattleGroundQueue
|
|||
uint32 GetAverageQueueWaitTime(GroupQueueInfo* ginfo, BGQueueIdBasedOnLevel queue_id);
|
||||
|
||||
void DecreaseGroupLength(uint32 queueId, uint32 AsGroup);
|
||||
void BGEndedRemoveInvites(BattleGround * bg);
|
||||
void AnnounceWorld(GroupQueueInfo *ginfo, const uint64& playerGUID, bool isAddedToQueue);
|
||||
|
||||
typedef std::map<uint64, PlayerQueueInfo> QueuedPlayersMap;
|
||||
|
|
@ -136,8 +135,8 @@ class BattleGroundQueue
|
|||
class BGQueueInviteEvent : public BasicEvent
|
||||
{
|
||||
public:
|
||||
BGQueueInviteEvent(const uint64& pl_guid, uint32 BgInstanceGUID, BattleGroundTypeId BgTypeId) :
|
||||
m_PlayerGuid(pl_guid), m_BgInstanceGUID(BgInstanceGUID), m_BgTypeId(BgTypeId)
|
||||
BGQueueInviteEvent(const uint64& pl_guid, uint32 BgInstanceGUID, BattleGroundTypeId BgTypeId, uint32 removeTime) :
|
||||
m_PlayerGuid(pl_guid), m_BgInstanceGUID(BgInstanceGUID), m_BgTypeId(BgTypeId), m_RemoveTime(removeTime)
|
||||
{
|
||||
};
|
||||
virtual ~BGQueueInviteEvent() {};
|
||||
|
|
@ -147,17 +146,20 @@ class BGQueueInviteEvent : public BasicEvent
|
|||
private:
|
||||
uint64 m_PlayerGuid;
|
||||
uint32 m_BgInstanceGUID;
|
||||
uint32 m_RemoveTime;
|
||||
BattleGroundTypeId m_BgTypeId;
|
||||
};
|
||||
|
||||
/*
|
||||
This class is used to remove player from BG queue after 2 minutes from first invitation
|
||||
This class is used to remove player from BG queue after 1 minute 20 seconds from first invitation
|
||||
We must store removeInvite time in case player left queue and joined and is invited again
|
||||
We must store bgQueueTypeId, because battleground can be deleted already, when player entered it
|
||||
*/
|
||||
class BGQueueRemoveEvent : public BasicEvent
|
||||
{
|
||||
public:
|
||||
BGQueueRemoveEvent(const uint64& pl_guid, uint32 bgInstanceGUID, BattleGroundTypeId BgTypeId, uint32 playersTeam) :
|
||||
m_PlayerGuid(pl_guid), m_BgInstanceGUID(bgInstanceGUID), m_BgTypeId(BgTypeId), m_PlayersTeam(playersTeam)
|
||||
BGQueueRemoveEvent(const uint64& pl_guid, uint32 bgInstanceGUID, BattleGroundTypeId BgTypeId, BattleGroundQueueTypeId bgQueueTypeId, uint32 removeTime) :
|
||||
m_PlayerGuid(pl_guid), m_BgInstanceGUID(bgInstanceGUID), m_BgTypeId(BgTypeId), m_BgQueueTypeId(bgQueueTypeId), m_RemoveTime(removeTime)
|
||||
{
|
||||
};
|
||||
virtual ~BGQueueRemoveEvent() {};
|
||||
|
|
@ -167,8 +169,9 @@ class BGQueueRemoveEvent : public BasicEvent
|
|||
private:
|
||||
uint64 m_PlayerGuid;
|
||||
uint32 m_BgInstanceGUID;
|
||||
uint32 m_PlayersTeam;
|
||||
uint32 m_RemoveTime;
|
||||
BattleGroundTypeId m_BgTypeId;
|
||||
BattleGroundQueueTypeId m_BgQueueTypeId;
|
||||
};
|
||||
|
||||
class BattleGroundMgr
|
||||
|
|
@ -190,10 +193,6 @@ class BattleGroundMgr
|
|||
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, BattleGroundTypeId bgTypeId, uint32 team);
|
||||
|
||||
/* Battlegrounds */
|
||||
BattleGround* GetBattleGroundThroughClientInstance(uint32 instanceId, BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id);
|
||||
BattleGround* GetBattleGround(uint32 InstanceID, BattleGroundTypeId bgTypeId); //there must be uint32 because MAX_BATTLEGROUND_TYPE_ID means unknown
|
||||
|
|
|
|||
|
|
@ -583,17 +583,15 @@ bool GameObject::LoadFromDB(uint32 guid, Map *map)
|
|||
if (!Create(guid,entry, map, phaseMask, x, y, z, ang, rotation0, rotation1, rotation2, rotation3, animprogress, go_state) )
|
||||
return false;
|
||||
|
||||
switch(GetGOInfo()->type)
|
||||
if(!GetDespawnPossibility())
|
||||
{
|
||||
case GAMEOBJECT_TYPE_DOOR:
|
||||
case GAMEOBJECT_TYPE_BUTTON:
|
||||
/* this code (in comment) isn't correct because in battlegrounds we need despawnable doors and buttons, pls remove
|
||||
SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NODESPAWN);
|
||||
m_spawnedByDefault = true;
|
||||
m_respawnDelayTime = 0;
|
||||
m_respawnTime = 0;
|
||||
break;*/
|
||||
default:
|
||||
}
|
||||
else
|
||||
{
|
||||
if(data->spawntimesecs >= 0)
|
||||
{
|
||||
m_spawnedByDefault = true;
|
||||
|
|
@ -613,7 +611,6 @@ bool GameObject::LoadFromDB(uint32 guid, Map *map)
|
|||
m_respawnDelayTime = -data->spawntimesecs;
|
||||
m_respawnTime = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -479,6 +479,20 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject
|
|||
}
|
||||
}
|
||||
|
||||
bool GetDespawnPossibility() const
|
||||
{
|
||||
switch(GetGoType())
|
||||
{
|
||||
case GAMEOBJECT_TYPE_DOOR: return GetGOInfo()->door.noDamageImmune;
|
||||
case GAMEOBJECT_TYPE_BUTTON: return GetGOInfo()->button.noDamageImmune;
|
||||
case GAMEOBJECT_TYPE_QUESTGIVER: return GetGOInfo()->questgiver.noDamageImmune;
|
||||
case GAMEOBJECT_TYPE_GOOBER: return GetGOInfo()->goober.noDamageImmune;
|
||||
case GAMEOBJECT_TYPE_FLAGSTAND: return GetGOInfo()->flagstand.noDamageImmune;
|
||||
case GAMEOBJECT_TYPE_FLAGDROP: return GetGOInfo()->flagdrop.noDamageImmune;
|
||||
default: return true;
|
||||
}
|
||||
}
|
||||
|
||||
time_t GetRespawnTime() const { return m_respawnTime; }
|
||||
time_t GetRespawnTimeEx() const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2516,7 +2516,7 @@ SpellMissInfo Unit::MagicSpellHitResult(Unit *pVictim, SpellEntry const *spell)
|
|||
HitChance -= int32(((Player*)pVictim)->GetRatingBonusValue(CR_HIT_TAKEN_SPELL)*100.0f);
|
||||
|
||||
if (HitChance < 100) HitChance = 100;
|
||||
if (HitChance > 9900) HitChance = 9900;
|
||||
if (HitChance > 10000) HitChance = 10000;
|
||||
|
||||
int32 tmp = 10000 - HitChance;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "7630"
|
||||
#define REVISION_NR "7635"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue