mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-22 10:05:32 +01:00
Merge pull request #7855 from horn/master
Core/LFG: Implemented seasonal bosses options and fixed entrance points for dungeons with multiple parts (like Dire Maul, Scarlet Monastery etc.)
This commit is contained in:
56
sql/updates/world/2012_10_05_00_world_misc.sql
Normal file
56
sql/updates/world/2012_10_05_00_world_misc.sql
Normal file
@@ -0,0 +1,56 @@
|
||||
/*!40101 SET NAMES utf8 */;
|
||||
|
||||
/*!40101 SET SQL_MODE=''*/;
|
||||
|
||||
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
||||
/* Table structure for table `lfg_entrance` */
|
||||
|
||||
DROP TABLE IF EXISTS `lfg_entrances`;
|
||||
|
||||
CREATE TABLE `lfg_entrances` (
|
||||
`dungeonId` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Unique id from LFGDungeons.dbc',
|
||||
`name` varchar(255) DEFAULT NULL,
|
||||
`position_x` float NOT NULL DEFAULT '0',
|
||||
`position_y` float NOT NULL DEFAULT '0',
|
||||
`position_z` float NOT NULL DEFAULT '0',
|
||||
`orientation` float NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`dungeonId`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
|
||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
||||
|
||||
|
||||
-- only The Frost Lord Ahune and The Crown Chemical Co. were taken from sniffs, others from areatrigger_teleport or guessed
|
||||
-- TODO: replace them by sniffed positions and probably use this table for all dungeons instead of areatrigger_teleport
|
||||
-- note: this table should be used more in Cataclysm and Mists of Pandaria (there will be all events like Zalazane's Fall and scenarios)
|
||||
DELETE FROM `lfg_entrances`;
|
||||
INSERT INTO `lfg_entrances` (`dungeonId`,`name`,`position_x`,`position_y`,`position_z`,`orientation`) VALUES
|
||||
(18,'Scarlet Monastery - Graveyard',1688.99,1053.48,18.6775,0.00117),
|
||||
(26,'Maraudon - Orange Crystals',1019.69,-458.31,-43.43,0.31),
|
||||
(34,'Dire Maul - East',44.4499,-154.822,-2.71201,0),
|
||||
(36,'Dire Maul - West',-62.9658,159.867,-3.46206,3.14788),
|
||||
(38,'Dire Maul - North',255.249,-16.0561,-2.58737,4.7),
|
||||
(40,'Stratholme - Main Gate',3395.09,-3380.25,142.702,0.1),
|
||||
(163,'Scarlet Monastery - Armory',1610.83,-323.433,18.6738,6.28022),
|
||||
(164,'Scarlet Monastery - Cathedral',855.683,1321.5,18.6709,0.001747),
|
||||
(165,'Scarlet Monastery - Library',255.346,-209.09,18.6773,6.26656),
|
||||
(272,'Maraudon - Purple Crystals',752.91,-616.53,-33.11,1.37)
|
||||
(273,'Maraudon - Pristine Waters',495.701904,17.337202,-96.31284,3.118538), -- guessed
|
||||
(274,'Stratholme - Service Entrance',3593.15,-3646.56,138.5,5.33),
|
||||
(285,'The Headless Horseman',1797.517212,1347.381104,18.8876,3.142), -- guessed
|
||||
(286,'The Frost Lord Ahune',-100.396,-95.9996,-4.28423,4.712389),
|
||||
(287,'Coren Direbrew',897.494995,-141.976349,-49.7563,2.125502), -- guessed
|
||||
(288,'The Crown Chemical Co.',-238.075,2166.43,88.853,1.134464);
|
||||
|
||||
DELETE FROM `lfg_dungeon_rewards` WHERE `dungeonId` BETWEEN 285 AND 288;
|
||||
INSERT INTO `lfg_dungeon_rewards` (`dungeonId`,`maxLevel`,`firstQuestId`,`firstMoneyVar`,`firstXPVar`,`otherQuestId`,`otherMoneyVar`,`otherXPVar`) VALUES
|
||||
(285,80,25482,0,0,0,0,0),
|
||||
(286,80,25484,0,0,0,0,0),
|
||||
(287,80,25483,0,0,0,0,0),
|
||||
(288,80,25485,0,0,0,0,0);
|
||||
|
||||
UPDATE `quest_template` SET `SpecialFlags`=`SpecialFlags`|8|1 WHERE `Id` IN (25482,25483,25484,25485);
|
||||
@@ -1203,7 +1203,7 @@ struct LFGDungeonEntry
|
||||
uint32 recmaxlevel; // 22
|
||||
int32 map; // 23
|
||||
uint32 difficulty; // 24
|
||||
//uint32 flags; // 25 (flags & 4) = IsHoliday
|
||||
uint32 flags; // 25
|
||||
uint32 type; // 26
|
||||
//uint32 unk; // 27
|
||||
//char* iconname; // 28
|
||||
|
||||
@@ -77,7 +77,7 @@ const char ItemLimitCategoryEntryfmt[]="nxxxxxxxxxxxxxxxxxii";
|
||||
const char ItemRandomPropertiesfmt[]="nxiiixxssssssssssssssssx";
|
||||
const char ItemRandomSuffixfmt[]="nssssssssssssssssxxiiixxiiixx";
|
||||
const char ItemSetEntryfmt[]="dssssssssssssssssxiiiiiiiiiixxxxxxxiiiiiiiiiiiiiiiiii";
|
||||
const char LFGDungeonEntryfmt[]="nxxxxxxxxxxxxxxxxxiiiiiiixixxixixxxxxxxxxxxxxxxxx";
|
||||
const char LFGDungeonEntryfmt[]="nxxxxxxxxxxxxxxxxxiiiiiiiiixxixixxxxxxxxxxxxxxxxx";
|
||||
const char LiquidTypefmt[]="nxxixixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||
const char LockEntryfmt[]="niiiiiiiiiiiiiiiiiiiiiiiixxxxxxxx";
|
||||
const char MailTemplateEntryfmt[]="nxxxxxxxxxxxxxxxxxssssssssssssssssx";
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "SocialMgr.h"
|
||||
#include "LFGMgr.h"
|
||||
#include "GroupMgr.h"
|
||||
#include "GameEventMgr.h"
|
||||
#include "LFGScripts.h"
|
||||
#include "LFGGroupData.h"
|
||||
#include "LFGPlayerData.h"
|
||||
@@ -185,6 +186,38 @@ void LFGMgr::LoadRewards()
|
||||
sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u lfg dungeon rewards in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
|
||||
}
|
||||
|
||||
void LFGMgr::LoadEntrancePositions()
|
||||
{
|
||||
uint32 oldMSTime = getMSTime();
|
||||
m_entrancePositions.clear();
|
||||
|
||||
QueryResult result = WorldDatabase.Query("SELECT dungeonId, position_x, position_y, position_z, orientation FROM lfg_entrances");
|
||||
|
||||
if (!result)
|
||||
{
|
||||
sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 lfg entrance positions. DB table `lfg_entrances` is empty!");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 count = 0;
|
||||
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
uint32 dungeonId = fields[0].GetUInt32();
|
||||
Position pos;
|
||||
pos.m_positionX = fields[1].GetFloat();
|
||||
pos.m_positionY = fields[2].GetFloat();
|
||||
pos.m_positionZ = fields[3].GetFloat();
|
||||
pos.m_orientation = fields[4].GetFloat();
|
||||
m_entrancePositions[dungeonId] = pos;
|
||||
++count;
|
||||
}
|
||||
while (result->NextRow());
|
||||
|
||||
sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u lfg entrance positions in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
|
||||
}
|
||||
|
||||
void LFGMgr::Update(uint32 diff)
|
||||
{
|
||||
if (!m_update)
|
||||
@@ -438,6 +471,12 @@ void LFGMgr::InitializeLockedDungeons(Player* player)
|
||||
locktype = LFG_LOCKSTATUS_TOO_LOW_LEVEL;
|
||||
else if (dungeon->maxlevel < level)
|
||||
locktype = LFG_LOCKSTATUS_TOO_HIGH_LEVEL;
|
||||
else if (dungeon->flags & LFG_FLAG_SEASONAL)
|
||||
{
|
||||
if (HolidayIds holiday = sLFGMgr->GetDungeonSeason(dungeon->ID))
|
||||
if (!IsHolidayActive(holiday))
|
||||
locktype = LFG_LOCKSTATUS_NOT_IN_SEASON;
|
||||
}
|
||||
else if (locktype == LFG_LOCKSTATUS_OK && ar)
|
||||
{
|
||||
if (ar->achievement && !player->HasAchieved(ar->achievement))
|
||||
@@ -460,7 +499,6 @@ void LFGMgr::InitializeLockedDungeons(Player* player)
|
||||
locktype = LFG_LOCKSTATUS_TOO_HIGH_GEAR_SCORE;
|
||||
locktype = LFG_LOCKSTATUS_ATTUNEMENT_TOO_LOW_LEVEL;
|
||||
locktype = LFG_LOCKSTATUS_ATTUNEMENT_TOO_HIGH_LEVEL;
|
||||
locktype = LFG_LOCKSTATUS_NOT_IN_SEASON; // Need list of instances and needed season to open
|
||||
*/
|
||||
|
||||
if (locktype != LFG_LOCKSTATUS_OK)
|
||||
@@ -1808,13 +1846,16 @@ void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false*
|
||||
|
||||
if (!mapid)
|
||||
{
|
||||
AreaTrigger const* at = sObjectMgr->GetMapEntranceTrigger(dungeon->map);
|
||||
if (!at)
|
||||
LfgEntrancePositionMap::const_iterator itr = m_entrancePositions.find(dungeon->ID);
|
||||
if (itr != m_entrancePositions.end())
|
||||
{
|
||||
sLog->outError(LOG_FILTER_LFG, "LfgMgr::TeleportPlayer: Failed to teleport [" UI64FMTD "]: No areatrigger found for map: %u difficulty: %u", player->GetGUID(), dungeon->map, dungeon->difficulty);
|
||||
error = LFG_TELEPORTERROR_INVALID_LOCATION;
|
||||
mapid = dungeon->map;
|
||||
x = itr->second.GetPositionX();
|
||||
y = itr->second.GetPositionY();
|
||||
z = itr->second.GetPositionZ();
|
||||
orientation = itr->second.GetOrientation();
|
||||
}
|
||||
else
|
||||
else if (AreaTrigger const* at = sObjectMgr->GetMapEntranceTrigger(dungeon->map))
|
||||
{
|
||||
mapid = at->target_mapId;
|
||||
x = at->target_X;
|
||||
@@ -1822,6 +1863,11 @@ void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false*
|
||||
z = at->target_Z;
|
||||
orientation = at->target_Orientation;
|
||||
}
|
||||
else
|
||||
{
|
||||
sLog->outError(LOG_FILTER_LFG, "LfgMgr::TeleportPlayer: Failed to teleport [" UI64FMTD "]: No areatrigger found for map: %u difficulty: %u", player->GetGUID(), dungeon->map, dungeon->difficulty);
|
||||
error = LFG_TELEPORTERROR_INVALID_LOCATION;
|
||||
}
|
||||
}
|
||||
|
||||
if (error == LFG_TELEPORTERROR_OK)
|
||||
@@ -1889,11 +1935,11 @@ void LFGMgr::RewardDungeonDoneFor(const uint32 dungeonId, Player* player)
|
||||
ClearState(guid);
|
||||
SetState(guid, LFG_STATE_FINISHED_DUNGEON);
|
||||
|
||||
// Give rewards only if its a random dungeon
|
||||
// Give rewards only if its a random or seasonal dungeon
|
||||
LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(rDungeonId);
|
||||
if (!dungeon || dungeon->type != LFG_TYPE_RANDOM)
|
||||
if (!dungeon || (dungeon->type != LFG_TYPE_RANDOM && !(dungeon->flags & LFG_FLAG_SEASONAL)))
|
||||
{
|
||||
sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::RewardDungeonDoneFor: [" UI64FMTD "] dungeon %u is not random", guid, rDungeonId);
|
||||
sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::RewardDungeonDoneFor: [" UI64FMTD "] dungeon %u is not random nor seasonal", guid, rDungeonId);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2001,6 +2047,31 @@ std::string LFGMgr::ConcatenateGuids(LfgGuidList check)
|
||||
return o.str();
|
||||
}
|
||||
|
||||
HolidayIds LFGMgr::GetDungeonSeason(uint32 dungeonId)
|
||||
{
|
||||
HolidayIds holiday = HOLIDAY_NONE;
|
||||
|
||||
switch (dungeonId)
|
||||
{
|
||||
case 285:
|
||||
holiday = HOLIDAY_HALLOWS_END;
|
||||
break;
|
||||
case 286:
|
||||
holiday = HOLIDAY_FIRE_FESTIVAL;
|
||||
break;
|
||||
case 287:
|
||||
holiday = HOLIDAY_BREWFEST;
|
||||
break;
|
||||
case 288:
|
||||
holiday = HOLIDAY_LOVE_IS_IN_THE_AIR;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return holiday;
|
||||
}
|
||||
|
||||
LfgState LFGMgr::GetState(uint64 guid)
|
||||
{
|
||||
sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::GetState: [" UI64FMTD "]", guid);
|
||||
|
||||
@@ -41,6 +41,14 @@ enum LFGenum
|
||||
LFG_SPELL_LUCK_OF_THE_DRAW = 72221
|
||||
};
|
||||
|
||||
enum LfgFlags
|
||||
{
|
||||
LFG_FLAG_UNK1 = 0x1,
|
||||
LFG_FLAG_UNK2 = 0x2,
|
||||
LFG_FLAG_SEASONAL = 0x4,
|
||||
LFG_FLAG_UNK3 = 0x8
|
||||
};
|
||||
|
||||
/// Determines the type of instance
|
||||
enum LfgType
|
||||
{
|
||||
@@ -143,6 +151,7 @@ typedef std::map<uint64, LfgProposalPlayer*> LfgProposalPlayerMap;
|
||||
typedef std::map<uint32, LfgPlayerBoot*> LfgPlayerBootMap;
|
||||
typedef std::map<uint64, LfgGroupData> LfgGroupDataMap;
|
||||
typedef std::map<uint64, LfgPlayerData> LfgPlayerDataMap;
|
||||
typedef std::map<uint32, Position> LfgEntrancePositionMap;
|
||||
|
||||
// Data needed by SMSG_LFG_JOIN_RESULT
|
||||
struct LfgJoinResultData
|
||||
@@ -279,6 +288,7 @@ class LFGMgr
|
||||
void UpdateProposal(uint32 proposalId, uint64 guid, bool accept);
|
||||
|
||||
// Teleportation
|
||||
void LoadEntrancePositions();
|
||||
void TeleportPlayer(Player* player, bool out, bool fromOpcode = false);
|
||||
|
||||
// Vote kick
|
||||
@@ -286,6 +296,8 @@ class LFGMgr
|
||||
void UpdateBoot(Player* player, bool accept);
|
||||
void OfferContinue(Group* grp);
|
||||
|
||||
HolidayIds GetDungeonSeason(uint32 dungeonId);
|
||||
|
||||
void InitializeLockedDungeons(Player* player);
|
||||
|
||||
void _LoadFromDB(Field* fields, uint64 guid);
|
||||
@@ -349,6 +361,7 @@ class LFGMgr
|
||||
uint32 m_NumWaitTimeHealer; ///< Num of players used to calc healers wait time
|
||||
uint32 m_NumWaitTimeDps; ///< Num of players used to calc dps wait time
|
||||
LfgDungeonMap m_CachedDungeonMap; ///< Stores all dungeons by groupType
|
||||
LfgEntrancePositionMap m_entrancePositions; ///< Stores special entrance positions
|
||||
// Reward System
|
||||
LfgRewardMap m_RewardMap; ///< Stores rewards for random dungeons
|
||||
// Queue
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "LFGMgr.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "GroupMgr.h"
|
||||
#include "GameEventMgr.h"
|
||||
#include "InstanceScript.h"
|
||||
|
||||
void BuildPlayerLockDungeonBlock(WorldPacket& data, const LfgLockMap& lock)
|
||||
@@ -156,16 +157,25 @@ void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& /*recv_data
|
||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFD_PLAYER_LOCK_INFO_REQUEST [" UI64FMTD "]", guid);
|
||||
|
||||
// Get Random dungeons that can be done at a certain level and expansion
|
||||
// FIXME - Should return seasonals (when not disabled)
|
||||
LfgDungeonSet randomDungeons;
|
||||
uint8 level = GetPlayer()->getLevel();
|
||||
uint8 expansion = GetPlayer()->GetSession()->Expansion();
|
||||
for (uint32 i = 0; i < sLFGDungeonStore.GetNumRows(); ++i)
|
||||
{
|
||||
LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(i);
|
||||
if (dungeon && dungeon->type == LFG_TYPE_RANDOM && dungeon->expansion <= expansion &&
|
||||
dungeon->minlevel <= level && level <= dungeon->maxlevel)
|
||||
if (dungeon && dungeon->expansion <= expansion && dungeon->minlevel <= level && level <= dungeon->maxlevel)
|
||||
{
|
||||
if (dungeon->flags & LFG_FLAG_SEASONAL)
|
||||
{
|
||||
if (HolidayIds holiday = sLFGMgr->GetDungeonSeason(dungeon->ID))
|
||||
if (!IsHolidayActive(holiday))
|
||||
continue;
|
||||
}
|
||||
else if (dungeon->type != LFG_TYPE_RANDOM)
|
||||
continue;
|
||||
|
||||
randomDungeons.insert(dungeon->Entry());
|
||||
}
|
||||
}
|
||||
|
||||
// Get player locked Dungeons
|
||||
|
||||
@@ -1467,6 +1467,9 @@ void World::SetInitialWorldSettings()
|
||||
sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading LFG rewards...");
|
||||
sLFGMgr->LoadRewards();
|
||||
|
||||
sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading LFG entrance positions...");
|
||||
sLFGMgr->LoadEntrancePositions();
|
||||
|
||||
sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading SpellArea Data..."); // must be after quest load
|
||||
sSpellMgr->LoadSpellAreas();
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ EndScriptData */
|
||||
#include "ScriptedCreature.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "scarlet_monastery.h"
|
||||
#include "LFGMgr.h"
|
||||
|
||||
//this texts are already used by 3975 and 3976
|
||||
enum Says
|
||||
@@ -562,6 +563,13 @@ public:
|
||||
CAST_AI(mob_wisp_invis::mob_wisp_invisAI, wisp->AI())->SetType(4);
|
||||
if (instance)
|
||||
instance->SetData(DATA_HORSEMAN_EVENT, DONE);
|
||||
|
||||
Map::PlayerList const& players = me->GetMap()->GetPlayers();
|
||||
if (!players.isEmpty())
|
||||
for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
|
||||
if (Player* player = i->getSource())
|
||||
if (player->IsAtGroupRewardDistance(me))
|
||||
sLFGMgr->RewardDungeonDoneFor(285, player);
|
||||
}
|
||||
|
||||
void SpellHit(Unit* caster, const SpellInfo* spell)
|
||||
|
||||
Reference in New Issue
Block a user