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:
kandera
2012-10-05 06:05:53 -07:00
8 changed files with 175 additions and 14 deletions

View 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);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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