Merge branch 'master' of github.com:TrinityCore/TrinityCore into 4.3.4

Conflicts:
	src/server/game/Entities/Vehicle/Vehicle.cpp
	src/server/game/Globals/ObjectMgr.cpp
	src/server/game/Spells/SpellMgr.cpp
	src/server/game/Weather/Weather.h
	src/server/shared/Database/Implementation/WorldDatabase.cpp
	src/tools/CMakeLists.txt
This commit is contained in:
Vincent_Michael committed 2013-02-18 18:51:52 +01:00
commit 71eaceae5d
74 files changed
+1107 -570

No files matched your search

@@ -1,4 +1,4 @@
SET @NPC_DRAKE := 29709;
SET @NPC_DRAKE := 29709;
DELETE FROM `waypoint_data` WHERE `id`=@NPC_DRAKE;
INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_flag`,`action`,`action_chance`,`wpguid`) VALUES
@@ -0,0 +1 @@
UPDATE `creature_template` SET `Armor_mod`=0 WHERE `entry`=29747;
@@ -0,0 +1,11 @@
DELETE FROM `spell_target_position` WHERE `id` IN (64014,64024,64025,64028,64029,64030,64031,64032,65042);
INSERT INTO `spell_target_position` (`id`, `target_map`, `target_position_x`, `target_position_y`, `target_position_z`, `target_orientation`) VALUES
(64014, 603, -705.9705, -92.55729, 430.8192, 0),
(64024, 603, 2086.224, -24.05382, 422.2889, 0),
(64025, 603, 2518.131, 2569.342, 412.6822, 0),
(64028, 603, 553.243, -12.30903, 410.5428, 0),
(64029, 603, 1859.563, -24.83773, 449.1945, 6.230825),
(64030, 603, 1497.989, -24.16162, 421.6254, 0.03490658),
(64031, 603, 926.2917, -11.44444, 418.9779, 0.01745329),
(64032, 603, 131.1389, -35.36806, 410.187, 0),
(65042, 603, 1855.073, -11.48785, 334.559, 5.532694);
@@ -0,0 +1,8 @@
-- Lurgglbr
DELETE FROM `creature_text` WHERE `entry`=25208;
INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES
(25208,0,0, 'You can''t hold me against my will! You''ve all been brainwashed!', 12,0,100,0,0,0, 'Lurgglbr'),
(25208,1,0, 'Together we will fight our way out of here. Are you ready?', 12,0,100,0,0,0, 'Lurgglbr'),
(25208,2,0, 'This is far enough. I can make it on my own from here.', 12,0,100,0,0,0, 'Lurgglbr'),
(25208,3,0, 'Thank you for rescuing me, $r. Please tell the king that I am back.', 12,0,100,0,0,0, 'Lurgglbr');
@@ -0,0 +1,14 @@
-- quest fix cuergo's gold (q2882)
SET @ENTRY :=7898;
UPDATE `creature_template` SET `AIName`= 'SmartAI', `ScriptName`='' WHERE `entry`=@ENTRY;
DELETE FROM `creature_ai_scripts` WHERE `creature_id`=@ENTRY;
DELETE FROM `smart_scripts` WHERE `source_type`=0 AND`entryorguid`=@ENTRY;
DELETE FROM `smart_scripts` WHERE `source_type`=9 AND`entryorguid`=@ENTRY*100;
INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
(@ENTRY,0,0,0,63,0,100,0,0,0,0,0,80,@ENTRY*100,0,0,0,0,0,1,0,0,0,0,0,0,0, 'Trigger - on respawn - run script'),
(@ENTRY*100,9,0,0,0,0,100,0,0,0,300000,300000,11,11463,0,0,0,0,0,1,0,0,0,0,0,0,0,'Timed Actionscript - spawn pirate1'),
(@ENTRY*100,9,1,0,0,0,100,0,0,0,300000,300000,11,11463,0,0,0,0,0,1,0,0,0,0,0,0,0,'Timed Actionscript - spawn pirate2'),
(@ENTRY*100,9,2,0,0,0,100,0,0,0,300000,300000,11,11485,0,0,0,0,0,1,0,0,0,0,0,0,0,'Timed Actionscript - spawn buccaneer1'),
(@ENTRY*100,9,3,0,0,0,100,0,0,0,300000,300000,11,11485,0,0,0,0,0,1,0,0,0,0,0,0,0,'Timed Actionscript - spawn buccaneer2'),
(@ENTRY*100,9,4,0,0,0,100,0,0,0,300000,300000,11,11487,0,0,0,0,0,1,0,0,0,0,0,0,0,'Timed Actionscript - spawn swashbuckler'),
(@ENTRY*100,9,5,0,0,0,100,0,0,0,0,0,41,0,0,0,0,0,0,1,0,0,0,0,0,0,0,'Timed Actionscript - despawn trigger');
@@ -0,0 +1,6 @@
-- Remove Zulian Mudskunk from Zulian Crocolisk's loot template
DELETE FROM `creature_loot_template` WHERE `entry`=15043 and `item`=19975;
-- Add Vicious Oil (Item) into loot template of Vicious Oil (NPC)
DELETE FROM `creature_loot_template` WHERE `entry`=30325 and `item`=42640;
INSERT INTO `creature_loot_template` (`entry`, `item`, `ChanceOrQuestChance`, `lootmode`, `groupid`, `mincountOrRef`, `maxcount`) values
(30325,42640,-100,1,0,1,1);
@@ -0,0 +1,17 @@
-- Previous quest should be The Defense of Warsong Hold not To Conquest Hold, But Be Careful!
UPDATE `quest_template` SET `PrevQuestId`=11596 WHERE `Id`=12486;
-- Change grouping so Alliance and Horde quests are no longer in 1 group
UPDATE `quest_template` SET `ExclusiveGroup`=-12222 WHERE `Id` IN(12222,12223);
-- Hellscreams Champion requires some conditions to start the quest
UPDATE `quest_template` SET `ExclusiveGroup`=0,`NextQuestId`=0 WHERE `Id` IN(11652,11705,11722);
UPDATE `quest_template` SET `NextQuestId`=11709 WHERE `Id`=11705;
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` IN (19,20) AND `SourceEntry`=11916;
INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES
(20,0,11916,0,0,8,0,11652,0,0,0,0, '', 'Player must have completed The Plains of Nasam before been able to accept Hellscream''s Champion'),
(19,0,11916,0,0,8,0,11652,0,0,0,0, '', 'Player must have completed The Plains of Nasam before been able to accept Hellscream''s Champion'),
(20,0,11916,0,0,8,0,11705,0,0,0,0, '', 'Player must have completed The Foolish Endeavors before been able to accept Hellscream''s Champion'),
(19,0,11916,0,0,8,0,11705,0,0,0,0, '', 'Player must have completed The Foolish Endeavors before been able to accept Hellscream''s Champion'),
(20,0,11916,0,0,8,0,11722,0,0,0,0, '', 'Player must have completed The Trophies of Gammoth before been able to accept Hellscream''s Champion'),
(19,0,11916,0,0,8,0,11722,0,0,0,0, '', 'Player must have completed The Trophies of Gammoth before been able to accept Hellscream''s Champion');
-- Fix SAI issue for Hugh Glass (wrong npcflag was set)
UPDATE `smart_scripts` SET `action_param1`=643 WHERE `entryorguid`=2648400 AND `source_type`=9 AND `id`=6;
@@ -0,0 +1,14 @@
DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_sindragosa_frost_breath';
DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_item_unsated_craving';
INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES
(69649,'spell_sindragosa_frost_breath'),
(71056,'spell_sindragosa_frost_breath'),
(71057,'spell_sindragosa_frost_breath'),
(71058,'spell_sindragosa_frost_breath'),
(73061,'spell_sindragosa_frost_breath'),
(73062,'spell_sindragosa_frost_breath'),
(73063,'spell_sindragosa_frost_breath'),
(73064,'spell_sindragosa_frost_breath'),
(71168,'spell_item_unsated_craving');
DELETE FROM `spell_linked_spell` WHERE `spell_trigger`=71952;
@@ -0,0 +1,73 @@
-- creature_template.equipment_id deleted
-- creature_equip_template.entry == creature_template.entry
-- id field added to creature_equip_template -> PK(entry, id)
-- id field in creature_equip_template starts at 1
-- creature.equipment_id references id of creature_equip_template
-- creature.equipment_id = 0 means no equipment at all (default 1)
-- creature.equipment_id = -1 means pick a random equipment from creature_equip_template
-- Diff_entries should use the same template of the normal entry
UPDATE `creature_template` SET `equipment_id` = 0 WHERE `name` LIKE '%(1)' OR `name` LIKE '%(2)' OR `name` LIKE '%(3)' OR `name` LIKE '%(4)';
-- Delete unused templates
DROP TABLE IF EXISTS `temp_c_e`;
CREATE TABLE IF NOT EXISTS `temp_c_e` (`entry` mediumint(8));
ALTER TABLE `temp_c_e` ADD INDEX `ind` (`entry`);
INSERT INTO `temp_c_e` SELECT `equipment_id` FROM `creature_template` WHERE `equipment_id` != 0 UNION
SELECT `equipment_id` FROM `creature` WHERE `equipment_id` != 0 UNION
SELECT `equipment_id` FROM `game_event_model_equip` WHERE `equipment_id` != 0;
DELETE FROM `creature_equip_template` WHERE `entry` NOT IN (SELECT `entry` FROM `temp_c_e`);
DROP TABLE `temp_c_e`;
-- Create temporary table to hold the values of creature_equip_template with converted entry
DROP TABLE IF EXISTS `creature_equip_template2`;
CREATE TABLE IF NOT EXISTS `creature_equip_template2` (
`entry` mediumint(8) unsigned NOT NULL DEFAULT '0',
`id` tinyint(3) unsigned NOT NULL DEFAULT '1',
`itemEntry1` mediumint(8) unsigned NOT NULL DEFAULT '0',
`itemEntry2` mediumint(8) unsigned NOT NULL DEFAULT '0',
`itemEntry3` mediumint(8) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`entry`, `id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `creature_equip_template2` (`entry`, `id`, `itemEntry1`, `itemEntry2`, `itemEntry3`)
SELECT `creature_template`.`entry`, 1, `itemEntry1`, `itemEntry2`, `itemEntry3`
FROM `creature_template`
JOIN `creature_equip_template` ON `creature_equip_template`.`entry` = `equipment_id`
WHERE `equipment_id` != 0;
INSERT IGNORE INTO `creature_equip_template2` (`entry`, `id`, `itemEntry1`, `itemEntry2`, `itemEntry3`)
SELECT `id`, 2, `itemEntry1`, `itemEntry2`, `itemEntry3`
FROM `creature`
JOIN `creature_equip_template` ON `creature_equip_template`.`entry` = `equipment_id`
WHERE `equipment_id` != 0;
DROP TABLE `creature_equip_template`;
RENAME TABLE `creature_equip_template2` TO `creature_equip_template`;
UPDATE `creature` SET `equipment_id` = 2 WHERE `equipment_id` != 0;
UPDATE `creature` SET `equipment_id` = 1 WHERE `equipment_id` = 0;
-- From game_event_model_equip
UPDATE `creature` SET `equipment_id` = 1 WHERE `guid` IN (12088, 12093, 12095, 79670, 79675, 79676, 79690, 79792, 79807, 79814);
UPDATE `game_event_model_equip` SET `equipment_id` = 2 WHERE `guid` IN (12088, 12093, 12095, 79670, 79675, 79676, 79690, 79792, 79807, 79814);
DELETE FROM `creature_equip_template` WHERE `entry` IN (1976, 23585, 424) AND `id`=2;
INSERT INTO `creature_equip_template` (`entry`, `id`, `itemEntry1`, `itemEntry2`, `itemEntry3`) VALUES
(1976, 2, 2715, 143, 0),
(23585, 2, 2715, 143, 0),
(424, 2, 2715, 143, 0);
-- ALTER TABLE `creature_equip_template` CHANGE `entry` `entry` mediumint(8) unsigned NOT NULL;
-- ALTER TABLE `creature_equip_template` ADD `id` tinyint(3) unsigned NOT NULL DEFAULT '1' AFTER `entry`;
-- ALTER TABLE `creature_equip_template` DROP INDEX `PRIMARY`, ADD PRIMARY KEY (`entry`, `id`);
ALTER TABLE `creature_template` DROP `equipment_id`;
ALTER TABLE `creature` CHANGE `equipment_id` `equipment_id` tinyint(3) unsigned NOT NULL DEFAULT '1';
ALTER TABLE `game_event_model_equip` CHANGE `equipment_id` `equipment_id` tinyint(3) unsigned NOT NULL DEFAULT '1';
-- Conversion from SAI
UPDATE `smart_scripts` SET `action_param1` = 1 WHERE `entryorguid` = 2523901 AND `source_type` = 9 AND `id` = 3;
UPDATE `smart_scripts` SET `action_param1` = 0 WHERE `entryorguid` = 2523900 AND `source_type` = 9 AND `id` = 2;
UPDATE `smart_scripts` SET `action_param1` = 2 WHERE `entryorguid` = 32720 AND `source_type` = 0 AND `id` = 0;
DELETE FROM `creature_equip_template` WHERE `entry` = 25239 AND `id`=1;
INSERT INTO `creature_equip_template` (`entry`, `id`, `itemEntry1`, `itemEntry2`, `itemEntry3`) VALUES
(25239, 1, 6829, 0, 0);
@@ -0,0 +1,3 @@
DELETE FROM `trinity_string` WHERE `entry` = 5036;
INSERT INTO `trinity_string` (`entry`, `content_default`) VALUES
(5036, 'EquipmentId: %u (Original: %u).');
@@ -370,9 +370,7 @@ void ScriptedAI::SetEquipmentSlots(bool loadDefault, int32 mainHand /*= EQUIP_NO
{
if (loadDefault)
{
if (CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(me->GetEntry()))
me->LoadEquipment(creatureInfo->equipmentId, true);
me->LoadEquipment(me->GetOriginalEquipmentId(), true);
return;
}
@@ -1459,15 +1459,16 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (Creature* npc = (*itr)->ToCreature())
{
uint32 slot[3];
if (e.action.equip.entry)
int8 equipId = (int8)e.action.equip.entry;
if (equipId)
{
EquipmentInfo const* einfo = sObjectMgr->GetEquipmentInfo(e.action.equip.entry);
EquipmentInfo const* einfo = sObjectMgr->GetEquipmentInfo(npc->GetEntry(), equipId);
if (!einfo)
{
sLog->outError(LOG_FILTER_SQL, "SmartScript: SMART_ACTION_EQUIP uses non-existent equipment info entry %u", e.action.equip.entry);
sLog->outError(LOG_FILTER_SQL, "SmartScript: SMART_ACTION_EQUIP uses non-existent equipment info id %u for creature %u", equipId, npc->GetEntry());
return;
}
npc->SetCurrentEquipmentId(e.action.equip.entry);
npc->SetCurrentEquipmentId(equipId);
slot[0] = einfo->ItemEntry[0];
slot[1] = einfo->ItemEntry[1];
slot[2] = einfo->ItemEntry[2];
@@ -1478,11 +1479,11 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
slot[1] = e.action.equip.slot2;
slot[2] = e.action.equip.slot3;
}
if (!e.action.equip.mask || e.action.equip.mask & 1)
if (!e.action.equip.mask || (e.action.equip.mask & 1))
npc->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, slot[0]);
if (!e.action.equip.mask || e.action.equip.mask & 2)
if (!e.action.equip.mask || (e.action.equip.mask & 2))
npc->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, slot[1]);
if (!e.action.equip.mask || e.action.equip.mask & 4)
if (!e.action.equip.mask || (e.action.equip.mask & 4))
npc->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2, slot[2]);
}
}
@@ -2028,6 +2029,45 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
delete targets;
break;
}
case SMART_ACTION_SET_GO_FLAG:
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
if (IsGameObject(*itr))
(*itr)->ToGameObject()->SetUInt32Value(GAMEOBJECT_FLAGS, e.action.goFlag.flag);
delete targets;
break;
}
case SMART_ACTION_ADD_GO_FLAG:
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
if (IsGameObject(*itr))
(*itr)->ToGameObject()->SetFlag(GAMEOBJECT_FLAGS, e.action.goFlag.flag);
delete targets;
break;
}
case SMART_ACTION_REMOVE_GO_FLAG:
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
if (IsGameObject(*itr))
(*itr)->ToGameObject()->RemoveFlag(GAMEOBJECT_FLAGS, e.action.goFlag.flag);
delete targets;
break;
}
default:
sLog->outError(LOG_FILTER_SQL, "SmartScript::ProcessAction: Entry %d SourceType %u, Event %u, Unhandled Action type %u", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
break;
@@ -907,6 +907,9 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
case SMART_ACTION_SET_HOME_POS:
case SMART_ACTION_SET_HEALTH_REGEN:
case SMART_ACTION_SET_ROOT:
case SMART_ACTION_SET_GO_FLAG:
case SMART_ACTION_ADD_GO_FLAG:
case SMART_ACTION_REMOVE_GO_FLAG:
break;
default:
sLog->outError(LOG_FILTER_SQL, "SmartAIMgr: Not handled action_type(%u), event_type(%u), Entry %d SourceType %u Event %u, skipped.", e.GetActionType(), e.GetEventType(), e.entryOrGuid, e.GetScriptType(), e.event_id);
@@ -427,7 +427,6 @@ enum SMART_ACTION
SMART_ACTION_SET_INVINCIBILITY_HP_LEVEL = 42, // MinHpValue(+pct, -flat)
SMART_ACTION_MOUNT_TO_ENTRY_OR_MODEL = 43, // Creature_template entry(param1) OR ModelId (param2) (or 0 for both to dismount)
SMART_ACTION_SET_INGAME_PHASE_MASK = 44, // mask
SMART_ACTION_SET_DATA = 45, // Field, Data (only creature TODO)
SMART_ACTION_MOVE_FORWARD = 46, // distance
SMART_ACTION_SET_VISIBILITY = 47, // on/off
@@ -450,7 +449,6 @@ enum SMART_ACTION
SMART_ACTION_STORE_TARGET_LIST = 64, // varID,
SMART_ACTION_WP_RESUME = 65, // none
SMART_ACTION_SET_ORIENTATION = 66, //
SMART_ACTION_CREATE_TIMED_EVENT = 67, // id, InitialMin, InitialMax, RepeatMin(only if it repeats), RepeatMax(only if it repeats), chance
SMART_ACTION_PLAYMOVIE = 68, // entry
SMART_ACTION_MOVE_TO_POS = 69, // PointId, xyz
@@ -488,8 +486,11 @@ enum SMART_ACTION
SMART_ACTION_SET_HOME_POS = 101, // none
SMART_ACTION_SET_HEALTH_REGEN = 102, // 0/1
SMART_ACTION_SET_ROOT = 103, // off/on
SMART_ACTION_SET_GO_FLAG = 104, // Flags
SMART_ACTION_ADD_GO_FLAG = 105, // Flags
SMART_ACTION_REMOVE_GO_FLAG = 106, // Flags
SMART_ACTION_END = 104
SMART_ACTION_END = 107
};
struct SmartAction
@@ -926,6 +927,11 @@ struct SmartAction
uint32 root;
} setRoot;
struct
{
uint32 flag;
} goFlag;
//! Note for any new future actions
//! All parameters must have type uint32
+15 -5
View File
@@ -1,4 +1,4 @@
/*
/*
* Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/>
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
@@ -56,7 +56,7 @@ AccountOpResult AccountMgr::CreateAccount(std::string username, std::string pass
RBACData* rbac = new RBACData(GetId(username), username, -1);
// No need to Load From DB, as it's new data
RBACGroupContainer const& groupsToAdd = _defaultGroups[0]; // 0: Default sec level
RBACGroupContainer const& groupsToAdd = _defaultSecGroups[0]; // 0: Default sec level
for (RBACGroupContainer::const_iterator it = groupsToAdd.begin(); it != groupsToAdd.end(); ++it)
rbac->AddGroup(*it, -1);
@@ -426,13 +426,23 @@ void AccountMgr::LoadRBAC()
uint8 secId = field[0].GetUInt8();
if (lastSecId != secId)
groups = &_defaultGroups[secId];
groups = &_defaultSecGroups[secId];
groups->insert(field[1].GetUInt32());
}
while (result->NextRow());
sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u permission definitions, %u role definitions and %u group definitions in %u ms", count1, count2, count3, GetMSTimeDiffToNow(oldMSTime));
// Load default groups to be added to any RBAC Object.
std::string defaultGroups = ConfigMgr::GetStringDefault("RBAC.DefaultGroups", "");
Tokenizer tokens(defaultGroups, ',');
for (Tokenizer::const_iterator itr = tokens.begin(); itr != tokens.end(); ++itr)
if (uint32 groupId = atoi(*itr))
{
sLog->outError(LOG_FILTER_LFG, "Adding default group %u", groupId);
_defaultGroups.insert(groupId);
}
}
void AccountMgr::UpdateAccountAccess(RBACData* rbac, uint32 accountId, uint8 securityLevel, int32 realmId)
@@ -459,7 +469,7 @@ void AccountMgr::UpdateAccountAccess(RBACData* rbac, uint32 accountId, uint8 sec
uint8 secLevel = field[0].GetUInt8();
int32 realmId = field[1].GetUInt32();
RBACGroupContainer const& groupsToRemove = _defaultGroups[secLevel];
RBACGroupContainer const& groupsToRemove = _defaultSecGroups[secLevel];
for (RBACGroupContainer::const_iterator it = groupsToRemove.begin(); it != groupsToRemove.end(); ++it)
rbac->RemoveGroup(*it, realmId);
}
@@ -467,7 +477,7 @@ void AccountMgr::UpdateAccountAccess(RBACData* rbac, uint32 accountId, uint8 sec
}
// Add new groups depending on the new security Level
RBACGroupContainer const& groupsToAdd = _defaultGroups[securityLevel];
RBACGroupContainer const& groupsToAdd = _defaultSecGroups[securityLevel];
for (RBACGroupContainer::const_iterator it = groupsToAdd.begin(); it != groupsToAdd.end(); ++it)
rbac->AddGroup(*it, realmId);
+3 -1
View File
@@ -77,12 +77,14 @@ class AccountMgr
RBACGroupsContainer const& GetRBACGroupList() const { return _groups; }
RBACRolesContainer const& GetRBACRoleList() const { return _roles; }
RBACPermissionsContainer const& GetRBACPermissionList() const { return _permissions; }
RBACGroupContainer const& GetRBACDefaultGroups() const { return _defaultGroups; }
private:
RBACPermissionsContainer _permissions;
RBACRolesContainer _roles;
RBACGroupsContainer _groups;
RBACDefaultSecurityGroupContainer _defaultGroups;
RBACDefaultSecurityGroupContainer _defaultSecGroups;
RBACGroupContainer _defaultGroups;
};
#define sAccountMgr ACE_Singleton<AccountMgr, ACE_Null_Mutex>::instance()
+5
View File
@@ -296,6 +296,11 @@ void RBACData::LoadFromDB()
while (result->NextRow());
}
// Add default groups
RBACGroupContainer const& groups = sAccountMgr->GetRBACDefaultGroups();
for (RBACGroupContainer::const_iterator itr = groups.begin(); itr != groups.end(); ++itr)
AddGroup(*itr);
// Force calculation of permissions, it wasn't performed at load time
// while adding groups, roles and permissions
CalculateNewPermissions();
+1 -1
View File
@@ -135,7 +135,7 @@ class RBACGroup: public RBACObject
RBACRoleContainer _roles; ///> Set of Roles
};
/*
/**
* @name RBACData
* @brief Contains all needed information about the acccount
*
+13 -13
View File
@@ -145,7 +145,7 @@ Creature::Creature(bool isWorldObject): Unit(isWorldObject), MapCreature(),
lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), lootingGroupLowGUID(0),
m_PlayerDamageReq(0), m_lootRecipient(0), m_lootRecipientGroup(0), m_corpseRemoveTime(0), m_respawnTime(0),
m_respawnDelay(300), m_corpseDelay(60), m_respawnradius(0.0f), m_reactState(REACT_AGGRESSIVE),
m_defaultMovementType(IDLE_MOTION_TYPE), m_DBTableGuid(0), m_equipmentId(0), m_AlreadyCallAssistance(false),
m_defaultMovementType(IDLE_MOTION_TYPE), m_DBTableGuid(0), m_equipmentId(1), m_originalEquipmentId(1), m_AlreadyCallAssistance(false),
m_AlreadySearchedAssistance(false), m_regenHealth(true), m_AI_locked(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL),
m_creatureInfo(NULL), m_creatureData(NULL), m_path_id(0), m_formation(NULL)
{
@@ -323,8 +323,8 @@ bool Creature::InitEntry(uint32 Entry, uint32 /*team*/, const CreatureData* data
// Load creature equipment
if (!data || data->equipmentId == 0) // use default from the template
LoadEquipment(cinfo->equipmentId);
else if (data && data->equipmentId != -1) // override, -1 means no equipment
LoadEquipment(GetOriginalEquipmentId());
else if (data && data->equipmentId != 0) // override, 0 means no equipment
LoadEquipment(data->equipmentId);
SetName(normalInfo->Name); // at normal entry always
@@ -1080,7 +1080,7 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
data.mapid = mapid;
data.phaseMask = phaseMask;
data.displayid = displayId;
data.equipmentId = GetEquipmentId();
data.equipmentId = GetCurrentEquipmentId();
data.posX = GetPositionX();
data.posY = GetPositionY();
data.posZ = GetPositionZMinusOffset();
@@ -1115,7 +1115,7 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
stmt->setUInt8(index++, spawnMask);
stmt->setUInt16(index++, uint16(GetPhaseMask()));
stmt->setUInt32(index++, displayId);
stmt->setInt32(index++, int32(GetEquipmentId()));
stmt->setInt32(index++, int32(GetCurrentEquipmentId()));
stmt->setFloat(index++, GetPositionX());
stmt->setFloat(index++, GetPositionY());
stmt->setFloat(index++, GetPositionZ());
@@ -1270,14 +1270,14 @@ bool Creature::CreateFromProto(uint32 guidlow, uint32 Entry, uint32 vehId, uint3
if (!vehId)
vehId = cinfo->VehicleId;
if (vehId && !CreateVehicleKit(vehId, Entry))
vehId = 0;
Object::_Create(guidlow, Entry, vehId ? HIGHGUID_VEHICLE : HIGHGUID_UNIT);
if (!UpdateEntry(Entry, team, data))
return false;
if (vehId && !CreateVehicleKit(vehId, Entry))
vehId = 0;
return true;
}
@@ -1355,24 +1355,24 @@ bool Creature::LoadCreatureFromDB(uint32 guid, Map* map, bool addToMap)
return true;
}
void Creature::LoadEquipment(uint32 equip_entry, bool force)
void Creature::LoadEquipment(int8 id, bool force /*= true*/)
{
if (equip_entry == 0)
if (id == 0)
{
if (force)
{
for (uint8 i = 0; i < 3; ++i)
for (uint8 i = 0; i < MAX_EQUIPMENT_ITEMS; ++i)
SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + i, 0);
m_equipmentId = 0;
}
return;
}
EquipmentInfo const* einfo = sObjectMgr->GetEquipmentInfo(equip_entry);
EquipmentInfo const* einfo = sObjectMgr->GetEquipmentInfo(GetEntry(), id);
if (!einfo)
return;
m_equipmentId = equip_entry;
m_equipmentId = id;
for (uint8 i = 0; i < 3; ++i)
SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + i, einfo->ItemEntry[i]);
}
+10 -7
View File
@@ -138,7 +138,6 @@ struct CreatureTemplate
uint32 questItems[MAX_CREATURE_QUEST_ITEMS];
uint32 movementId;
bool RegenHealth;
uint32 equipmentId;
uint32 MechanicImmuneMask;
uint32 flags_extra;
uint32 ScriptID;
@@ -234,7 +233,8 @@ struct EquipmentInfo
};
// Benchmarked: Faster than std::map (insert/find)
typedef UNORDERED_MAP<uint16, EquipmentInfo> EquipmentInfoContainer;
typedef UNORDERED_MAP<uint8, EquipmentInfo> EquipmentInfoContainerInternal;
typedef UNORDERED_MAP<uint32, EquipmentInfoContainerInternal> EquipmentInfoContainer;
// from `creature` table
struct CreatureData
@@ -244,7 +244,7 @@ struct CreatureData
uint16 mapid;
uint16 phaseMask;
uint32 displayid;
int32 equipmentId;
int8 equipmentId;
float posX;
float posY;
float posZ;
@@ -453,13 +453,12 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature
bool Create(uint32 guidlow, Map* map, uint32 phaseMask, uint32 Entry, uint32 vehId, uint32 team, float x, float y, float z, float ang, const CreatureData* data = NULL);
bool LoadCreaturesAddon(bool reload = false);
void SelectLevel(const CreatureTemplate* cinfo);
void LoadEquipment(uint32 equip_entry, bool force=false);
void LoadEquipment(int8 id = 1, bool force = false);
uint32 GetDBTableGUIDLow() const { return m_DBTableGuid; }
void Update(uint32 time); // overwrited Unit::Update
void GetRespawnPosition(float &x, float &y, float &z, float* ori = NULL, float* dist =NULL) const;
uint32 GetEquipmentId() const { return GetCreatureTemplate()->equipmentId; }
void SetCorpseDelay(uint32 delay) { m_corpseDelay = delay; }
uint32 GetCorpseDelay() const { return m_corpseDelay; }
@@ -552,8 +551,11 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature
void UpdateMaxPower(Powers power);
void UpdateAttackPowerAndDamage(bool ranged = false);
void UpdateDamagePhysical(WeaponAttackType attType);
uint8 GetOriginalEquipmentId() const { return m_originalEquipmentId; }
uint32 GetCurrentEquipmentId() { return m_equipmentId; }
void SetCurrentEquipmentId(uint32 entry) { m_equipmentId = entry; }
void SetCurrentEquipmentId(uint8 id) { m_equipmentId = id; }
float GetSpellDamageMod(int32 Rank);
VendorItemData const* GetVendorItems() const;
@@ -748,7 +750,8 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature
void Regenerate(Powers power);
MovementGeneratorType m_defaultMovementType;
uint32 m_DBTableGuid; ///< For new or temporary creatures is 0 for saved it is lowguid
uint32 m_equipmentId;
uint8 m_equipmentId;
uint8 m_originalEquipmentId;
bool m_AlreadyCallAssistance;
bool m_AlreadySearchedAssistance;
+1 -1
View File
@@ -26027,7 +26027,7 @@ bool Player::AddItem(uint32 itemId, uint32 count)
ItemPosCountVec dest;
InventoryResult msg = CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemId, count, &noSpaceForCount);
if (msg != EQUIP_ERR_OK)
count = noSpaceForCount;
count -= noSpaceForCount;
if (count == 0 || dest.empty())
{
+7
View File
@@ -29,6 +29,8 @@
#include "QuestDef.h"
#include "SpellMgr.h"
#include "Unit.h"
#include "Opcodes.h"
#include "WorldSession.h"
#include <string>
#include <vector>
@@ -1813,6 +1815,11 @@ class Player : public Unit, public GridObject<Player>
return mMitems.erase(id) ? true : false;
}
void SendOnCancelExpectedVehicleRideAura()
{
WorldPacket data(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, 0);
GetSession()->SendPacket(&data);
}
void PetSpellInitialize();
void CharmSpellInitialize();
void PossessSpellInitialize();
+20 -75
View File
@@ -2936,7 +2936,9 @@ void Unit::DeMorph()
Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint8 effMask, Unit* caster, int32* baseAmount /*= NULL*/, Item* castItem /*= NULL*/, uint64 casterGUID /*= 0*/)
{
ASSERT(casterGUID || caster);
if (!casterGUID)
// Check if these can stack anyway
if (!casterGUID && !newAura->IsStackableOnOneSlotWithDifferentCasters())
casterGUID = caster->GetGUID();
// passive and Incanter's Absorption and auras with different type can stack with themselves any number of times
@@ -7585,48 +7587,6 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
return false;
break;
}
// Shadow's Fate (Shadowmourne questline)
case 71169:
{
// Victim needs more checks so bugs, rats or summons can not be affected by the proc.
if (GetTypeId() != TYPEID_PLAYER || !victim || victim->GetTypeId() != TYPEID_UNIT || victim->GetCreatureType() == CREATURE_TYPE_CRITTER)
return false;
Player* player = ToPlayer();
if (player->GetQuestStatus(24547) == QUEST_STATUS_INCOMPLETE)
{
break;
}
else if (player->GetDifficulty(true) == RAID_DIFFICULTY_25MAN_NORMAL || player->GetDifficulty(true) == RAID_DIFFICULTY_25MAN_HEROIC)
{
uint32 spellId = 0;
uint32 questId = 0;
switch (victim->GetEntry())
{
case 36678: // NPC: Professor Putricide
questId = 24749; // Quest: Unholy Infusion
spellId = 71516; // Spell: Shadow Infusion
break;
case 37955: // NPC: Blood-Queen Lana'thel
questId = 24756; // Quest: Blood Infusion
spellId = 72154; // Spell: Thirst Quenched
break;
case 36853: // NPC: Sindragosa
questId = 24757; // Quest: Frost Infusion
spellId = 72290; // Spell: Frost-Imbued Blade
break;
default:
return false;
}
if (player->GetQuestStatus(questId) != QUEST_STATUS_INCOMPLETE || !player->HasAura(spellId))
return false;
break;
}
else
return false;
}
}
if (cooldown && GetTypeId() == TYPEID_PLAYER && ToPlayer()->HasSpellCooldown(trigger_spell_id))
@@ -10248,8 +10208,6 @@ void Unit::Mount(uint32 mount, uint32 VehicleId, uint32 creatureEntry)
{
if (CreateVehicleKit(VehicleId, creatureEntry))
{
GetVehicleKit()->Reset();
// Send others that we now have a vehicle
WorldPacket data(SMSG_PLAYER_VEHICLE_DATA, GetPackGUID().size()+4);
data.appendPackGUID(GetGUID());
@@ -14823,7 +14781,10 @@ bool Unit::SetCharmedBy(Unit* charmer, CharmType type, AuraApplication const* au
// dismount players when charmed
if (GetTypeId() == TYPEID_PLAYER)
Dismount();
RemoveAurasByType(SPELL_AURA_MOUNTED);
if (charmer->GetTypeId() == TYPEID_PLAYER)
charmer->RemoveAurasByType(SPELL_AURA_MOUNTED);
ASSERT(type != CHARM_TYPE_POSSESS || charmer->GetTypeId() == TYPEID_PLAYER);
ASSERT((type == CHARM_TYPE_VEHICLE) == IsVehicle());
@@ -16082,31 +16043,10 @@ void Unit::_EnterVehicle(Vehicle* vehicle, int8 seatId, AuraApplication const* a
{
if (vehicle->GetBase()->GetTypeId() == TYPEID_PLAYER && player->isInCombat())
return;
InterruptNonMeleeSpells(false);
player->StopCastingCharm();
player->StopCastingBindSight();
Dismount();
RemoveAurasByType(SPELL_AURA_MOUNTED);
// drop flag at invisible in bg
if (Battleground* bg = player->GetBattleground())
bg->EventPlayerDroppedFlag(player);
WorldPacket data(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, 0);
player->GetSession()->SendPacket(&data);
player->UnsummonPetTemporaryIfAny();
}
ASSERT(!m_vehicle);
m_vehicle = vehicle;
if (!m_vehicle->AddPassenger(this, seatId))
{
m_vehicle = NULL;
return;
}
(void)vehicle->AddPassenger(this, seatId);
}
void Unit::ChangeSeat(int8 seatId, bool next)
@@ -16114,15 +16054,17 @@ void Unit::ChangeSeat(int8 seatId, bool next)
if (!m_vehicle)
return;
if (seatId < 0)
{
seatId = m_vehicle->GetNextEmptySeat(GetTransSeat(), next);
if (seatId < 0)
return;
}
else if (seatId == GetTransSeat() || !m_vehicle->HasEmptySeat(seatId))
// Don't change if current and new seat are identical
if (seatId == GetTransSeat())
return;
SeatMap::const_iterator seat = (seatId < 0 ? m_vehicle->GetNextEmptySeat(GetTransSeat(), next) : m_vehicle->Seats.find(seatId));
// The second part of the check will only return true if seatId >= 0. @Vehicle::GetNextEmptySeat makes sure of that.
if (seat == m_vehicle->Seats.end() || seat->second.Passenger)
return;
// Todo: the functions below could be consolidated and refactored to take
// SeatMap::const_iterator as parameter, to save redundant map lookups.
m_vehicle->RemovePassenger(this);
if (!m_vehicle->AddPassenger(this, seatId))
ASSERT(false);
@@ -16149,6 +16091,9 @@ void Unit::ExitVehicle(Position const* /*exitPosition*/)
void Unit::_ExitVehicle(Position const* exitPosition)
{
/// It's possible m_vehicle is NULL, when this function is called indirectly from @VehicleJoinEvent::Abort.
/// In that case it was not possible to add the passenger to the vehicle. The vehicle aura has already been removed
/// from the target in the aforementioned function and we don't need to do anything else at this point.
if (!m_vehicle)
return;
+2
View File
@@ -332,6 +332,7 @@ class UnitAI;
class Totem;
class Transport;
class Vehicle;
class VehicleJoinEvent;
class TransportBase;
class SpellCastTargets;
@@ -2170,6 +2171,7 @@ class Unit : public WorldObject
uint32 GetRedirectThreatPercent() { return _redirectThreadInfo.GetThreatPct(); }
Unit* GetRedirectThreatTarget() { return _redirectThreadInfo.GetTargetGUID() ? GetUnit(*this, _redirectThreadInfo.GetTargetGUID()) : NULL; }
friend class VehicleJoinEvent;
bool IsAIEnabled, NeedChangeAI;
bool CreateVehicleKit(uint32 id, uint32 creatureEntry);
void RemoveVehicleKit();
+411 -136
View File
@@ -30,9 +30,12 @@
#include "SpellInfo.h"
#include "MoveSplineInit.h"
#include "TemporarySummon.h"
#include "EventProcessor.h"
#include "Player.h"
#include "Battleground.h"
Vehicle::Vehicle(Unit* unit, VehicleEntry const* vehInfo, uint32 creatureEntry) :
_me(unit), _vehicleInfo(vehInfo), _usableSeatNum(0), _creatureEntry(creatureEntry), _status(STATUS_NONE)
UsableSeatNum(0), _me(unit), _vehicleInfo(vehInfo), _creatureEntry(creatureEntry), _status(STATUS_NONE)
{
for (uint32 i = 0; i < MAX_VEHICLE_SEATS; ++i)
{
@@ -41,10 +44,16 @@ _me(unit), _vehicleInfo(vehInfo), _usableSeatNum(0), _creatureEntry(creatureEntr
{
Seats.insert(std::make_pair(i, VehicleSeat(veSeat)));
if (veSeat->CanEnterOrExit())
++_usableSeatNum;
++UsableSeatNum;
}
}
// Set or remove correct flags based on available seats. Will overwrite db data (if wrong).
if (UsableSeatNum)
_me->SetFlag(UNIT_NPC_FLAGS, (_me->GetTypeId() == TYPEID_PLAYER ? UNIT_NPC_FLAG_PLAYER_VEHICLE : UNIT_NPC_FLAG_SPELLCLICK));
else
_me->RemoveFlag(UNIT_NPC_FLAGS, (_me->GetTypeId() == TYPEID_PLAYER ? UNIT_NPC_FLAG_PLAYER_VEHICLE : UNIT_NPC_FLAG_SPELLCLICK));
InitMovementInfoForBase();
}
@@ -56,6 +65,15 @@ Vehicle::~Vehicle()
ASSERT(!itr->second.Passenger);
}
/**
* @fn void Vehicle::Install()
*
* @brief Initializes power type for vehicle. Nothing more.
*
* @author Machiavelli
* @date 17-2-2013
*/
void Vehicle::Install()
{
if (Creature* creature = _me->ToCreature())
@@ -114,15 +132,26 @@ void Vehicle::InstallAllAccessories(bool evading)
InstallAccessory(itr->AccessoryEntry, itr->SeatId, itr->IsMinion, itr->SummonedType, itr->SummonTime);
}
/**
* @fn void Vehicle::Uninstall()
*
* @brief Removes all passengers and sets status to STATUS_UNINSTALLING.
* No new passengers can be added to the vehicle after this call.
*
* @author Machiavelli
* @date 17-2-2013
*/
void Vehicle::Uninstall()
{
/// @Prevent recursive uninstall call. (Bad script in OnUninstall/OnRemovePassenger/PassengerBoarded hook.)
if (_status == STATUS_UNINSTALLING)
if (_status == STATUS_UNINSTALLING && !GetBase()->HasUnitTypeMask(UNIT_MASK_MINION))
{
sLog->outError(LOG_FILTER_VEHICLES, "Vehicle GuidLow: %u, Entry: %u attempts to uninstall, but already has STATUS_UNINSTALLING! "
"Check Uninstall/PassengerBoarded script hooks for errors.", _me->GetGUIDLow(), _me->GetEntry());
return;
}
_status = STATUS_UNINSTALLING;
sLog->outDebug(LOG_FILTER_VEHICLES, "Vehicle::Uninstall Entry: %u, GuidLow: %u", _creatureEntry, _me->GetGUIDLow());
RemoveAllPassengers();
@@ -131,26 +160,39 @@ void Vehicle::Uninstall()
sScriptMgr->OnUninstall(this);
}
/**
* @fn void Vehicle::Reset(bool evading )
*
* @brief Reapplies immunities and reinstalls accessories. Only has effect for creatures.
*
* @author Machiavelli
* @date 17-2-2013
*
* @param evading true if called from CreatureAI::EnterEvadeMode
*/
void Vehicle::Reset(bool evading /*= false*/)
{
sLog->outDebug(LOG_FILTER_VEHICLES, "Vehicle::Reset Entry: %u, GuidLow: %u", _creatureEntry, _me->GetGUIDLow());
if (_me->GetTypeId() == TYPEID_PLAYER)
{
if (_usableSeatNum)
_me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PLAYER_VEHICLE);
}
else
{
ApplyAllImmunities();
InstallAllAccessories(evading);
if (_usableSeatNum)
_me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
}
if (GetBase()->GetTypeId() != TYPEID_UNIT)
return;
if (GetBase()->GetTypeId() == TYPEID_UNIT)
sScriptMgr->OnReset(this);
sLog->outDebug(LOG_FILTER_VEHICLES, "Vehicle::Reset (Entry: %u, GuidLow: %u, DBGuid: %u)", GetCreatureEntry(), _me->GetGUIDLow(), _me->ToCreature()->GetDBTableGUIDLow());
ApplyAllImmunities();
InstallAllAccessories(evading);
sScriptMgr->OnReset(this);
}
/**
* @fn void Vehicle::ApplyAllImmunities()
*
* @brief Applies specific immunities that cannot be set in DB.
*
* @author Machiavelli
* @date 17-2-2013
*/
void Vehicle::ApplyAllImmunities()
{
// This couldn't be done in DB, because some spells have MECHANIC_NONE
@@ -199,10 +241,28 @@ void Vehicle::ApplyAllImmunities()
}
}
/**
* @fn void Vehicle::RemoveAllPassengers()
*
* @brief Removes all current and pending passengers from the vehicle.
*
* @author Machiavelli
* @date 17-2-2013
*/
void Vehicle::RemoveAllPassengers()
{
sLog->outDebug(LOG_FILTER_VEHICLES, "Vehicle::RemoveAllPassengers. Entry: %u, GuidLow: %u", _creatureEntry, _me->GetGUIDLow());
/// Setting to_Abort to true will cause @VehicleJoinEvent::Abort to be executed on next @Unit::UpdateEvents call
/// This will properly "reset" the pending join process for the passenger.
while (_pendingJoinEvents.size())
{
VehicleJoinEvent* e = _pendingJoinEvents.front();
e->to_Abort = true;
_pendingJoinEvents.pop_front();
}
// Passengers always cast an aura with SPELL_AURA_CONTROL_VEHICLE on the vehicle
// We just remove the aura and the unapply handler will make the target leave the vehicle.
// We don't need to iterate over Seats
@@ -215,6 +275,19 @@ void Vehicle::RemoveAllPassengers()
// ASSERT(!itr->second.passenger);
}
/**
* @fn bool Vehicle::HasEmptySeat(int8 seatId) const
*
* @brief Checks if vehicle's seat specified by 'seatId' is empty.
*
* @author Machiavelli
* @date 17-2-2013
*
* @param seatId Identifier for the seat.
*
* @return true if empty seat, false if not.
*/
bool Vehicle::HasEmptySeat(int8 seatId) const
{
SeatMap::const_iterator seat = Seats.find(seatId);
@@ -223,6 +296,19 @@ bool Vehicle::HasEmptySeat(int8 seatId) const
return !seat->second.Passenger;
}
/**
* @fn Unit* Vehicle::GetPassenger(int8 seatId) const
*
* @brief Gets a passenger on specified seat.
*
* @author Machiavelli
* @date 17-2-2013
*
* @param seatId Seat to look on.
*
* @return null if it not found, else pointer to passenger if in world
*/
Unit* Vehicle::GetPassenger(int8 seatId) const
{
SeatMap::const_iterator seat = Seats.find(seatId);
@@ -232,78 +318,105 @@ Unit* Vehicle::GetPassenger(int8 seatId) const
return ObjectAccessor::GetUnit(*GetBase(), seat->second.Passenger);
}
int8 Vehicle::GetNextEmptySeat(int8 seatId, bool next) const
/**
* @fn SeatMap::const_iterator Vehicle::GetNextEmptySeat(int8 seatId, bool next) const
*
* @brief Gets the next empty seat based on current seat.
*
* @author Machiavelli
* @date 17-2-2013
*
* @param seatId Identifier for the current seat.
* @param next true if iterating forward, false means iterating backwards.
*
* @return The next empty seat.
*/
SeatMap::const_iterator Vehicle::GetNextEmptySeat(int8 seatId, bool next) const
{
SeatMap::const_iterator seat = Seats.find(seatId);
if (seat == Seats.end())
return -1;
return seat;
while (seat->second.Passenger || (!seat->second.SeatInfo->CanEnterOrExit() && !seat->second.SeatInfo->IsUsableByOverride()))
{
if (next)
{
++seat;
if (seat == Seats.end())
if (++seat == Seats.end())
seat = Seats.begin();
}
else
{
if (seat == Seats.begin())
if (seat-- == Seats.begin())
seat = Seats.end();
--seat;
}
// Make sure we don't loop indefinetly
if (seat->first == seatId)
return -1; // no available seat
return Seats.end();
}
return seat->first;
return seat;
}
/**
* @fn void Vehicle::InstallAccessory(uint32 entry, int8 seatId, bool minion, uint8 type,
* uint32 summonTime)
*
* @brief Installs an accessory.
*
* @author Machiavelli
* @date 17-2-2013
*
* @param entry The NPC entry of accessory.
* @param seatId Identifier for the seat to add the accessory to.
* @param minion true if accessory considered a 'minion'. Implies that the accessory will despawn when the vehicle despawns.
* Essentially that it has no life without the vehicle. Their fates are bound.
* @param type See enum @SummonType.
* @param summonTime Time after which the minion is despawned in case of a timed despawn @type specified.
*/
void Vehicle::InstallAccessory(uint32 entry, int8 seatId, bool minion, uint8 type, uint32 summonTime)
{
/// @Prevent adding accessories when vehicle is uninstalling. (Bad script in OnUninstall/OnRemovePassenger/PassengerBoarded hook.)
if (_status == STATUS_UNINSTALLING)
{
sLog->outError(LOG_FILTER_VEHICLES, "Vehicle GuidLow: %u, Entry: %u attempts to install accessory Entry: %u on seat %d with STATUS_UNINSTALLING! "
"Check Uninstall/PassengerBoarded script hooks for errors.", _me->GetGUIDLow(), _me->GetEntry(), entry, (int32)seatId);
sLog->outError(LOG_FILTER_VEHICLES, "Vehicle (GuidLow: %u, DB GUID: %u, Entry: %u) attempts to install accessory (Entry: %u) on seat %i with STATUS_UNINSTALLING! "
"Check Uninstall/PassengerBoarded script hooks for errors.", _me->GetGUIDLow(),
(_me->GetTypeId() == TYPEID_UNIT ? _me->ToCreature()->GetDBTableGUIDLow() : _me->GetGUIDLow()), GetCreatureEntry(), entry, (int32)seatId);
return;
}
sLog->outDebug(LOG_FILTER_VEHICLES, "Vehicle: Installing accessory entry %u on vehicle entry %u (seat:%i)", entry, GetCreatureEntry(), seatId);
if (Unit* passenger = GetPassenger(seatId))
{
// already installed
if (passenger->GetEntry() == entry)
{
ASSERT(passenger->GetTypeId() == TYPEID_UNIT);
if (_me->GetTypeId() == TYPEID_UNIT)
{
if (_me->ToCreature()->IsInEvadeMode() && passenger->ToCreature()->IsAIEnabled)
passenger->ToCreature()->AI()->EnterEvadeMode();
return;
}
}
else
passenger->ExitVehicle(); // this should not happen
}
sLog->outDebug(LOG_FILTER_VEHICLES, "Vehicle (GuidLow: %u, DB Guid: %u, Entry %u): installing accessory (Entry: %u) on seat: %i",
_me->GetGUIDLow(), (_me->GetTypeId() == TYPEID_UNIT ? _me->ToCreature()->GetDBTableGUIDLow() : _me->GetGUIDLow()), GetCreatureEntry(),
entry, (int32)seatId);
if (TempSummon* accessory = _me->SummonCreature(entry, *_me, TempSummonType(type), summonTime))
{
if (minion)
accessory->AddUnitTypeMask(UNIT_MASK_ACCESSORY);
TempSummon* accessory = _me->SummonCreature(entry, *_me, TempSummonType(type), summonTime);
ASSERT(accessory);
if (!_me->HandleSpellClick(accessory, seatId))
{
accessory->UnSummon();
return;
}
if (minion)
accessory->AddUnitTypeMask(UNIT_MASK_ACCESSORY);
if (GetBase()->GetTypeId() == TYPEID_UNIT)
sScriptMgr->OnInstallAccessory(this, accessory);
}
(void)_me->HandleSpellClick(accessory, seatId);
/// If for some reason adding accessory to vehicle fails it will unsummon in
/// @VehicleJoinEvent::Abort
}
/**
* @fn bool Vehicle::AddPassenger(Unit* unit, int8 seatId)
*
* @brief Attempts to add a passenger to the vehicle on 'seatId'.
*
* @author Machiavelli
* @date 17-2-2013
*
* @param [in,out] The prospective passenger.
* @param seatId Identifier for the seat. Value of -1 indicates the next available seat.
*
* @return true if it succeeds, false if it fails.
*/
bool Vehicle::AddPassenger(Unit* unit, int8 seatId)
{
/// @Prevent adding passengers when vehicle is uninstalling. (Bad script in OnUninstall/OnRemovePassenger/PassengerBoarded hook.)
@@ -314,10 +427,19 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId)
return false;
}
if (unit->GetVehicle() != this)
return false;
sLog->outDebug(LOG_FILTER_VEHICLES, "Unit %s scheduling enter vehicle (entry: %u, vehicleId: %u, guid: %u (dbguid: %s) on seat %d",
unit->GetName().c_str(), _me->GetEntry(), _vehicleInfo->m_ID, _me->GetGUIDLow(),
(_me->GetTypeId() == TYPEID_UNIT ? _me->ToCreature()->GetDBTableGUIDLow() : 0), (int32)seatId);
// The seat selection code may kick other passengers off the vehicle.
// While the validity of the following may be arguable, it is possible that when such a passenger
// exits the vehicle will dismiss. That's why the actual adding the passenger to the vehicle is scheduled
// asynchronously, so it can be cancelled easily in case the vehicle is uninstalled meanwhile.
SeatMap::iterator seat;
VehicleJoinEvent* e = new VehicleJoinEvent(this, unit);
unit->m_Events.AddEvent(e, unit->m_Events.CalculateTime(0));
_pendingJoinEvents.push_back(e);
if (seatId < 0) // no specific seat requirement
{
for (seat = Seats.begin(); seat != Seats.end(); ++seat)
@@ -325,86 +447,47 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId)
break;
if (seat == Seats.end()) // no available seat
{
CancelJoinEvent(e);
return false;
}
e->Seat = seat;
}
else
{
seat = Seats.find(seatId);
if (seat == Seats.end())
{
CancelJoinEvent(e);
return false;
}
e->Seat = seat;
if (seat->second.Passenger)
{
if (Unit* passenger = ObjectAccessor::GetUnit(*GetBase(), seat->second.Passenger))
passenger->ExitVehicle();
else
seat->second.Passenger = 0;
Unit* passenger = ObjectAccessor::GetUnit(*GetBase(), seat->second.Passenger);
ASSERT(passenger);
passenger->ExitVehicle();
}
ASSERT(!seat->second.Passenger);
}
sLog->outDebug(LOG_FILTER_VEHICLES, "Unit %s enter vehicle entry %u id %u dbguid %u seat %d", unit->GetName().c_str(), _me->GetEntry(), _vehicleInfo->m_ID, _me->GetGUIDLow(), (int32)seat->first);
seat->second.Passenger = unit->GetGUID();
if (seat->second.SeatInfo->CanEnterOrExit())
{
ASSERT(_usableSeatNum);
--_usableSeatNum;
if (!_usableSeatNum)
{
if (_me->GetTypeId() == TYPEID_PLAYER)
_me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PLAYER_VEHICLE);
else
_me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
}
}
if (seat->second.SeatInfo->m_flags && !(seat->second.SeatInfo->m_flags & VEHICLE_SEAT_FLAG_ALLOW_TURNING))
unit->AddUnitState(UNIT_STATE_ONVEHICLE);
VehicleSeatEntry const* veSeat = seat->second.SeatInfo;
unit->m_movementInfo.t_pos.m_positionX = veSeat->m_attachmentOffsetX;
unit->m_movementInfo.t_pos.m_positionY = veSeat->m_attachmentOffsetY;
unit->m_movementInfo.t_pos.m_positionZ = veSeat->m_attachmentOffsetZ;
unit->m_movementInfo.t_pos.SetOrientation(0);
unit->m_movementInfo.t_time = 0; // 1 for player
unit->m_movementInfo.t_seat = seat->first;
unit->m_movementInfo.t_guid = _me->GetGUID();
if (_me->GetTypeId() == TYPEID_UNIT && unit->GetTypeId() == TYPEID_PLAYER &&
seat->second.SeatInfo->m_flags & VEHICLE_SEAT_FLAG_CAN_CONTROL)
ASSERT(_me->SetCharmedBy(unit, CHARM_TYPE_VEHICLE))
if (_me->IsInWorld())
{
unit->SendClearTarget(); // SMSG_BREAK_TARGET
unit->SetControlled(true, UNIT_STATE_ROOT); // SMSG_FORCE_ROOT - In some cases we send SMSG_SPLINE_MOVE_ROOT here (for creatures)
// also adds MOVEMENTFLAG_ROOT
Movement::MoveSplineInit init(unit);
init.DisableTransportPathTransformations();
init.MoveTo(veSeat->m_attachmentOffsetX, veSeat->m_attachmentOffsetY, veSeat->m_attachmentOffsetZ);
init.SetFacing(0.0f);
init.SetTransportEnter();
init.Launch();
if (_me->GetTypeId() == TYPEID_UNIT)
{
if (_me->ToCreature()->IsAIEnabled)
_me->ToCreature()->AI()->PassengerBoarded(unit, seat->first, true);
// update all passenger's positions
//Passenger's spline OR vehicle movement will update positions
//RelocatePassengers(_me->GetPositionX(), _me->GetPositionY(), _me->GetPositionZ(), _me->GetOrientation());
}
}
if (GetBase()->GetTypeId() == TYPEID_UNIT)
sScriptMgr->OnAddPassenger(this, unit, seatId);
return true;
}
/**
* @fn void Vehicle::RemovePassenger(Unit* unit)
*
* @brief Removes the passenger from the vehicle.
*
* @author Machiavelli
* @date 17-2-2013
*
* @param [in,out] unit The passenger to remove..
*/
void Vehicle::RemovePassenger(Unit* unit)
{
if (unit->GetVehicle() != this)
@@ -413,20 +496,12 @@ void Vehicle::RemovePassenger(Unit* unit)
SeatMap::iterator seat = GetSeatIteratorForPassenger(unit);
ASSERT(seat != Seats.end());
sLog->outDebug(LOG_FILTER_VEHICLES, "Unit %s exit vehicle entry %u id %u dbguid %u seat %d", unit->GetName().c_str(), _me->GetEntry(), _vehicleInfo->m_ID, _me->GetGUIDLow(), (int32)seat->first);
sLog->outDebug(LOG_FILTER_VEHICLES, "Unit %s exit vehicle entry %u id %u dbguid %u seat %d",
unit->GetName().c_str(), _me->GetEntry(), _vehicleInfo->m_ID, _me->GetGUIDLow(), (int32)seat->first);
seat->second.Passenger = 0;
if (seat->second.SeatInfo->CanEnterOrExit())
{
if (!_usableSeatNum)
{
if (_me->GetTypeId() == TYPEID_PLAYER)
_me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PLAYER_VEHICLE);
else
_me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
}
++_usableSeatNum;
}
if (seat->second.SeatInfo->CanEnterOrExit() && ++UsableSeatNum)
_me->SetFlag(UNIT_NPC_FLAGS, (_me->GetTypeId() == TYPEID_PLAYER ? UNIT_NPC_FLAG_PLAYER_VEHICLE : UNIT_NPC_FLAG_SPELLCLICK));
unit->ClearUnitState(UNIT_STATE_ONVEHICLE);
@@ -435,7 +510,7 @@ void Vehicle::RemovePassenger(Unit* unit)
if (_me->IsInWorld())
{
unit->m_movementInfo.t_pos.Relocate(0, 0, 0, 0);
unit->m_movementInfo.t_pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f);
unit->m_movementInfo.t_time = 0;
unit->m_movementInfo.t_seat = 0;
}
@@ -451,7 +526,15 @@ void Vehicle::RemovePassenger(Unit* unit)
sScriptMgr->OnRemovePassenger(this, unit);
}
//! Must be called after m_base::Relocate
/**
* @fn void Vehicle::RelocatePassengers()
*
* @brief Relocate passengers. Must be called after m_base::Relocate
*
* @author Machiavelli
* @date 17-2-2013
*/
void Vehicle::RelocatePassengers()
{
ASSERT(_me->GetMap());
@@ -466,21 +549,40 @@ void Vehicle::RelocatePassengers()
float px, py, pz, po;
passenger->m_movementInfo.t_pos.GetPosition(px, py, pz, po);
CalculatePassengerPosition(px, py, pz, po);
passenger->UpdatePosition(px, py, pz, po);
}
}
}
/**
* @fn void Vehicle::Dismiss()
*
* @brief Dismiss the vehicle. Removes passengers and despawns self. Only valid for creatures.
*
* @author Machiavelli
* @date 17-2-2013
*/
void Vehicle::Dismiss()
{
if (GetBase()->GetTypeId() != TYPEID_UNIT)
return;
sLog->outDebug(LOG_FILTER_VEHICLES, "Vehicle::Dismiss Entry: %u, GuidLow %u", _creatureEntry, _me->GetGUIDLow());
sLog->outDebug(LOG_FILTER_VEHICLES, "Vehicle::Dismiss Entry: %u, GuidLow %u, DBGuid: %u", GetCreatureEntry(), _me->GetGUIDLow(), _me->ToCreature()->GetDBTableGUIDLow());
Uninstall();
GetBase()->ToCreature()->DespawnOrUnsummon();
}
/**
* @fn void Vehicle::InitMovementInfoForBase()
*
* @brief Sets correct MovementFlags2 based on VehicleFlags from DBC.
*
* @author Machiavelli
* @date 17-2-2013
*/
void Vehicle::InitMovementInfoForBase()
{
uint32 vehicleFlags = GetVehicleInfo()->m_flags;
@@ -497,6 +599,19 @@ void Vehicle::InitMovementInfoForBase()
_me->AddExtraUnitMovementFlag(MOVEMENTFLAG2_FULL_SPEED_PITCHING);
}
/**
* @fn VehicleSeatEntry const* Vehicle::GetSeatForPassenger(Unit* passenger)
*
* @brief Returns information on the seat of specified passenger, represented by the format in VehicleSeat.dbc
*
* @author Machiavelli
* @date 17-2-2013
*
* @param [in,out] The passenger for which we check the seat info.
*
* @return null if passenger not found on vehicle, else the DBC record for the seat.
*/
VehicleSeatEntry const* Vehicle::GetSeatForPassenger(Unit* passenger)
{
SeatMap::iterator itr;
@@ -507,6 +622,19 @@ VehicleSeatEntry const* Vehicle::GetSeatForPassenger(Unit* passenger)
return NULL;
}
/**
* @fn SeatMap::iterator Vehicle::GetSeatIteratorForPassenger(Unit* passenger)
*
* @brief Gets seat iterator for specified passenger.
*
* @author Machiavelli
* @date 17-2-2013
*
* @param [in,out] passenger Passenger to look up.
*
* @return The seat iterator for specified passenger if it's found on the vehicle. Otherwise Seats.end() (invalid iterator).
*/
SeatMap::iterator Vehicle::GetSeatIteratorForPassenger(Unit* passenger)
{
SeatMap::iterator itr;
@@ -517,6 +645,17 @@ SeatMap::iterator Vehicle::GetSeatIteratorForPassenger(Unit* passenger)
return Seats.end();
}
/**
* @fn uint8 Vehicle::GetAvailableSeatCount() const
*
* @brief Gets the available seat count.
*
* @author Machiavelli
* @date 17-2-2013
*
* @return The available seat count.
*/
uint8 Vehicle::GetAvailableSeatCount() const
{
uint8 ret = 0;
@@ -547,3 +686,139 @@ void Vehicle::CalculatePassengerOffset(float& x, float& y, float& z, float& o)
y = (iny - inx * tan(GetBase()->GetOrientation())) / (cos(GetBase()->GetOrientation()) + std::sin(GetBase()->GetOrientation()) * tan(GetBase()->GetOrientation()));
x = (inx + iny * tan(GetBase()->GetOrientation())) / (cos(GetBase()->GetOrientation()) + std::sin(GetBase()->GetOrientation()) * tan(GetBase()->GetOrientation()));
}
/**
* @fn void Vehicle::CancelJoinEvent(VehicleJoinEvent* e)
*
* @brief Aborts delayed @VehicleJoinEvent objects.
* Implies that the related unit will not be boarding the vehicle after all.
*
* @author Machiavelli
* @date 17-2-2013
*
* @param [in,out] e The VehicleJoinEvent* to process.
*/
void Vehicle::CancelJoinEvent(VehicleJoinEvent* e)
{
e->to_Abort = true;
_pendingJoinEvents.pop_back();
}
/**
* @fn bool VehicleJoinEvent::Execute(uint64, uint32)
*
* @brief Actually adds the passenger @Passenger to vehicle @Target.
*
* @author Machiavelli
* @date 17-2-2013
*
* @param parameter1 Unused
* @param parameter2 Unused.
*
* @return true, cannot fail.
*
*/
bool VehicleJoinEvent::Execute(uint64, uint32)
{
ASSERT(Passenger->IsInWorld());
ASSERT(Target->GetBase()->IsInWorld());
Passenger->m_vehicle = Target;
Seat->second.Passenger = Passenger->GetGUID();
if (Seat->second.SeatInfo->CanEnterOrExit())
{
ASSERT(Target->UsableSeatNum);
--(Target->UsableSeatNum);
if (!Target->UsableSeatNum)
{
if (Target->GetBase()->GetTypeId() == TYPEID_PLAYER)
Target->GetBase()->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PLAYER_VEHICLE);
else
Target->GetBase()->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
}
}
Passenger->InterruptNonMeleeSpells(false);
Player* player = Passenger->ToPlayer();
if (player)
{
// drop flag
if (Battleground* bg = player->GetBattleground())
bg->EventPlayerDroppedFlag(player);
player->StopCastingCharm();
player->StopCastingBindSight();
player->SendOnCancelExpectedVehicleRideAura();
player->UnsummonPetTemporaryIfAny();
}
if (Seat->second.SeatInfo->m_flags && !(Seat->second.SeatInfo->m_flags & VEHICLE_SEAT_FLAG_ALLOW_TURNING))
Passenger->AddUnitState(UNIT_STATE_ONVEHICLE);
VehicleSeatEntry const* veSeat = Seat->second.SeatInfo;
Passenger->m_movementInfo.t_pos.Relocate(veSeat->m_attachmentOffsetX, veSeat->m_attachmentOffsetY, veSeat->m_attachmentOffsetZ);
Passenger->m_movementInfo.t_time = 0; // 1 for player
Passenger->m_movementInfo.t_seat = Seat->first;
Passenger->m_movementInfo.t_guid = Target->GetBase()->GetGUID();
if (Target->GetBase()->GetTypeId() == TYPEID_UNIT && Passenger->GetTypeId() == TYPEID_PLAYER &&
Seat->second.SeatInfo->m_flags & VEHICLE_SEAT_FLAG_CAN_CONTROL)
ASSERT(Target->GetBase()->SetCharmedBy(Passenger, CHARM_TYPE_VEHICLE)) // SMSG_CLIENT_CONTROL
Passenger->SendClearTarget(); // SMSG_BREAK_TARGET
Passenger->SetControlled(true, UNIT_STATE_ROOT); // SMSG_FORCE_ROOT - In some cases we send SMSG_SPLINE_MOVE_ROOT here (for creatures)
// also adds MOVEMENTFLAG_ROOT
Movement::MoveSplineInit init(Passenger);
init.DisableTransportPathTransformations();
init.MoveTo(veSeat->m_attachmentOffsetX, veSeat->m_attachmentOffsetY, veSeat->m_attachmentOffsetZ, false, true);
init.SetFacing(0.0f);
init.SetTransportEnter();
init.Launch();
if (Target->GetBase()->GetTypeId() == TYPEID_UNIT)
{
if (Target->GetBase()->ToCreature()->IsAIEnabled)
Target->GetBase()->ToCreature()->AI()->PassengerBoarded(Passenger, Seat->first, true);
sScriptMgr->OnAddPassenger(Target, Passenger, Seat->first);
// Actually quite a redundant hook. Could just use OnAddPassenger and check for unit typemask inside script.
if (Passenger->HasUnitTypeMask(UNIT_MASK_ACCESSORY))
sScriptMgr->OnInstallAccessory(Target, Passenger->ToCreature());
// update all passenger's positions
//Passenger's spline OR vehicle movement will update positions
//RelocatePassengers(_me->GetPositionX(), _me->GetPositionY(), _me->GetPositionZ(), _me->GetOrientation());
}
return true;
}
/**
* @fn void VehicleJoinEvent::Abort(uint64)
*
* @brief Aborts the event. Implies that unit @Passenger will not be boarding vehicle @Target after all.
*
* @author Machiavelli
* @date 17-2-2013
*
* @param parameter1 Unused
*/
void VehicleJoinEvent::Abort(uint64)
{
sLog->outDebug(LOG_FILTER_VEHICLES, "Passenger GuidLow: %u, Entry: %u, board on vehicle GuidLow: %u, Entry: %u SeatId: %i cancelled",
Passenger->GetGUIDLow(), Passenger->GetEntry(), Target->GetBase()->GetGUIDLow(), Target->GetBase()->GetEntry(), (int32)Seat->first);
/// @SPELL_AURA_CONTROL_VEHICLE auras can be applied even when the passenger is not (yet) on the vehicle.
/// When this code is triggered it means that something went wrong in @Vehicle::AddPassenger, and we should remove
/// the aura manually.
Target->GetBase()->RemoveAurasByType(SPELL_AURA_CONTROL_VEHICLE, Passenger->GetGUID());
if (Passenger->IsInWorld() && Passenger->HasUnitTypeMask(UNIT_MASK_ACCESSORY))
Passenger->ToCreature()->DespawnOrUnsummon();
}
+28 -9
View File
@@ -23,12 +23,12 @@
#include "Object.h"
#include "VehicleDefines.h"
#include "Unit.h"
#include <deque>
struct VehicleEntry;
class Unit;
typedef std::set<uint64> GuidSet;
class VehicleJoinEvent;
class Vehicle : public TransportBase
{
@@ -46,7 +46,7 @@ class Vehicle : public TransportBase
bool HasEmptySeat(int8 seatId) const;
Unit* GetPassenger(int8 seatId) const;
int8 GetNextEmptySeat(int8 seatId, bool next) const;
SeatMap::const_iterator GetNextEmptySeat(int8 seatId, bool next) const;
uint8 GetAvailableSeatCount() const;
bool AddPassenger(Unit* passenger, int8 seatId = -1);
@@ -61,10 +61,14 @@ class Vehicle : public TransportBase
void SetLastShootPos(Position const& pos) { m_lastShootPos.Relocate(pos); }
Position GetLastShootPos() { return m_lastShootPos; }
SeatMap Seats;
SeatMap Seats; ///< The collection of all seats on the vehicle. Including vacant ones.
VehicleSeatEntry const* GetSeatForPassenger(Unit* passenger);
protected:
friend class VehicleJoinEvent;
uint32 UsableSeatNum; ///< Number of seats that match VehicleSeatEntry::UsableByPlayer, used for proper display flags
protected:
friend bool Unit::CreateVehicleKit(uint32 id, uint32 creatureEntry);
Vehicle(Unit* unit, VehicleEntry const* vehInfo, uint32 creatureEntry);
@@ -88,12 +92,27 @@ class Vehicle : public TransportBase
/// This method transforms supplied global coordinates into local offsets
void CalculatePassengerOffset(float& x, float& y, float& z, float& o);
Unit* _me;
VehicleEntry const* _vehicleInfo;
Unit* _me; ///< The underlying unit with the vehicle kit. Can be player or creature.
VehicleEntry const* _vehicleInfo; ///< DBC data for vehicle
GuidSet vehiclePlayers;
uint32 _usableSeatNum; // Number of seats that match VehicleSeatEntry::UsableByPlayer, used for proper display flags
uint32 _creatureEntry; // Can be different than me->GetBase()->GetEntry() in case of players
Status _status;
uint32 _creatureEntry; ///< Can be different than the entry of _me in case of players
Status _status; ///< Internal variable for sanity checks
Position m_lastShootPos;
std::deque<VehicleJoinEvent*> _pendingJoinEvents; ///< Collection of delayed join events for prospective passengers
void CancelJoinEvent(VehicleJoinEvent* e);
};
class VehicleJoinEvent : public BasicEvent
{
friend class Vehicle;
protected:
VehicleJoinEvent(Vehicle* v, Unit* u) : Target(v), Passenger(u), Seat(Target->Seats.end()) {}
bool Execute(uint64, uint32);
void Abort(uint64);
Vehicle* Target;
Unit* Passenger;
SeatMap::iterator Seat;
};
#endif
+15 -19
View File
@@ -450,8 +450,8 @@ void GameEventMgr::LoadFromDB()
{
uint32 oldMSTime = getMSTime();
// 0 1 2 3
QueryResult result = WorldDatabase.Query("SELECT creature.guid, game_event_model_equip.eventEntry, game_event_model_equip.modelid, game_event_model_equip.equipment_id "
// 0 1 2 3 4
QueryResult result = WorldDatabase.Query("SELECT creature.guid, creature.id, game_event_model_equip.eventEntry, game_event_model_equip.modelid, game_event_model_equip.equipment_id "
"FROM creature JOIN game_event_model_equip ON creature.guid=game_event_model_equip.guid");
if (!result)
@@ -466,7 +466,8 @@ void GameEventMgr::LoadFromDB()
Field* fields = result->Fetch();
uint32 guid = fields[0].GetUInt32();
uint16 event_id = fields[1].GetUInt8();
uint32 entry = fields[1].GetUInt32();
uint16 event_id = fields[2].GetUInt8();
if (event_id >= mGameEventModelEquip.size())
{
@@ -476,17 +477,18 @@ void GameEventMgr::LoadFromDB()
ModelEquipList& equiplist = mGameEventModelEquip[event_id];
ModelEquip newModelEquipSet;
newModelEquipSet.modelid = fields[2].GetUInt32();
newModelEquipSet.equipment_id = fields[3].GetUInt32();
newModelEquipSet.modelid = fields[3].GetUInt32();
newModelEquipSet.equipment_id = fields[4].GetUInt8();
newModelEquipSet.equipement_id_prev = 0;
newModelEquipSet.modelid_prev = 0;
if (newModelEquipSet.equipment_id > 0)
{
if (!sObjectMgr->GetEquipmentInfo(newModelEquipSet.equipment_id))
int8 equipId = static_cast<int8>(newModelEquipSet.equipment_id);
if (!sObjectMgr->GetEquipmentInfo(entry, equipId))
{
sLog->outError(LOG_FILTER_SQL, "Table `game_event_model_equip` have creature (Guid: %u) with equipment_id %u not found in table `creature_equip_template`, set to no equipment.",
guid, newModelEquipSet.equipment_id);
sLog->outError(LOG_FILTER_SQL, "Table `game_event_model_equip` have creature (Guid: %u, entry: %u) with equipment_id %u not found in table `creature_equip_template`, set to no equipment.",
guid, entry, newModelEquipSet.equipment_id);
continue;
}
}
@@ -1103,14 +1105,8 @@ void GameEventMgr::UnApplyEvent(uint16 event_id)
void GameEventMgr::ApplyNewEvent(uint16 event_id)
{
switch (sWorld->getIntConfig(CONFIG_EVENT_ANNOUNCE))
{
case 0: // disable
break;
case 1: // announce events
sWorld->SendWorldText(LANG_EVENTMESSAGE, mGameEvent[event_id].description.c_str());
break;
}
if (sWorld->getBoolConfig(CONFIG_EVENT_ANNOUNCE))
sWorld->SendWorldText(LANG_EVENTMESSAGE, mGameEvent[event_id].description.c_str());
sLog->outInfo(LOG_FILTER_GAMEEVENTS, "GameEvent %u \"%s\" started.", event_id, mGameEvent[event_id].description.c_str());
@@ -1332,7 +1328,7 @@ void GameEventMgr::ChangeEquipOrModel(int16 event_id, bool activate)
itr->second.equipement_id_prev = creature->GetCurrentEquipmentId();
itr->second.modelid_prev = creature->GetDisplayId();
creature->LoadEquipment(itr->second.equipment_id, true);
if (itr->second.modelid >0 && itr->second.modelid_prev != itr->second.modelid)
if (itr->second.modelid > 0 && itr->second.modelid_prev != itr->second.modelid)
{
CreatureModelInfo const* minfo = sObjectMgr->GetCreatureModelInfo(itr->second.modelid);
if (minfo)
@@ -1347,7 +1343,7 @@ void GameEventMgr::ChangeEquipOrModel(int16 event_id, bool activate)
else
{
creature->LoadEquipment(itr->second.equipement_id_prev, true);
if (itr->second.modelid_prev >0 && itr->second.modelid_prev != itr->second.modelid)
if (itr->second.modelid_prev > 0 && itr->second.modelid_prev != itr->second.modelid)
{
CreatureModelInfo const* minfo = sObjectMgr->GetCreatureModelInfo(itr->second.modelid_prev);
if (minfo)
@@ -1370,7 +1366,7 @@ void GameEventMgr::ChangeEquipOrModel(int16 event_id, bool activate)
sObjectMgr->GetCreatureModelRandomGender(&displayID);
if (data2->equipmentId == 0)
itr->second.equipement_id_prev = cinfo->equipmentId;
itr->second.equipement_id_prev = 1;
else if (data2->equipmentId != -1)
itr->second.equipement_id_prev = data->equipmentId;
itr->second.modelid_prev = displayID;
+2 -2
View File
@@ -73,9 +73,9 @@ struct GameEventData
struct ModelEquip
{
uint32 modelid;
uint32 equipment_id;
uint32 modelid_prev;
uint32 equipement_id_prev;
uint8 equipment_id;
uint8 equipement_id_prev;
};
struct NPCVendorEntry
+49 -33
View File
@@ -427,8 +427,8 @@ void ObjectMgr::LoadCreatureTemplates()
"spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, "
// 71 72 73 74 75 76 77 78 79 80 81 82
"InhabitType, HoverHeight, Health_mod, Mana_mod, Mana_mod_extra, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, "
// 83 84 85 86 87 88 89
" questItem6, movementId, RegenHealth, equipment_id, mechanic_immune_mask, flags_extra, ScriptName "
// 83 84 85 86 87 88
" questItem6, movementId, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName "
"FROM creature_template;");
if (!result)
@@ -525,10 +525,9 @@ void ObjectMgr::LoadCreatureTemplates()
creatureTemplate.movementId = fields[82].GetUInt32();
creatureTemplate.RegenHealth = fields[83].GetBool();
creatureTemplate.equipmentId = fields[84].GetUInt32();
creatureTemplate.MechanicImmuneMask = fields[85].GetUInt32();
creatureTemplate.flags_extra = fields[86].GetUInt32();
creatureTemplate.ScriptID = GetScriptId(fields[87].GetCString());
creatureTemplate.MechanicImmuneMask = fields[84].GetUInt32();
creatureTemplate.flags_extra = fields[85].GetUInt32();
creatureTemplate.ScriptID = GetScriptId(fields[86].GetCString());
++count;
}
@@ -877,15 +876,6 @@ void ObjectMgr::CheckCreatureTemplate(CreatureTemplate const* cInfo)
const_cast<CreatureTemplate*>(cInfo)->MovementType = IDLE_MOTION_TYPE;
}
if (cInfo->equipmentId > 0) // 0 no equipment
{
if (!GetEquipmentInfo(cInfo->equipmentId))
{
sLog->outError(LOG_FILTER_SQL, "Table `creature_template` lists creature (Entry: %u) with `equipment_id` %u not found in table `creature_equip_template`, set to no equipment.", cInfo->Entry, cInfo->equipmentId);
const_cast<CreatureTemplate*>(cInfo)->equipmentId = 0;
}
}
/// if not set custom creature scale then load scale from CreatureDisplayInfo.dbc
if (cInfo->scale <= 0.0f)
{
@@ -1011,11 +1001,28 @@ CreatureAddon const* ObjectMgr::GetCreatureTemplateAddon(uint32 entry)
return NULL;
}
EquipmentInfo const* ObjectMgr::GetEquipmentInfo(uint32 entry)
EquipmentInfo const* ObjectMgr::GetEquipmentInfo(uint32 entry, int8& id)
{
EquipmentInfoContainer::const_iterator itr = _equipmentInfoStore.find(entry);
if (itr != _equipmentInfoStore.end())
return &(itr->second);
if (itr == _equipmentInfoStore.end())
return NULL;
if (itr->second.empty())
return NULL;
if (id == -1) // select a random element
{
EquipmentInfoContainerInternal::const_iterator ritr = itr->second.begin();
std::advance(ritr, urand(0u, itr->second.size()));
id = std::distance(itr->second.begin(), ritr) + 1;
return &ritr->second;
}
else
{
EquipmentInfoContainerInternal::const_iterator itr2 = itr->second.find(id);
if (itr2 != itr->second.end())
return &itr2->second;
}
return NULL;
}
@@ -1024,7 +1031,8 @@ void ObjectMgr::LoadEquipmentTemplates()
{
uint32 oldMSTime = getMSTime();
QueryResult result = WorldDatabase.Query("SELECT entry, itemEntry1, itemEntry2, itemEntry3 FROM creature_equip_template");
// 0 1 2 3 4
QueryResult result = WorldDatabase.Query("SELECT entry, id, itemEntry1, itemEntry2, itemEntry3 FROM creature_equip_template");
if (!result)
{
@@ -1037,13 +1045,21 @@ void ObjectMgr::LoadEquipmentTemplates()
{
Field* fields = result->Fetch();
uint16 entry = fields[0].GetUInt16();
uint32 entry = fields[0].GetUInt32();
EquipmentInfo& equipmentInfo = _equipmentInfoStore[entry];
if (!sObjectMgr->GetCreatureTemplate(entry))
{
sLog->outError(LOG_FILTER_SQL, "Creature template (Entry: %u) does not exist but has a record in `creature_equip_template`", entry);
continue;
}
equipmentInfo.ItemEntry[0] = fields[1].GetUInt32();
equipmentInfo.ItemEntry[1] = fields[2].GetUInt32();
equipmentInfo.ItemEntry[2] = fields[3].GetUInt32();
uint8 id = fields[1].GetUInt8();
EquipmentInfo& equipmentInfo = _equipmentInfoStore[entry][id];
equipmentInfo.ItemEntry[0] = fields[2].GetUInt32();
equipmentInfo.ItemEntry[1] = fields[3].GetUInt32();
equipmentInfo.ItemEntry[2] = fields[4].GetUInt32();
for (uint8 i = 0; i < MAX_EQUIPMENT_ITEMS; ++i)
{
@@ -1054,8 +1070,8 @@ void ObjectMgr::LoadEquipmentTemplates()
if (!dbcItem)
{
sLog->outError(LOG_FILTER_SQL, "Unknown item (entry=%u) in creature_equip_template.itemEntry%u for entry = %u, forced to 0.",
equipmentInfo.ItemEntry[i], i+1, entry);
sLog->outError(LOG_FILTER_SQL, "Unknown item (entry=%u) in creature_equip_template.itemEntry%u for entry = %u and id=%u, forced to 0.",
equipmentInfo.ItemEntry[i], i+1, entry, id);
equipmentInfo.ItemEntry[i] = 0;
continue;
}
@@ -1070,8 +1086,8 @@ void ObjectMgr::LoadEquipmentTemplates()
dbcItem->InventoryType != INVTYPE_THROWN &&
dbcItem->InventoryType != INVTYPE_RANGEDRIGHT)
{
sLog->outError(LOG_FILTER_SQL, "Item (entry=%u) in creature_equip_template.itemEntry%u for entry = %u is not equipable in a hand, forced to 0.",
equipmentInfo.ItemEntry[i], i+1, entry);
sLog->outError(LOG_FILTER_SQL, "Item (entry=%u) in creature_equip_template.itemEntry%u for entry = %u and id = %u is not equipable in a hand, forced to 0.",
equipmentInfo.ItemEntry[i], i+1, entry, id);
equipmentInfo.ItemEntry[i] = 0;
}
}
@@ -1518,13 +1534,13 @@ void ObjectMgr::LoadCreatures()
if (!ok)
continue;
// -1 no equipment, 0 use default
if (data.equipmentId > 0)
// -1 random, 0 no equipment, 1 is default (may or may not have equipment)
if (data.equipmentId != 0)
{
if (!GetEquipmentInfo(data.equipmentId))
if (!GetEquipmentInfo(data.id, data.equipmentId) && data.equipmentId != 1)
{
sLog->outError(LOG_FILTER_SQL, "Table `creature` have creature (Entry: %u) with equipment_id %u not found in table `creature_equip_template`, set to no equipment.", data.id, data.equipmentId);
data.equipmentId = -1;
data.equipmentId = 1;
}
}
@@ -1698,7 +1714,7 @@ uint32 ObjectMgr::AddCreData(uint32 entry, uint32 /*team*/, uint32 mapId, float
data.id = entry;
data.mapid = mapId;
data.displayid = 0;
data.equipmentId = cInfo->equipmentId;
data.equipmentId = 1;
data.posX = x;
data.posY = y;
data.posZ = z;
+1 -1
View File
@@ -672,7 +672,7 @@ class ObjectMgr
CreatureModelInfo const* GetCreatureModelRandomGender(uint32* displayID);
static uint32 ChooseDisplayId(uint32 team, const CreatureTemplate* cinfo, const CreatureData* data = NULL);
static void ChooseCreatureFlags(const CreatureTemplate* cinfo, uint32& npcflag, uint32& unit_flags, uint32& dynamicflags, const CreatureData* data = NULL);
EquipmentInfo const* GetEquipmentInfo(uint32 entry);
EquipmentInfo const* GetEquipmentInfo(uint32 entry, int8& id);
CreatureAddon const* GetCreatureAddon(uint32 lowguid);
CreatureAddon const* GetCreatureTemplateAddon(uint32 entry);
ItemTemplate const* GetItemTemplate(uint32 entry);
+1 -1
View File
@@ -665,7 +665,7 @@ void Group::ChangeLeader(uint64 guid)
if (!player)
return;
sScriptMgr->OnGroupChangeLeader(this, m_leaderGuid, guid);
sScriptMgr->OnGroupChangeLeader(this, guid, m_leaderGuid);
if (!isBGGroup() && !isBFGroup())
{
+1 -2
View File
@@ -1650,8 +1650,7 @@ void WorldSession::HandleCancelMountAuraOpcode(WorldPacket& /*recvData*/)
return;
}
_player->Dismount();
_player->RemoveAurasByType(SPELL_AURA_MOUNTED);
_player->RemoveAurasByType(SPELL_AURA_MOUNTED); // Calls Dismount()
}
void WorldSession::HandleMoveSetCanFlyAckOpcode(WorldPacket& recvData)
+2 -1
View File
@@ -1041,7 +1041,8 @@ enum TrinityStrings
LANG_COMMAND_NO_ACHIEVEMENT_CRITERIA_FOUND = 5033,
LANG_COMMAND_NO_OUTDOOR_PVP_FORUND = 5034,
LANG_CALL_FOR_HELP = 5035,
// Room for more Trinity strings 5036-9999
LANG_NPCINFO_EQUIPMENT = 5036,
// Room for more Trinity strings 5037-9999
// Level requirement notifications
LANG_SAY_REQ = 6604,
@@ -5320,10 +5320,7 @@ void AuraEffect::HandleAuraSetVehicle(AuraApplication const* aurApp, uint8 mode,
target->SendMessageToSet(&data, true);
if (apply)
{
data.Initialize(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, 0);
target->ToPlayer()->GetSession()->SendPacket(&data);
}
target->ToPlayer()->SendOnCancelExpectedVehicleRideAura();
}
void AuraEffect::HandlePreventResurrection(AuraApplication const* aurApp, uint8 mode, bool apply) const
+84 -78
View File
@@ -933,6 +933,10 @@ bool Aura::CanBeSaved() const
if (HasEffectType(SPELL_AURA_OPEN_STABLE))
return false;
// Can't save vehicle auras, it requires both caster & target to be in world
if (HasEffectType(SPELL_AURA_CONTROL_VEHICLE))
return false;
// Incanter's Absorbtion - considering the minimal duration and problems with aura stacking
// we skip saving this aura
// Also for some reason other auras put as MultiSlot crash core on keeping them after restart,
@@ -1814,16 +1818,17 @@ void Aura::LoadScripts()
bool Aura::CallScriptCheckAreaTargetHandlers(Unit* target)
{
bool result = true;
for (std::list<AuraScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
{
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_CHECK_AREA_TARGET);
std::list<AuraScript::CheckAreaTargetHandler>::iterator hookItrEnd = (*scritr)->DoCheckAreaTarget.end(), hookItr = (*scritr)->DoCheckAreaTarget.begin();
for (; hookItr != hookItrEnd; ++hookItr)
if (!(*hookItr).Call(*scritr, target))
return false;
result &= hookItr->Call(*scritr, target);
(*scritr)->_FinishScriptCall();
}
return true;
return result;
}
void Aura::CallScriptDispel(DispelInfo* dispelInfo)
@@ -1833,7 +1838,8 @@ void Aura::CallScriptDispel(DispelInfo* dispelInfo)
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_DISPEL);
std::list<AuraScript::AuraDispelHandler>::iterator hookItrEnd = (*scritr)->OnDispel.end(), hookItr = (*scritr)->OnDispel.begin();
for (; hookItr != hookItrEnd; ++hookItr)
(*hookItr).Call(*scritr, dispelInfo);
hookItr->Call(*scritr, dispelInfo);
(*scritr)->_FinishScriptCall();
}
}
@@ -1845,7 +1851,8 @@ void Aura::CallScriptAfterDispel(DispelInfo* dispelInfo)
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_AFTER_DISPEL);
std::list<AuraScript::AuraDispelHandler>::iterator hookItrEnd = (*scritr)->AfterDispel.end(), hookItr = (*scritr)->AfterDispel.begin();
for (; hookItr != hookItrEnd; ++hookItr)
(*hookItr).Call(*scritr, dispelInfo);
hookItr->Call(*scritr, dispelInfo);
(*scritr)->_FinishScriptCall();
}
}
@@ -1858,14 +1865,15 @@ bool Aura::CallScriptEffectApplyHandlers(AuraEffect const* aurEff, AuraApplicati
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_APPLY, aurApp);
std::list<AuraScript::EffectApplyHandler>::iterator effEndItr = (*scritr)->OnEffectApply.end(), effItr = (*scritr)->OnEffectApply.begin();
for (; effItr != effEndItr; ++effItr)
{
if ((*effItr).IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
(*effItr).Call(*scritr, aurEff, mode);
}
if (effItr->IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
effItr->Call(*scritr, aurEff, mode);
if (!preventDefault)
preventDefault = (*scritr)->_IsDefaultActionPrevented();
(*scritr)->_FinishScriptCall();
}
return preventDefault;
}
@@ -1877,12 +1885,12 @@ bool Aura::CallScriptEffectRemoveHandlers(AuraEffect const* aurEff, AuraApplicat
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_REMOVE, aurApp);
std::list<AuraScript::EffectApplyHandler>::iterator effEndItr = (*scritr)->OnEffectRemove.end(), effItr = (*scritr)->OnEffectRemove.begin();
for (; effItr != effEndItr; ++effItr)
{
if ((*effItr).IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
(*effItr).Call(*scritr, aurEff, mode);
}
if (effItr->IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
effItr->Call(*scritr, aurEff, mode);
if (!preventDefault)
preventDefault = (*scritr)->_IsDefaultActionPrevented();
(*scritr)->_FinishScriptCall();
}
return preventDefault;
@@ -1895,10 +1903,9 @@ void Aura::CallScriptAfterEffectApplyHandlers(AuraEffect const* aurEff, AuraAppl
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_AFTER_APPLY, aurApp);
std::list<AuraScript::EffectApplyHandler>::iterator effEndItr = (*scritr)->AfterEffectApply.end(), effItr = (*scritr)->AfterEffectApply.begin();
for (; effItr != effEndItr; ++effItr)
{
if ((*effItr).IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
(*effItr).Call(*scritr, aurEff, mode);
}
if (effItr->IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
effItr->Call(*scritr, aurEff, mode);
(*scritr)->_FinishScriptCall();
}
}
@@ -1910,10 +1917,9 @@ void Aura::CallScriptAfterEffectRemoveHandlers(AuraEffect const* aurEff, AuraApp
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_AFTER_REMOVE, aurApp);
std::list<AuraScript::EffectApplyHandler>::iterator effEndItr = (*scritr)->AfterEffectRemove.end(), effItr = (*scritr)->AfterEffectRemove.begin();
for (; effItr != effEndItr; ++effItr)
{
if ((*effItr).IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
(*effItr).Call(*scritr, aurEff, mode);
}
if (effItr->IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
effItr->Call(*scritr, aurEff, mode);
(*scritr)->_FinishScriptCall();
}
}
@@ -1926,14 +1932,15 @@ bool Aura::CallScriptEffectPeriodicHandlers(AuraEffect const* aurEff, AuraApplic
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_PERIODIC, aurApp);
std::list<AuraScript::EffectPeriodicHandler>::iterator effEndItr = (*scritr)->OnEffectPeriodic.end(), effItr = (*scritr)->OnEffectPeriodic.begin();
for (; effItr != effEndItr; ++effItr)
{
if ((*effItr).IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
(*effItr).Call(*scritr, aurEff);
}
if (effItr->IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
effItr->Call(*scritr, aurEff);
if (!preventDefault)
preventDefault = (*scritr)->_IsDefaultActionPrevented();
(*scritr)->_FinishScriptCall();
}
return preventDefault;
}
@@ -1944,10 +1951,9 @@ void Aura::CallScriptEffectUpdatePeriodicHandlers(AuraEffect* aurEff)
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_UPDATE_PERIODIC);
std::list<AuraScript::EffectUpdatePeriodicHandler>::iterator effEndItr = (*scritr)->OnEffectUpdatePeriodic.end(), effItr = (*scritr)->OnEffectUpdatePeriodic.begin();
for (; effItr != effEndItr; ++effItr)
{
if ((*effItr).IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
(*effItr).Call(*scritr, aurEff);
}
if (effItr->IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
effItr->Call(*scritr, aurEff);
(*scritr)->_FinishScriptCall();
}
}
@@ -1959,10 +1965,9 @@ void Aura::CallScriptEffectCalcAmountHandlers(AuraEffect const* aurEff, int32 &
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_CALC_AMOUNT);
std::list<AuraScript::EffectCalcAmountHandler>::iterator effEndItr = (*scritr)->DoEffectCalcAmount.end(), effItr = (*scritr)->DoEffectCalcAmount.begin();
for (; effItr != effEndItr; ++effItr)
{
if ((*effItr).IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
(*effItr).Call(*scritr, aurEff, amount, canBeRecalculated);
}
if (effItr->IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
effItr->Call(*scritr, aurEff, amount, canBeRecalculated);
(*scritr)->_FinishScriptCall();
}
}
@@ -1974,10 +1979,9 @@ void Aura::CallScriptEffectCalcPeriodicHandlers(AuraEffect const* aurEff, bool &
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_CALC_PERIODIC);
std::list<AuraScript::EffectCalcPeriodicHandler>::iterator effEndItr = (*scritr)->DoEffectCalcPeriodic.end(), effItr = (*scritr)->DoEffectCalcPeriodic.begin();
for (; effItr != effEndItr; ++effItr)
{
if ((*effItr).IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
(*effItr).Call(*scritr, aurEff, isPeriodic, amplitude);
}
if (effItr->IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
effItr->Call(*scritr, aurEff, isPeriodic, amplitude);
(*scritr)->_FinishScriptCall();
}
}
@@ -1989,10 +1993,9 @@ void Aura::CallScriptEffectCalcSpellModHandlers(AuraEffect const* aurEff, SpellM
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_CALC_SPELLMOD);
std::list<AuraScript::EffectCalcSpellModHandler>::iterator effEndItr = (*scritr)->DoEffectCalcSpellMod.end(), effItr = (*scritr)->DoEffectCalcSpellMod.begin();
for (; effItr != effEndItr; ++effItr)
{
if ((*effItr).IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
(*effItr).Call(*scritr, aurEff, spellMod);
}
if (effItr->IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
effItr->Call(*scritr, aurEff, spellMod);
(*scritr)->_FinishScriptCall();
}
}
@@ -2004,11 +2007,13 @@ void Aura::CallScriptEffectAbsorbHandlers(AuraEffect* aurEff, AuraApplication co
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_ABSORB, aurApp);
std::list<AuraScript::EffectAbsorbHandler>::iterator effEndItr = (*scritr)->OnEffectAbsorb.end(), effItr = (*scritr)->OnEffectAbsorb.begin();
for (; effItr != effEndItr; ++effItr)
{
if ((*effItr).IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
(*effItr).Call(*scritr, aurEff, dmgInfo, absorbAmount);
}
defaultPrevented = (*scritr)->_IsDefaultActionPrevented();
if (effItr->IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
effItr->Call(*scritr, aurEff, dmgInfo, absorbAmount);
if (!defaultPrevented)
defaultPrevented = (*scritr)->_IsDefaultActionPrevented();
(*scritr)->_FinishScriptCall();
}
}
@@ -2020,10 +2025,9 @@ void Aura::CallScriptEffectAfterAbsorbHandlers(AuraEffect* aurEff, AuraApplicati
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_AFTER_ABSORB, aurApp);
std::list<AuraScript::EffectAbsorbHandler>::iterator effEndItr = (*scritr)->AfterEffectAbsorb.end(), effItr = (*scritr)->AfterEffectAbsorb.begin();
for (; effItr != effEndItr; ++effItr)
{
if ((*effItr).IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
(*effItr).Call(*scritr, aurEff, dmgInfo, absorbAmount);
}
if (effItr->IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
effItr->Call(*scritr, aurEff, dmgInfo, absorbAmount);
(*scritr)->_FinishScriptCall();
}
}
@@ -2035,10 +2039,9 @@ void Aura::CallScriptEffectManaShieldHandlers(AuraEffect* aurEff, AuraApplicatio
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_MANASHIELD, aurApp);
std::list<AuraScript::EffectManaShieldHandler>::iterator effEndItr = (*scritr)->OnEffectManaShield.end(), effItr = (*scritr)->OnEffectManaShield.begin();
for (; effItr != effEndItr; ++effItr)
{
if ((*effItr).IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
(*effItr).Call(*scritr, aurEff, dmgInfo, absorbAmount);
}
if (effItr->IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
effItr->Call(*scritr, aurEff, dmgInfo, absorbAmount);
(*scritr)->_FinishScriptCall();
}
}
@@ -2050,10 +2053,9 @@ void Aura::CallScriptEffectAfterManaShieldHandlers(AuraEffect* aurEff, AuraAppli
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_AFTER_MANASHIELD, aurApp);
std::list<AuraScript::EffectManaShieldHandler>::iterator effEndItr = (*scritr)->AfterEffectManaShield.end(), effItr = (*scritr)->AfterEffectManaShield.begin();
for (; effItr != effEndItr; ++effItr)
{
if ((*effItr).IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
(*effItr).Call(*scritr, aurEff, dmgInfo, absorbAmount);
}
if (effItr->IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
effItr->Call(*scritr, aurEff, dmgInfo, absorbAmount);
(*scritr)->_FinishScriptCall();
}
}
@@ -2065,26 +2067,27 @@ void Aura::CallScriptEffectSplitHandlers(AuraEffect* aurEff, AuraApplication con
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_SPLIT, aurApp);
std::list<AuraScript::EffectSplitHandler>::iterator effEndItr = (*scritr)->OnEffectSplit.end(), effItr = (*scritr)->OnEffectSplit.begin();
for (; effItr != effEndItr; ++effItr)
{
if ((*effItr).IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
(*effItr).Call(*scritr, aurEff, dmgInfo, splitAmount);
}
if (effItr->IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
effItr->Call(*scritr, aurEff, dmgInfo, splitAmount);
(*scritr)->_FinishScriptCall();
}
}
bool Aura::CallScriptCheckProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo)
{
bool result = true;
for (std::list<AuraScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
{
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_CHECK_PROC, aurApp);
std::list<AuraScript::CheckProcHandler>::iterator hookItrEnd = (*scritr)->DoCheckProc.end(), hookItr = (*scritr)->DoCheckProc.begin();
for (; hookItr != hookItrEnd; ++hookItr)
if (!(*hookItr).Call(*scritr, eventInfo))
return false;
result &= hookItr->Call(*scritr, eventInfo);
(*scritr)->_FinishScriptCall();
}
return true;
return result;
}
bool Aura::CallScriptPrepareProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo)
@@ -2095,12 +2098,14 @@ bool Aura::CallScriptPrepareProcHandlers(AuraApplication const* aurApp, ProcEven
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_PREPARE_PROC, aurApp);
std::list<AuraScript::AuraProcHandler>::iterator effEndItr = (*scritr)->DoPrepareProc.end(), effItr = (*scritr)->DoPrepareProc.begin();
for (; effItr != effEndItr; ++effItr)
(*effItr).Call(*scritr, eventInfo);
effItr->Call(*scritr, eventInfo);
if (prepare)
prepare = !(*scritr)->_IsDefaultActionPrevented();
if (prepare && (*scritr)->_IsDefaultActionPrevented())
prepare = false;
(*scritr)->_FinishScriptCall();
}
return prepare;
}
@@ -2111,7 +2116,8 @@ void Aura::CallScriptProcHandlers(AuraApplication const* aurApp, ProcEventInfo&
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_PROC, aurApp);
std::list<AuraScript::AuraProcHandler>::iterator hookItrEnd = (*scritr)->OnProc.end(), hookItr = (*scritr)->OnProc.begin();
for (; hookItr != hookItrEnd; ++hookItr)
(*hookItr).Call(*scritr, eventInfo);
hookItr->Call(*scritr, eventInfo);
(*scritr)->_FinishScriptCall();
}
}
@@ -2123,7 +2129,8 @@ void Aura::CallScriptAfterProcHandlers(AuraApplication const* aurApp, ProcEventI
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_AFTER_PROC, aurApp);
std::list<AuraScript::AuraProcHandler>::iterator hookItrEnd = (*scritr)->AfterProc.end(), hookItr = (*scritr)->AfterProc.begin();
for (; hookItr != hookItrEnd; ++hookItr)
(*hookItr).Call(*scritr, eventInfo);
hookItr->Call(*scritr, eventInfo);
(*scritr)->_FinishScriptCall();
}
}
@@ -2136,12 +2143,12 @@ bool Aura::CallScriptEffectProcHandlers(AuraEffect const* aurEff, AuraApplicatio
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_PROC, aurApp);
std::list<AuraScript::EffectProcHandler>::iterator effEndItr = (*scritr)->OnEffectProc.end(), effItr = (*scritr)->OnEffectProc.begin();
for (; effItr != effEndItr; ++effItr)
{
if ((*effItr).IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
(*effItr).Call(*scritr, aurEff, eventInfo);
}
if (effItr->IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
effItr->Call(*scritr, aurEff, eventInfo);
if (!preventDefault)
preventDefault = (*scritr)->_IsDefaultActionPrevented();
(*scritr)->_FinishScriptCall();
}
return preventDefault;
@@ -2154,10 +2161,9 @@ void Aura::CallScriptAfterEffectProcHandlers(AuraEffect const* aurEff, AuraAppli
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_AFTER_PROC, aurApp);
std::list<AuraScript::EffectProcHandler>::iterator effEndItr = (*scritr)->AfterEffectProc.end(), effItr = (*scritr)->AfterEffectProc.begin();
for (; effItr != effEndItr; ++effItr)
{
if ((*effItr).IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
(*effItr).Call(*scritr, aurEff, eventInfo);
}
if (effItr->IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
effItr->Call(*scritr, aurEff, eventInfo);
(*scritr)->_FinishScriptCall();
}
}
+1 -1
View File
@@ -3610,7 +3610,7 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)
unitTarget->CastSpell(unitTarget, iTmpSpellId, true);
Creature* npc = unitTarget->ToCreature();
npc->LoadEquipment(npc->GetEquipmentId());
npc->LoadEquipment();
return;
}
// Emblazon Runeblade
+6
View File
@@ -1188,6 +1188,12 @@ bool SpellInfo::IsMultiSlotAura() const
return IsPassive() || Id == 55849 || Id == 40075 || Id == 44413; // Power Spark, Fel Flak Fire, Incanter's Absorption
}
bool SpellInfo::IsStackableOnOneSlotWithDifferentCasters() const
{
/// TODO: Re-verify meaning of SPELL_ATTR3_STACK_FOR_DIFF_CASTERS and update conditions here
return StackAmount > 1 && !IsChanneled() && !(AttributesEx3 & SPELL_ATTR3_STACK_FOR_DIFF_CASTERS);
}
bool SpellInfo::IsDeathPersistent() const
{
return AttributesEx3 & SPELL_ATTR3_DEATH_PERSISTENT;
+1
View File
@@ -443,6 +443,7 @@ public:
bool IsStackableWithRanks() const;
bool IsPassiveStackableWithRanks() const;
bool IsMultiSlotAura() const;
bool IsStackableOnOneSlotWithDifferentCasters() const;
bool IsDeathPersistent() const;
bool IsRequiringDeadTarget() const;
bool IsAllowingDeadTarget() const;
+12 -1
View File
@@ -3354,6 +3354,17 @@ void SpellMgr::LoadSpellInfoCorrections()
case 64596: // Cosmic Smash (Algalon the Observer)
spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(6); // 100yd
break;
case 64014: // Expedition Base Camp Teleport
case 64024: // Conservatory Teleport
case 64025: // Halls of Invention Teleport
case 64028: // Colossal Forge Teleport
case 64029: // Shattered Walkway Teleport
case 64030: // Antechamber Teleport
case 64031: // Scrapyard Teleport
case 64032: // Formation Grounds Teleport
case 65042: // Prison of Yogg-Saron Teleport
spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DB);
break;
// ENDOF ULDUAR SPELLS
//
// TRIAL OF THE CRUSADER SPELLS
@@ -3447,7 +3458,7 @@ void SpellMgr::LoadSpellInfoCorrections()
case 71518: // Unholy Infusion Quest Credit (Professor Putricide)
case 72934: // Blood Infusion Quest Credit (Blood-Queen Lana'thel)
case 72289: // Frost Infusion Quest Credit (Sindragosa)
spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // another missing radius
spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // another missing radius
break;
case 71708: // Empowered Flare (Blood Prince Council)
case 72785: // Empowered Flare (Blood Prince Council)
+3
View File
@@ -222,6 +222,9 @@ bool Weather::UpdateWeather()
char const* wthstr;
switch (state)
{
case WEATHER_STATE_FOG:
wthstr = "fog";
break;
case WEATHER_STATE_LIGHT_RAIN:
wthstr = "light rain";
break;
+1 -1
View File
@@ -46,7 +46,7 @@ struct WeatherData
enum WeatherState
{
WEATHER_STATE_FINE = 0,
WEATHER_STATE_UNK = 1, // Used in some instance encounters.
WEATHER_STATE_FOG = 1, // Used in some instance encounters.
WEATHER_STATE_LIGHT_RAIN = 3,
WEATHER_STATE_MEDIUM_RAIN = 4,
WEATHER_STATE_HEAVY_RAIN = 5,
+4 -4
View File
@@ -979,7 +979,7 @@ void World::LoadConfigSettings(bool reload)
m_int_configs[CONFIG_CHATFLOOD_MESSAGE_DELAY] = ConfigMgr::GetIntDefault("ChatFlood.MessageDelay", 1);
m_int_configs[CONFIG_CHATFLOOD_MUTE_TIME] = ConfigMgr::GetIntDefault("ChatFlood.MuteTime", 10);
m_int_configs[CONFIG_EVENT_ANNOUNCE] = ConfigMgr::GetIntDefault("Event.Announce", 0);
m_bool_configs[CONFIG_EVENT_ANNOUNCE] = ConfigMgr::GetIntDefault("Event.Announce", false);
m_float_configs[CONFIG_CREATURE_FAMILY_FLEE_ASSISTANCE_RADIUS] = ConfigMgr::GetFloatDefault("CreatureFamilyFleeAssistanceRadius", 30.0f);
m_float_configs[CONFIG_CREATURE_FAMILY_ASSISTANCE_RADIUS] = ConfigMgr::GetFloatDefault("CreatureFamilyAssistanceRadius", 10.0f);
@@ -1445,12 +1445,12 @@ void World::SetInitialWorldSettings()
sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Creature Model Based Info Data...");
sObjectMgr->LoadCreatureModelInfo();
sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Equipment templates...");
sObjectMgr->LoadEquipmentTemplates();
sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Creature templates...");
sObjectMgr->LoadCreatureTemplates();
sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Equipment templates..."); // must be after LoadCreatureTemplates
sObjectMgr->LoadEquipmentTemplates();
sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Creature template addons...");
sObjectMgr->LoadCreatureTemplateAddons();
+1 -1
View File
@@ -174,6 +174,7 @@ enum WorldBoolConfigs
CONFIG_WINTERGRASP_ENABLE,
CONFIG_GUILD_LEVELING_ENABLED,
CONFIG_UI_QUESTLEVELS_IN_DIALOGS, // Should we add quest levels to the title in the NPC dialogs?
CONFIG_EVENT_ANNOUNCE,
BOOL_CONFIG_VALUE_COUNT
};
@@ -265,7 +266,6 @@ enum WorldIntConfigs
CONFIG_CHATFLOOD_MESSAGE_COUNT,
CONFIG_CHATFLOOD_MESSAGE_DELAY,
CONFIG_CHATFLOOD_MUTE_TIME,
CONFIG_EVENT_ANNOUNCE,
CONFIG_CREATURE_FAMILY_ASSISTANCE_DELAY,
CONFIG_CREATURE_FAMILY_FLEE_DELAY,
CONFIG_WORLD_BOSS_LEVEL_DIFF,
+1
View File
@@ -649,6 +649,7 @@ public:
handler->PSendSysMessage(LANG_NPCINFO_CHAR, target->GetDBTableGUIDLow(), target->GetGUIDLow(), faction, npcflags, Entry, displayid, nativeid);
handler->PSendSysMessage(LANG_NPCINFO_LEVEL, target->getLevel());
handler->PSendSysMessage(LANG_NPCINFO_EQUIPMENT, target->GetCurrentEquipmentId(), target->GetOriginalEquipmentId());
handler->PSendSysMessage(LANG_NPCINFO_HEALTH, target->GetCreateHealth(), target->GetMaxHealth(), target->GetHealth());
handler->PSendSysMessage(LANG_NPCINFO_FLAGS, target->GetUInt32Value(UNIT_FIELD_FLAGS), target->GetUInt32Value(UNIT_DYNAMIC_FLAGS), target->getFaction());
handler->PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(), curRespawnDelayStr.c_str());
+3 -4
View File
@@ -495,10 +495,9 @@ public:
cInfo->questItems[5] = fields[78].GetUInt32();
cInfo->movementId = fields[79].GetUInt32();
cInfo->RegenHealth = fields[80].GetBool();
cInfo->equipmentId = fields[81].GetUInt32();
cInfo->MechanicImmuneMask = fields[82].GetUInt32();
cInfo->flags_extra = fields[83].GetUInt32();
cInfo->ScriptID = sObjectMgr->GetScriptId(fields[84].GetCString());
cInfo->MechanicImmuneMask = fields[81].GetUInt32();
cInfo->flags_extra = fields[82].GetUInt32();
cInfo->ScriptID = sObjectMgr->GetScriptId(fields[83].GetCString());
sObjectMgr->CheckCreatureTemplate(cInfo);
}
@@ -32,12 +32,20 @@ enum Say
SAY_LEASH = 1,
};
enum Events
{
EVENT_CLEAVE = 1,
EVENT_MORTAL_STRIKE = 2,
EVENT_BLAST_WAVE = 3,
EVENT_KNOCK_BACK = 4,
};
enum Spells
{
SPELL_CLEAVE = 26350,
SPELL_BLASTWAVE = 23331,
SPELL_MORTALSTRIKE = 24573,
SPELL_KNOCKBACK = 25778
SPELL_BLAST_WAVE = 23331,
SPELL_MORTAL_STRIKE = 24573,
SPELL_KNOCK_BACK = 25778
};
class boss_broodlord : public CreatureScript
@@ -54,17 +62,13 @@ public:
{
boss_broodlordAI(Creature* creature) : ScriptedAI(creature) {}
uint32 Cleave_Timer;
uint32 BlastWave_Timer;
uint32 MortalStrike_Timer;
uint32 KnockBack_Timer;
void Reset()
{
Cleave_Timer = 8000; // These times are probably wrong
BlastWave_Timer = 12000;
MortalStrike_Timer = 20000;
KnockBack_Timer = 30000;
// These timers are probably wrong
events.ScheduleEvent(EVENT_CLEAVE, 8000);
events.ScheduleEvent(EVENT_BLAST_WAVE, 12000);
events.ScheduleEvent(EVENT_MORTAL_STRIKE, 20000);
events.ScheduleEvent(EVENT_KNOCK_BACK, 30000);
}
void EnterCombat(Unit* /*who*/)
@@ -78,45 +82,51 @@ public:
if (!UpdateVictim())
return;
//Cleave_Timer
if (Cleave_Timer <= diff)
{
DoCast(me->getVictim(), SPELL_CLEAVE);
Cleave_Timer = 7000;
} else Cleave_Timer -= diff;
if (EnterEvadeIfOutOfCombatArea(diff))
Talk(SAY_LEASH);
// BlastWave
if (BlastWave_Timer <= diff)
{
DoCast(me->getVictim(), SPELL_BLASTWAVE);
BlastWave_Timer = urand(8000, 16000);
} else BlastWave_Timer -= diff;
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
//MortalStrike_Timer
if (MortalStrike_Timer <= diff)
while (uint32 eventId = events.ExecuteEvent())
{
DoCast(me->getVictim(), SPELL_MORTALSTRIKE);
MortalStrike_Timer = urand(25000, 35000);
} else MortalStrike_Timer -= diff;
if (KnockBack_Timer <= diff)
{
if (Unit* target = me->getVictim())
switch (eventId)
{
DoCast(target, SPELL_KNOCKBACK);
// Drop 50% aggro
if (DoGetThreat(target))
DoModifyThreatPercent(target, -50);
case EVENT_CLEAVE:
DoCastVictim(SPELL_CLEAVE);
events.ScheduleEvent(EVENT_CLEAVE, 8000);
break;
case EVENT_MORTAL_STRIKE:
DoCastVictim(SPELL_MORTAL_STRIKE);
events.ScheduleEvent(EVENT_MORTAL_STRIKE, 20000);
break;
case EVENT_BLAST_WAVE:
DoCastVictim(SPELL_BLAST_WAVE);
events.ScheduleEvent(EVENT_BLAST_WAVE, 12000);
break;
case EVENT_KNOCK_BACK:
if (Unit* target = me->getVictim())
{
DoCast(target, SPELL_BLAST_WAVE);
// Drop 50% of threat
if (DoGetThreat(target))
DoModifyThreatPercent(target, -50);
}
events.ScheduleEvent(EVENT_KNOCK_BACK, 30000);
break;
default:
break;
}
KnockBack_Timer = urand(15000, 30000);
} else KnockBack_Timer -= diff;
}
if (EnterEvadeIfOutOfCombatArea(diff))
Talk(SAY_LEASH);
DoMeleeAttackIfReady();
}
private:
EventMap events; /// @todo: change BWL to instance script and bosses to BossAI
};
};
@@ -102,10 +102,8 @@ public:
npc_unworthy_initiateAI(Creature* creature) : ScriptedAI(creature)
{
me->SetReactState(REACT_PASSIVE);
if (!me->GetEquipmentId())
if (const CreatureTemplate* info = sObjectMgr->GetCreatureTemplate(28406))
if (info->equipmentId)
const_cast<CreatureTemplate*>(me->GetCreatureTemplate())->equipmentId = info->equipmentId;
if (!me->GetCurrentEquipmentId())
me->SetCurrentEquipmentId(me->GetOriginalEquipmentId());
}
uint64 playerGUID;
@@ -237,7 +237,7 @@ public:
case 2:
me->SetStandState(UNIT_STAND_STATE_STAND);
DoCast(me, SPELL_KOLTIRA_TRANSFORM);
me->LoadEquipment(me->GetEquipmentId());
me->LoadEquipment();
break;
case 3:
SetEscortPaused(true);
@@ -185,7 +185,7 @@ public:
++_summonDeaths;
if (_summonDeaths == 11) // All summons died
{
SendWeather(WEATHER_STATE_UNK, 0.0f);
SendWeather(WEATHER_STATE_FOG, 0.0f);
me->RemoveAurasDueToSpell(SPELL_PTAH_EXPLOSION);
events.SetPhase(PHASE_NORMAL);
events.ScheduleEvent(EVENT_RAGING_SMASH, urand(7000, 12000), 0, PHASE_NORMAL);
@@ -107,7 +107,7 @@ public:
}
}
};
CreatureAI* GetAI(Creature* creature) const
{
return new npc_aged_dying_ancient_kodoAI(creature);
@@ -45,11 +45,13 @@ enum Spells
SPELL_SHROUD_OF_SORROW = 70986,
SPELL_FRENZIED_BLOODTHIRST_VISUAL = 71949,
SPELL_VAMPIRIC_BITE = 71726,
SPELL_VAMPIRIC_BITE_DUMMY = 71837,
SPELL_ESSENCE_OF_THE_BLOOD_QUEEN_PLR = 70879,
SPELL_ESSENCE_OF_THE_BLOOD_QUEEN_HEAL = 70872,
SPELL_FRENZIED_BLOODTHIRST = 70877,
SPELL_UNCONTROLLABLE_FRENZY = 70923,
SPELL_PRESENCE_OF_THE_DARKFALLEN = 71952,
SPELL_PRESENCE_OF_THE_DARKFALLEN = 70994,
SPELL_PRESENCE_OF_THE_DARKFALLEN_2 = 71952,
SPELL_BLOOD_MIRROR_DAMAGE = 70821,
SPELL_BLOOD_MIRROR_VISUAL = 71510,
SPELL_BLOOD_MIRROR_DUMMY = 70838,
@@ -88,6 +90,7 @@ uint32 const vampireAuras[3][MAX_DIFFICULTY] =
#define ESSENCE_OF_BLOOD_QUEEN_PLR RAID_MODE<uint32>(70879, 71525, 71530, 71531)
#define FRENZIED_BLOODTHIRST RAID_MODE<uint32>(70877, 71474, 70877, 71474)
#define DELIRIOUS_SLASH RAID_MODE<uint32>(71623, 71624, 71625, 71626)
#define PRESENCE_OF_THE_DARKFALLEN RAID_MODE<uint32>(70994, 71962, 71963, 71964)
enum Events
{
@@ -220,6 +223,7 @@ class boss_blood_queen_lana_thel : public CreatureScript
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_BLOOD_MIRROR_DUMMY);
instance->DoRemoveAurasDueToSpellOnPlayers(DELIRIOUS_SLASH);
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_PACT_OF_THE_DARKFALLEN);
instance->DoRemoveAurasDueToSpellOnPlayers(PRESENCE_OF_THE_DARKFALLEN);
}
void DoAction(int32 const action)
@@ -357,8 +361,11 @@ class boss_blood_queen_lana_thel : public CreatureScript
{
Unit* target = targets.front();
DoCast(target, SPELL_VAMPIRIC_BITE);
DoCastAOE(SPELL_VAMPIRIC_BITE_DUMMY, true);
Talk(SAY_VAMPIRIC_BITE);
_vampires.insert(target->GetGUID());
target->CastSpell(target, SPELL_PRESENCE_OF_THE_DARKFALLEN, TRIGGERED_FULL_MASK);
target->CastSpell(target, SPELL_PRESENCE_OF_THE_DARKFALLEN_2, TRIGGERED_FULL_MASK);
}
break;
}
@@ -377,9 +384,10 @@ class boss_blood_queen_lana_thel : public CreatureScript
_offtank->CastSpell(me->getVictim(), SPELL_BLOOD_MIRROR_DAMAGE, true);
me->getVictim()->CastSpell(_offtank, SPELL_BLOOD_MIRROR_DUMMY, true);
DoCastVictim(SPELL_BLOOD_MIRROR_VISUAL);
if (Item* shadowsEdge = _offtank->GetWeaponForAttack(BASE_ATTACK, true))
if (!_offtank->HasAura(SPELL_THIRST_QUENCHED) && shadowsEdge->GetEntry() == ITEM_SHADOW_S_EDGE && !_offtank->HasAura(SPELL_GUSHING_WOUND))
_offtank->CastSpell(_offtank, SPELL_GUSHING_WOUND, true);
if (Is25ManRaid() && _offtank->GetQuestStatus(QUEST_BLOOD_INFUSION) == QUEST_STATUS_INCOMPLETE &&
_offtank->HasAura(SPELL_UNSATED_CRAVING) && !_offtank->HasAura(SPELL_THIRST_QUENCHED) &&
!_offtank->HasAura(SPELL_GUSHING_WOUND))
_offtank->CastSpell(_offtank, SPELL_GUSHING_WOUND, TRIGGERED_FULL_MASK);
}
}
@@ -396,13 +404,7 @@ class boss_blood_queen_lana_thel : public CreatureScript
{
std::list<Player*> targets;
SelectRandomTarget(false, &targets);
uint32 targetCount = 2;
// do not combine these checks! we want it incremented TWICE when both conditions are met
if (IsHeroic())
++targetCount;
if (Is25ManRaid())
++targetCount;
Trinity::Containers::RandomResizeList<Player*>(targets, targetCount);
Trinity::Containers::RandomResizeList(targets, Is25ManRaid() ? 3 : 2);
if (targets.size() > 1)
{
Talk(SAY_PACT_OF_THE_DARKFALLEN);
@@ -554,33 +556,36 @@ class spell_blood_queen_vampiric_bite : public SpellScriptLoader
uint32 spellId = sSpellMgr->GetSpellIdForDifficulty(SPELL_FRENZIED_BLOODTHIRST, GetCaster());
GetCaster()->RemoveAura(spellId, 0, 0, AURA_REMOVE_BY_ENEMY_SPELL);
GetCaster()->CastSpell(GetCaster(), SPELL_ESSENCE_OF_THE_BLOOD_QUEEN_PLR, true);
// Presence of the Darkfallen buff on Blood-Queen
if (GetCaster()->GetMap()->IsHeroic())
GetCaster()->CastSpell(GetCaster(), SPELL_PRESENCE_OF_THE_DARKFALLEN, true);
GetCaster()->CastSpell(GetCaster(), SPELL_ESSENCE_OF_THE_BLOOD_QUEEN_PLR, TRIGGERED_FULL_MASK);
// Shadowmourne questline
if (GetCaster()->ToPlayer()->GetQuestStatus(QUEST_BLOOD_INFUSION) == QUEST_STATUS_INCOMPLETE)
if (Aura* aura = GetCaster()->GetAura(SPELL_GUSHING_WOUND))
{
if (Aura* aura = GetCaster()->GetAura(SPELL_GUSHING_WOUND))
if (aura->GetStackAmount() == 3)
{
if (aura->GetStackAmount() == 3)
{
GetCaster()->CastSpell(GetCaster(), SPELL_THIRST_QUENCHED, true);
GetCaster()->RemoveAura(aura);
}
else
GetCaster()->CastSpell(GetCaster(), SPELL_GUSHING_WOUND, true);
GetCaster()->CastSpell(GetCaster(), SPELL_THIRST_QUENCHED, TRIGGERED_FULL_MASK);
GetCaster()->RemoveAura(aura);
}
else
GetCaster()->CastSpell(GetCaster(), SPELL_GUSHING_WOUND, TRIGGERED_FULL_MASK);
}
if (InstanceScript* instance = GetCaster()->GetInstanceScript())
if (Creature* bloodQueen = ObjectAccessor::GetCreature(*GetCaster(), instance->GetData64(DATA_BLOOD_QUEEN_LANA_THEL)))
bloodQueen->AI()->SetGUID(GetHitUnit()->GetGUID(), GUID_VAMPIRE);
}
void HandlePresence(SpellEffIndex /*effIndex*/)
{
GetHitUnit()->CastSpell(GetHitUnit(), SPELL_PRESENCE_OF_THE_DARKFALLEN, TRIGGERED_FULL_MASK);
GetHitUnit()->CastSpell(GetHitUnit(), SPELL_PRESENCE_OF_THE_DARKFALLEN_2, TRIGGERED_FULL_MASK);
}
void Register()
{
OnCheckCast += SpellCheckCastFn(spell_blood_queen_vampiric_bite_SpellScript::CheckTarget);
BeforeHit += SpellHitFn(spell_blood_queen_vampiric_bite_SpellScript::OnCast);
OnEffectHitTarget += SpellEffectFn(spell_blood_queen_vampiric_bite_SpellScript::HandlePresence, EFFECT_1, SPELL_EFFECT_TRIGGER_SPELL);
}
};
@@ -84,7 +84,9 @@ enum Spells
SPELL_CONCUSSIVE_SHOCK = 71337,
// Frost Infusion
SPELL_FROST_INFUSION_CREDIT = 72289
SPELL_FROST_INFUSION_CREDIT = 72289,
SPELL_FROST_IMBUED_BLADE = 72290,
SPELL_FROST_INFUSION = 72292,
};
enum Events
@@ -147,11 +149,7 @@ enum MovementPoints
enum Shadowmourne
{
QUEST_FROST_INFUSION = 24757,
ITEM_SHADOW_S_EDGE = 49888,
SPELL_FROST_INFUSION = 72292,
SPELL_FROST_IMBUED_BLADE = 72290,
QUEST_FROST_INFUSION = 24757
};
Position const RimefangFlyPos = {4413.309f, 2456.421f, 233.3795f, 2.890186f};
@@ -390,47 +388,10 @@ class boss_sindragosa : public CreatureScript
void SpellHitTarget(Unit* target, SpellInfo const* spell)
{
if (uint32 spellId = sSpellMgr->GetSpellIdForDifficulty(70127, me))
{
if (spellId == spell->Id)
{
if (Aura const* mysticBuffet = target->GetAura(spell->Id))
_mysticBuffetStack = std::max<uint8>(_mysticBuffetStack, mysticBuffet->GetStackAmount());
return;
}
}
// Frost Infusion
if (Player* player = target->ToPlayer())
{
if (uint32 spellId = sSpellMgr->GetSpellIdForDifficulty(_isThirdPhase ? SPELL_FROST_BREATH_P2 : SPELL_FROST_BREATH_P1, me))
{
if (spellId == spell->Id)
{
Item* shadowsEdge = player->GetWeaponForAttack(BASE_ATTACK, true);
if (player->GetQuestStatus(QUEST_FROST_INFUSION) == QUEST_STATUS_INCOMPLETE && shadowsEdge)
{
if (!player->HasAura(SPELL_FROST_IMBUED_BLADE) && shadowsEdge->GetEntry() == ITEM_SHADOW_S_EDGE)
{
if (Aura* infusion = player->GetAura(SPELL_FROST_INFUSION))
{
if (infusion->GetStackAmount() == 3)
{
player->CastSpell(player, SPELL_FROST_IMBUED_BLADE, true);
player->RemoveAura(infusion);
}
else
player->CastSpell(player, SPELL_FROST_INFUSION, true);
}
else
player->CastSpell(player, SPELL_FROST_INFUSION, true);
}
}
return;
}
}
}
}
void UpdateAI(uint32 const diff)
@@ -1155,6 +1116,50 @@ class spell_sindragosa_unchained_magic : public SpellScriptLoader
}
};
class spell_sindragosa_frost_breath : public SpellScriptLoader
{
public:
spell_sindragosa_frost_breath() : SpellScriptLoader("spell_sindragosa_frost_breath") { }
class spell_sindragosa_frost_breath_SpellScript : public SpellScript
{
PrepareSpellScript(spell_sindragosa_frost_breath_SpellScript);
void HandleInfusion()
{
Player* target = GetHitPlayer();
if (!target)
return;
if (target->GetQuestStatus(QUEST_FROST_INFUSION) != QUEST_STATUS_INCOMPLETE)
return;
// Check if player has Shadow's Edge equipped and not ready for infusion
if (!target->HasAura(SPELL_UNSATED_CRAVING) || target->HasAura(SPELL_FROST_IMBUED_BLADE))
return;
Aura* infusion = target->GetAura(SPELL_FROST_INFUSION, target->GetGUID());
if (infusion && infusion->GetStackAmount() >= 3)
{
target->RemoveAura(infusion);
target->CastSpell(target, SPELL_FROST_IMBUED_BLADE, TRIGGERED_FULL_MASK);
}
else
target->CastSpell(target, SPELL_FROST_INFUSION, TRIGGERED_FULL_MASK);
}
void Register()
{
AfterHit += SpellHitFn(spell_sindragosa_frost_breath_SpellScript::HandleInfusion);
}
};
SpellScript* GetSpellScript() const
{
return new spell_sindragosa_frost_breath_SpellScript();
}
};
class spell_sindragosa_instability : public SpellScriptLoader
{
public:
@@ -1577,6 +1582,7 @@ void AddSC_boss_sindragosa()
new npc_sindragosa_trash();
new spell_sindragosa_s_fury();
new spell_sindragosa_unchained_magic();
new spell_sindragosa_frost_breath();
new spell_sindragosa_instability();
new spell_sindragosa_frost_beacon();
new spell_sindragosa_ice_tomb();
@@ -56,6 +56,7 @@ enum SharedSpells
SPELL_FROSTMOURNE_TELEPORT_VISUAL = 73078,
// Shadowmourne questline
SPELL_UNSATED_CRAVING = 71168,
SPELL_SHADOWS_FATE = 71169
};
@@ -435,7 +435,7 @@ class instance_icecrown_citadel : public InstanceMapScript
// these 2 gates are functional only on 25man modes
case GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_01:
case GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_04:
if (instance->GetSpawnMode() & 1)
if (instance->Is25ManRaid())
AddDoor(go, true);
break;
case GO_LADY_DEATHWHISPER_ELEVATOR:
@@ -565,10 +565,6 @@ class instance_ulduar : public InstanceMapScript
}
HandleGameObject(KologarnBridgeGUID, false);
}
if (state == IN_PROGRESS)
HandleGameObject(KologarnDoorGUID, false);
else
HandleGameObject(KologarnDoorGUID, true);
break;
case BOSS_HODIR:
if (state == DONE)
@@ -316,7 +316,7 @@ public:
me->SetDisplayId(MODEL_NIGHTELF);
// and reseting equipment
me->LoadEquipment(me->GetEquipmentId());
me->LoadEquipment();
if (instance && instance->GetData64(DATA_LEOTHERAS_EVENT_STARTER))
{
@@ -410,7 +410,7 @@ public:
if (me->HasAura(AURA_BANISH))
return;
me->LoadEquipment(me->GetEquipmentId());
me->LoadEquipment();
}
void UpdateAI(const uint32 diff)
@@ -558,7 +558,7 @@ public:
{
//switch to nightelf form
me->SetDisplayId(MODEL_NIGHTELF);
me->LoadEquipment(me->GetEquipmentId());
me->LoadEquipment();
CastConsumingMadness();
DespawnDemon();
@@ -589,7 +589,7 @@ public:
Talk(SAY_FINAL_FORM);
me->SetDisplayId(MODEL_NIGHTELF);
me->LoadEquipment(me->GetEquipmentId());
me->LoadEquipment();
}
}
};
+42 -29
View File
@@ -813,7 +813,40 @@ class spell_item_scroll_of_recall : public SpellScriptLoader
enum ShadowsFate
{
SPELL_SOUL_FEAST = 71203,
QUEST_A_FEAST_OF_SOULS = 24547
};
class spell_item_unsated_craving : public SpellScriptLoader
{
public:
spell_item_unsated_craving() : SpellScriptLoader("spell_item_unsated_craving") { }
class spell_item_unsated_craving_AuraScript : public AuraScript
{
PrepareAuraScript(spell_item_unsated_craving_AuraScript);
bool CheckProc(ProcEventInfo& procInfo)
{
Unit* caster = procInfo.GetActor();
if (!caster || caster->GetTypeId() != TYPEID_PLAYER)
return false;
Unit* target = procInfo.GetActionTarget();
if (!target || target->GetTypeId() != TYPEID_UNIT || target->GetCreatureType() == CREATURE_TYPE_CRITTER || target->isSummon())
return false;
return true;
}
void Register()
{
DoCheckProc += AuraCheckProcFn(spell_item_unsated_craving_AuraScript::CheckProc);
}
};
AuraScript* GetAuraScript() const
{
return new spell_item_unsated_craving_AuraScript();
}
};
class spell_item_shadows_fate : public SpellScriptLoader
@@ -825,41 +858,20 @@ class spell_item_shadows_fate : public SpellScriptLoader
{
PrepareAuraScript(spell_item_shadows_fate_AuraScript);
bool Validate(SpellInfo const* /*spellInfo*/)
void HandleProc(ProcEventInfo& procInfo)
{
if (!sSpellMgr->GetSpellInfo(SPELL_SOUL_FEAST))
return false;
if (!sObjectMgr->GetQuestTemplate(QUEST_A_FEAST_OF_SOULS))
return false;
return true;
}
Unit* caster = procInfo.GetActor();
Unit* target = GetCaster();
if (!caster || !target)
return;
bool Load()
{
_procTarget = NULL;
return true;
}
bool CheckProc(ProcEventInfo& /*eventInfo*/)
{
_procTarget = GetCaster();
return _procTarget && _procTarget->GetTypeId() == TYPEID_PLAYER && _procTarget->ToPlayer()->GetQuestStatus(QUEST_A_FEAST_OF_SOULS) == QUEST_STATUS_INCOMPLETE;
}
void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/)
{
PreventDefaultAction();
GetTarget()->CastSpell(_procTarget, SPELL_SOUL_FEAST, true);
caster->CastSpell(target, SPELL_SOUL_FEAST, TRIGGERED_FULL_MASK);
}
void Register()
{
DoCheckProc += AuraCheckProcFn(spell_item_shadows_fate_AuraScript::CheckProc);
OnEffectProc += AuraEffectProcFn(spell_item_shadows_fate_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY);
OnProc += AuraProcFn(spell_item_shadows_fate_AuraScript::HandleProc);
}
private:
Unit* _procTarget;
};
AuraScript* GetAuraScript() const
@@ -2481,6 +2493,7 @@ void AddSC_item_spell_scripts()
new spell_item_piccolo_of_the_flaming_fire();
new spell_item_savory_deviate_delight();
new spell_item_scroll_of_recall();
new spell_item_unsated_craving();
new spell_item_shadows_fate();
new spell_item_shadowmourne();
new spell_item_shadowmourne_soul_fragment();
@@ -78,7 +78,7 @@ void WorldDatabaseConnection::DoPrepareStatements()
PrepareStatement(WORLD_INS_CREATURE_TRANSPORT, "INSERT INTO creature_transport (guid, npc_entry, transport_entry, TransOffsetX, TransOffsetY, TransOffsetZ, TransOffsetO) values (?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(WORLD_UPD_CREATURE_TRANSPORT_EMOTE, "UPDATE creature_transport SET emote = ? WHERE transport_entry = ? AND guid = ?", CONNECTION_ASYNC);
PrepareStatement(WORLD_SEL_COMMANDS, "SELECT name, security, help FROM command", CONNECTION_SYNCH);
PrepareStatement(WORLD_SEL_CREATURE_TEMPLATE, "SELECT difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction_A, faction_H, npcflag, speed_walk, speed_run, scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, unit_flags2, dynamicflags, family, trainer_type, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, type_flags, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, Health_mod, Mana_mod, Mana_mod_extra, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, movementId, RegenHealth, equipment_id, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ?", CONNECTION_SYNCH);
PrepareStatement(WORLD_SEL_CREATURE_TEMPLATE, "SELECT difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction_A, faction_H, npcflag, speed_walk, speed_run, scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, unit_flags2, dynamicflags, family, trainer_type, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, type_flags, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, Health_mod, Mana_mod, Mana_mod_extra, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, movementId, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ?", CONNECTION_SYNCH);
PrepareStatement(WORLD_SEL_WAYPOINT_SCRIPT_BY_ID, "SELECT guid, delay, command, datalong, datalong2, dataint, x, y, z, o FROM waypoint_scripts WHERE id = ?", CONNECTION_SYNCH);
PrepareStatement(WORLD_SEL_IP2NATION_COUNTRY, "SELECT c.country FROM ip2nationCountries c, ip2nation i WHERE i.ip < ? AND c.code = i.country ORDER BY i.ip DESC LIMIT 0,1", CONNECTION_SYNCH);
PrepareStatement(WORLD_SEL_ITEM_TEMPLATE_BY_NAME, "SELECT entry FROM item_template WHERE name = ?", CONNECTION_SYNCH);
+9 -1
View File
@@ -1028,7 +1028,7 @@ Event.Announce = 0
#
# BeepAtStart
# Description: Beep when the world server finished starting (Unix/Linux systems).
# Description: Beep when the world server finished starting.
# Default: 1 - (Enabled)
# 0 - (Disabled)
@@ -1093,6 +1093,14 @@ DBC.EnforceItemAttributes = 1
AccountInstancesPerHour = 5
#
# RBAC.DefaultGroups
# Description: Comma separated list of groups to be added to any account
# Check auth.rbac_groups for correct ids
# Default: "" (No group)
RBAC.DefaultGroups = ""
#
###################################################################################################
+3 -1
View File
@@ -12,4 +12,6 @@ add_subdirectory(map_extractor)
add_subdirectory(vmap4_assembler)
add_subdirectory(vmap4_extractor)
add_subdirectory(mmaps_generator)
# add_subdirectory(mesh_extractor)
#if (WITH_MESHEXTRACTOR)
# add_subdirectory(mesh_extractor)
#endif()